php how to generate dynamic list()? - php

base on my understanding, this how list() work.
list($A1,$A2,$A3) = array($B1,B2,B3);
So with the help of list() we can assign value out from array accordingly.
here is my question... how to generate a dynamic list()?
1). base on database return result, I'm not sure how many of it but I assign it all into array
2). so we can use count(array) to know how many of it.
3). so then HOW CAN I GENERATE/PREPARE a list for it?
Example: client A, have 3 kids, name Apple, Boy, Cat
so I use list($kid1, $kid2, $kid3) for it.
but when client B, have more then 3 kids, I only get first 3
or if client C, have only 1 kids, then error encounter.
I know if base on the situation above, there is many way to solve it without using list()
but I wish to know or find out the solution with using list().
How to generate dynamic list() base on count of array()
thanks guys/gals

If you have a variable number of elements, use arrays for them! It does not make sense to extract them into individual variables if you do not know how many variables you'll be dealing with. Say you did extract those values into variables $kid1 through $kidN, what is the code following this going to do? You have no idea how many variables there are in the scope now, and you have no practical method of finding out or iterating them next to testing whether $kid1 through $kidN are isset or not. That's insane use of variables. Just use arrays.
Having said that, variable variables:
$i = 1;
foreach ($array as $value) {
$varname = 'kid' . $i++;
$$varname = $value;
}

You can create a lambda expression with create_function() for this. The list() will be only accessible within the expression.

This creates variables $A1, $A2, .... $AN for each element in your array:
$list = array("a", "b", "c", "d");
extract(array_combine(array_map(function($i) {
return "A" . $i;
}, range(1, count($list))), $list));
echo implode(" ", array($A1, $A2, $A3, $A4)), PHP_EOL;
You can modify the name of the variables in the array_map callback. I hope I'll never see code like that in production ;)

This is not what PHP's list is meant for. From the official PHP docs
list is not really a function, but a language construct.
list() is used to assign a list of variables in one operation.
In other words, the compiler does not actually invoke a function but directly compiles your code into allocations for variables and assignment.
You can specifically skip to a given element, by setting commas as follows:
list($var1, , $var2) = Array($B1, B2, B3);
echo "$var1 is before $var2 \n";
or take the third element
list( , , $var3) = Array($B1, B2, B3);
(I am assuming B2, B3 are constants? Or are you missing a $?)
Specifically using list, you can use PHP's variable variables to create variables from an arbitrary one-dimensional array as follows:
$arr = array("arrindex0" => "apple", "banana", "pear");
reset($arr);
while (list($key, $val) = each($arr)) {
$key = is_numeric($key) ? "someprefix_" . $key : $key;
echo "key sdf: $key <br />\n";
$$key = $val;
}
var_dump($arrindex0, $someprefix_0, $someprefix_1);
Result
string 'apple' (length=5)
string 'banana' (length=6)
string 'pear' (length=4)

Related

Ampersand before a variable in foreach php

I have seen an ampersand symbol before a variable in foreach. I know the ampersand is used for fetching the variable address which is defined earlier.
I have seen a code like this:
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element
?>
I just need to know the use of & before $value. I haven't seen any variable declared before to fetch the variable address.
Please help me why its declared like this. Any help would be appreciated.
The ampersand in the foreach-block allows the array to be directly manipulated, since it fetches each value by reference.
$arr = array(1,2,3,4);
foreach($arr as $value) {
$value *= 2;
}
Each value is multiplied by two in this case, then immediately discarded.
$arr = array(1,2,3,4);
foreach($arr as &$value) {
$value *= 2;
}
Since this is passed in by reference, each value in the array is actually altered (and thus, $arr becomes array(2,4,6,8))
The ampersand is not unique to PHP and is in fact used in other languages (such as C++). It indicates that you are passing a variable by reference. Just Google "php pass by reference", and everything you need to explain this to you will be there. Some useful links:
http://www.php.net/manual/en/language.references.pass.php
Are PHP Variables passed by value or by reference?
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/ (this is for C++, but the same principle applies in PHP)

Change variable name in loop

