Я хочу отправить данные в кодировке строки json на серверную часть PHP. Для этого я использую параметр GET с данными json, закодированными в URL-адресе, в виде массива, подобного этому: ["mystring1","mystring2"]
Когда я сейчас пытаюсь декодировать его с помощью функции php json_decode, она возвращает null. Кроме того, использование этой входной строки вообще ничего не меняет: {"mykey":["mystring1","mystring2"]}.
Вот мой полный пример кода:
JavaScript:
var myArr = [];
myArr.push('mystring1');
myArr.push('mystring2');
window.location.href = 'example.com/index.php?myparam=' + encodeURIComponent(JSON.stringify(myArr));
Бэкэнд-сайт PHP:
$jsonStr = filter_input(\INPUT_GET, 'myparam', \FILTER_SANITIZE_STRING);
var_dump($jsonStr);
var_dump(json_decode($jsonStr, true));
Первый var_dump правильно печатает строку json, второй возвращает null. Использование флага assoc (2-й параметр json_encode) ничего не меняет.
Что я ожидал получить:
array(2) { [0]=> string(9) "mystring1" [1]=> string(9) "mystring2" }
Что на самом деле получил:
NULL
var_dump для $jsonStr возвращает мне следующее:
string(41) "["mystring1","mystring2"]"
Если вам нужна дополнительная помощь, покажите результат var_dump($jsonStr);
Используя приведенные выше примеры, ошибки нет: $jsonStr = '{"mykey":["mystring1","mystring2"]}'; var_dump(json_decode($jsonStr, true)); печатает ожидаемый результат. Единственная причина, почему это может не получиться, заключается в том, что вы не вставили строку JSON. Так что, пока мы не увидим реальный результат работы вашего $jsonStr, мы не сможем вам помочь.
@feeela Это правда. Но я имел в виду, что если вы используете json_decode('["mystring1","mystring2"]');, это приведет к null.
@feeela Я подозреваю, что проблема в том, что encodeURIComponent(JSON.stringify(myArr)) приводит к %5B%22mystring1%22%2C%22mystring2%22%5D, который, конечно, не является допустимым JSON, поэтому, если сервер уже не декодировал это, возникнет проблема. Я думаю, это можно изменить, но было бы проще просто использовать POST и поместить JSON в тело (или просто использовать обычные отдельные параметры строки запроса).
@ alpham8 json_decode('["mystring1","mystring2"]'); не приводит к NULL - см. демонстрацию: eval.in/1025111
Когда я использую (улучшенный) var_dump($jsonStr);, я получаю ["mystring1","mystring2"], который выглядит странно. Конечно, это похоже на то, что FILTER_SANITIZE_STRING ломает JSON.
@ alpham8 Нет, это не так: var_dump(json_decode('["mystring1","mystring2"]')); печатает ожидаемый массив: array(2) { [0] => string(9) "mystring1" [1] => string(9) "mystring2" }
@feeela Ну, действительно, этот простой возвращает именно то, что мы ожидали. Но получение его с filter_input, похоже, вызывает ошибку. Если я посмотрю на json_last_error_msg(), он вернет syntax error, но я на 100% уверен, что это действительный json.
«Я на 100% уверен, что это действительный json», если есть синтаксическая ошибка, то все, что вы скармливаете json_decode, явно недействительно. Возможно, он изначально был действительным, но он прошел через процессы кодирования URI и фильтрации, прежде чем он добрался до json_decode, поэтому его можно было легко изменить. Поэтому, пожалуйста, расскажите нам (как уже просили), что выводит var_dump($jsonStr);? В любом случае, как я сказал ранее, отправка JSON в строке запроса не является хорошей идеей - подобные проблемы возникают часто. Я настоятельно рекомендую перейти на POST-запрос, именно так world + dog отправляет JSON.
FILTER_SANITIZE_STRING сломает JSON@apokryfos Ага, вот и все :-) Отправьте это в ответ, чтобы я мог дать вам решенный чек :-)
string(41) является странным, потому что напечатанная строка на самом деле имеет длину всего 25 символов ... предположительно, там также есть некоторые скрытые, пробельные или непечатаемые символы, которые не считаются допустимыми JSON. Как говорит апокирфос, это, скорее всего, результат фильтрации, которая в данном сценарии кажется ненужной задачей. Кодирование URl также является осложнением, которого можно избежать.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ошибка здесь не в JSON, а в запросе с использованием закодированных компонентов URI.
Если вы используете encodeURIComponent на стороне JS, вам также придется использовать urldecode на стороне PHP.
<?php
$jsonStr = '%5B%22mystring1%22%2C%22mystring2%22%5D';
var_dump(
json_decode(urldecode($jsonStr), true)
);
См .: http://php.net/manual/en/function.urldecode.php
нет, см. комментарий выше. Он уже правильно закодирован в представляющей строке.
Я передаю записку от Что делает FILTER_SANITIZE_STRING?, но весь принятый ответ на этот вопрос объясняет это намного лучше:
First -
php_filter_strip. It doesn't do much, just takes the flags you pass to the function and processes them accordingly. It does the well-documented stuff.Then we construct some kind of map and call
php_filter_encode_html. It's more interesting: it converts stuff like ", ', & and chars with their ASCII codes lower than 32 and higher than 127 to HTML entities, so & in your string becomes &. Again, it uses flags for this.Then we get call to
php_strip_tags_ex, which just strips HTML, XML and PHP tags (according to its definition in /ext/standard/string.c) and removes NULL bytes, like the comment says.
(Подчеркнул важную часть).
Короче говоря, FILTER_SANITIZE_STRING сломает ваш JSON, потому что он будет кодировать то, чего не должен. Если вы хотите проверить этот ввод, не используйте этот фильтр.
Ответ здесь - не использовать FILTER_SANITIZE_STRING.
Разумный способ проверить строку JSON - выполнить json_decode и проверить, является ли она нулевой.
$jsonStr = filter_input(\INPUT_GET, 'myparam');
var_dump($jsonStr);
var_dump(json_decode($jsonStr, true));
Большое спасибо за расследование! :-)
Я настоятельно рекомендую вам использовать компонент Symphony VarDumper при отладке, потому что он будет отображать строку дословно вместо того, чтобы выгружать ее в окно браузера и позволять браузеру отображать ее как HTML.
Что ж, спасибо за подсказку, но в некоторые из наших простых проектов на PHP невозможно интегрировать композитор. Если я подойду к той же проблеме, я буду сравнивать ее содержимое в двоичном формате в будущем. Думаю, это тоже может помочь.
есть ли шанс, что вы можете использовать для этого POST и вместо этого поместить JSON в тело запроса? Тогда вам не нужно кодировать его URI. В любом случае, если json_decode ничего не вернул, это, вероятно, не удалось - используйте эту функцию: php.net/manual/en/function.json-last-error-msg.php, чтобы узнать, почему.