PHP JSON get the name of an object - php

<?
stdClass Object
(
[image_header] => Array
(
[0] => stdClass Object
(
[img] => /headers/header.jpg
)
)
)
?>
Object name image_header is variable, so it can be any string. Can I access this string without knowing what it is?
#Jon his answer was satisfying for me.
For others who want to use variable objectnames this way:
To acces this object with the variablename I had to use curly brackets:
$key = key(get_object_vars($_json));
$_json->{$key}[0]->img;

You can do it conveniently with get_object_vars:
$propertyName = key(get_object_vars($object));

If you don't know what the name of the property is, you can use PHP's Reflection classes, or more simply use get_object_vars().
get_object_vars() is probably what you're looking for here - it "Returns an associative array of defined object accessible non-static properties for the specified object in scope. If a property has not been assigned a value, it will be returned with a NULL value." So, you get the property names and their values returned in an associative array.
Alternatively, you could use some of PHP's reflection magic, although it might be a bit overkill here, depending on your end goal. The reflection classes are very powerful, and may be worth using if you have more complex requirements for what you're trying to achieve. As an example:
// let's say $obj is the object you provided in your question
// Instantiate the reflection object
$reflector = new ReflectionClass($obj);
// Get properties of $obj, returned as an array of ReflectionProperty objects
$properties = $reflector->getProperties();
foreach ( $properties as $property ) {
echo $property->getName(); // In your example, this would echo 'image_header'
}

There are a couple of possibilities. If you're using json_decode() you can pass true in as the second parameter to parse the data as an associative array.
$data = json_decode($myJson, true);
print_r( $data['image_header'] );
You can also access an object property from a variable like this.
$myProperty = 'image_header';
print_r( $data->$myProperty );
If by "you don't know what it is" you mean you don't know the key at all you can use my first example and use array_values() to get the values by index.
$values = array_values($data);
// image_header
print_r( $values[0] );

Related

Why stdClass is coming instead of our custom object name?

