I have a JSON file like that:

{
  "product": "www.example.com",
  "enabled": true,
  ...
}

After using file_get_contents() and json_decode($string,FALSE) I got a classic stdClass Object with properties. Var_dump() returns the following output :

object(stdClass)#2 (7) {
  ["product"] => string(15) "www.example.com"
  ["enabled"] => bool(true)
  ...
}

Then, things get weird.

In 99% of cases, $myobject->product returns the string "www.example.com". That is what you expected, right?

But sometimes (in average: 2 times per minute on our production servers), $myobject->product returns NULL. I can't explain that.

I've added some debugs before and after that line, this is what I get when the wrong behaviour occurs:

var_dump($myobject) : gives the output given before
print_r($myobject) : OK
var_export($myobject) : OK
is_object($myobject) : TRUE
isset($myobject->product) : TRUE
is_string($myobject->product) : FALSE !!!
gettype($myobject->product) : NULL !!!
get_object_vars($myobject) : Array('product'=>'www.example.com', 'enabled'=>true, ...)
get_class_methods($myobject) : Array()
ReflectionClass::export($myobject) : Class [ <internal:Core> class stdClass ] (0 constant, 0 property, 0 method, ...)

I run the PHP code through Apache. I get no Apache error, no PHP error, nothing. It's simply the property returning null when I try to access it, but it's obviously present when I dump the variable object just before and after the code.

  1. Apache Version : Apache/2.2.14 (Ubuntu)
  2. PHP Version : PHP 5.3.2-1ubuntu4.14
  3. PHP Extension Build : API20090626,NTS
  4. APC version : 3.1.3p1
  5. Json module : enabled, 1.2.1 (according to phpinfo())

Can you help me? I'm stuck with this problem, because it's hard to reproduce (randomly), and because it's completely illogical.

Thanks in advance!

PS : I can't give exact files and code, due to the policy of my company, but I'd be happy to answer to all your questions.

UPDATE

UPDATE with a PHP code you can test:

<?php
// Show me all errors
ini_set("display_errors",1);
error_reporting(-1);

// Initialize the object
$object = json_decode('{"product": "www.example.com"}', false);

echo "\n *** DUMP *** \n";
var_dump($object);
echo "\n Product : ";
echo $object->product;
echo "\n Is the variable an object ? ".(is_object($object) ? "Yes" : "No");
echo "\n Is the property set ? ".(isset($object->product) ? "Yes" : "No");
echo "\n Is the property a string ? ".(is_string($object->product) ? "Yes" : "No");
echo "\n Is the property null ? ".(is_null($object->product) ? "Yes" : "No");
echo "\n END";

Expected result, that I got for 98/100 of the Apache requests

HTTP/1.1 200 OK
Date: Thu, 23 Jan 2014 17:18:37 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.14
Vary: Accept-Encoding
Content-Length: 241
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
Accept-Ranges: none


 *** DUMP *** 
object(stdClass)#1 (1) {
  ["product"]=>
  string(15) "www.example.com"
}

 Product : www.example.com
 Is the variable an object ? Yes
 Is the property set ? Yes
 Is the property a string ? Yes
 Is the property null ? No
 END

Buggy result I got too...

HTTP/1.1 200 OK
Date: Thu, 23 Jan 2014 17:18:37 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.14
Vary: Accept-Encoding
Content-Length: 580
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
Accept-Ranges: none


 *** DUMP *** 
object(stdClass)#1 (1) {
  ["product"]=>
  string(15) "www.example.com"
}

 Product : 
Notice: Trying to get property of non-object in /var/[...]/test_object.php on line 12

 Is the variable an object ? Yes
 Is the property set ? Yes
Notice: Trying to get property of non-object in /var/[...]/test_object.php on line 15

 Is the property a string ? No
Notice: Trying to get property of non-object in /var/[...]test_object.php on line 16

 Is the property null ? Yes
 END
有帮助吗?

解决方案 4

Upgrading to PHP 5.3.10 (shipped with Ubuntu 12.04) fixed the PHP bug.

其他提示

It seems like a PHP internal bug to me, however, to fix it, you should first identify the real problem by producing the smallest possible script that is able to reproduce the issue, for example, does a script, like the one below, reproduce the issue on your production servers while putting it under load?:

$object = json_decode('{"product": "www.example.com"}', false);
echo $object->product;

If it does, create a PHP bug report at https://bugs.php.net/ with the script and the relevant information. If it doesn't, it means you have to increase the script with more similar operations than what's in your real life application by:

  1. Reading bigger content => just the same one that reproduces your error
  2. Reading data from file using file_get_contents()
  3. ...

Until you have been able to reproduce the error with a small snippet.

Finally, create the bug report with what was required to make it reproducible, you might find that in the mean time, the issue was caused by some invalid data (malformed json? wrong unicode sequences? ...) and might even be reproducible on demand.

Note that StackOverflow isn't really suited to investigate bugs.

Looking at your script, the version of PHP and APC you are using, it's clearly not a PHP problem, but an APC one, upgrade it, your PHP as well if possible, and your bug will, almost for sure, varnish!

After an intense investigation, we came to the conclusion there is a bug in PHP 5.3.2 that prevent access to properties from all objects inherited from stdClass. Variable "globale std_object_handlers" goes corrupted. This is exactly what is described here: https://bugs.php.net/bug.php?id=50027#1289900303 (the revision number in later messages might be wrong)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top