is it possible to make stdClass objects work like a generically indexed array?
i.e.
$array = Array
(
[0] => 120
[1] => 382
[2] => 552
[3] => 595
[4] => 616
)
would be constructed like
$a = array();
$array[] = 120;
$array[] = 382;
etc.
but if i do that with an object it just overwrites itself:
$obj = new stdClass;
$obj->a = 120;
$obj->a = 382;
i know i can change 'a' every time,
sorry if this is a stupid question but it's stumping me for some reason!
Appreciate any help :)
Dan
In short, no, because you will always have to name your properties. Going through the trouble of writing a simple class with ArrayAccess makes no sense either as you've essentially recreated an array with nothing to show for it except extreme sacrifices in performance and transparency.
Is there some reason your problem cannot be solved infinitely more simply by using an array, or is this just a wish-I-knew question?
EDIT: Check out this question for more info.
No, you can't. Using the brackets ([]) like that is called "ArrayAccess" in PHP, and is not implemented on the stdClass object.
It sounds like you might want something like
$foo = new stdClass();
$foo->items = array();
$foo->items[] = 'abc';
$foo->items[] = '123';
$foo->items[] = 'you and me';
You could also try casting an array as a stdClass to see what happens.
$foo = array();
$foo[] = 'abc';
$foo[] = '123';
$foo[] = 'you and me';
$foo = (object) $foo;
var_dump($foo);
I can't really see what you mean to do, short of
<?php
$obj->a = array();
$obj->a[] = 120;
$obj->a[] = 382;
// ...
?>
You cannot simply "push" a field onto an object. You need to know the name of the field in order to retrieve the value anyways, so it's pretty much nonsense.
An object is not an array. If you want numerically indexed elements, use an array.
If you want named elements use either an Object or an Associative Array.
As for why you're getting different behaviour, it's because in the Array, you are not specifying an index, so PHP uses the length of the Array as the index. With the Object, you have to specify the name (in this case 'a').
The other thing you may want to do is have an Object, with a member that is an array:
$obj = new stdClass;
$obj->arr = array();
$obj->arr[] = 'foo';
$obj->arr[] = 'bar';
also don't forget you can cast an array to an object:
$obj = (object) array(
'arr' => array(
'foo',
'bar'
)
);
Only for the sake of OOP, don't use classes. If you really want to implement this functionality, use this class:
class ArrayClass
{
protected $storage = array();
public function push($content) {
$this->storage[] = $content;
return $this;
}
public function get($index) {
if (isset($this->storage[$index])) {
return $this->storage[$index];
} else {
//throw an error or
return false;
}
}
}
You can get exactly this in JavaScript.
Related
Just so you know I'm working in WordPress. I have an array and want to create an object with only certain values from that array.
Then I have another separate array, I'd like to add to this new object. I might be over complicating things. If I am, please let me know.
Here's what I have so far:
$custom = get_post_custom(); //Gets array of values
$picObject = (object)$custom; //Creates object
$picCount = $custom['picturecount'][0];
for ($x = 1; $x <= $picCount; $x++) {
// This assembles a URL that I want to add to the array.
$finalUrl = $picUrl.$gsi.'&picfilename='.$vin.'_00'.$x.'.jpg';
}
Let me know if you need anything else. Thanks in advance everyone!
If you want to create an object with only some values from your array, you shouldn't cast the array because you'll end up with all of its values. Instead, create a new object and set the values you want:
$array = array(
'foo' => 'bar',
'bar' => 'baz'
);
$object = new stdClass();
$object->bar = $array['bar'];
$object->something_else = 'w00t!';
Casting an array to object (i.e. (object)$array) will get you the same type of object, so you can still use $object->new_property = 'foo'; to add stuff to it.
Well, after I rewrote my problem description 2 times i'll do it somehow less abstract now.
I need a way to return data within an array so that this array accepts this returned data as native key / value pair.
Illustration:
simple array:
$a = array('a' => 'b');
I could access the value of 'a' by simply calling $a['a']... clearly
I now need a way to exactly get this result via a function call or hack or something!
something like
$a = array(foo('a','b'));
the problem is, when "foo" return an array, the structure of my $a (array) will look like this:
array(array('a','b')) and not like array('a' => 'b')
and will prevent me from being able to access the data via $a['a']
The reason I need this is that I instance objects on demand within this array definition and also modify these instances on the fly, but I do need 2 different returns (of functions) of one and the same object and don't want to copy past half the initialization. Further more I don't want to first declare object instances outside the array because this would be a absolute overkill and would perfectly destroy all readability.
So.. is there a possibility to extract returned values to native language features?
PS. I also don't want to iterate over the array to re-process the data
$a = foo('a','b');
with
function foo($x,$y) {
return array($x => $y);
}
If foo() is returning an array, why not;
$a = foo('a','b');
Seems simple enough, right?
Easiest way:
$a[]= foo();
function foo() {
return array(1,2);
}
Or use reference:
$value = NULL;
$a = array(foo($value), $value);
with
function foo(&$value) {
$value = 'b';
return 'a';
}
function foo($key) {
$r = array(
'a' => 'b',
$key2 => $value2,
$key3 => $value3,
$key4 => $value4
// ...
);
return $r[$key];
}
$a = foo('a'); // means $a = 'b';
Do it solves your problem ?
If I wanted to create an array in PHP with the following format, what would be the best way to approach it? Basically I want to declare the array beforehand, and then be able to add the values to person_id, name and age.
'person_id' => array('name'=>'jonah', 'age'=> 35)
To the first answer #Joe, first of all, your class doesn't support encapsulation since your attributes are public. Also, for someone who doesn't know how to create an array, this concept may be a bit complicated.
For the answer, changing a bit the class provided by #Joe, PHP provide a simple way of using arrays:
If you need many rows for this array, each row has a number, if not, remove the [0] for only one entry.
$persons = array();
$persons[0]['person_id'] = 1;
$persons[0]['name'] = 'John';
$persons[0]['age'] = '27';
Depending on how you want to use it, you could make a simple object:
class Person
{
public $person_id;
public $name;
public $age;
}
$person = new Person; // make the object beforehand
$person->person_id = 123; // their id
$person->name = 'Joe'; // my name
$person->age = 21; // yeah, right
This is virtually identical to an array (in terms of how it's used) except for:
Instead of new array() you use new Person (no brackets)
Instead of accessing items with ['item'] you use ->item
You can start with an empty array:
$arr = Array();
Then add stuff to that array:
$arr['person_id'] = Array();
$arr['person_id']['name'] = "jonah";
$arr['person_id']['age'] = 35;
I would like to know what is the right of creating objects arrays in php.
My goal here is to be able to get data like this:
$obj = new MyClass();
echo $obj[0]->parameter; //value1
echo $obj[1]->parameter; //value2
Thanks for your time.
EDIT:
And if I want to do it in class it should look like this?
class MyClass{
public $property;
public function __construct() {
$this->property[] = new ProjectsList();
}
}
Any of the following are valid:
$myArray = array();
$myArray[] = new Object();
$myArray[1] = new Object();
array_push($myArray, new Object);
Try this,
$obj = array(new stdClass(), new stdClass())
or
$obj = array()
$obj[] = new stdClass()
$obj[] = new stdClass()
EDIT:
Class to stdClass
An important hint ...
The memory allocation for PHP arrays is exponential. A simple example: All array entries fit into an array, that allocates 2MB of memory. If this memory is no longer sufficient for all array entries, the memory allocation is expanded exponentially until the PHP memory limit is reached. If the array needs more than the 2 MB in this example, it will expand to 4MB, 16MB, etc.
When dealing with objects, better use collections. PHP provides the SplObjectStorage. This kind of collection allocates the exactly needed memory for its contents. Iteration over this collections behaves like using a yield. Only the memory for the current object in iteration is allocated. Beside that the SplObjectStorage class takes objects only. Should work perfectly for your purposes.
<?php
declare('strict_types=1');
namespace Marcel;
$collection = new SplObjectStorage();
$object1 = new stdClass();
$object2 = new stdClass();
$collection->attach($object1);
$collection->attach($object2);
The above shown code allows some stricter searching.
$collection->contains($object1); // returns true
Detaching an item works like a charme.
$collection->detach($object1);
$collection->contains($object1); // returns false
Iterations works with a pretty fast foreach loop or a while loop.
$collection->rewind();
foreach ($collection as $object) {
// yielding works here
}
$collection->rewind();
while ($collection->valid()) {
// yielding also works here automatically
$collection->next();
}
hope this will be helpful
$newArray[] = (object) array();
Honestly, I think you are on the right path. from what it sounds like you are not just trying to add to arrays, but convert arrays to objects.
<?php
$obj = (object) 'ciao';
echo $obj->scalar; // outputs 'ciao'
?>
PHP Objects
EDIT: I don't think you could add an object like this:
$this->property[] = new ProjectsList();
the "new ProjectsList()" would be how you would create an object from a class. ProjectsList would need to be a class. it would look more like this:
$obj = new ProjectsList;
$this->property[] = $obj;
you would need to make sure the ProjectsList existed first though.
I want create arrays with object keys in PHP, i.e. something like this:
<?php
$keyObject = new KeyObject;
$valueObject = new ValueObject;
$hash = array($keyObject => $valueObject);
However, this raises an error. Arrays may only have integer or string keys. I end up having to do something like:
$hash = array(
'key' => $keyObject,
'value' => $valueObject);
This works but it's not as neat as I'd like. Is there a better way? (Perhaps something from the SPL that I'm missing...)
TIA
You can use SplObjectStorage from the SPL as a map with object keys:
$map = new SplObjectStorage;
$key = new StdClass;
$value = new StdClass;
$map[$key] = $value;