php shorthand to append to object - php

I'm pulling through data from my database and wish to add an object to the end of each item. The following code works, but I'm assuming there's a better way than repeating all the info and adding to a new object.
$cs = $client->contact()->get();
foreach ($cs as $c) {
$contact = (object)[
'id' => $c->id,
'name' => $c->name,
'role' => $c->role,
'phone' => $c->phone,
'address' => $c->address,
'postcode' => $c->postcode,
'otherClients' => Contact::find($c->id)->clients()->get(), //this is the additional info
];
$contacts[]=$contact;

You could simply mutate the original objects if you don't need to leave $cs intact.
foreach ($cs as $c) {
$c->otherClients = Contact::find($c->id)->clients()->get();
}

you can use
As suggested by #MrCode
$cs = $client->contact()->get();
PHP 5.4+
foreach ($cs as $c) {
$c->otherClients = Contact::find($c->id)->clients()->get(), //this is the additional info
}
PHP 4 Or below
foreach ($cs as &$c) {
$c->otherClients = Contact::find($c->id)->clients()->get(), //this is the additional info
}

Related

write foreach inside calling class

hi im using this php code
$data = new $models([
'number' => $row[0],
'name' => $row[1],
]);
like this its working fine but what i want is that i dont know the keys 'number' and 'name' what if i want them come from array like this ..
$array = ['name','number','anything'];
$data = new $models([
foreach($array as $key => $arr)
{
$arr => $row[$key];
}
]);
how can i do something like this ..
calling foreach inside creating new class ..
thanks ..
<?php
class Foo{}
$className='Foo';
$array = ['name','number','anything'];
$row = ['name_v', 'number_v', 'anything_v'];
$foo = new $className();
foreach(array_combine($array, $row) as $k => $v){
$foo->$k = $v;
}
print(json_encode($foo));
So long as they have the same number of elements in the order that you want, just combine them:
$array = ['name', 'number', 'anything'];
$data = new $models(array_combine($array, $row));
You can do it in one line:
$data = new $models(array_combine(['name', 'number', 'anything'], $row));

Passing an array copy to a function expecting a reference

I have a loop of the following kind:
foreach ($values as $key => $value) {
$attrs = array('NAME' => $key);
myproc ($attrs);
......
}
Where in myproc the first parameter is defined by reference:
function myproc (& attrs) { .... }
myproc adds the passed value to some structure.
The trouble with this is that at loop end, all the arrays added to the generated structure contains the same value, the last value extracted from the loop.
I tried also something like this :
foreach ($values as $key => $value) {
$attrs = array('NAME' => $key);
$copy = $attrs;
myproc ($copy);
......
}
but the result is the same. I'not allowed to modify the procedure. Any suggestions?
Based on the comment below your question, it seems that the problem is that you are passing a reference and this reference gets updated in the loop, leading to updates in the object you are generating in your function.
To avoid this, you need to unset the variable after the function call so that the link between the value in your object and the referenced variable is broken:
foreach ($values as $key => $value) {
$attrs = array('NAME' => $key);
myproc ($attrs);
// unset the variable so that newer values of it will have no effect
// on the object generated in `myproc`
unset($attrs);
......
}
Also see the manual.
<?php
foreach(['red','pink','green'] as $colour) {
$attrs = ['colour' => $colour];
if(colourToAction($attrs)) {
$results[] = $attrs;
}
}
var_export($results);
function colourToAction(&$attrs) {
$actions = ['red'=>'stop','amber'=>'wait', 'green' => 'go'];
if(isset($attrs['colour']) && isset($actions[$attrs['colour']])){
$attrs['action'] = $actions[$attrs['colour']];
return true;
}
}
Output:
array (
0 =>
array (
'colour' => 'red',
'action' => 'stop',
),
1 =>
array (
'colour' => 'green',
'action' => 'go',
),
)

Loop over one array as if it was a multidimensional array

I have an array like:
$array = array(
'name' => 'Humphrey',
'email' => 'humphrey#wilkins.com
);
This is retrieved through a function that gets from the database. If there is more than one result retrieved, it looks like:
$array = array(
[0] => array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
[1] => array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
If the second is returned, I can do a simple foreach($array as $key => $person), but if there is only one result returned (the first example), I can't run a foreach on this as I need to access like: $person['name'] within the foreach loop.
Is there any way to make the one result believe its a multidimensional array?
Try this :
if(!is_array($array[0])) {
$new_array[] = $array;
$array = $new_array;
}
I would highly recommended making your data's structure the same regardless of how many elements are returned. It will help log terms and this will have to be done anywhere that function is called which seems like a waste.
You can check if a key exists and do some logic based on that condition.
if(array_key_exists("name", $array){
//There is one result
$array['name']; //...
} else {
//More then one
foreach($array as $k => $v){
//Do logic
}
}
You will have the keys in the first instance in the second yours keys would be the index.
Based on this, try:
function isAssoc(array $arr)
{
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}
if(isAssoc($array)){
$array[] = $array;
}
First check if the array key 'name' exists in the given array.
If it does, then it isn't a multi-dimensional array.
Here's how you can make it multi-dimensional:
if(array_key_exists("name",$array))
{
$array = array($array);
}
Now you can loop through the array assuming it's a multidimensional array.
foreach($array as $key => $person)
{
$name = $person['name'];
echo $name;
}
The reason of this is probably because you use either fetch() or fetchAll() on your db. Anyway there are solutions that uses some tricks like:
$arr = !is_array($arr[0]) ? $arr : $arr[0];
or
is_array($arr[0]) && ($arr = $arr[0]);
but there is other option with array_walk_recursive()
$array = array(
array(
'name' => 'Humphrey1',
'email' => 'humphrey1#wilkins.com'
),
array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
)
);
$array2 = array(
'name' => 'Humphrey2',
'email' => 'humphrey2#wilkins.com'
);
$print = function ($item, $key) {
echo $key . $item .'<br>';
};
array_walk_recursive($array, $print);
array_walk_recursive($array2, $print);

php remove object from array of objects

I'm trying to remove an object from an array of objects by its' index. Here's what I've got so far, but i'm stumped.
$index = 2;
$objectarray = array(
0=>array('label'=>'foo', 'value'=>'n23'),
1=>array('label'=>'bar', 'value'=>'2n13'),
2=>array('label'=>'foobar', 'value'=>'n2314'),
3=>array('label'=>'barfoo', 'value'=>'03n23')
);
//I've tried the following but it removes the entire array.
foreach ($objectarray as $key => $object) {
if ($key == $index) {
array_splice($object, $key, 1);
//unset($object[$key]); also removes entire array.
}
}
Any help would be appreciated.
Updated Solution
array_splice($objectarray, $index, 1); //array_splice accepts 3 parameters
//(array, start, length) removes the given array and then normalizes the index
//OR
unset($objectarray[$index]); //removes the array at given index
$reindex = array_values($objectarray); //normalize index
$objectarray = $reindex; //update variable
array_splice($objectarray, $index, 1);
//array_splice accepts 3 parameters (array, start, length) and removes the given
//array and then normalizes the index
//OR
unset($objectarray[$index]); //removes the array at given index
$reindex = array_values($objectarray); //normalize index
$objectarray = $reindex; //update variable
You have to use the function unset on your array.
So its like that:
<?php
$index = 2;
$objectarray = array(
0 => array('label' => 'foo', 'value' => 'n23'),
1 => array('label' => 'bar', 'value' => '2n13'),
2 => array('label' => 'foobar', 'value' => 'n2314'),
3 => array('label' => 'barfoo', 'value' => '03n23')
);
var_dump($objectarray);
foreach ($objectarray as $key => $object) {
if ($key == $index) {
unset($objectarray[$index]);
}
}
var_dump($objectarray);
?>
Remember, your array will have odd indexes after that and you must (if you want) reindex it.
$foo2 = array_values($objectarray);
in that case you won't need that foreach just unset directly
unset($objectarray[$index]);

Setting value in Nested Php Array

Hi I'm trying to loop through a array and set a keys value. Very basic question.
The Code I tried is below.
http://pastebin.com/d3ddab156
<?php
$testArray = array("bob1" => array( 'name' => "bob1", 'setTest' => '2'));
foreach($testArray as $item)
{
$item['setTest'] = 'bob';
}
print_r($testArray);
I imagine I'm missing something stupid here and it is going to be a D'oh! moment for me. What is wrong with it?
Thanks.
You do:
$testArray = array("bob1" => array( 'name' => "bob1", 'setTest' => '2'));
foreach($testArray as $item)
{
$item['setTest'] = 'bob';
}
print_r($testArray);
$item is a copy. You change the copy, not the real array. Try this:
$testArray = array("bob1" => array( 'name' => "bob1", 'setTest' => '2'));
foreach($testArray as $key => $item)
{
$testArray[$key]['setTest'] = 'bob';
}
print_r($testArray);
Or, if you have a lot of data in the array and want to avoid creating a complete copy of each element over every iteration, simply iterate over each element as a reference. Then only a reference to that item is created i memory and you can directly manipulate the array element by using $item:
$testArray = array("bob1" => array( 'name' => "bob1", 'setTest' => '2'));
foreach($testArray as &$item)
{
$item['setTest'] = 'bob';
}
print_r($testArray);
NOTE: be sure to unset $item after the loop so you don't inadvertantly modify the array later by using that variable name.

Categories