Upgrading to PHP 5.3.10 (shipped with Ubuntu 12.04) fixed the PHP bug.
$obj->property is null, but it's well defined according to print_r/var_dump
Frage
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.
- Apache Version : Apache/2.2.14 (Ubuntu)
- PHP Version : PHP 5.3.2-1ubuntu4.14
- PHP Extension Build : API20090626,NTS
- APC version : 3.1.3p1
- 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
Lösung 4
Andere Tipps
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:
- Reading bigger content => just the same one that reproduces your error
- Reading data from file using
file_get_contents()
- ...
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)