Can't access array by index, but can iterate with foreach - php

How come that I can't access array by index $obj->property[0] but can iterate through the array (each has only one value) and then get the value.
foreach($obj->property as $inner_obj)
{
foreach($inner_obj->property as $inner_inner_obj)
echo $inner_inner_obj->property;
}
If I access array by index I get Undefined offset: 0
Edit: Output of var_dump
array(1) {
[0]=> object(FooClass)#141 {
// yadda yadda
}
}

if you make class by implements Countable, Iterator you can make a object that work with foreach but it is not array

$obj is not array its stdClass Object and
because of that $obj->property[0] will show you Undefined offset: 0
try to use it like this for getting 1st value of property
$obj->property->property;

Because you're looping over properties of an array in a foreach. With [0] you explicitly try to access it as an array. You can have your object extend ArrayObject and make php access your object as an array which is what you want I think.
The interfaces that gives the ability to use your object as an array:
http://www.php.net/manual/en/class.arrayaccess.php
http://www.php.net/manual/en/class.countable.php
http://www.php.net/manual/en/class.iteratoraggregate.php
The object itself which you can extend:
http://www.php.net/manual/en/class.arrayobject.php
Imo, it's never a good idea to loop over an object without array interface as it means you are using public variables. My suggestion is to always make them protected or private unless not possible otherwise (SOAP?). You can access them by getters and setters.

The $obj->property could be an array without having key 0.
The keys in your array might not be numeric. So your array might be an associative array not a regular.
If you want numeric indexing try this:
$numArray = array_values($obj->property);
var_dump($numArray);
If you want to access the first value of an array use:
$first = reset($obj->property);
It works if your variable is an array.

Related

Create Iterator from array with AMPHP

I have an array in php:
$array = [1,2,3];
When I do:
while(yield $array->advance())
I get Call to a member function advance() on array
How do I turn my array into an iterator?
You can call ->advance() only on instances of Amp\Iterator.
So you need to convert your basic php array first with the fromIterable method.
Amp\Iterator\fromIterable($array)

get object values as array in php

I have object with setter and getter
class obj{
private $a;
private $b;
}
I would like to create an array that get only the value of the object , for example
array = ["1","2"]
tried get_object_vars but its an associative array
To condense an associative array to an indexed array, use array_values:
array_values(get_object_vars($object));
However, given that you have private member variables, you might just want to use an array cast instead of get_object_vars:
array_values((array)$object);
See it online at 3v4l.org.

Class member reference to another object in PHP

First code and then the question:
class MyArray
{
private $arrayRef;
function __construct(&$array){
$this->arrayRef = $array;
}
function addElement($newElement){
$this->arrayRef[] = $newElement;
}
function print(){
print_r($this->arrayRef);
}
}
$array = ['first', 'second'];
$arrayObject = new MyArray($array);
$arrayObject->addElement('third');
print_r($array); // prints array containing 2 elements
echo '<br/>';
$arrayObject->print(); // prints array containing 3 elements
Class member $arrayRef, in this example doesn't work as a reference to another array provided in constructor. Argument in constructor is passed by reference, but I guess that doesn't make member $arrayRef also a reference to that array as well.
Why doesn't it work like that and how to make it work?
If you still don't get what I mean: first print_r prints array containing 2 elements, even thought it may be expected to contain 3.
When I pass third element to $arrayObject via addElement() I also want it to be added in the $array that I passed to constructor of class.
The answer is actually quite simple. Yes, you pass the array by reference via &$array but this reference gets lost when you assign/copy it to the member variable. To keep the reference, you can use the =& operator like so
$this->arrayRef =& $array;
See it work in this fiddle. You can read more about it in this question/answer (just look for reference).
Beware not to use &= (which does a bitwise operation) instead of =& (which assigns by reference).

How does ArrayObject in PHP work?

I'm trying to understand this object but i can't figure out a simple fact. If count method shows public properties and the result is the number of keys in an array that was passed. In the case of an associative array when i try to access a key like a public property is not found. Maybe i misunderstood the interface.
//example
$currentDate = getdate();
//applying print_r() we can see the content
$objectDate = new ArrayObject();
//verifying the public properties- result is 11
$objectDate->count();
//but can't access keys like public properties
$objectDate->hours;
You can access array entries as properties (->) by passing the ArrayObject::ARRAY_AS_PROPS flag to the ArrayObject constructor:
//example
$currentDate = getdate();
print_r($currentDate);
// create ArrayObject from array, make entries accessible as properties (read and write).
$objectDate = new ArrayObject($currentDate, ArrayObject::ARRAY_AS_PROPS);
// verifying the public methods - result is 11
print_r($objectDate->count());
print "\n";
// accessing entries like public properties
print_r($objectDate->hours);
Such class implements ArrayAccess interface, so you can write:
$objectDate['hours']
With brackets notation, but not with arrow [->] one.

Use object property as array key

I have a PHP array of objects, say with two properties a and b. So for example I can do
$arr['a1']->a = $z;
$x = $arr['a1']->b;
The array is currently using the value of each object's a property as the array key, e.g.
$arr['a1']->a == 'a1'
This is so I can quickly look up the object by that property. I now need to quickly look up by b, and so want to switch the keys from being set to property a to being set to b (both are unique).
Is there an easy way to do this? In-place or into another array are both fine.
foreach($arr as $key => $object)
{
$arr2[$object->b] = $object;
}
This will create a new array that points to the same objects.
If you want them in one array, you can do as Joost suggested in the comments ($arr[$object->b] = $object; in the loop instead). However, that will only work if there are no duplicate keys between the two sets.

Categories