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.
Related
Hey in a recent project I got this working and was quite amazed that such a snipped works.
$parentRef = &$elements[$targetPath]->
{$contentTypeMap[$contentTypeIdMap[$contentTypeId]]};
if(is_array($parentRef)) {
$parentRef = &$parentRef[];
}
$parentRef = $element;
It was quite intuitive that it might work that way but what exactly is
$parentRef[] returning to make this work?
If I var_dump it, i get null.
Here is a simplified example which seems to work.
<?php
$arr = [1, 2];
$ref = &$arr[];
$ref = 3;
foreach($arr as $n) {
echo $n;
}
This example returns 123 just to verify that it works.
In your example $arr[] will create new element in array with NULL value. The ampersand is reference to this position, so when you store something to $ref, it will be stored in this new position, because $ref is just reference (something like pointer, but its not pointer!) to this new element in array
I have a problem occurring in one function, for me it's strange because I thought that the behaviour of objects were different. The function is:
function getMessages($imapCon)
{
$messageHeaders = array();
$tempObj = new stdClass();
$totalMessages = imap_num_msg($imapCon);
for ($i = $totalMessages; $i > 0; $i--)
{
$headers = imap_headerinfo($imapCon, $i);
$tempObj->Unseen = $headers->Unseen;
$tempObj->fromaddress = $headers->fromaddress;
$tempObj->Date = $headers->Date;
$tempObj->Subject = $headers->Subject;
$tempObj->uid = imap_uid($imapCon, $i);
array_push($messageHeaders, $tempObj);
}
return json_encode($messageHeaders);
}
In the json encoded, I get the same values for all properties (Unseen, fromaddress, Date...). The properties are set correct, but the values are duplicated. Why?
If I do something like:
for ($i = $totalMessages; $i > 0; $i--)
{
$tempObj = new stdClass();
...
array_push($messageHeaders, $tempObj);
unset($tempObj);
}
return json_encode($messageHeaders);
}
declaring the object inside the for, it works. But I believe this is a poor fix and nor the right thing to do...
Creating a new $tempObj inside the loop is the right way. When you add this object into array, it's not copied, but a pointer to it is added into the array. Check this documentation - http://php.net/manual/en/language.oop5.basic.php#example-191 (look at the simple assignment, ignore the $reference variable for now).
So you end up with array containing the whole bunch of links pointing to the same object. But if you create a new $tempObj inside the loop, all objects will be different.
Alternatively, you can do this:
array_push($messageHeaders, clone($tempObj));
but although this will equally work in this case, it may not work if the $tempObj would have more complex structure, such as instances of othe classes as properties of $tempObj.
On a side note, in PHP4 your code would work as you expected as PHP4 was copying actual objects on assignment instead of just pointers as PHP5 does.
It looks like you are just pushing a reference into the $messageHeaders array each time, but you are reassigning the data on the same instance. Not sure where you got the idea that it was wrong to create a new $tempObj on each iteration but that is one way you could solve this. Another way would be to just add to the $messageHeaders array directly like this:
$messageHeaders[] = array(
'Unseen' => $headers->Unseen,
'fromaddress' => $headers->fromaddress,
'Date' => $headers->Date,
'Subject' => $headers->Subject,
'uid' => imap_uid($imapCon, $i)
);
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've this piece of code, it retrieves a node from my node type 'Student'.
I try different things to, save all values in '$node' into an array. But $node is a object.
My question is how doe I store 'all' values in $node into a array. In Java an C# it's simpler to do that.
$results = db_query(db_rewrite_sql("SELECT nid FROM {node} WHERE type =
'student'"));
while($nid = db_result($results)) {
$node = node_load($nid);
// Do something with $node
}
in java or c# you can say in a for/foreach/while 'loop'
String item[] = null;
for(int i = 0; i<=myNode; i++) {
item.add(myNode[i]); // the item and value UgentID, name student, location student are been stored in item array.
}
I don't know if PHP has that too. "yourObject.Add(otherObject)"
The following let's your object behave (access-wise) as an array:
$result = new ArrayObject( $node );
If you truly want an array, simply cast it afterwards:
$result = (array) $result;
Heck, come to think of it, you could even simply do:
$result = (array) $node;
:-)
Both methods of casting to array will actually expose protected/private properties as well, I just found out. :-S Horrible.
edit:
// initiate array
$nodes = array();
while($nid = db_result($results)) {
// either do one of the following, to push
$nodes[] = node_load($nid);
// or:
array_push( $nodes, node_load($nid) );
// Do something with $node
}
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.