0

I'm having a very interesting problem with PHP. The following code grabs a line from a text file, decodes that text as json into an stdClass object, then puts it into an array conditionally on one of its properties.

$fileStream = @fopen($fileName, 'r+');
    $lastUpdate = $_POST['lastUpdate'];
    if($fileStream) {
        $eventArray = array();
        while (($buffer = fgets($fileStream, 8192)) !== false) {
                $decodedEvent = json_decode($buffer);
                echo var_dump($decodedEvent);
            if ($decodedEvent->timestamp > $lastUpdate) {
                array_push($eventArray, $decodedEvent);
            }
        }
        $jsonEvents = json_encode($eventArray);
        echo $jsonEvents;
    }
    else {
        $fileStream = @fopen($fileName, 'a');
    }
    @fclose($fileStream);

This produces the error:

Notice:Trying to get property of non-object in C:\****\gameManager.php on line 23

I know that the object is valid in multiple ways. For instance, var_dump is producing this:

object(stdClass)#1 (3) {
 ["name"]=>
 string(4) "move"
 ["args"]=>
 array(3) {
   [0]=>
   int(24)
   [1]=>
   int(300)
   [2]=>
   int(50)
 }
 ["timestamp"]=>
 float(1352223678463)
}

If I try to access $decodedEvent using $decodedEvent["timestamp"] I get an error telling me that objects can't be accessed as arrays.

Also, it does indeed echo proper json, which can only be encoded from a proper object:

[{"name":"move","args":[24,300,50],"timestamp":1352223678463}]

Am I missing something here, or is PHP misbehaving? Any help is greatly appreciated.

EDIT: Here is the input from the file:

{"name":"move","args":[24,300,50],"timestamp":1352223678463}
Bloodyaugust
  • 2,463
  • 8
  • 30
  • 46

2 Answers2

1

Your JSON format is incorrect. That's not to say invalid. But given this format the root element is an array of stdClass.

array(1) {
  [0] =>
  class stdClass#1 (3) {
     // ...

If this is a truly a single object, I would resolve this at the source with the following, proper JSON:

{"name":"move","args":[24,300,50],"timestamp":1352223678463}

If that is not possible, you need to access it in PHP with proper array notation:

echo $decodedEvent[0]->timestamp;

UPDATE

The updated JSON you provided appears valid and correctly formatted given your code. My guess is a line in the file does not contain valid JSON (e.g. empty line) and as such json_decode() is failing which results in the PHP Notice.

I encourage you to test for this in your loop:

if ($decodedEvent && $decodedEvent->timestamp > $lastUpdate)

Also bear in mind this is a notice. And while I advocate clean code, it is not an error strictly speaking.

Jason McCreary
  • 71,546
  • 23
  • 135
  • 174
0

you can try this Function to Convert stdClass Objects to Multidimensional Arrays

    function objectToArray($d) {
        if (is_object($d)) {
            // Gets the properties of the given object
            // with get_object_vars function
            $d = get_object_vars($d);
        }

        if (is_array($d)) {
            /*
            * Return array converted to object
            * Using __FUNCTION__ (Magic constant)
            * for recursive call
            */
            return array_map(__FUNCTION__, $d);
        }
        else {
            // Return array
            return $d;
        }
    } 

Sources

Julien
  • 1,946
  • 3
  • 33
  • 51
  • You can have json_decode return an array, set true as the second argument. I'd like to know why the above isn't working. – Bloodyaugust Nov 06 '12 at 18:30