Parsing HTTP data into PHP variables - php

I have a reasonably large number of variables encoded in the form:
foo=bar&spam[eggs]=delicious&...
These are all in a single string (eg, $data = "foo=bar&spam[eggs]=delicious&..."). The variables are arbitrarily deeply nested -- easily four or five levels deep ("spam[eggs][bloody][vikings]=loud").
Is there an easy, reliable way to get a multi-dimensional PHP array from this? I assume PHP has a parser to do this, though I don't know if it's exposed for my use. Ideally, I could do something like:
// given $data == "foo=bar&spam[eggs]=delicious"
$arr = some_magical_function( $data );
/* arr = Array
(
[foo] => bar
[spam] => Array
(
[eggs] => delicious
)
)
*/

If your string is in URI params format, parse_str is the magic function you are looking for.

You might want to take a look at parse_str ; here's an example :
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str, $output);
echo $output['first']; // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz
And, with your input :
$str = 'oo=bar&spam[eggs]=delicious&spam[eggs][bloody][vikings]=loud';
$output = array();
parse_str($str, $output);
var_dump($output);
You'll get this :
array
'oo' => string 'bar' (length=3)
'spam' =>
array
'eggs' =>
array
'bloody' =>
array
'vikings' => string 'loud' (length=4)
Which should be what you want ;-)
(notice the multi-level array ; and the fact that ths first spam[eggs] has been overriden by the second one, btw)

If your data comes from the request uri, use $_GET

Related

Print result is different in the array function

I have a problem with the array PHP function, below is my first sample code:
$country = array(
"Holland" => "David",
"England" => "Holly"
);
print_r ($country);
This is the result Array ( [Holland] => David [England] => Holly )
I want to ask, is possible to make the array data become variables? For second example like below the sample code, I want to store the data in the variable $data the put inside the array.:
$data = '"Holland" => "David","England" => "Holly"';
$country = array($data);
print_r ($country);
But this result is shown me like this: Array ( [0] => "Holland" => "David","England" => "Holly" )
May I know these two conditions why the results are not the same? Actually, I want the two conditions can get the same results, which is Array ( [Holland] => David [England] => Holly ).
Hope someone can guide me on how to solve this problem. Thanks.
You can use the following Code.
<?php
$country = array(
"Holland" => "David",
"England" => "Holly"
);
foreach ($country as $index => $value)
{
$$index = $value;
}
?>
Now, Holland & England are two variables. You can use them using $Holland etc.
A syntax such as $$variable is called Variable Variable. Actually The inner $ resolves the a variable to a string, and the outer one resolves a variable by that string.
So there is this thing called
Destructuring
You can do it something like ["Holland" => $eolland, "England" => $england] = $country;
And now you have your array elements inside the variables.
Go read the article above if you want more information about this because it gets really useful (especially in unit tests usind data provders from my experience).
If you want to extract elements from an associative array such that the keys become variable names and values become the value of that variable you can use extract
extract($country);
To check what changed you can do
print_r(get_defined_vars());
Explanation on why the below does not work
$data = '"Holland" => "David","England" => "Holly"';
When you enclose the above in single quotes ' php would recognise it as a string. And php will parse a string as a string and not as an array.
Do note it is not enough to create a string with the same syntax as the code and expect php to parse it as code. The codes will work if you do this
$data = ["Holland" => "David","England" => "Holly"];
However, now $data itself is an array.
A simple copy of an array can be made by using
$data = $country;

Get an array from URL

