set element values using foreach not working as expected - php

I have a muti-dimention array like this:
$arrayTest = array(0=>array("label"=>"test","category"=>"test","content"=>array(0=>array("label"=>"test","category"=>"test"),1=>array("label"=>"test","category"=>"test"))));
then I want to set all the labels in the content array like this:
foreach($arrayTest as $obj) {
foreach($obj["content"] as $anobj){
$anobj["label"] = "hello";
}
}
After that I print out the array
echo json_encode($arrayTest);
On the browser I saw:
[{"label":"test","category":"test","content":[{"label":"test","category":"test"},{"label":"test","category":"test"}]}]
Nothing changed, but if I try
$arrayTest[0]["content"][0]["label"] = "hello";
$arrayTest[0]["content"][1]["label"] = "hello";
Then it seems working. I want to know why the first method not working?

You need to iterate over the array by reference for the changes to stick:
foreach($arrayTest as &$obj) { // by reference
foreach($obj["content"] as &$anobj){ // by reference
$anobj["label"] = "hello";
}
}
// Whenever you iterate by reference it's a good idea to unset the variables
// when finished, because assigning to them again will have unexpected results.
unset($obj);
unset($anobj);
Alternatively, you can index into the array using keys, starting from the root:
foreach($arrayTest as $key1 => $obj) {
foreach($obj["content"] as $key2 => $anobj){
$arrayTest[$key1]["content"][$key2]["label"] = "hello";
}
}

Related

How to get index of array of object without using loop in PHP

I need to get index of from array of objects without using loop as per the key name using PHP. Here I am explaining my code below.
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
$key = array_search('Jack', $arr);
echo $key;exit;
Here my code does not give any output. By using some key name I need the index of that object present inside array and also I dont want to use any loop. I need Is ther any PHP in build method so that I can get the result directly.
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
function myfunction($v){return $v['name'];}
echo array_search('Jack', array_map( 'myfunction', $arr ));
<?php
$arr = array(array("name"=>"Jack","ID"=>10),array("name"=>"Jam","ID"=>11),array("name"=>"Joy","ID"=>12));
//calling function searchByName
$key = searchByName('Jasck',$arr);
if($key != '-1'){
print_r($arr[$key]);
}else{
echo "No match found";
}
//function to chek if the name is there or not.
function searchByName($name, $array) {
foreach ($array as $key => $val) {
if ($val['name'] == $name) {
return $key;
}
}
return '-1';
}
sandbox

how to get the value of an object inside an array?