$index = 0;
foreach ($sxml->entry as $entry) {
$array + variable index number here = array('title' => $title);
$index++;
}
I'm trying to change an array name depending on my index count. Is it possible to change variable name (ie. $array1, $array2 $array3 etc.) in the loop?
Edit:
After the loop has finished, I will generate a number number (depending on the count of $index) and then use this array... probably it's a stupid way of accomplishing what Im trying to do, but I don't have a better idea.
You might want to try this instead:
$index = 0;
$arrays = array();
foreach ($sxml->entry as $entry) {
$arrays[$index] = array('title' => $title);
$index++;
}
While it is technically possible to do what you are asking, using an array of arrays will probably work better from you.
This type of indexing is exactly what arrays are designed for, you have a lot of items and want to be able to refer to them by number.
Unless you have a very specific reason to use the name of the variable to represent it's number you will probably have a much simpler time using it's index in the outer array.
Yes you can user an associate array. Generating a string dynamically based on the iteration number and using that as a key in the array.
You can use variable variables. php.net
PHP supports Variable variables:
$num = 1;
$array_name = 'array' . $num;
$$array_name = array(1,2,3);
print_r($array1);
http://php.net/manual/en/language.variables.variable.php

PHP Assign array to variables

I'm not sure if my memory is wrong, but when I last used PHP (years ago), I vaguely remember doing something like this:
$firstVariable, $secondVariable = explode(' ', 'Foo Bar');
Note that the above is incorrect syntax, however in this example it would assign 'Foo' to $firstVariable, and 'Bar' to $secondVariable.
What is the correct syntax for this?
Thanks.
list($firstVar, $secondVar) = explode(' ', 'Foo Bar');
list() is what you are after.
From php7.1, you can do Symmetric array destructuring.
https://www.php.net/manual/en/migration71.new-features.php#migration71.new-features.symmetric-array-destructuring
Code: (Demo)
$array = [1, 2, 3];
[$a, $b, $c] = $array;
echo "$a $b $c";
// displays: 1 2 3
Without calling list().
This is the new modern approach when "swapping" element positions without declaring a temporary variable. See examples here and here and here and here.
For in-depth breakdown and examples, have a long look at this post: https://sebastiandedeyne.com/the-list-function-and-practical-uses-of-array-destructuring-in-php/
As for using explode() with list() or array destructuring, if you are not guaranteed a certain number of elements,
it is best practice to declare the 3rd parameter of explode() to limit the number of generated elements. This will not force the production of so many elements; rather it will merely tell php to stop exploding when that number of elements is achieved.
[$firstVariable, $secondVariable] = explode(' ', $stringToBeHalved, 2);
If you aren't 100% assured that your exploded data will provide balanced data to the other side of the assignment operator, you can implement a maximum with the technique above and use something akin to array_replace() to provide a minimum number of elements on the right side of the assignment operator.
Code: (Demo)
$strings = [
"1,2,3,4",
"1,2,3",
"1,2"
];
$minElements = 3;
$defElements = array_fill(0, $minElements, null);
foreach ($strings as $string) {
[$a, $b, $c] = array_replace($defElements, explode(',', $string, $minElements));
var_export($a);
echo ' _ ';
var_export($b);
echo ' _ ';
var_export($c);
echo "\n-----------------\n";
}
Output:
'1' _ '2' _ '3,4'
-----------------
'1' _ '2' _ '3'
-----------------
'1' _ '2' _ NULL
-----------------
In fact, symmetric array destructuring even permits accessing the same element/value more than once -- which may feel a little awkward at first glance.
For example, you can push a solitary value into two arrays like this:
[0 => $array1[], 0 => $array2[]] = ['zeroIndexedElement'];
Read more at: While destructuring an array, can the same element value be accessed more than once?
And one more technique that is very seldom advised is to call extract(). This function can be dangerous if you don't have complete control of the data that it is processing because it will push all of the data's keys into the global scope as variable names -- potentially overwriting variables and leading to script vulnerability or breakage.
To prepare the data for extraction, convert the indexed array into an associative array by assigning keys.
Code: (Demo)
$threeKeys = ['a', 'b', 'c'];
foreach ($strings as $string) {
extract(array_combine($threeKeys, explode(',', $string, 3)));
// now you can use $a, $b, and $c
}
The above demo shows some of the Warnings generated when not providing balanced/expected volumes of data. So the moral of this story is to be careful and eliminate possible fringe cases by ensuring the data processors will always receive what they require.
First a few examples with list() alone, then 2 examples with list() combined with explode().
The examples on the PHP manual page for list() are especially illuminating:
Basically, your list can be as long as you want, but it is an absolute list. In other words the order of the items in the array obviously matters, and to skip things, you have to leave the corresponding spots empty in your list().
Finally, you can't list string.
<?php
$info = array('coffee', 'brown', 'caffeine');
// Listing all the variables
list($drink, $color, $power) = $info;
echo "$drink is $color and $power makes it special.\n";
// Listing some of them
list($drink, , $power) = $info;
echo "$drink has $power.\n";
// Or let's skip to only the third one
list( , , $power) = $info;
echo "I need $power!\n";
// list() doesn't work with strings
list($bar) = "abcde";
var_dump($bar); // NULL
?>
A few cases by example:
Applying list(), explode() and Arrays to dysfunctional relationships:
<?php
// What they say.
list($firstVar, $secondVar, , , $thirdVar) = explode(' ', 'I love to hate you');
// What you hear.
// Disaplays: I love you
echo "$firstVar $secondVar $thirdVar";
?>
Finally, you can use list() in conjunction with arrays. $VARIABLE[] stores an item into the last slot in an array. The order things are stored should be noted, since it's probably the reverse of what you expect:
<?php
list(, $Var[], ,$Var[] , $Var[]) = explode(' ', 'I love to hate you');
// Displays:
// Array ( [0] => you [1] => hate [2] => love )
print_r($Var);
?>
The explanation of why the order things are stored in is as it is is given in the warning on the list() manual page:
list() assigns the values starting with the right-most parameter. If you are
using plain variables, you don't have to worry about this. But if you are
using arrays with indices you usually expect the order of the indices in
the array the same you wrote in the list() from left to right; which it isn't.
It's assigned in the reverse order.

