PHP push new key and value in existing object array - php

In my study how objects and arrays work with PHP I have a new problem. Searching in existing questions didn't give myself the right "push".
I have this for example:
$html_doc = (object) array
(
"css" => array(),
"js" => array()
);
array_push($html_doc , "title" => "testtitle");
Why is this not working? Do i need to specify first the key title? Or is there another "1 line" solution?

array_push() doesn't allow you to specify keys, only values: use
$html_doc["title"] = "testtitle";
.... except you're not working with an array anyway, because you're casting that array to an object, so use
$html_doc->title = "testtitle";

You can simply use $html_doc["title"] = "testtitle";
Check this comment on the array_push manual page.

Related

Associative array of arrays

Ive come upon the following code and having trouble deciphering its use.
(changed up the variable names a bit for simplicity)
$fooo = array(
'dog' => array('pages', 'home'),
'cat' => array('users', 'login'),
'bird' => array('users', 'reset', 1),
);
I am familiar with associative arrays but have not seen this "nested array" implementation before.
Is this code creating an array of arrays?
For example, $fooo['dog'] returns an array where $dog[0]='pages' and $dog[1]='home'
That seems wrong.
Yes, this is an array of arrays. But it perhaps may be more accurate to describe it as an associative array with an indexed array for every value.
The following can be done with it:
$fooo['dog'] // gets array("pages", "home")
$fooo['bird'][0] // gets "users"
$fooo['cat'][1] // gets "login"
$fooo['cow'] = array('x', 'y'); // adds another value to the outer array
$fooo['bird'][] = 2; // $fooo['bird'] now equals array('users', 'reset', 1, 2)
There is nothing wrong with this code, but your example is lacking practicality. There is plenty of code that uses such structures though. For example, a logical representation of a menu with sub-menus on a website (which seems like the source of your sample), this data structure can then be looped to generate an HTML/CSS menu.

PHP - How do I add onto an array?

I have an existing array. I need to use array_push, or similar, to add a value onto the end of an array and assign it.
Code: http://pastebin.com/tNg7gZ91
array_push($playerHolo, 'player' => 'UsernameHere'); //invalid syntax (the =>)
var_dump($playerHolo);
I'm trying to add the value "player" and assign the string "UsernameHere" to it.
Other Information
array_push($playerHolo['1'], array('player' => 'UsernameHere'));
Displays
http://pastebin.com/GTDe8Ex9
Suggestions?
The second parameter must be an array using valid array syntax if it is an associative array:
array_push($this->playerHolo, array('player' => 'UsernameHere'));
array_push($this->playerHolo, ['player' => 'UsernameHere']);
But why don't you just use a simple assignment?
$this->playerHolo['player'] = 'UsernameHere';
You'll notice I used $this->playerHolo. This is because you are also using the wrong syntax for accessing class member variables. This will save you from the next error you will encounter.
You can do this in 2 ways:
array_push($playerHolo, array('player' => 'UsernameHere'));
or
$playerHolo['player'] = 'UsernameHere';

How to change data of reference passed Array in Closure

I have an Eventbus that takes a filter name as its first parameter and a Closure as second parameter. Like this:
$this->EventBus->subscribe('FilterTestEvent', function(){/*Do Something*/});
It's called like this:
$filteredValue = $this->EventBus->filter('FilterTestEvent', $anyValue);
What I want now is to pass an array as reference to the Closure that then is changed in any way (here: add elements) and then return something as the filtered value:
$item_to_change = array('e1' => 'v1', 'e2' => 'v2');
$this->EventBus->subscribe('FilterTestEvent', function(&$item){
$item['new'] = 'LoremIpsum';
return true;
});
$filtered = $this->EventBus->filter('FilterTestEvent', $item_to_change);
Now I would a print_r($item_to_change) expect to look like the following:
Array
(
[e1] => v1
[e2] => v2
[new] => LoremIpsum
)
But instead it looks like the original array:
Array
(
[e1] => v1
[e2] => v2
)
The eventbus internally stores all closures and calls them if needed through call_user_func_array() with the closure as first argument and the value as the only argument array element.
How can I achieve what it's meant to do?
Source Code to the Eventbus: http://goo.gl/LAAO7B
Probably this line:
$filtered = $this->EventBus->filter('FilterTestEvent', $item_to_change);
is supposed to return a new filtered array, not modify the original one.
So check it:
print_r($filtered);
Passing by reference is possible by modifying a function (adding &):
function filter(&$array){ //Note & mark
$array['new_index'] = "Something new" ;
}
$array = array("a"=> "a");
filter($array); //The function now receives the array by reference, not by value.
var_dump($array); //The array should be modified.
Edit:
Make your callback return the filtered array:
$this->EventBus->subscribe('FilterTestEvent', function(&$item){
$item['new'] = 'LoremIpsum';
return $item ;
});
Passing by reference should not work here, because in the source code that $value variable is swapped with another value and returned after.
Ok. I found the answer. The filter function needs to be changed so that it accepts arrays as value, in which I can save the reference. For details see difference Revision 1 and Revision 2 of the Eventbus source code, here: goo.gl/GBocgl