Here My class name is User, When I print my class properties I'm getting my objective name properly. After that, I encoded the data with json_encode(). and then I decoding with json_decode(). I'm getting stdClass objective why?
<?php
class User
{
public $name;
public $age;
public $salary;
}
$user = new User();
$user->name = 'Siddhu';
$user->age = 24;
$user->salary = 7000.80;
print_r($user);
//Output: User Object ( [name] => Siddhu [age] => 24 [salary] => 7000.8 )
print_r(json_encode($user));
//Output: {"name":"Siddhu","age":24,"salary":7000.8}
$d = json_encode($user);
$s = json_decode($d);
print_r($s);
//Output: stdClass Object ( [name] => Siddhu [age] => 24 [salary] => 7000.8 )
If you noticed stdClass is coming, How can I change to user
There is no direct way you can get data in class object either you need to used custom method to decode else you can use serialize() && unserialize() function to get data in the class object when you decode;
$serialized_user_object = serialize($user);
$deserialized_user_object = unserialize($serialized_user_object);
In json_decode you can pass true in second argument if you want data as array.
like this.
var_dump(json_decode($json, true));
to know more about json_decode see here.
The reason this happens can be demonstrated quite easily...
class foo{
public $bar = 'bar';
}
$json = json_encode(new foo);
echo $json."\n\n";
print_r(json_decode($json));
Output
{"bar":"bar"}
stdClass Object
(
[bar] => bar
)
Sandbox
As you can see the output {"bar":"bar"} contains no information about what if any class this was, it could have been ['bar'=>'bar'] and the JSON would be the same... Then when decoding it, you don't have json_decode set to return as an array (second argument set to true), which is fine as that's not really what you want, but when it's set that way you get stdClass objects instead of an associative array for items with non-numeric keys. In short there is no way to recover the class "foo" from the json {"bar":"bar"} as that information does't exist (you can make it exist, but that's another tale for another day).
Using serialize we get something very different.
class foo{
public $bar = 'bar';
}
$json = serialize(new foo);
echo $json."\n\n";
print_r(unserialize($json));
Output
O:3:"foo":1:{s:3:"bar";s:3:"bar";}
foo Object
(
[bar] => bar
)
Sandbox
This O:3:foo means an Object with a class name 3 in length named "foo". So it preserves that information for PHP to use when "decoding" the data.
The whole thing reads like this:
Object (3) "foo" with 1 property named (s)tring (3) "bar" with a value of (s)tring (3) "bar", or something like that.
Make sense.
AS a note PHP's serialize is less portable then JSON, as it only works in PHP, It's also much harder to manually edit then JSON, but if you really want to encode a class than that is the easiest way to do it. That said you can also "repopulate" the class from JSON data, but that can also be hard to maintain.

Retrieving PHP property name as string

I have some JSON, if I var_dump the output looks like:
var_dump( $oJSON->{$oQ->sQuestionName} );
object(stdClass)[14]
public 'Lease' => boolean true
I would like to retrieve 'Lease' as a string.
I've tried casting it:
(string)$oJSON->{$oQ->sQuestionName}
but it returns an E_RECOVERABLE:
E_RECOVERABLE_ERROR Error: Object of class stdClass could not be converted to string
The following works, however I feel there must be a better way?
array_shift(array_values(array_keys(get_object_vars($oJSON->{$oQ->sQuestionName}))));
N.B. I can't use to use the following due to compatability issues
array_keys(get_object_vars($oJSON->{$oQ->sQuestionName}))[0]
Use ReflectionClass::getProperties() to get a list of the object's properties.
$reflect = new ReflectionClass($foo);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
You can convert your desired object to an array first
$array = (array) $oJSON->{$oQ->sQuestionName};
Then you can take its first element's key
echo key($array); // Should say Lease
Fiddle
You can use json_decode with second parameter true
For example:
$str = '{"0":{"id":"123","name":"Title"}}';
var_dump(json_decode($str,true));
So, you will have an array with string objects.

Session variable in PHP containing object is changed when original object is changed

In some third party code, that I am not allowed to change, something peculiar is happening.
They write a variable (an array containing objects) to the session (without serialising it) and then iterate using a foreach on the original variable (without using references). Whenever they change a value, the corresponding value in the session is also changed. I was able to create a smaller example that has the same behaviour:
$test = array((object)array("categories" => "test"));
$_SESSION['woot'] = $test;
print_r($_SESSION['woot']);
foreach ($test as $a) {
if (!is_array($a->categories)) $a->categories = array();
}
print_r($_SESSION['woot']);
This is the result:
Array
(
[0] => stdClass Object
(
[categories] => test
)
)
Array
(
[0] => stdClass Object
(
[categories] => Array
(
)
)
)
I already noticed that, when I serialize and unserialize the object array, the problem does not occur.
Does anyone have an idea about what's happening here? Is it the code? Is it an incorrect server setting? I'd like to know a little more before I contact the devs of the code.
Additional information:
I am using PHP Version 5.3.14
Register globals is switched off
Regards,
Joost.
A variable holding an object only holds a reference to that object. Assigning an object (an object reference) from one variable to another does not make a copy of the object, there's still only one object. If you modify that object, all variables holding a reference to that object will see the change, because there's only one object instance.
If you want to make a copy of an object, you need to explicitly clone it.
In PHP objects are passed by reference and PHP uses copy-on-write.
$test = array((object)array("categories" => "test"));
// it is still the same array
$_SESSION['woot'] = $test;
foreach ($test as $a) {
// You change something in an object, which is passed by reference
if (!is_array($a->categories)) $a->categories = array();
}
Serialization and deserialization creates new objects
$test = array((object)array("categories" => "test"));
// new array with new objects
$test = unserialize(serialize($test));

PHP Undefined index of array. Why?

This is... I don't even know what this is happening.
// var_dump of items before
object(stdClass)[84]
public '75' => object(stdClass)[87]
$items = (array) $items; // Casting unserialized stdClass to array
var_dump($items);
//Result of var dump:
array
'75' =>
object(stdClass)[87]
//Now lets get this item:
var_dump($items[75]); // Error
var_dump($items['75']); // Error
What the?
Thanks.
I think, you are using a debug extension, so the var_dump() output is different then standart library, properties can not be numeric but $obj->{'75'} is okay.
If can you reach to the sub object by $items->{'75'} yes you have a numeric property.
otherwise you can try print_r($items); and see the original output, or check the array after get_object_vars()
<?php
$items = new stdClass();
$items->{'75'} = new stdClass();
$items->{'75'}->{'85'} = new stdClass();
$items = (array) $items; // Casting unserialized stdClass to array
$items_array = get_object_vars($items); // getting object vars as an array.
var_dump($items["75"]); // Error
var_dump($items['75']); // Error
var_dump($items_array['75']); // Works
PHP issue : #45959
Read the casting blockquote: http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
Casting to an array doesn't work like that.
See here: get_object_vars() vs. cast to array
and here: http://www.php.net/manual/en/language.types.array.php#language.types.array.casting
Blockquote
"If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side.

Dynamically discover/process PHP object

Is it possible to dynamically discover the properties of a PHP object? I have an object I want to strip and return it as a fully filled stdClass object, therefore I need to get rid of some sublevel - internal - objecttypes used in the input.
My guess is I need it to be recursive, since properties of objects in the source-object can contain objects, and so on.
Any suggestions, I'm kinda stuck? I've tried fiddling with the reflection-class, get_object_vars and casting the object to an array. All without any success to be honest..
tested and this seems to work:
<?php
class myobj {private $privatevar = 'private'; public $hello = 'hellooo';}
$obj = (object)array('one' => 1, 'two' => (object)array('sub' => (object)(array('three' => 3, 'obj' => new myobj))));
var_dump($obj);
echo "\n", json_encode($obj), "\n";
$recursive_public_vars = json_decode(json_encode($obj));
var_dump($recursive_public_vars);
You can walk through an object's (public) properties using foreach:
foreach ($object as $property => $value)
... // do stuff
if you encounter another object in there (if (is_object($value))), you would have to repeat the same thing. Ideally, this would happen in a recursive function.

Categories