each() and list() function

I don't understand the each() and the list() function that well. Can anyone please give me a little more detail and explain to me how can it be useful?
Edit:
<?php
$foo = array("bob", "fred", "jussi", "jouni", "egon", "marliese");
$bar = each($foo);
print_r($bar);
?>
Array
(
[1] => bob
[value] => bob
[0] => 0
[key] => 0
)
So does this mean in array[1] there's the value bob, but it's clearly in array[0]?
list is not a function per se, as it is used quite differently.
Say you have an array
$arr = array('Hello', 'World');
With list, you can quickly assign those different array members to variables
list($item1, $item2) = $arr; //$item1 equals 'Hello' and $item2 equals 'World'
The each() function returns the current element key and value, and moves the internal pointer forward.
each()
The list function — Assigns variables as if they were an array
list()
Example usage is for iteration through arrays
while(list($key,$val) = each($array))
{
echo "The Key is:$key \n";
echo "The Value is:$val \n";
}
A very common example for list is when thinking about CSV files. Imagine you have a simple database stored as CSV with the columns id, title and text, such a file could look like this:
1|Foo|Lorem ipsum dolor|
2|Bar|sit amet|
...
Now when you parse this file you could do it like this, using the list function:
$lines = file( 'myFile.csv' );
for ( $i = 0; $i < count( $lines ); $i++ )
{
list( $id, $title, $text, $null ) = explode( '|', $lines[$i], 4 );
echo "Id: $id, Title: $title\n$text\n\n";
}
The other function, each, is basically just an old way to walk through arrays, using internal pointers. A more common way to do that is by using foreach now.
Edit: its probably worth noting that each has been deprecated
Warning: This function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged
lets look first at each() : it returns the current value (at first that's $array[0 | "first value in association array ] . so
$prices = ('x'=>100 , 'y'=>200 , 'z'= 300 );
say I wanna loop over these array without using a foreach loop .
while( $e = each($prices) ){
echo $e[key] . " " . $e[value] . "<br/>" ;
}
when each reaches point at a non existing element that would cause
the while loop to terminate .
When you call each(), it gives you an array with four values and the four indices to the array locations.The locations 'key' and 0 contain the key of the current element, and the locations 'value' and 1 contain the
value of the current element.
so this loop would list each key of the array a space and the value then
secondly lets look at list() .
it basically will do the same thing with renaming of 'value' and 'key' although it has to be use in conjunction with each()
while( list($k , $v ) = each($prices) ){
echo $k /*$e[key]*/ . " " . $v /*$e[value]*/ . "<br/>" ;
}
So in a nutshell each() iterates over the array each time returning an array . list() rename the value , key pairs of the array to be used inside the loop .
NOTICE : reset($prices) :
resets each() pointer for that array to be the first element .
http://www.php.net/list
list isn't a function, it is a language construct. It is used to assign multiple values to different variables.
list($a, $b, $c) = array(1, 2, 3);
Now $a is equal to 1, and so on.
http://www.php.net/each
Every array has an internal pointer that points to an element in its array. By default, it points to the beginning.
each returns the current key and value from the specified array, and then advances the pointer to the next value. So, put them together:
list($key, $val) = each($array);
The RHS is returning an array, which is assigned to $key and $val. The internal pointer in `$array' is moved to the next element.
Often you'll see that in a loop:
while(list($key, $val) = each($array)):
It's basically the same thing as:
foreach($array as $key => $val):
To answer the question in your first edit:
Basically, PHP is creating a hybrid array with the key/value pair from the current element in the source array.
So, you can get the key by using $bar[0] and the value by using $bar[1]. OR, you can get the key by using $bar['key'] and the value using $bar['value']. It's always a single key/value pair from the source array, it's just giving you two different avenues of accessing the actual key and actual value.
Say you have a multi-dimensional array:
+---+------+-------+
|ID | Name | Job |
| 1 | Al | Cop |
| 2 | Bob | Cook |
+---+------+-------+
You might do something like:
<?php
while(list($id,$name,$job) = each($array)) {
echo "".$name." is a ".$job;
}
?>
Using them together is, basically, an early way to iterate over associative arrays, especially if you didn't know the names of the array's keys.
Nowadays there's really no reason I know of not to just use foreach instead.
list() can be used separately from each() in order to assign an array's elements to more easily-readable variables.

PHP: Apply a function to multiple variables without using an array

I have a function (for ease, I'll just use count()) that I want to apply to maybe 4-5 different variables. Right now, I am doing this:
$a = count($a);
$b = count($b);
$c = count($c);
$d = count($d);
Is there a better way? I know arrays can use the array_map function, but I want the values to remain as separate values, instead of values inside of an array.
Thanks.
I know you said you don't want the values to be in an array, but how about just creating an array specifically for looping through the values? i.e.:
$arr = Array($a, $b, $c, $d);
foreach ($arr as &$var)
{
$var = count($var);
}
I'm not sure if that really is much tidier than the original way, though.
If you have a bunch of repeating variables to collect data your code is poorly designed and should just be using an array to store the values, instead of dozens of variables. So perhaps you want something like:
$totals = array("Visa"=>0,"Mastercard"=>0,"Discover"=>0,"AmericanExpress"=>0);
then you simply add to your array element (say from a while loop from your SQL or whatever you are doing)
$totals['Visa'] += $row['total'];
But if you really want to go down this route, you could use the tools given to you, if you want to do this with a large batch then an array is a good choice. Then foreach the array and use variable variables, like so:
$variables = array('a','b','c'...);
foreach ( $variables as $var )
{
${$var} = count(${var});
}
What Ben and TravisO said, but use array_walk for a little cleaner code:
$arr = Array($a, $b, $c, $d);
array_walk($arr, count);
You can use extract to get the values back out again.
//test data
$a = range(1, rand(4,9));
$b = range(1, rand(4,9));
$c = range(1, rand(4,9));
//the code
$arr = array('a' => $a, 'b' => $b, 'c' => $c);
$arr = array_map('count', $arr);
extract($arr);
//whats the count now then?
echo "a is $a, b is $b and c is $c.\n";
How do you measure "better"? You might be able to come up with something clever and shorter, but what you have seems like it's easiest to understand, which is job 1. I'd leave it as it is, but assign to new variables (e.g. $sum_a, ...).

Categories