I have this array of objects:
$table=[{"count":"2","id_f":"2255"},{"count":"6","id_f":"5886"}];
I want to get the value of id_f of each object and check if this value exist in another array ,I tried with this but it gives me the wrong result:
foreach($table as $t){
if (in_array($t[$id_f],$array){
//dosomething}
}else{
//do something else
}
}
I also tried with this:
foreach($table as $t){
if (in_array($t->$id_f,$array){
//dosomething}
}else{
//do something else
}
}
I can't get the right result , I will appreciate any help.
Another approach without foreach loop:
<?php
$table=json_decode('[{"count":"2","id_f":"2255"},{"count":"6","id_f":"5886"}]');
$data = [10, 20, 2255];
array_walk($table, function($obj) use (&$data) {
if (in_array($obj->id_f, $data)) {
echo "+";
} else {
echo "-";
}
});
The output obviously is:
+-
You dont show a json_decode() anywhere in your code, thats the first thing to do with a JSON String, to decode it into a PHP data structure. In this case an array of objects.
$other_array = array('2255', '9999');
$table='[{"count":"2","id_f":"2255"},{"count":"6","id_f":"5886"}]';
$array = json_decode($table);
foreach ( $array as $obj ) {
if (in_array($obj->id_f, $other_array)) {
echo 'Found one ' . $obj->id_f . PHP_EOL;
} else {
echo 'No match for ' . $obj->id_f . PHP_EOL;
}
}
Results
Found one 2255
No match for 5886
There's no need for the dollar sign before your Object property name (actually, it won't work, except of course if $id_f is a real variable which has for value 'id_f', but somehow I doubt it) :
foreach ($table as $t) {
if (in_array($t->id_f, $array){
// do something
} else {
// do something else
}
}
it can be done like this:
to define the object array you can define like below with json string approach. or to define object is like this $table = new stdClass();
<?php
$table='[{"count":"2","id_f":"2255"},{"count":"6","id_f":"5886"}]';
$obj = json_decode($table);
$array=array("2555","2255");
foreach($obj as $t){
if (in_array($t->id_f,$array)){
//dosomething
}else{
//do something else
}
}
?>

Add element to array then encode it to json

I have this code
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
//print_r($arr);
}
echo json_encode($arr);
what I am trying to do is to add something => false to each record of the array
so lets say I got from the database
array of
title:"aaaaa",
start: "xxxx",
end: "cccc",
I want to add to each one something :false to become like
title:"aaaaa",
start: "xxxx",
end: "cccc",
something,false
for each record
but the problem is when I print using the print_r its fine, but the json_encode print only the last one.
Passing by value vs. by reference
You are passing your $arr by value in your foreach loop. Try to pass it by reference.
This is done by adding a & just before your $arr variable in your loop declaration:
foreach ($data['events'] as &$arr) {
settype($arr,"array");
$arr['something'] = false;
}
echo json_encode($data['events']);
How it works
Passing by value means that your foreach loop instanciates a local copy or your array. All modifications made inside the loop will affect only the local copy.
Passing by reference means that inside your loop, you are working directly on the original array. But be careful when doing that because it can be dangerous. For instance, I don't know what are the consequences of calling setType($arr,"array"); for the rest of your code.
You're not collecting $arr from each iteration of your loop into anything. It looks like you probably want to push $arr onto another array that stores everything, and then JSON encode that new array.
Try this:
$collection = array();
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
array_push($collection, $arr);
}
echo json_encode($collection);
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as &$arr) {
settype($arr,"array");//This if there is not array
$arr['something'] = false;
}
echo json_encode($data['events']);
Try to make your own json like this
$strJson = '';
$data['events'] = $this->calendar_model->get_events();
foreach ($data['events'] as $arr) {
settype($arr,"array");
$arr['something'] = false;
//Assign value as yours in blow code
$strJson .= '{"title" : "'.$arr.'","start" : "'.$arr.'","end" : "'.$arr.'"},';
}
$strJson1=rtrim($strJson, ",");
$newStr = '['.$strJson1.']';
echo $newStr;

how filter array recursive if match condition in php

lets say i have a array
array
array
key1 = 'hello im a text'
key2 = true;
key3 = '><><';
array
array
key1 = 'hello another text'
key2 = 'im a text too'
key3 = false;
array
key1 = ')(&#'
array
key1 = 'and so on'
how can i get something like below from the above arrays?
array
1 => 'hello im a text';
2 => 'hello another text;
3 => 'im a text too';
4 => 'and so on';
heres what ive done
$found = array();
function search_text($item, $key)
{
global $found;
if (strlen($item) > 5)
{
$found[] = $item;
}
}
array_walk_recursive($array, 'search_text');
var_dump($found);
but somehow it doesn't work
Try something similar to this:
function array_simplify($array, $newarray=array()) { //default of $newarray to be empty, so now it is not a required parameter
foreach ($array as $i) {
if (is_array($i)) { //if it is an array, we need to handle differently
$newarray = array_simplify($i, $newarray); // recursively calls the same function, since the function only appends to $newarray, doesn't reset it
continue; // goes to the next value in the loop, we know it isn't a string
}
if (is_string($i) && strlen($i)>5) { // so we want it in the one dimensional array
$newarray[] = $i; //append the value to $newarray
}
}
return $newarray; // passes the new array back - thus also updating $newarray after the recursive call
}
My note: I haven't tested this, if there's bugs, please tell me and I'll try to fix them.
Something like this should work,
as condition i've used
if(is_string($son))
in order to get some results, you can adjust it as you prefer
$input = <your input array>;
$output = array();
foreach($input AS $object)
{
search_text($object,$output);
}
var_dump($output);
function search_text($object, &$output)
{
foreach($object AS $son)
{
if(is_object($son))
{
search_text($son, $output);
}
else
{
if(is_string($son))
{
$output[] = $son;
}
}
}
}
Description:
search_text gets 2 parameters: the $object and the resulting array $output.
It checks foreach object's property if it is an object or not.
If it is then that object needs to be checked itself,
otherwise search_text checks if the input is a string, if it is the it is stored into the $output array

