Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP objects with Int variables

Tags:

object

php

I've noticed something quite strange with PHP Objects and can't find a documented cause of it.

The following code demonstrates the behaviour

<?php
$a = (object) array( 0 => 1 );
foreach($a as $b => $c) {
  $a->$b = ++$c;  //I'm expecting the key to be overwritten here
}
var_dump($a);
$var = 0;
var_dump($a->$var);
$var = "0";
var_dump($a->$var);

and the output

object(stdClass)#1 (2) {
  [0]=>
  int(1)
  ["0"]=>
  int(2)
}
int(2)
int(2)

Is the numeric part of the class inaccessible using -> syntax?

like image 644
exussum Avatar asked Nov 25 '14 12:11

exussum


People also ask

How do you declare an integer variable in PHP?

Method 1: Using number_format() Function. The number_format() function is used to convert string into a number. It returns the formatted number on success otherwise it gives E_WARNING on failure. echo number_format( $num , 2);

Is stdClass an object PHP?

The stdClass is the empty class in PHP which is used to cast other types to object. It is similar to Java or Python object. The stdClass is not the base class of the objects. If an object is converted to object, it is not modified.

How can I access the elements of an object in PHP?

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!


2 Answers

When you perform an (object) cast on an array you promote that array as the internal property list of an anonymous object (i.e. stdClass).

The way properties are indexed in an object is slightly different than that of an array; specifically, object property names are always treated as strings whereas array indices are looked up based on the intended type (e.g. numeric strings are seen as integers).

The above behaviour doesn't affect foreach loops because there's no hashing involved there; as far as PHP is concerned, a regular array is being iterated.

To answer your question, yes, the numeric keys from your original array can't be accessed using the -> operator. To avoid this you should remove the numeric indices from your array before the cast is performed.

It's hard to find this behaviour in the documentation, but a hint of it can be found here:

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 ...

FYI

In this particular case you can circumvent the issue by using references; this is not recommended, please follow the earlier advise of not using numeric property names:

foreach ($a as &$c) {
    ++$c;
}
unset($c);

Update

2014-11-26: I've updated the documentation; the live pages will be updated this Friday - commit.

like image 186
Ja͢ck Avatar answered Oct 12 '22 22:10

Ja͢ck


stdClass handles data terribly loosely, since it's an object representation of an internal array (thus the ability of of casting without problems).

$stdClassObject->property = "value";

The property is handled as a string, but upon casting, the property type doesn't change (which is somehow understandable, as if you cast to an object and then to an array again, you'd have lost all the integer indexes).

I don't think they could do better than that, but you can create your own alternative to stdClass :-)

like image 34
Shotgun Avatar answered Oct 13 '22 00:10

Shotgun