PHP JSON解析给出错误

时间:2010-09-14 14:14:41

标签: php jquery ajax json

我正在尝试使用PHP解析JSON字符串,使用jQuery $.ajax以这种格式[{"value":"59"},{"value":"7"},{"value":"46"}]将JSON发送到PHP文件,但由于某些奇怪的原因,我不断收到此错误{ {1}},这是我的PHP和jQuery代码,

jQuery的:

"Invalid argument supplied for foreach()"

PHP:

    $(".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)
                }
        });

正如您所看到的,我正在使用Zend框架的JSON解码函数来解码传递给PHP的JSON字符串,这种格式对我来说似乎是正确的,因此我不知道它可能导致此错误,也许是编码?有什么想法吗?

提前Thanx!

9 个答案:

答案 0 :(得分:7)

看起来json_decode()无法处理该post参数中的数据。在脚本中添加一些错误处理。

$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(),因此您可能需要“手动”检查字符串和编码,例如

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 '</pre>';
  // for debugging purposes only -->
  die('data is not encoded as valid json');

在将值作为字符串文字混合到sql语句中时,您还必须使用mysql_real_escape_string(),请参阅CWE-89: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')

$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 - Prepared statements and stored procedures

答案 1 :(得分:2)

听起来像$test并不是你的其他服务器中的数组,所以json_decode可能没有返回数组。 json_decode甚至可以在该服务器上使用吗?它仅在php 5.2.0之后可用。查看phpinfo()了解版本详情。

error_reporting(E_ALL)ini_set('display_errors', 1)设置在最顶层,以便在foreach之前看到任何错误。

答案 2 :(得分:2)

由于foreach()仅适用于数组,因此在调用is_array($test)之前,您应该使用foreach()检查您是否从json获得了数组。

答案 3 :(得分:1)

当我在$ json上执行var_dump时,我得到这个字符串(19)“[{\”value \“:\”6 \“}]”

看起来magic_quotes_gpc已启用。实际的json编码字符串将是[{"value":"6"}]但是由于可怕的魔术引号,所有双引号都被替换为\“这使得它对json_decode()无效。你可以使用stripslashes()来”逆转损坏”

$json = get_magic_quotes_gpc()
  ? stripslashes($_POST['systems']) : $_POST['systems'];

答案 4 :(得分:0)

检查$ test和$ json的值。 $ json似乎不是注释中所述的JSON-Array,因此$ test不会成为PHP数组。

在foreach循环中使用$ test之前,应检查$ test是否为数组。

if(is_array($test)) {
  // proceed..
}

答案 5 :(得分:0)

只需更改以下内容:

$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.
}

答案 6 :(得分:0)

正如其他人所说,如果你试图将它与一个不是数组或根本没有设置的变量一起使用,foreach()将抛出此错误,所以如果可能发生这种情况,你应该检查is_array( )在foreach循环之前。

但是,我想发布一个答案,并指出您所看到的消息只是PHP中的警告级别消息。换句话说,遇到此错误后,程序将继续工作(它将跳过foreach()循环并继续执行)。此外,可以使用PHP.ini设置PHP以禁止显示警告消息(或实际上任何其他错误消息)。因此,有可能(例如,如果您对系统进行了更改,或者如果您在不同的系统上运行程序),您可能一直有错误,但之前从未见过它。

答案 7 :(得分:0)

在通过Zend_Json::decode()解码之前,您是否检查了字符串的编码?这是一个常见问题 - 例如,如果您将格式强制为utf8(通过utf8_encode()),它可能适合您。

答案 8 :(得分:0)

您可能尝试的一件事是当您在.each循环中声明系统时,将值包装在引号中。像这样:

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

PHP解析器可能要求值在引号