Return PHP Object by Index Number (Not Name)

Return PHP object by index number (not name)

Normally, PHP variable names can't start with a digit. You can't access $data as an array either as stdClass does not implement ArrayAccess — it's just a normal base class.

However, in cases like this you can try accessing the object attribute by its numeric name like so:

echo $data->{'0'}->UserName;

The only reason I can think of why Spudley's answer would cause an error is because you're running PHP 4, which doesn't support using foreach to iterate objects.

Access to element with index [0]

Converting to an array does not help. PHP has the nasty habit of creating an inaccessible array element if you try:

  1. The object property name is always a string, even if it is a digit.
  2. Converting that object to an array will keep all property names as new array keys - this also applies to strings with only numbers.
  3. Trying to use the string "0" as an array index will be converted by PHP to an integer, and an integer key does not exist in the array.

Some test code:

$o = new stdClass();
$p = "0";
$o->$p = "foo";

print_r($o); // This will hide the true nature of the property name!
var_dump($o); // This reveals it!

$a = (array) $o;
var_dump($a); // Converting to an array also shows the string array index.

echo $a[$p]; // This will trigger a notice and output NULL. The string
// variable $p is converted to an INT

echo $o->{"0"}; // This works with the original object.

Output created by this script:

stdClass Object
(
[0] => foo
)
class stdClass#1 (1) {
public $0 =>
string(3) "foo"
}
array(1) {
'0' =>
string(3) "foo"
}

Notice: Undefined index: 0 in ...

foo

Praise @MarcB because he got it right in the comments first!

How to access object properties with names like integers or invalid property names?

Updated for PHP 7.2

PHP 7.2 introduced a behavioral change to converting numeric keys in object and array casts, which fixes this particular inconsistency and makes all the following examples behave as expected.

One less thing to be confused about!


Original answer (applies to versions earlier than 7.2.0)

PHP has its share of dark alleys that you really don't want to find yourself inside. Object properties with names that are numbers is one of them...

What they never told you

Fact #1: You cannot access properties with names that are not legal variable names easily

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->123foo; // error

Fact #2: You can access such properties with curly brace syntax

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'}; // OK!

Fact #3: But not if the property name is all digits!

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'}; // OK!
echo $o->{'123'}; // error!

Live example.

Fact #4: Well, unless the object didn't come from an array in the first place.

$a = array('123' => '123');
$o1 = (object)$a;
$o2 = new stdClass;
$o2->{'123'} = '123'; // setting property is OK

echo $o1->{'123'}; // error!
echo $o2->{'123'}; // works... WTF?

Live example.

Pretty intuitive, don't you agree?

What you can do

Option #1: do it manually

The most practical approach is simply to cast the object you are interested in back into an array, which will allow you to access the properties:

$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
$a = (array)$o;
echo $o->{'123'}; // error!
echo $a['123']; // OK!

Unfortunately, this does not work recursively. So in your case you 'd need to do something like:

$highlighting = (array)$myVar->highlighting;
$data = (array)$highlighting['448364']->Data;
$value = $data['0']; // at last!

Option #2: the nuclear option

An alternative approach would be to write a function that converts objects to arrays recursively:

function recursive_cast_to_array($o) {
$a = (array)$o;
foreach ($a as &$value) {
if (is_object($value)) {
$value = recursive_cast_to_array($value);
}
}

return $a;
}

$arr = recursive_cast_to_array($myVar);
$value = $arr['highlighting']['448364']['Data']['0'];

However, I 'm not convinced that this is a better option across the board because it will needlessly cast to arrays all of the properties that you are not interested in as well as those you are.

Option #3: playing it clever

An alternative of the previous option is to use the built-in JSON functions:

$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];

The JSON functions helpfully perform a recursive conversion to array without the need to define any external functions. However desirable this looks, it has the "nuke" disadvantage of option #2 and additionally the disadvantage that if there is any strings inside your object, those strings must be encoded in UTF-8 (this is a requirement of json_encode).

How to find object in php array and delete it?

$found = false;  
foreach($values as $key => $value) {
if ($value->id == 4) {
$found = true;
break;
}
}

if ($found) unset($values[$key]);

This is considered to be faster then any other solution since we only iterate the array to until we find the object we want to remove.

Note: You should not remove an element of an array while iterating so we do it afterwards here.

array creates object with index name of variable

You're calling $stmt->fetch_object() and you get what you ask for - an object that represents a row of data returned from the database.

Replace

while($id = $stmt->fetch_object()) {
$var1[] = $id;
}

with

while($row = $stmt->fetch_object()) {
$var1[] = $row->id;
}

to get an array of IDs.

Get a PHP object property that is a number

This should work:

$object->content->{'5'}

Access non-numeric Object properties by index?

"I'm specifically looking to target the index, just like the first example - if it's possible."

No, it isn't possible.

The closest you can get is to get an Array of the object's keys, and use that:

var keys = Object.keys( obj );

...but there's no guarantee that the keys will be returned in the order you defined. So it could end up looking like:

keys[ 0 ];  // 'evenmore'
keys[ 1 ]; // 'something'

Most efficient way to search for object in an array by a specific property's value

You can iterate that objects:

function findObjectById($id){
$array = array( /* your array of objects */ );

foreach ( $array as $element ) {
if ( $id == $element->id ) {
return $element;
}
}

return false;
}

Edit:

Faster way is to have an array with keys equals to objects' ids (if unique);

Then you can build your function as follow:

function findObjectById($id){
$array = array( /* your array of objects with ids as keys */ );

if ( isset( $array[$id] ) ) {
return $array[$id];
}

return false;
}


Related Topics



Leave a reply



Submit