I have a URL in this format:
https://www.example.com/page?=item1&item2&item3&item4&item5
I need to put each item into a variable, likes this:
$var1 = item1;
$var2 = item2;
$var3 = item3;
$var4 = item4;
$var5 = item5;
It does not actually say item1, item2 etc in the URL, their actual values are different every time.
Does anyone know how to do this?
Thanks!
The URL Query String / GET-Parameters
Your example URL https://www.example.com/page?=item1&item2&item3&item4&item5 is malformed. The query string starting after the question mark ? is parsed with the format:
name1=value1&name2=value2...
Your URL means:
<empty name> = item1
item2 = ''
item3 = ''
...
Empty names are ignored when PHP parses GET-parameters.
Let's assume you have an URL https://www.example.com/page?item1&item2&item3&item4&item5 instead. (Note the remove =.)
Accessing GET-Parameters
If the given URL is the one of you PHP current script, you can easily access the GET-parameter using the preinitialized global variable $_GET. Try var_dump($_GET) and you get:
array (size=5)
'item1' => string '' (length=0)
'item2' => string '' (length=0)
'item3' => string '' (length=0)
'item4' => string '' (length=0)
'item5' => string '' (length=0)
As you can see, item1...item5 are the keys of the associative array, each with an empty string '' as the default value since you did not set any by item1=the+item.
Get The Keys as Array
To get closer to your needs specified in the title of your question, you can extract the keys using array_keys:
$url_keys = array_keys($_GET);
Now you have an array like this:
array (size=5)
0 => string 'item1' (length=5)
1 => string 'item2' (length=5)
2 => string 'item3' (length=5)
3 => string 'item4' (length=5)
4 => string 'item5' (length=5)
Extracting as Variables
I do not recommend to extract any changing data structures into your variable scope. Be aware that the client could even manipulate the request sending you something you do not expect. It is hard to find variable names when you do not exactly know what you get. Prefer to operate on arrays.
However, if you really need to import the keys into your variables scope, here are the ways how you can achieve that. PHP does provide a function extract that can do that in several ways. We want to use the numeric indexes with a prefix to become the variable names:
extract(array_keys($_GET), EXTR_PREFIX_ALL, 'var');
The result will be:
$var_0 = item1,
$var_1 = item2
The zero-based numbering is due to the fact, that arrays are nubered zero-based by default, so the returned array from the function array_keys.
To get the numbering as illustrated in your question, you can also renumber the array of keys.
extract(array_combine(range(1, count($_GET)),array_keys($_GET)), EXTR_PREFIX_ALL, 'var');
If you are bothered by the underscore within the names, you can also extract the keys using dynamic variable creation in a fairly simple loop:
foreach (array_keys($_GET) as $k => $v)
${'var'. ($k+1)} = $v;
When you want global variables instead, use
foreach (array_keys($_GET) as $k => $v)
$GLOBALS['var'. ($k+1)] = $v;
Extract Keys from Arbitrary URL
If you have to analyze a URL string from somewhere, you can use the parse_url function to extract the query first and then use parse_str which parses a query in the same way as PHP does automatically with the script's URL when building the $_GET associative array on startup.
parse_str(parse_url($url, PHP_URL_QUERY), $params);
$params is now
array (size=5)
'item1' => string '' (length=0)
'item2' => string '' (length=0)
'item3' => string '' (length=0)
'item4' => string '' (length=0)
'item5' => string '' (length=0)
You can handle that in the same way as shown above with the $_GET array.
You could try this
$var1 = $_GET['item1'];
$var2 = $_GET['item2'];
$var3 = $_GET['item3'];
$var4 = $_GET['item4'];
$var5 = $_GET['item5'];
All your URL variables are stored in the GET array
I am not sure about your URL format...
However, as already answered here, you can extract each parameter (if specified by name) using $_GET['item1'] etc...
And, if there some other format or Unknown number of values, you can work over the whole URL by getting it using $_SERVER['REQUEST_URI'] which will give the string:
/page?=item1&item2&item3&item4&item5
then, splitting that string with seperator &, assuming every splitted substring is a value of an item in the array (?) in the URL.
As you say, you want to get all parameters in your URL.
Actually, $_GET is already an array that you also can use. But when you want to create your own array / variable list, that is also possible.
To do that, you can use the super global $_GET, this is an array with every URL parameter in it.
For example, I made this code for you
<?php
$return = [];
foreach($_GET as $key => $value) {
$return[$key] = $value;
}
var_dump($_GET);
var_dump($return);
?>
When I visit the page (http://example.com/temp.php?a&b), it will result in
array(2) { ["a"]=> string(0) "" ["b"]=> string(0) "" } array(2) { ["a"]=> string(0) "" ["b"]=> string(0) "" }
As you can see, this has the same data. And, because you say that the values and maybe also the keys (file.php?key=value) can be diffrent, I recommend you to use the array.
So, you can also save them in formats like JSON, to easilly save the in the database, so you can use the afterwards.
When I use json_encode on one of the arrays it gives me a string that you can use.
{"a":"","b":""}
With json_decode you can change it back to the array

PHP Save string and variable to a array

How do I save the string below with the variables to a array? It doesnt seem to work..
$str[] = {'name':'$data['name']','y':$data['values'],'key':'$data['key']'},
$str_str = implode(' ', $str);
echo $str_str;
Thanks.
You should read about basic array and string handling in PHP. Something like this should work:
$str[] = [
'name' => $data['name'],
'y' => $data['values'],
'key' => $data['key']
];
Maybe the best way is just use $str[] = json_encode($data);
Are you trying to save a JSON string into an array?
$var[] saves a value to the first available numeric key in the array $var
The string you would like to save looks like a JSON string, if that's what you want you can do so by:
$var[] = json_encode($data)
If the data array contains the following:
Array
(
[name] => value name
[y] => value y
[key] => value key
)
JSON encoding this array will give you:
{"name":"value name","y":"value y","key":"value key"}

How to know the predefined parameter in php functions?

If there is 2 parameter in php function how to know which parameter is kept in first and another second.
This is a php function array_search($needle,$array). This will search $needle in an array $array.
In array_slice($array, 2) slice is to be done in an array $array is first parameter.
In trim($string, 'abc') trim is to be done in string $string is a first parameter.
Is there any way to remember which parameter come first? I think we can remember function but remembering parameter also is not possible for all functions.
Thanks
Welcome to PHP ,
The likely most common complaint you get to hear about PHP is the
inconsistent and unclear naming of functions in the standard library,
as well as the equally inconsistent and unclear order of parameters.
Some typical examples:
// different naming conventions
strpos
str_replace
// totally unclear names
strcspn // STRing Complement SPaN
strpbrk // STRing Pointer BReaK
// inverted parameter order
strpos($haystack, $needle)
array_search($needle, $haystack)
so if you want to check (within your application and away from man pages)
as a work around to get around this, you may make use of Reflection collection in php :
for example:
function getFunctionInfo($functionName) {
$function = new ReflectionFunction($functionName);
return [
'name' => $function->getName(),
'parameters' => array_column($function->getParameters(), 'name'),
'numberOfParameters' => $function->getNumberOfParameters(),
'requiredParameters' => $function->getNumberOfRequiredParameters()
];
}
print_r(getFunctionInfo('explode'));
this will output:
Array (
[name] => explode
[parameters] => Array (
[0] => separator
[1] => str
[2] => limit
)
[numberOfParameters] => 3
[requiredParameters] => 2
)
and for live view: https://3v4l.org/T2Nad
the above quote had been quoted from : nikic.github.io

PHP Prepend two elements to associative array

I have the following array, I'm trying to append the following ("","--") code
Array
(
[0] => Array
(
[Name] => Antarctica
)
)
Current JSON output
[{"Name":"Antarctica"}]
Desired output
{"":"--","Name":"Antarctica"}]
I have tried using the following:
$queue = array("Name", "Antarctica");
array_unshift($queue, "", "==");
But its not returning correct value.
Thank you
You can prepend by adding the original array to an array containing the values you wish to prepend
$queue = array("Name" => "Antarctica");
$prepend = array("" => "--");
$queue = $prepend + $queue;
You should be aware though that for values with the same key, the prepended value will overwrite the original value.
The translation of PHP Array to JSON generates a dictionary unless the array has only numeric keys, contiguous, starting from 0.
So in this case you can try with
$queue = array( 0 => array( "Name" => "Antarctica" ) );
$queue[0][""] = "--";
print json_encode($queue);
If you want to reverse the order of the elements (which is not really needed, since dictionaries are associative and unordered - any code relying on their being ordered in some specific way is potentially broken), you can use a sort function on $queue[0], or you can build a different array:
$newqueue = array(array("" => "--"));
$newqueue[0] += $queue[0];
which is equivalent to
$newqueue = array(array_merge(array("" => "--"), $queue[0]));
This last approach can be useful if you need to merge large arrays. The first approach is probably best if you need to only fine tune an array. But I haven't ran any performance tests.
Try this:
$queue = array(array("Name" => "Antarctica")); // Makes it multidimensional
array_unshift($queue, array("" => "--"));
Edit
Oops, just noticed OP wanted a Prepend, not an Append. His syntax was right, but we was missing the array("" => "--") in his unshift.
You can try this :
$queue = array("Name" => "Antarctica");
$result = array_merge(array("" => "=="), $queue);
var_dump(array_merge(array(""=>"--"), $arr));

Categories