Запретить цитирование определенных значений с помощью PHP json_encode () - PullRequest
5 голосов
/ 16 марта 2011

При использовании PHP-json_encode для кодирования массива в виде строки JSON, есть ли какой-нибудь способ предотвратить функцию цитирования определенных значений в возвращаемой строке?Причина, по которой я спрашиваю, заключается в том, что мне нужен javascript для интерпретации определенных значений в объекте как фактических имен переменных, например имени существующей функции javascript.

Моя конечная цель - использовать выведенный json в качестве объекта конфигурациидля компонента меню ExtJS, поэтому тот факт, что все заключено в кавычки, не позволяет мне успешно установить такие свойства, как «обработчик» (функция обработчика события щелчка) массивов дочерних элементов.

Ответы [ 7 ]

3 голосов
/ 17 марта 2011

То, что мы делаем (и то же самое делает Zend_Json::encode()), это использование специального класса marker , который инкапсулирует выражения Javascript в специальный класс.Затем кодирование проходит рекурсивно через наш кодируемый массив и заменяет все экземпляры marker некоторой строкой.После использования встроенного json_encode() мы просто выполняем замену строки, чтобы заменить каждую специальную строку значением __toString() соответствующего экземпляра marker .

Вы можете либо использовать Zend_Json напрямую (если это возможно), либо проверить как они это делают и адаптировать код под свои нужды.

2 голосов
/ 20 сентября 2012

Функция Билла почти сработала, просто нужно добавить функцию is_assoc ()

Но пока я разбирался с этим, я немного его почистил. Это, кажется, работает очень хорошо для меня:

<?php

/**
 * JSObject class.
 */

class JSObject {
    var $jsexp = 'JSEXP:';

    /**
     * is_assoc function.
     *
     * Determines whether or not the object is an associative array
     * 
     * @access public
     * @param mixed $arr
     * @return boolean
     */
    function is_assoc($arr) {
        return (is_array($arr) && count(array_filter(array_keys($arr),'is_string')) == count($arr));
    }

    /**
     * Encode object
     *
     * Encodes the object as a json string, parsing out items that were flagged as objects so that they are not wrapped in double quotes.
     *
     * @param     array   $properties
     * @return    string
     */
    function encode($properties = array()) {

        $is_assoc = $this->is_assoc($properties);

        $enc_left  = $is_assoc ? '{' : '[';
        $enc_right = $is_assoc ? '}' : ']';

        $outputArray = array();

        foreach ($properties as $prop => $value) {

            if ((is_array($value) && !empty($value)) || (is_string($value) && strlen(trim(str_replace($this->jsexp, '', $value))) > 0) || is_int($value) || is_float($value) || is_bool($value)) {

                $output = (is_string($prop)) ? $prop.': ' : '';

                if (is_array($value)) {
                    $output .= $this->encode($value);
                }
                else if (is_string($value)) {
                    $output .= (substr($value, 0, strlen($this->jsexp)) == $this->jsexp) ?  substr($value, strlen($this->jsexp))  : json_encode($value);
                }
                else {
                    $output .= json_encode($value);
                }


                $outputArray[] = $output;
            }
        }

        $fullOutput = implode(', ', $outputArray);

        return $enc_left . $fullOutput . $enc_right;
    }

    /**
     * JS expression
     *
     * Prefixes a string with the JS expression flag
     * Strings with this flag will not be quoted by encode() so they are evaluated as expressions
     *
     * @param   string  $str
     * @return  string
     */
    function js($str) {
        return $this->jsexp.$str;
    }
}
1 голос
/ 18 сентября 2016

мое исправление было так:

$myobject->withquotes = 'mystring';
$myobject->withoutquotes = '##noquote## mystring ##noquote##';

и позже

str_replace(array('"##noquote## ', ' ##noquote##"'), '', json_encode($myobject))

результат примерно такой

{"withquotes":"mystring","withoutquotes":mystring}
1 голос
/ 16 марта 2011

Функция json_encode не предоставляет никаких функций для управления кавычками.Кавычки также необходимы JavaScript для правильного формирования объекта на стороне JavaScript.

Чтобы использовать возвращаемое значение для создания объекта на стороне JavaScript, используйте строку json_encoded для установки флагов в вашей ассоциации.

Например:

json_encode( array( "click_handler"=> "FOO" ) );

Сторона JavaScript в AJAX:

if( json.click_handler == "FOO" ) {
  json.click_handler = Your_Handler;
}

После этих шагов вы можете передать свой объект куда-нибудь.

1 голос
/ 16 марта 2011

Нет, json_encode не может этого сделать.Вам необходимо вручную построить JS-выражение :

0 голосов
/ 18 февраля 2014

Следуя примеру Штефана Герига, я собрал этот грубый маленький класс. Пример ниже. Следует помнить, что нужно использовать метод сериализации, если он использовал метод mark, иначе маркеры сохранятся в окончательном json.

class json_extended {

    public static function mark_for_preservation($str) {
        return 'OINK' . $str . 'OINK'; // now the oinks will be next to the double quotes
    }

    public static function serialize($stuff) {
        $json = json_encode($stuff);
        $json = str_replace(array('"OINK', 'OINK"'), '', $json);
        return $json;
    }
}


$js_arguments['submitHandler'] = json_extended::mark_for_preservation('handle_submit');

<script>
$("form").validate(<?=json_extended::serialize($js_arguments)?>);
// produces: $("form").validate({"submitHandler":handle_submit});
function handle_submit() {alert( 'Yay, pigs!'); }
</script>
0 голосов
/ 06 декабря 2011

Это то, что я закончил, что довольно близко к тому, что Стефан предложил выше, я думаю:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...