Написал небольшой классик для перекодирования PHP массивов и объектов с любыми данными (за исключением ресурсов конечно) в JSON. PHP: <?php class JSONHelper { var $match = array('"', '\\', '/', "\n", "\r"); var $replace = array('\"', '\\\\', '\/', '\\n', '\\r'); /** * Object constructor * * @return JSONHelper */ function JSONHelper () { return $this; } //----------------------------------------------------------------------------- /** * Parse structure to JSON * * @param mixed $data * @return string */ function parse($data) { return '('.$this->encode($data).')'; } //----------------------------------------------------------------------------- /** * Converts PHP variable to JSON string * Can convert any PHP variable with any content to correct JSON structure * * @param mixed $data Data to convert * @return string */ function encode($data) { $type = $this->getType($data); switch ($type) { case 'object': $data = '{'.$this->processData($data, $type).'}'; break; case 'array': $data = '['.$this->processData($data, $type).']'; break; case 'number': $data = $data; break; case 'string': $data = '"'.$this->escape($data).'"'; break; case 'boolean': $data = ($data) ? 'true' : 'false'; break; case 'null': $data = 'null'; break; } return $data; } //----------------------------------------------------------------------------- /** * Enter description here... * * @param unknown_type $input * @param unknown_type $type * @return unknown */ function processData($data, $type) { $output = Array(); // If data is an object - it should be converted as a key => value pair if ($type == 'object'){ foreach($data as $key => $value) { $output[] = '"'.$key.'": '.$this->encode($value); } } else { foreach($data as $key => $value) { $output[] = $this->encode($value); } } return implode(',', $output);; } //----------------------------------------------------------------------------- /** * Function determines type of variable * * @param unknown_type $data * @return unknown */ function getType(&$data){ if (is_object($data)) { $type = 'object'; } elseif (is_array($data)) { // If array is assoc it should be processed as an object if($this->is_assoc($data)) { $type = 'object'; } else { $type = 'array'; } } elseif (is_numeric($data)) { $type = 'number'; } elseif(is_string($data)) { $type = 'string'; } elseif(is_bool($data)) { $type = 'boolean'; } elseif(is_null($data)) { $type = 'null'; } else { $type = 'string'; } return $type; } //----------------------------------------------------------------------------- /** * Function determines if array is associative * * @param array $array * @return bool */ function is_assoc($array) { // We do that by sorting array keys in reverse (numbers go before other symbols) // and probing first element key. 99.9% it will be a string key. krsort($array, SORT_STRING); return !is_numeric(key($array)); } //----------------------------------------------------------------------------- /** * Escapes special characters * Function escapes ", \, /, \n and \r symbols so that not to cause JavaScript error or * data loss * * @param string $string * @return string */ function escape($string) { return str_replace($this->match, $this->replace, $string); } //----------------------------------------------------------------------------- } Использовать проще пареной репы PHP: <?php $array = Array(10, 20, Array('bla' => 'blabla', 'blah' => 'double bla'), Array('asdfc23434', '3435435'); $json = new JSONHelper(); echo $json->parse($array); Всё что надо сделать на стороне JS это [js]var phpData = eval(responce.responseText);[/js]
Ивашка Оно даже не работает на таком массиве: PHP: <?php $array = Array("blablabla" => Array(10, 20, Array('bla' => 'blabla', 'blah' => 'double bla'), Array('asdfc23434', '3435435')), "sdfcasdf", "asdfdsf", false); 1). Invalid label получается, потому что JSON строку необходимо заключать в ( ). 2). Числовые значения в " " в JS не переводятся автоматом из строк в числа, вы явно не знаете систему кастинга в JS. что будет string + integer в JS ? Будет тоже самое что string . integer в PHP - они склеятся так как операция + в JavaScript является как сложением, так и слиянием строк. 3). Нам явно не нужно str_replace для integer и float. 4). Зачем для $k (key) вызывать рекурсивно php2js... ? Ну и есть пара глупостей которые больше относятся к стилю написания, к примеру явная несуразица с применением for и деланием count масиву на каждой итерации... PHP: <?php foreach ($a as $key => &$value) { if (is_string($key)) { $isList; break; } }
В общем, так. Да ну? PHP: <? $array = Array("blablabla" => Array(10, 20, Array('bla' => 'blabla', 'blah' => 'double bla'), Array('asdfc23434', '3435435')), "sdfcasdf", "asdfdsf", false); ?><script type="text/javascript"> //<![CDATA[ var response = '<?=php2js($array)?>'; // типа с сервера пришло var o = null; eval('o = '+response); alert(o.blablabla[2].bla); //]]> </script> У меня выдает "blabla" а у вас? Сфигали? Т.е. так ли оно необходимо? [js]var a = {}; var b = ({}); [/js] Наличие ExpressionStatement во втором случае нам ничего не дает. Да и при желании, дописать две скобочки мы всегда можем. Я в курсе С php так работать удобнее, и дурные ошибки не будут вылезать Т.е. по вашему, 123.45 и 123,45 js-интерпретатор разберет как одно и то-же число? Ну хотя бы затем, что $k может содержать что-нибудь из $jsonReplaces. Насчет стиля оспаривать не буду да и не в этом дело. Я просто хотел сказать, что все можно сделать гораздо проще.
я бы посоветовал все-таки $json = JSONHelper:arse($a); коротко и ясно. а то создай экземпляр, вызови метод. операция атомарная. по уму вообще функцией все сделать, что люди и делают. ггг
440Hz А ты глянь PEAR Serices_JSON... По сути писал как часть системы - там объектами всё. Выложил как было. Кому надо - заюзает, кто захочет - переделает.
1. не везде есть PHP > 3, так давайте писать на Brainfuck? 2. utf-8 давно уже очень стандартная кодировка де-факто Нативное расширение для PHP приоритетный выбор для решения вопроса. Темболее