开发者

PHP JSON parsing giving an error

开发者 https://www.devze.com 2023-01-16 06:45 出处:网络
I am trying to parse a JSON string using PHP, the JSON gets sent to the PHP file using jQuery $.ajax in this format, [{\"value\":\"59\"},{\"value\":\"7\"},{\"value\":\"46\"}] , but for some odd reason

I am trying to parse a JSON string using PHP, the JSON gets sent to the PHP file using jQuery $.ajax in this format, [{"value":"59"},{"value":"7"},{"value":"46"}] , but for some odd reason I keep getting this error "Invalid argument supplied for foreach()", here is my PHP and jQuery code,

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 databas开发者_如何学编程e
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);

As you can see I am using the Zend framework's JSON decode function to decode the JSON string that gets passed to the PHP, and the format seems correct to me so I have no idea what else it could be that is causing this error, maybe encoding? Any ideas?

Thanx in advance!


Looks like json_decode() couldn't handle the data in that post parameter. Add some error handling to your script.

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

You might also be interested in json_last_error()


update: Maybe it's an encoding issue. Since you don't have access to json_last_error() you might want to check the string and the encoding "manually", e.g.

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');

You also have to use mysql_real_escape_string() when mixing the values as string literals into the sql statement, see 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));

Or even better: use prepared, parametrized queries, see e.g. PDO - Prepared statements and stored procedures


Sounds like $test is not really an array in your other server, so json_decode probably didn't return an array. Is json_decode even available in that server? It's only available after php 5.2.0. Look at phpinfo() for version details.

Set error_reporting(E_ALL) and ini_set('display_errors', 1) on top so you see any errors before the foreach.


Since foreach() only works on Arrays, you should be using is_array($test) to check that you got an array from the json, before calling foreach().


When I do a var_dump on $json I get this string(19) "[{\"value\":\"6\"}]"

Looks like magic_quotes_gpc is on. The actual json-encoded string would be [{"value":"6"}] but thanks to the dreadful magic quotes all the double-quotes are replaced by \" which makes it invalid for json_decode(). You can use stripslashes() to "reverse the damage".

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


Inspect the value of $test and $json. $json does not seem to be an JSON-Array as stated in the comment, so $test will not become an PHP array.

You should check that $test is an array before using it in a foreach loop.

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


As others have said, foreach() will throw this error if you try to use it with a variable that is either not an array or not set at all, so if it's possible that this could happen you should check with is_array() before the foreach loop.

However I wanted to post an answer as well to point out that the message you're seeing is only a warning level message in PHP. In other words, your program will continue to work after this error is encountered (it will skip the foreach() loop and carry on after it). Also, it is possible to set PHP using PHP.ini to suppress warning messages (or indeed any other error messages) from being displayed. It is therefore possible (eg if you've made changes to your system or if you're running the program on a different system) that you may have been having the error all along but simply never seen it displayed before.


Just change the following:

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

To

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


Have you checked the encoding of the string before you decode it via the Zend_Json::decode()? This is a common issue - if you coerce the format to, for example, utf8 (via utf8_encode()) it might work for you.


One thing you might try is when you are declaring your systems in the .each loop, wrap the value in quotes. Something like this:

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

The PHP parser might require the value be in quotes

0

精彩评论

暂无评论...
验证码 换一张
取 消