php array to variables
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:
What is the correct syntax for this?
3 Answers 3
list() is what you are after.
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.
A few cases by example:
The explanation of why the order things are stored in is as it is is given in the warning on the list() manual page:
From php7.1, you can do Symmetric array destructuring.
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.
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.
To prepare the data for extraction, convert the indexed array into an associative array by assigning keys.
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.
extract
(PHP 4, PHP 5, PHP 7, PHP 8)
extract — Импортирует переменные из массива в текущую таблицу символов
Описание
Импортирует переменные из массива в текущую таблицу символов.
Каждый ключ проверяется на предмет корректного имени переменной. Также проверяются совпадения с существующими переменными в символьной таблице.
Список параметров
Возвращаемые значения
Возвращает количество переменных, успешно импортированных в текущую таблицу символов.
Примеры
Пример #1 Пример использования extract()
Результат выполнения данного примера:
Примечания
Смотрите также
User Contributed Notes 31 notes
They say «If the result is not a valid variable name, it is not imported into the symbol table.»
What they should say is that if _any_ of the results have invalid names, _none_ of the variables get extracted.
Under 4.3.10 on Windows 2000, I was pulling some mySQL records, but needed to convert two fields into IP addresses:
I had forgotten the second AS modifier in the SQL query. Because it couldn’t extract a variable called INET_NTOA(baz) into the symbol table, it didn’t do either of them.
(BTW I don’t normally stack functions up like that! Just to make a short example!)
[New Version]
This function is very useful for filtering complicated array structure.
Also, Some integer bitmasks and invalid UTF-8 sequence detection are available.
Example Usage:
[ ‘A’ ][ ‘a’ ] = ‘ CORRECT(including some spaces) ‘ ;
$_GET [ ‘A’ ][ ‘b’ ] = ‘ CORRECT(including some spaces) ‘ ;
$_GET [ ‘A’ ][ ‘c’ ] = «Invalid UTF-8 sequence: \xe3\xe3\xe3» ;
$_GET [ ‘A’ ][ ‘d’ ][ ‘invalid_structure’ ] = ‘INVALID’ ;
$_GET [ ‘B’ ][ ‘a’ ] = ‘ CORRECT(including some spaces) ‘ ;
$_GET [ ‘B’ ][ ‘b’ ] = «Invalid UTF-8 sequence: \xe3\xe3\xe3» ;
$_GET [ ‘B’ ][ ‘c’ ][ ‘invalid_structure’ ] = ‘INVALID’ ;
$_GET [ ‘B’ ][ «Invalid UTF-8 sequence: \xe3\xe3\xe3» ] = ‘INVALID’ ;
$_GET [ ‘C’ ][ ‘a’ ] = ‘ CORRECT(including some spaces) ‘ ;
$_GET [ ‘C’ ][ ‘b’ ] = «Invalid UTF-8 sequence: \xe3\xe3\xe3» ;
$_GET [ ‘C’ ][ ‘c’ ][ ‘invalid_structure’ ] = ‘INVALID’ ;
$_GET [ ‘C’ ][ «Invalid UTF-8 sequence: \xe3\xe3\xe3» ] = ‘INVALID’ ;
$_GET [ ‘unneeded_item’ ] = ‘UNNEEDED’ ;
Following up on ktwombley at gmail dot com’s post:
Presumably one easy way of dealing with this security issue is to use the EXTR_IF_EXISTS flag and make sure
a) your define acceptable input variables beforehand (i.e. as empty variables)
b) Sanitise any user input to avoid unacceptable variable content.
If you do these two things, then I’m not sure I see the difference between extract($_REQUEST,EXTR_IF_EXISTS); and assigning each of the variables by hand.
I’m not talking here about the idea of storing the variables in a database, just the immediately necessary steps to allow you to use extract on REQUEST arrays with relative safety.
Using extract’s return parameter can lead to unintended results, particularly with EXTR_REFS:
When extracting from a row after a database query using for example:
$row = mysql_fetch_array($result, MYSQL_ASSOC)
extract($row);
I find that the resultant variables may not match the variable type in the database. In particular I have found integers in the database may gettype() to string on the extracted variable.
Notice: Undefined variable: 1 in /Users/Lutashi/t.php on line 7
NULL
Sometimes you may want to extract only a named subset of the key/value pairs in an array. This keeps things more orderly and could prevent an unrelated variable from getting clobbered from an errant key. For example,
$things = ‘unsaid’;
$REQUEST = array(He=>This, said=>1, my=>is, info=>2, had=>a,
very=>3, important=>test, things=>4);
$aVarToExtract = array(my, important, info);
extract (array_intersect_key ($REQUEST, array_flip($aVarToExtract)));
will extract
$my = ‘is’;
$important = ‘test’;
$info = 2;
but will leave certain
$things = ‘unsaid’
For instance, the submission by kake26 at gmail dot com will not only perfectly emulate register globals (that’s bad), but it’ll store it in a database and recall the same variables every time the script runs (essentially allowing an attacker to attack your script every time it runs via one attack). Oops!
Dan O’Donnell’s suggestion needs a third requirement to work as described:
Without that condition the difference between extract() and assigning variables by hand (and the resulting security implications) should be obvious.
It is possible to use this as a way to create public attributes for a class.
As shown in the example, if your ‘prefix’ is used, a single underscore is added to the name of the extracted variable. Meaning, a prefix of ‘p’ becomes a prefix of ‘p_’, so ‘blarg’ prefixed would be ‘p_blarg’.
If you’re not sure what variables you’ve created through extraction, you can call get_defined_vars() to see all defined variables in the current scope.
Re: anon at anon dot org, about extract() and null values
Personally I’ve found use extracting multiple resultsets from db where the latter would overwrite the previous when a variable is not null ( and optionally if its not >0 )
with something like this:
EXTR_OVERWRITE_NULL
— If there is a collision, overwrite the existing variable if it is null
EXTR_OVERWRITE_0
— Same thing but == 0 or null
EXTR_SKIP_NULL
— If there is a collision, skip the new variable if the existing is not null
EXTR_SKIP_0
— Same thing but == 0 or null
Those ought to cover a few good cases that aren’t covered now.
A warning about extract() and null values.
This might be an actual Zend2 Engine bug, but it’s bad programming practice, so I’m sharing it here instead.
I often work in envrionments where E_STRICT (which would prevent errors like this) isn’t on, and I don’t have access to change it. I also use a very simple template class that in a nutshell works like this:
display() more or less looks like this:
In a nutshell, if you start getting wierd behavior when using extract() make sure that the array or object you are trying to get variables out of doesn’t contain null keys or values!
In response to Dan O’Donnell’s note:
«Presumably one easy way of dealing with this security issue is to use the EXTR_IF_EXISTS flag and make sure»
seems all well and good if we had a url like
as that would specifically find joe bloggs of 20 any street.
however what if someone typed in
SELECT table_name FROM information_schema.tables
could be a real disaster!
Of course, this is only a basic example, but it could be quite easy to forget about global variables and these global variables could quite easily be used with extract to cause serious security risks if GET, REQUEST or POST is sent to extract!
We can use extract () function for Template Engine:
Page Header
This is the content page
Here is a little example of how an extraction method should look like when it needs to work recursive (work on nested_arrays too).
Note that this is only an example, it can be done more easily, and more advanced too.
In the meantime, I’m using this:
// extract alternative
# extracts variables where new value is above the threshold or if old value is on or below the threshold (or var is not defined)
# an associative array is obviously the sane thing to pass
#
# I am absolutely certain someone will find obvious problems or errors with this
# I haven’t even tried to compare other values than 0 so if you need to do that and surely finds obvious flaws,
# please mail me, I’d really like to know.
# benjaminATwebbutvecklarnaDOTse
// usage example:
# thrextract(mysql_fetch_assoc(mysql_query(«SELECT preset_this,preset_that FROM site_preset WHERE /># thrextract(mysql_fetch_assoc(mysql_query(«SELECT preset_this,preset_that FROM category_preset WHERE
Besides I teach PHP in a school, and this function has made my examples easier.
array
(PHP 4, PHP 5, PHP 7, PHP 8)
array — Create an array
Description
Creates an array. Read the section on the array type for more information on what an array is.
Parameters
Syntax «index => values», separated by commas, define index and values. index may be of type string or integer. When index is omitted, an integer index is automatically generated, starting at 0. If index is an integer, next generated index will be the biggest integer index + 1. Note that when two identical index are defined, the last overwrite the first.
Having a trailing comma after the last defined array entry, while unusual, is a valid syntax.
Return Values
Returns an array of the parameters. The parameters can be given an index with the => operator. Read the section on the array type for more information on what an array is.
Examples
The following example demonstrates how to create a two-dimensional array, how to specify keys for associative arrays, and how to skip-and-continue numeric indices in normal arrays.
Example #1 array() example
Example #2 Automatic index with array()
The above example will output:
Note that index ‘3’ is defined twice, and keep its final value of 13. Index 4 is defined after index 8, and next generated index (value 19) is 9, since biggest index was 8.
This example creates a 1-based array.
Example #3 1-based index with array()
The above example will output:
As in Perl, you can access a value from the array inside double quotes. However, with PHP you’ll need to enclose your array between curly braces.
Example #4 Accessing an array inside double quotes
Notes
array() is a language construct used to represent literal arrays, and not a regular function.
See Also
User Contributed Notes 38 notes
As of PHP 5.4.x you can now use ‘short syntax arrays’ which eliminates the need of this function.
So, for example, I needed to render a list of states/provinces for various countries in a select field, and I wanted to use each country name as an label. So, with this function, if only a single array is passed to the function (i.e. «arrayToSelect($stateList)») then it will simply spit out a bunch of » » elements. On the other hand, if two arrays are passed to it, the second array becomes a «key» for translating the first array.
Here’s a further example:
$countryList = array(
‘CA’ => ‘Canada’,
‘US’ => ‘United States’);
$stateList[‘CA’] = array(
‘AB’ => ‘Alberta’,
‘BC’ => ‘British Columbia’,
‘AB’ => ‘Alberta’,
‘BC’ => ‘British Columbia’,
‘MB’ => ‘Manitoba’,
‘NB’ => ‘New Brunswick’,
‘NL’ => ‘Newfoundland/Labrador’,
‘NS’ => ‘Nova Scotia’,
‘NT’ => ‘Northwest Territories’,
‘NU’ => ‘Nunavut’,
‘ON’ => ‘Ontario’,
‘PE’ => ‘Prince Edward Island’,
‘QC’ => ‘Quebec’,
‘SK’ => ‘Saskatchewan’,
‘YT’ => ‘Yukon’);
$stateList[‘US’] = array(
‘AL’ => ‘Alabama’,
‘AK’ => ‘Alaska’,
‘AZ’ => ‘Arizona’,
‘AR’ => ‘Arkansas’,
‘CA’ => ‘California’,
‘CO’ => ‘Colorado’,
‘CT’ => ‘Connecticut’,
‘DE’ => ‘Delaware’,
‘DC’ => ‘District of Columbia’,
‘FL’ => ‘Florida’,
‘GA’ => ‘Georgia’,
‘HI’ => ‘Hawaii’,
‘ID’ => ‘Idaho’,
‘IL’ => ‘Illinois’,
‘IN’ => ‘Indiana’,
‘IA’ => ‘Iowa’,
‘KS’ => ‘Kansas’,
‘KY’ => ‘Kentucky’,
‘LA’ => ‘Louisiana’,
‘ME’ => ‘Maine’,
‘MD’ => ‘Maryland’,
‘MA’ => ‘Massachusetts’,
‘MI’ => ‘Michigan’,
‘MN’ => ‘Minnesota’,
‘MS’ => ‘Mississippi’,
‘MO’ => ‘Missouri’,
‘MT’ => ‘Montana’,
‘NE’ => ‘Nebraska’,
‘NV’ => ‘Nevada’,
‘NH’ => ‘New Hampshire’,
‘NJ’ => ‘New Jersey’,
‘NM’ => ‘New Mexico’,
‘NY’ => ‘New York’,
‘NC’ => ‘North Carolina’,
‘ND’ => ‘North Dakota’,
‘OH’ => ‘Ohio’,
‘OK’ => ‘Oklahoma’,
‘OR’ => ‘Oregon’,
‘PA’ => ‘Pennsylvania’,
‘RI’ => ‘Rhode Island’,
‘SC’ => ‘South Carolina’,
‘SD’ => ‘South Dakota’,
‘TN’ => ‘Tennessee’,
‘TX’ => ‘Texas’,
‘UT’ => ‘Utah’,
‘VT’ => ‘Vermont’,
‘VA’ => ‘Virginia’,
‘WA’ => ‘Washington’,
‘WV’ => ‘West Virginia’,
‘WI’ => ‘Wisconsin’,
‘WY’ => ‘Wyoming’);
Are arrays in PHP copied as value or as reference to new variables, and when passed to functions?
1) When an array is passed as an argument to a method or function, is it passed by reference, or by value?
2) When assigning an array to a variable, is the new variable a reference to the original array, or is it new copy?
What about doing this:
8 Answers 8
For the second part of your question, see the array page of the manual, which states (quoting) :
Array assignment always involves value copying. Use the reference operator to copy an array by reference.
And the given example :
For the first part, the best way to be sure is to try 😉
Consider this example of code :
It’ll give this output :
Which indicates the function has not modified the «outside» array that was passed as a parameter : it’s passed as a copy, and not a reference.
If you want it passed by reference, you’ll have to modify the function, this way :
And the output will become :
As, this time, the array has been passed «by reference».
Don’t hesitate to read the References Explained section of the manual : it should answer some of your questions 😉
With regards to your first question, the array is passed by reference UNLESS it is modified within the method / function you’re calling. If you attempt to modify the array within the method / function, a copy of it is made first, and then only the copy is modified. This makes it seem as if the array is passed by value when in actual fact it isn’t.
However if you modify the array, a copy of it is made first (which uses more memory but leaves your original array unaffected).
a) the method/function only reads the array argument => implicit (internal) reference
b) the method/function modifies the array argument => value
c) the method/function array argument is explicitly marked as a reference (with an ampersand) => explicit (user-land) reference
Or this:
— non-ampersand array param: passed by reference; the writing operations alter a new copy of the array, copy which is created on the first write;
— ampersand array param: passed by reference; the writing operations alter the original array.
Pascal MARTIN was right. Kosta Kontos was even more so.
Answer
Long version
I think I’m writing this down for myself. I should have a blog or something.
Whenever people talk of references (or pointers, for that matter), they usually end up in a logomachy (just look at this thread!).
PHP being a venerable language, I thought I should add up to the confusion (even though this a summary of the above answers). Because, although two people can be right at the same time, you’re better off just cracking their heads together into one answer.
First off, you should know that you’re not a pedant if you don’t answer in a black-and-white manner. Things are more complicated than «yes/no».
As you will see, the whole by-value/by-reference thing is very much related to what exactly are you doing with that array in your method/function scope: reading it or modifying it?
What does PHP says? (aka «change-wise»)
The manual says this (emphasis mine):
By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.
To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition
Read on, my fellow traveller.
What does PHP actually do? (aka «memory-wise»)
It wouldn’t be ideal to pass HUGE arrays to various functions, and PHP to make copies of them (that’s what «pass-by-value» does, after all):
Well now, if this actually was pass-by-value, we’d have some 3mb+ RAM gone, because there are two copies of that array, right?
Facts
So, when an array is passed as an argument to a method or function is it passed by reference?
I came up with three (yeah, three) cases:
a) the method/function only reads the array argument
b) the method/function modifies the array argument
c) the method/function array argument is explicitly marked as a reference (with an ampersand)
Firstly, let’s see how much memory that array actually eats (run here):
That many bytes. Great.
a) the method/function only reads the array argument
Now let’s make a function which only reads the said array as an argument and we’ll see how much memory the reading logic takes:
b) the method/function modifies the array argument
Now, let’s write to that param, instead of reading from it:
c) the method/function array argument is explicitly marked as a reference (with an ampersand)
My bet is that you get 200 max! So this eats approximately as much memory as reading from a non-ampersand param.
Will Anderson
Converting PHP Associative Arrays to Variables
EDIT: Nick Ohrn pointed out that extract does this automatically. The following post is still a valid look at how this could be implemented if the functionality didn’t already exist, but it is better to use extract because it is likely more efficient.
Associative arrays are one of my favorite PHP features. They’re simple to use and easy to understand. Sometimes though, being able to reference the values of associative arrays with variables can be more convenient. Today I’m going to share a simple way to convert a associative arrays to variables.
OK, if you’re not sure what we’re trying to accomplish here, take a look at the following example.
To reference the elements in the array, you’ll have to use the array key like this.
What we’d like to do instead is reference the values using variable names like this.
This is possible through what the PHP Manual calls ‘variable variables’. The idea is that the value of one variable is used as the name of another variable. Here’s an example.
Now it’s not a big step to expand this to an associative array. Consider the following code.
So we’ve accomplished what we set out to do. I must caution you, though, about a couple of things which might trip you up.
First, make sure the keys are valid variable names. If you don’t you’ll run into problems when you execute the script.
Second, be very careful when using this with user input. For example, the following code is insecure.
To use something like this, you’d still need to check for invalid variable names, but I won’t go into that for this example.
I haven’t configured comments for this blog, but if you want to get in touch, you can find me on Twitter