Разбор PHP JSON дает ошибку - PullRequest
       4

Разбор PHP JSON дает ошибку

2 голосов
/ 14 сентября 2010

Я пытаюсь проанализировать строку JSON с помощью PHP, JSON отправляется в файл PHP с использованием jQuery $.ajax в этом формате [{"value":"59"},{"value":"7"},{"value":"46"}], но по какой-то странной причине я продолжаю получать эту ошибку "Invalid argument supplied for foreach()" мой код PHP и jQuery,

JQuery:

    $(".systems").each( function(i, system) {
        // for each location block
        system = $(system);
        var sys = {
            'value' : $("select[data-prod='products']", system).val()
        };
        allSystems.push( sys );
    });

        $.ajax({
                type: 'POST',
                url: 'systems.php',
                dataType: 'json',
                data: { systems: JSON.stringify(allSystems), uid: uid },
                success: function(data){
                    alert(data)
                }
        });

PHP:

require_once 'classes/Zend/Json.php';

$json = $_POST['systems'];
$uid = $_POST['uid'];
$array= Zend_Json::decode("$json"); 

mysql_connect('localhost','user','pass') or die(mysql_error());
mysql_select_db('products') or die(mysql_error());

//insert the suppliers products into the database
foreach($array as $key){
    $query = mysql_query("INSERT INTO suppliersProducts (product_id, supplier_id) VALUES('".$key['value']."', '".$uid."' ) ") or die(mysql_error());
}

print_r($json);

Как видите, я использую функцию декодирования JSON фреймворка Zend Framework для декодирования строки JSON, которая передается в PHP, и формат мне кажется правильным, поэтому я понятия не имею, что еще может быть причиной этой ошибки. может кодировка? Есть идеи?

Спасибо заранее!

Ответы [ 9 ]

7 голосов
/ 14 сентября 2010

Похоже, что json_decode () не может обработать данные в этом параметре записи.Добавьте некоторую обработку ошибок в ваш скрипт.

$test = json_decode($json, true);
if ( is_null($test) ) {
  die('data is not encoded as valid json');
}
else if ( !is_array($test) ) {
  die('Unexpected data structure. Array expected.');
}

Возможно, вас также заинтересует json_last_error ()


: возможно, это проблема с кодировкой.Поскольку у вас нет доступа к json_last_error (), вы можете проверить строку и кодировку «вручную», например,

<code>if ( is_null($test) ) {
  // <--- for debugging purposes only
  echo '<pre>Debug: $json=';
  var_dump($json);
  echo 'hex=';
  for($i=0; $i<strlen($json); $i++) {
    printf('%02X ', ord($json[$i]));
  }
  echo '
';// только для целей отладки -> die ('данные не закодированы как действительные json');

Вы также должны использовать mysql_real_escape_string () при смешивании значений в виде строковых литералов в операторе sql, см. CWE-89: неправильная нейтрализация специальныхЭлементы, используемые в команде SQL («SQL-инъекция»)

$mysql = mysql_connect('localhost','user','password') or die(mysql_error());
mysql_select_db('products', $mysql) or die(mysql_error($mysql));

...

$sql = "
  INSERT INTO
    suppliersProducts
    (product_id, supplier_id)
  VALUES
    (
      '" . mysql_real_escape_string($key['value'], $mysql) . "'
      , '" . mysql_real_escape_string($uid, $mysql) . "'
    )
";
$query = mysql_query($sql, $mysql) or die(mysql_error($mysql));

Или даже лучше: используйте подготовленные параметризованные запросы, см., Например, PDO - подготовленные операторы и хранимые процедуры

2 голосов
/ 14 сентября 2010

Поскольку foreach() работает только с массивами, вы должны использовать is_array($test), чтобы проверить, что вы получили массив от json, перед вызовом foreach().

2 голосов
/ 14 сентября 2010

Похоже, $test на самом деле не является массивом на вашем другом сервере, поэтому json_decode, вероятно, не вернул массив. json_decode даже доступен на этом сервере? Это доступно только после php 5.2.0. Посмотрите на phpinfo() для деталей версии.

Установите error_reporting(E_ALL) и ini_set('display_errors', 1) сверху, чтобы вы могли видеть любые ошибки перед foreach.

1 голос
/ 15 сентября 2010
Когда я делаю var_dump для $ json, я получаю эту строку (19) "[{\" value \ ": \" 6 \ "}]"

Похоже, magic_quotes_gpc включено. Фактическая строка в кодировке json будет [{"value":"6"}], но благодаря ужасным магическим кавычкам все двойные кавычки заменяются на \ ", что делает ее недействительной для json_decode (). Вы можете использовать stripslashes (), чтобы" обратить ущерб ".

$json = get_magic_quotes_gpc()
  ? stripslashes($_POST['systems']) : $_POST['systems'];
0 голосов
/ 16 сентября 2010

Одна вещь, которую вы можете попробовать, - когда вы объявляете свои системы в цикле .each, заключите значение в кавычки.Примерно так:

    var sys = {
        'value' : "'" +  $("select[data-prod='products']", system).val() + "'"
    };

Для парсера PHP может потребоваться указание значения в кавычках

0 голосов
/ 14 сентября 2010

Проверяли ли вы кодировку строки перед тем, как декодировать ее с помощью Zend_Json::decode()?Это распространенная проблема - если вы приведете формат, например, к utf8 (через utf8_encode()), он может работать для вас.

0 голосов
/ 14 сентября 2010

Как уже говорили другие, foreach () выдаст эту ошибку, если вы попытаетесь использовать ее с переменной, которая не является массивом или вообще не установлена, поэтому, если возможно, что это может произойти, вы должны проверить с помощью is_array) перед циклом foreach.

Однако я хотел также опубликовать ответ, чтобы указать, что сообщение, которое вы видите, является только сообщением уровня предупреждения в PHP.Другими словами, ваша программа будет продолжать работать после возникновения этой ошибки (она пропустит цикл foreach () и продолжит работу после него).Кроме того, можно настроить PHP с использованием PHP.ini для подавления отображения предупреждающих сообщений (или даже любых других сообщений об ошибках).Поэтому возможно (например, если вы внесли изменения в вашу систему или если вы запускаете программу в другой системе), что у вас могла быть ошибка все время, но вы просто не видели ее раньше.

0 голосов
/ 14 сентября 2010

Просто измените следующее:

$json = $_POST['systems']; 
$uid = $_POST['uid'];
$test = json_decode($json, true); 

Для

$json = !empty($_POST['systems']) ? json_decode($_POST['systems'], true) : array();
$json = is_array($json) ? $json : array();

$uid = $_POST['uid'];
foreach($json as $key => $value)
{
    //Less error prone.
}
0 голосов
/ 14 сентября 2010

Проверьте значения $ test и $ json. $ json не является JSON-массивом, как указано в комментарии, поэтому $ test не станет массивом PHP.

Вы должны проверить, что $ test является массивом, прежде чем использовать его в цикле foreach.

if(is_array($test)) {
  // proceed..
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...