PHP function for adding sub-array to a multi-dim array

I am having trouble finding the right function for this.
I have a session array
$_SESSION['cart_items'][0] = (
'item_name'=>'some name',
'item_price'=>'29.99',
...
)
I need to append another array that has a specific key. The array is from a $_POST object.
$_POST['copy'] = array (
'name'=>'my name',
'office'=>'my office'
)
Appended session to look like this.
$_SESSION['cart_items'][0] = (
'item_name'=>'some name',
'item_price'=>'29.99',
...
'copy'=>array(
'name'=>'my name',
'office'=>'my office'
)
)
I tried array push but this gives me an indexed key for the appended array instead of 'copy'
I know the index of the parent array so i could create the new sub array and then loop the $_POST into it but that doesn't seem right either.
I might be missing the point - but cant you just do:
$_SESSION['cart_items'][0]['copy'] = $_POST['copy'];
$_SESSION['cart_items'][0][$key] = $_POST[$key]; // as you said you know the key .. is it only one?

MongoDB search $in _id php

Usually when I search for one related ID I do it like this:
$thisSearch = $collection->find(array(
'relatedMongoID' => new MongoId($mongoIDfromSomewhereElse)
));
How would I do it if I wanted to do something like this:
$mongoIdArray = array($mongoIDfromSomewhereElseOne, $mongoIDfromSomewhereElseTwo, $mongoIDfromSomewhereElseThree);
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => new MongoId(mongoIdArray)
)));
I've tried it with and without the new MongoId(), i've even tried this with no luck.
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
how do I search '$in' "_id" when you need to have the new MongoID() ran on each _id?
Hmm your rtying to do it the SQL way:
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
Instead try:
$_ids = array();
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
That should produce a list of ObjectIds that can be used to search that field - relatedMongoID.
This is what I am doing
Basically, as shown in the documentation ( https://docs.mongodb.org/v3.0/reference/operator/query/in/ ) the $in operator for MongoDB in fact takes an array so you need to replicate this structure in PHP since the PHP driver is a 1-1 with the documentation on most fronts (except in some areas where you need to use an additional object, for example: MongoRegex)
Now, all _ids in MongoDB are in fact ObjectIds (unless you changed your structure) so what you need to do to complete this query is make an array of ObjectIds. The ObjectId in PHP is MongoId ( http://php.net/manual/en/class.mongoid.php )
So you need to make an array of MongoIds.
First, I walk through the array (could be done with array_walk) changing the values of each array element to a MongoId with the old value encapsulated in that object:
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
I use a ternary operator here to see if the value is already a MongoId encapsulated value, and if not encapsulate it.
Then I add this new array to the query object to form the $in query array as shown in the main MongoDB documentation:
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
So now when the query is sent to the server it forms a structure similar to:
{relatedMongoId: {$in: [ObjectId(''), ObjectId('')]}}
Which will return results.
Well... I came across the same issue and the solution might not be relevant anymore since the API might have changed. I solved this one with:
$ids = [
new \MongoDB\BSON\ObjectId('5ae0cc7bf3dd2b8bad1f71e2'),
new \MongoDB\BSON\ObjectId('5ae0cc7cf3dd2b8bae5aaf33'),
];
$collection->find([
'_id' => ['$in' => $_ids],
]);

Categories