PHP - array_push() & $array[] doesn't work?

1. PHP function.
I've created validating function, here it is in shorter version:
function my_function($input) {
$settings = my_source(); // function taht outputs a long array
foreach ($settings as $setting) {
$id = $setting['id'];
$foo = $setting['foo'];
$option = get_option('my_theme_settings');
if($foo == "bar") {
$valid_input[$id] = $input[$id];
}
}
return $valid_input;
};
Basically it takes $input and saves it as $valid_input. When it gets new $input it overwrites the old #valid_inpu and so on.
I want to create an additional $valid_input[$id] array that will not overwrite itself, but just push new elements inside.
2. Array_push() that doesn't work.
So the new updated code will look like that:
function my_function($input) {
$settings = my_source(); // function taht outputs a long array
foreach ($settings as $setting) {
$id = $setting['id'];
$foo = $setting['foo'];
$option = get_option('my_theme_settings');
if($foo == "bar") {
$valid_input[$id] = $input[$id];
}
else if($foo == "noupdate") { // it doesn't work
$valid_input[$id] = array();
array_push($valid_input[$id], $input[$id]);
}
}
return $valid_input;
};
As mentioned in comment above - this doesn't work, input always overwrites the option, it creates an array but it always contains only one element that is being erased with the new one (I guess array_push should prevent that behavior, right?).
3. The same happens with $array[] =
function my_function($input) {
$settings = my_source(); // function taht outputs a long array
foreach ($settings as $setting) {
$id = $setting['id'];
$foo = $setting['foo'];
$option = get_option('my_theme_settings');
if($foo == "bar") {
$valid_input[$id] = $input[$id];
}
else if($foo == "noupdate") { // it doesn't work
$valid_input[$id][] = $input[$id];
}
}
return $valid_input;
};
Still it overwrites the old value of $valid_input instead of pushing an element.
Any ideas? Maybe there's something wrong with the code? This whole function a Wordpress callback for function called register_setting(), but I guess it's mostly PHP related as folks on WPSE can't help me.
4. EDIT
This does exactly what I want, but why point 3. doesn't work then?
else if($foo == "noupdate") { // it doesn't work
$valid_input[$id][] = 'something';
$valid_input[$id][] = 'something_else';
$valid_input[$id][] = 'something_else2';
}
$valid_input[$id] needs to be set to array before you treat it as one.
$valid_input[$id] = array();
array_push( $valid_input[$id], "some stuff");
Same deal with [] notation
$valid_input[$id] = array();
$valid_input[$id][] = "some stuff";
To check if the array has been declared, so this:
if(!is_array($valid_input[$id]){
$valid_input[$id] = array();
}
The thing is that objects are passed as reference. you need to clone the objects before using the array_push function. here is a sample function that will clone an object:
function DeepCopy($ObjectToCopy) {
return unserialize(serialize($ObjectToCopy));
}
then you can use it this way
array_push($MyObjectsArray, DeepCopy($MyObject));
is it possible that you are trying to push a new value to the array with a key value that already exists? i would test for an existing key value in your array before trying to push a value/key pair to it. example:
if ( !isset( $arr[ $key ] ) ) {
$arr[ $key ] = $value;
} else {
echo " duplicate key value ";
}
Either array_push() or a variable used with the array append operator [] need to actually be an array or these won't work. Double check that whatever is in $valid_input[$id] is an array before doing array operations on the variable. Check by doing:
if (is_array($valid_input[$id])) {
// your code
}

Categories