PHP: How to create a good foreach shorthand? - php

I have a simple object (or array) like this...
stdClass Object (
[people] => Array
(
[0] => stdClass Object (
[name] => 'John',
[age] => 50,
)
[0] => stdClass Object (
[name] => 'Martin',
[age] => 47,
)
)
And I can easily loop through it using foreach like this
foreach ($people as $person) {
echo $person->name . '<br>';
}
But I would somehow like to have a shorter way to echo all names with something like this...
print_each($people->name)
And it would do exactly the same thing with only 1 short line of code as my 3 lines of foreach code did.
Is there a function like this or how would we go about creating a function like that?

You can use array_column and implode.
echo implode("<br>\n", array_column($arr, "name"));

Probably array_map is the closest to what you want.
array_map(function($person) { echo $person->name; }, $people);

Shortest way and not that ugly would be to add a
__toString
Method to the Person Object like this:
class Person {
public $name;
public function __toString()
{
return (string) $this->name;
}
}
This then enables you to use the very super short:
array_walk($people, 'printf');
Syntax.

If you have array, you can use array_column for that:
$people = [
['name' => 'John', 'age' => 3],
['name' => 'Carl', 'age' => 43]
];
var_dump(
array_column($people, 'name')
);
/*
array(2) {
[0]=>
string(4) "John"
[1]=>
string(4) "Carl"
}

Since PHP 7.4 you can do:
echo implode('', array_map(fn($person) => $person->name . '<br>', $people));
The inner array_map() function takes as second parameter your initial array $people.
The inner array_map() function takes as first parameter an arrow function fn() => that gets the single items $person out of your initial array $people
inside the arrow function each $person->name gets concated with '<br>' and written as value in a new array.
this new array will be returned by the array_map() function
The items of this array will be passed as second parameter to the implode() function and glued together with the empty string ''.
the entire string that implode() returns gets echoed out

If you want to get "smart" about it you can write something like this:
array_walk_recursive($a, function($v, $k) {echo $k === 'name' ? $v : '';});
But being smart over readability is a bad idea, always.

If I had to write a function to do that, it would be something along these lines:
function print_each($collection, $property) {
foreach ($collection as $item) {
echo $item->$property . "<br />";
}
}
Which could be used like so:
$people = [
(object)[
"name" => "Bob",
"age" => 25
],
(object)[
"name" => "Dan",
"age" => 31
],
(object)[
"name" => "Sally",
"age" => 45
]
];
print_each($people, "name"); // prints "Bob<br />Dan<br />Sally<br />"

Related

extract json objects from an array in php [duplicate]

From PHP code I want to create an json array:
[
{"region":"valore","price":"valore2"},
{"region":"valore","price":"valore2"},
{"region":"valore","price":"valore2"}
]
How can I do this?
Easy peasy lemon squeezy: http://www.php.net/manual/en/function.json-encode.php
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>
There's a post by andyrusterholz at g-m-a-i-l dot c-o-m on the aforementioned page that can also handle complex nested arrays (if that's your thing).
Use PHP's native json_encode, like this:
<?php
$arr = array(
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
)
);
echo json_encode($arr);
?>
Update: To answer your question in the comment. You do it like this:
$named_array = array(
"nome_array" => array(
array(
"foo" => "bar"
),
array(
"foo" => "baz"
)
)
);
echo json_encode($named_array);
Simple: Just create a (nested) PHP array and call json_encode on it. Numeric arrays translate into JSON lists ([]), associative arrays and PHP objects translate into objects ({}). Example:
$a = array(
array('foo' => 'bar'),
array('foo' => 'baz'));
$json = json_encode($a);
Gives you:
[{"foo":"bar"},{"foo":"baz"}]
Best way that you should go every time for creating json in php is to first convert values in ASSOCIATIVE array.
After that just simply encode using json_encode($associativeArray). I think it is the best way to create json in php because whenever we are fetching result form sql query in php most of the time we got values using fetch_assoc function, which also return one associative array.
$associativeArray = array();
$associativeArray ['FirstValue'] = 'FirstValue';
...
etc.
After that.
json_encode($associativeArray);
also for array you can use short annotattion:
$arr = [
[
"region" => "valore",
"price" => "valore2"
],
[
"region" => "valore",
"price" => "valore2"
],
[
"region" => "valore",
"price" => "valore2"
]
];
echo json_encode($arr);
That's how I am able to do with the help of solution given by #tdammers below.
The following line will be placed inside foreach loop.
$array[] = array('power' => trim("Some value"), 'time' => "time here" );
And then encode the array with json encode function
json_encode(array('newvalue'=> $array), 200)
Just typing this single line would give you a json array ,
echo json_encode($array);
Normally you use json_encode to read data from an ios or android app. so make sure you do not echo anything else other than the accurate json array.
I created a crude and simple jsonOBJ class to use for my code. PHP does not include json functions like JavaScript/Node do. You have to iterate differently, but may be helpful.
<?php
// define a JSON Object class
class jsonOBJ {
private $_arr;
private $_arrName;
function __construct($arrName){
$this->_arrName = $arrName;
$this->_arr[$this->_arrName] = array();
}
function toArray(){return $this->_arr;}
function toString(){return json_encode($this->_arr);}
function push($newObjectElement){
$this->_arr[$this->_arrName][] = $newObjectElement; // array[$key]=$val;
}
function add($key,$val){
$this->_arr[$this->_arrName][] = array($key=>$val);
}
}
// create an instance of the object
$jsonObj = new jsonOBJ("locations");
// add items using one of two methods
$jsonObj->push(json_decode("{\"location\":\"TestLoc1\"}",true)); // from a JSON String
$jsonObj->push(json_decode("{\"location\":\"TestLoc2\"}",true));
$jsonObj->add("location","TestLoc3"); // from key:val pairs
echo "<pre>" . print_r($jsonObj->toArray(),1) . "</pre>";
echo "<br />" . $jsonObj->toString();
?>
Will output:
Array
(
[locations] => Array
(
[0] => Array
(
[location] => TestLoc1
)
[1] => Array
(
[location] => TestLoc2
)
[2] => Array
(
[location] => TestLoc3
)
)
)
{"locations":[{"location":"TestLoc1"},{"location":"TestLoc2"},{"location":"TestLoc3"}]}
To iterate, convert to a normal object:
$myObj = $jsonObj->toArray();
Then:
foreach($myObj["locations"] as $locationObj){
echo $locationObj["location"] ."<br />";
}
Outputs:
TestLoc1 TestLoc2 TestLoc3
Access direct:
$location = $myObj["locations"][0]["location"];
$location = $myObj["locations"][1]["location"];
A practical example:
// return a JSON Object (jsonOBJ) from the rows
function ParseRowsAsJSONObject($arrName, $rowRS){
$jsonArr = new jsonOBJ($arrName); // name of the json array
$rows = mysqli_num_rows($rowRS);
if($rows > 0){
while($rows > 0){
$rd = mysqli_fetch_assoc($rowRS);
$jsonArr->push($rd);
$rows--;
}
mysqli_free_result($rowRS);
}
return $jsonArr->toArray();
}

PHP Object Iteration - Nested Structures

I'm iterating over an array of objects, some of them nested in a non-uniform way. I'm doing the following:
foreach($response['devices'] as $key => $object) {
foreach($object as $key => $value) {
echo $key . " : " . "$value . "<br>";
}
}
Which works...until it hits the next embedded array/object, where it gives me an 'Notice: Array to string conversion in C:\xampp\htdocs\index.php on line 65' error
I'm relatively new to PHP and have thus far only had to deal with uniform objects. This output is far more unpredictable and can't be quantified in the same way. How can I 'walk' through the data so that it handles each array it comes across?
You should make a recusive function this means, the function call itself until a condition is met and then it returns the result and pass through the stack of previously called function to determine the end results. Like this
<?php
// associative array containing array, string and object
$array = ['hello' => 1, 'world' => [1,2,3], '!' => ['hello', 'world'], 5 => new Helloworld()];
// class helloworld
class Helloworld {
public $data;
function __construct() {
$this->data = "I'm an object data";
}
}
//function to read all type of data
function recursive($obj) {
if(is_array($obj) or is_object($obj)) {
echo ' [ '.PHP_EOL;
foreach($obj as $key => $value) {
echo $key.' => ';
recursive($value);
}
echo ' ] '.PHP_EOL;
} else {
echo $obj.PHP_EOL;
}
}
// call recursive
recursive($array);
?>
This prints something like this :
[
hello => 1
world => [
0 => 1
1 => 2
2 => 3
]
! => [
0 => hello
1 => world
]
5 => [
data => I'm an object data
]
]
I hope this helps ?

Multidimensional arrays through functions (PHP)

Complete beginner here.
If I have a multi-dimensional array:
$main_array = array(
$sub_array1('name','value1','value2'),
$sub_array2('name','value1','value2'),
$sub_array3('name','value1','value2')
);
...and a user function:
function multiply($a, $b) {
$result = $a * $b};
return $result;
};
What's the best method to loop each sub-array through the function such that $a is value1 and $b is value2? How can I get the outcome to look something like:
Name1: result1
Name2: result2
Name3: result3
I'm currently fiddling with the following:
foreach($main_array as $x) {
print_r(multiply($x['value1'], $x['value2']));
};
...which is wrong in syntax, logic, or both.
First your array creation is incorrect
$main_array = array(
array('fred','1','2'),
array('bill','3','4'),
array('jane','5','6')
);
Now this array can be processed like this and the sub arrays which are not associative arrays and therefore are not name->value types have to be processed using their indexes
foreach ( $main_array as $sub_array ) {
echo $sub_array[0] , ' = ' . ($sub_array[1] * $sub_array[2]);
}
And will produce the output:
fred = 2
bill = 12
jane = 30
Note: print_r() is used to display arrays & onjects, you need to use echo or print to display scalar values.
Also there is no multiply function, just use old fashioned maths eg $x * $y
print_r will display a readable version of a variable, such as an object, array etc. Since you are looping through an array to display a value in a certain format - this will not work.
To get the intended result, a simple change is required:
foreach($main_array as $x) {
echo $x['name'] . multiply($x['value1'], $x['value2']);
};
Or ditch the user defined function 'multiply' for basic maths.
foreach($main_array as $x) {
echo $x['name'] . ($x['value1'] * $x['value2']);
};
Edit:
Also to Dagon's point above in the comments - the array you are using is not valid. The syntax is wrong and you aren't using named keys but you are referencing them. Change the structure like so:
$name = "Value";
$value = 10;
$main_array = array(
array('name' => $name, 'value1' => $value, 'value2' => $value),
array('name' => $name, 'value1' => $value, 'value2' => $value),
array('name' => $name, 'value1' => $value, 'value2' => $value),
);
Alternatively if you wanted to make it a bit more readable.
$nameValue = "test";
$value1 = 10;
$value2 = 10;
$subArray1 = [
"name" => $nameValue,
"value1" => $value1,
"value2" => $value2
];
$subArray2 = [
"name" => $nameValue,
"value1" => $value1,
"value2" => $value2
];
$subArray3 = [
"name" => $nameValue,
"value1" => $value1,
"value2" => $value2
];
$main_array = array($subArray1, $subArray2, $subArray3);
Updated for more completeness & assuming use of user function multiply

Get Value from Array as Array Key

How do I recursively get value from array where I need to explode a key?
I know, it's not good the question, let me explain.
I got an array
[
"abc" => "def",
"hij" => [
"klm" => "nop",
"qrs" => [
"tuv" => "wxy"
]
]
]
So, inside a function, I pass:
function xget($section) {
return $this->yarray["hij"][$section];
}
But when I want to get tuv value with this function, I want to make section as array, example:
To get hij.klm value (nop), I would do xget('klm'), but to get hij.klm.qrs.tuv, I can't do xget(['qrs', 'tuv']), because PHP consider $section as key, and does not recursively explode it. There's any way to do it without using some ifs and $section[$i] ?
function xget($section) {
return $this->yarray["hij"][$section];
}
that one is static function right?
you can do that also for this
function xget($section) {
if(isset($this->yarray["hij"][$section])){
return $this->yarray["hij"][$section];
}elseif(isset($this->yarray["hij"]["klm"]["qrs"][$section])){
return $this->yarray["hij"]["klm"]["qrs"][$section];
}
}
as long as the key name between two of them are not the same.
You could use array_walk_recursive to find tuv's value regardless of the nested structure:
$tuv_val='';
function find_tuv($k,$v)
{
global $tuv_val;
if ($k=='tuv')
$tuv_val=$v;
}
array_walk_recursive($this->yarray,"find_tuv");
echo "the value of 'tuv' is $tuv_val";
try my code
<?php
$array = array(
'aaa' => 'zxc',
'bbb' => 'asd',
'ccc' => array(
'ddd' => 'qwe',
'eee' => 'tyu',
'fff' => array(
'ggg' => 'uio',
'hhh' => 'hjk',
'iii' => 'bnm',
),
),
);
$find = '';
function xget($key){
$GLOBALS['find'] = $key;
$find = $key;
array_walk_recursive($GLOBALS['array'],'walkingRecursive');
}
function walkingRecursive($value, $key)
{
if ($key==$GLOBALS['find']){
echo $value;
}
}
xget('ggg');
?>

How to create an array for JSON using PHP?

From PHP code I want to create an json array:
[
{"region":"valore","price":"valore2"},
{"region":"valore","price":"valore2"},
{"region":"valore","price":"valore2"}
]
How can I do this?
Easy peasy lemon squeezy: http://www.php.net/manual/en/function.json-encode.php
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>
There's a post by andyrusterholz at g-m-a-i-l dot c-o-m on the aforementioned page that can also handle complex nested arrays (if that's your thing).
Use PHP's native json_encode, like this:
<?php
$arr = array(
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
)
);
echo json_encode($arr);
?>
Update: To answer your question in the comment. You do it like this:
$named_array = array(
"nome_array" => array(
array(
"foo" => "bar"
),
array(
"foo" => "baz"
)
)
);
echo json_encode($named_array);
Simple: Just create a (nested) PHP array and call json_encode on it. Numeric arrays translate into JSON lists ([]), associative arrays and PHP objects translate into objects ({}). Example:
$a = array(
array('foo' => 'bar'),
array('foo' => 'baz'));
$json = json_encode($a);
Gives you:
[{"foo":"bar"},{"foo":"baz"}]
Best way that you should go every time for creating json in php is to first convert values in ASSOCIATIVE array.
After that just simply encode using json_encode($associativeArray). I think it is the best way to create json in php because whenever we are fetching result form sql query in php most of the time we got values using fetch_assoc function, which also return one associative array.
$associativeArray = array();
$associativeArray ['FirstValue'] = 'FirstValue';
...
etc.
After that.
json_encode($associativeArray);
also for array you can use short annotattion:
$arr = [
[
"region" => "valore",
"price" => "valore2"
],
[
"region" => "valore",
"price" => "valore2"
],
[
"region" => "valore",
"price" => "valore2"
]
];
echo json_encode($arr);
That's how I am able to do with the help of solution given by #tdammers below.
The following line will be placed inside foreach loop.
$array[] = array('power' => trim("Some value"), 'time' => "time here" );
And then encode the array with json encode function
json_encode(array('newvalue'=> $array), 200)
Just typing this single line would give you a json array ,
echo json_encode($array);
Normally you use json_encode to read data from an ios or android app. so make sure you do not echo anything else other than the accurate json array.
I created a crude and simple jsonOBJ class to use for my code. PHP does not include json functions like JavaScript/Node do. You have to iterate differently, but may be helpful.
<?php
// define a JSON Object class
class jsonOBJ {
private $_arr;
private $_arrName;
function __construct($arrName){
$this->_arrName = $arrName;
$this->_arr[$this->_arrName] = array();
}
function toArray(){return $this->_arr;}
function toString(){return json_encode($this->_arr);}
function push($newObjectElement){
$this->_arr[$this->_arrName][] = $newObjectElement; // array[$key]=$val;
}
function add($key,$val){
$this->_arr[$this->_arrName][] = array($key=>$val);
}
}
// create an instance of the object
$jsonObj = new jsonOBJ("locations");
// add items using one of two methods
$jsonObj->push(json_decode("{\"location\":\"TestLoc1\"}",true)); // from a JSON String
$jsonObj->push(json_decode("{\"location\":\"TestLoc2\"}",true));
$jsonObj->add("location","TestLoc3"); // from key:val pairs
echo "<pre>" . print_r($jsonObj->toArray(),1) . "</pre>";
echo "<br />" . $jsonObj->toString();
?>
Will output:
Array
(
[locations] => Array
(
[0] => Array
(
[location] => TestLoc1
)
[1] => Array
(
[location] => TestLoc2
)
[2] => Array
(
[location] => TestLoc3
)
)
)
{"locations":[{"location":"TestLoc1"},{"location":"TestLoc2"},{"location":"TestLoc3"}]}
To iterate, convert to a normal object:
$myObj = $jsonObj->toArray();
Then:
foreach($myObj["locations"] as $locationObj){
echo $locationObj["location"] ."<br />";
}
Outputs:
TestLoc1 TestLoc2 TestLoc3
Access direct:
$location = $myObj["locations"][0]["location"];
$location = $myObj["locations"][1]["location"];
A practical example:
// return a JSON Object (jsonOBJ) from the rows
function ParseRowsAsJSONObject($arrName, $rowRS){
$jsonArr = new jsonOBJ($arrName); // name of the json array
$rows = mysqli_num_rows($rowRS);
if($rows > 0){
while($rows > 0){
$rd = mysqli_fetch_assoc($rowRS);
$jsonArr->push($rd);
$rows--;
}
mysqli_free_result($rowRS);
}
return $jsonArr->toArray();
}

Categories