A $_GET input parameter that is an Array - php

I'm trying to pass 3 parameter to a script, where the 3rd parameter $_GET['value3'] is supposed to be an array
$_GET['value1']
$_GET['value2']
$_GET['value3'] //an array of items
I'm calling the script like this: (notice my syntax for value3, I'm not sure it's correct)
http://localhost/test.php?value1=test1&value2=test2&value3=[the, array, values]
I then use a foreach to hopefully loop through the third parameter value3 which is the array
//process the first input $_GET['value1']
//process the second input $_GET['value2']
//process the third input $_GET['value3'] which is the array
foreach($_GET['value3'] as $arrayitem){
echo $arrayitem;
}
but I get the error Invalid argument supplied for foreach()
I'm not sure if my methodology is correct. Can some clarify how you'd go about doing the sort of thing

There is no such thing as "passing an array as a URL parameter" (or a form value, for that matter, because this is the same thing). These are strings, and anything that happens to them beyond that is magic that has been built into your application server, and therefore it is non-portable.
PHP happens to support the &value3[]=the&value3[]=array&value3[]=values notation to automagically create $_GET['value3'] as an array for you, but this is special to PHP and does not necessarily work elsewhere.
You can also be straight-forward and go for a cleaner URL, like this: value3=the,array,values, and then use explode(',', $_GET['value3']) in your PHP script to create an array. Of course this implies that your separator char cannot be part of the value.
To unambiguously transport structured data over HTTP, use a format that has been made for the purpose (namely: JSON) and then use json_decode() on the PHP side.

try
http://localhost/test.php?value1=test1&value2=test2&value3[]=the&value3[]=array&value3[]=values

For arrays you need to pass the query parameters as
value3[]=abc&value3[]=pqr&value3[]=xyz

You can cast the name of the index in the string too
?value1[a]=test1a&value1[b]=test1b&value2[c][]=test3a&value2[c][]=test3b
would be
$_GET['value1']['a'] = test1a
$_GET['value1']['b'] = test1b
$_GET['value2']['c'] = array( 'test3a', 'test3b' );

http://php.net/manual/en/reserved.variables.get.php
Check out the above link..
You will see how the GET method is implemented.
What happens is that the URL is taken, it is delimited using '&' and then they are added as a key-value pair.
public function fixGet($args) {
if(count($_GET) > 0) {
if(!empty($args)) {
$lastkey = "";
$pairs = explode("&",$args);
foreach($pairs as $pair) {
if(strpos($pair,":") !== false) {
list($key,$value) = explode(":",$pair);
unset($_GET[$key]);
$lastkey = "&$key$value";
} elseif(strpos($pair,"=") === false)
unset($_GET[$pair]);
else {
list($key, $value) = explode("=",$pair);
$_GET[$key] = $value;
}
}
}
return "?".((count($_GET) > 0)?http_build_query($_GET).$lastkey:"");
}
Since, they are added as a key-value pair you can't pass array's in the GET method...

The following would also work:
http://localhost/test.php?value3[]=the&value3[]=array&value3[]=values
A more advanced approach would be to serialize the PHP array and print it in your link:
http://localhost/test.php?value3=a:3:{i:0;s:3:"the";i:1;s:5:"array";i:2;s:6:"values";}
would, essentially, also work.

Related

Pushing values from a $_Get query to a value using implode

I am attempting to use a for loop or for each loop to push the values from a get query to another variable. May I have some help with this approach?
Ok here is where I am:
for ($i = 0 ; i < $_GET['delete']; i++) {
$_jid [] = $_GET['delete'];
}
You don't actually need a loop here. If $_jid already is an array containing some values, consider just merging it with $_GET['delete'].
if (is_array($_jid)) {
$_jid = array_merge($_jid, $_GET['delete']);
}
If $_jid is not an array and doesn't exist except as a container for $_GET['delete'] you do can just assign the array. There is no need to loop at all.
$_jid = $_GET['delete'];
Of course in that case, you don't even need to copy it. You can just use $_GET['delete'] directly, in any context you planned to read from $_jid.
Update:
If the contents of $_GET['delete'] are originally 923,936, that is not an array to begin with, but rather a string. If you want an array out of it, you need to explode() it on assignment:
$_jid = explode(',', $_GET['delete']);
But if you intend to implode() it in the end anyway, there's obviously no need to do that. You already have exactly the comma-delimited string you want.
As you can see if you do a var_dump($_GET), the variable $_GET is a hashmap.
You can easily use a foreach loop to look through every member of it :
foreach($_GET as $get) // $get will successively take the values of $_GET
{
echo $get."<br />\n"; // We print these values
}
The code above will print the value of the $_GET members (you can try it with a blank page and dull $_GET values, as "http://yoursite.usa/?get1=stuff&get2=morestuff")
Instead of a echo, you can put the $_GET values into an array (or other variables) :
$array = array(); // Creating an empty array
$i = 0; // Counter
foreach($_GET as $get)
{
$array[$i] = $get; // Each $_GET value is store in a $array slot
$i++;
}
In PHP, foreach is quite useful and very easy to use.
However, you can't use a for for $_GET because it's a hashmap, not an array (in fact, you can, but it's much more complicated).
Hope I helped

Calling PHP function in itself

In the following script function clean($data) calls it within it, that I understand but how it is cleaning data in the statement $data[clean($key)] = clean($value);??? Any help is appreciated.. I am trying to figure it out as I am new to PHP. Regards.
if (ini_get('magic_quotes_gpc')) {
function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[clean($key)] = clean($value);
}
} else {
$data = stripslashes($data);
}
return $data;
}
$_GET = clean($_GET);
$_POST = clean($_POST);
$_REQUEST = clean($_REQUEST);
$_COOKIE = clean($_COOKIE);
}
Your Question:
So if I undertsand correctly you want to know what is the function doing in the line
$data[clean($key)] = clean($value);
The Answer:
See the prime purpose of the function is to remove slashes from string with php's stripslashes method.
If the input item is an array then it tries to clean the keys of the array as well as the values of the array by calling itself on the key and value.
In php arrays are like hashmaps and you can iterate over the key and value both with foreach loop like following
foreach ($data as $key => $value) {....}
So if you want to summarize the algorithm in your code snippet it would be as under
Check if the input is array. If it is not then go to step 4
For each item of array clean the key and value by calling clean method on it (Recursively)
Return the array
clean the input string using stripslashes method
5 return the cleaned input
From my understanding it's not cleaning the key but creates a new element with a clean key while the uncleaned key remains.
$a['foo\bar'] : val\ue
becomes
$a['foo\bar'] : val\ue
$a['foobar'] : value
Someone correct me if im wrong.
Maybe you'll understand the code better if it's put this way:
foreach ($data as $key => $value) {
$key = clean($key); // Clean the key, the
$value = clean($value); // Clean the value
$data[$key] = $value; // Put it in the array that will be returned
}
Assuming you have an array like this:
$_POST = array(0 => 'foo', 1 => array('bar' => 'baz'));
the following will happen:
Call clean($_POST);
call clean 0
call clean 'foo'
$return[0] = 'foo'
call clean 1
call clean 'bar'
call clean 'baz'
$return[1] = array('bar' => 'baz');
You should probably read this: http://www.codewalkers.com/c/a/Miscellaneous/Recursion-in-PHP/
The main purpose of the function is to clean an associative array or a single variable. An associative array is an array where you define keys and values for that keys; so are special arrays used in PHP like $_GET $_POST and so on.
The meaning of "cleaning" is to check whether magic quotes are active - this causes some characters in these arrays to be escaped with backslashes when you post dynamic data to a PHP page.
$_GET["Scarlett"] = "O' Hara" becomes with magic quotes $_GET["Scarlett"] = "O\' Hara"
So if magic quotes are active, the function takes care of this, and slashes are stripped so that the strings retain their correct, not escaped value.
The algorithm checks if the data passed to the function is an array, if not it cleans directly the value.
$string = "Escapes\'in\'a string";
clean($string);
is it an array? No. Then return stripslashes(my data)
$array = array("key\'with\'escapes"=>"value\'with\'escapes", "another\'key"=>"another value");
clean($array)
is it an array? Yes. So cycle through each key/value pair with foreach, take the key and clean it like the first example; then take the value and do the same and put the cleaned versions in the array.
As you see the function has two different behaviours differentiated by that "if" statement.
If you pass an array, you activate the second behaviour that in turns passes couples of strings, not arrays, triggering the first behaviour.
My thought is that this function doesn't work properly, though. Anyone got the same sensation? I have it not tested yet but it seems it's not "cleaning" the key/values in the sense of replacing them, but adds the cleaned versions along the uncleaned ones.

using a foreach loop to initialize variables

I have built an empty associative array whos keynames refer to submitted post data. I can capture the postdata just fine, but I run into trouble trying to instantiate variables who's names match the array key.
for example:
$insArray = array('rUsername'=>'', 'rPass'=>'', 'rQuestion'=>'', 'rAnswer'=>'', 'rFName'=>'', 'rLName'=>'', 'rBDateD'=>'', 'rBDateM'=>'', 'rBDateY'=>'', 'rHCheck'=>'', 'rHCeckOption'=>'', 'rEmail'=>'');
foreach($insArray as $key=>$value){
if (filter_input(INPUT_POST, $key) != ''){
$key = stripslashes(filter_input(INPUT_POST, $key));
$insArray[$key] = $key;
}
}
First line creates the empty array, then the foreach loops through this array. Now it gets tricky.
filter_input(INPUT_POST, $key) captures the value located in the post data matching the current key, rUsername in this case
$key is where the problem lies. I want the NAME of the new variable to be the associative key name, for example I want to replace $key with $rUsername in the first iteration, $rPass in the second, and so on. I tried using two $$, but I know that's not right. Never tried doing this before, but it would be helpful if I could figure it out.
UPDATE:
This is the final code which was a combination of two of the answers provided.
if (isset($_POST['submit'])) {
//Build array of variables to be put into database
$insArray = array('rUsername'=>'', 'rPassword'=>'', 'rQuestion'=>'', 'rAnswer'=>'', 'rFName'=>'', 'rLName'=>'', 'rBDateD'=>'', 'rBDateM'=>'', 'rBDateY'=>'', 'rHCheck'=>'', 'rHCheckOption'=>'', 'rEmail'=>'');
foreach(array_keys($insArray) as $key){
$insArray[$key] = filter_input(INPUT_POST, $key);
$$key = filter_input(INPUT_POST, $key);
}
}
Gave me exactly the output I wanted, thanks guys!
You're not accessing $_POST at all, so all you're doing is taking some array members you defined yourself, filtering them for harmful POST characters (why would you attempt to inject your own code?) and then creating a new array from those self-defined key values.
If I'm guessing right at what you want, it should be this:
foreach(array_keys($insArray) as $key) {
$insArray[$key] = stripslashes(filter_input(INPUT_POST, $_POST[$key]));
}
The use of stripslashes suggests that you're on a braindead version of PHP which has magic_quotes enable. You should upgrade to a modern version of PHP and/or turn them off.
The solution is change
$key = stripslashes(filter_input(INPUT_POST, $key));
to
$$key = stripslashes(filter_input(INPUT_POST, $key));
See http://www.php.net/manual/en/language.variables.variable.php
Also, recheck your code, which are doing some mistakes..
If I understand you correctly, Im going to suggest this approach:
$defaultValues = array('rUsername'=>'', 'rPass'=>'', 'rQuestion'=>'', 'rAnswer'=>'', 'rFName'=>'', 'rLName'=>'', 'rBDateD'=>'', 'rBDateM'=>'', 'rBDateY'=>'', 'rHCheck'=>'', 'rHCeckOption'=>'', 'rEmail'=>'');
$values = array_map('stripslashes', array_merge($defaultValues, array_filter($_POST)));
extract($values, EXTR_SKIP);
echo $rUsername;
echo $rPass;
.........
By using the snippet above, you have to take into account the following
Im using the extract function with EXTR_SKIP so you dont overwrite existing variables. Make sure to only use the variables you need in your code and sanitize them appropietly.
By using array_filter on the $_POST superglobal im "erasing" all empty or null variables. so if an expected key was not sent via $_POST, it defaults to the value specified by the $defaultValues array.
I dont quite understand why you are using filter_input without the third parameter (filter constants).
Hope this will help, If not may be I have misunderstood the problem.
Instead of
$key = stripslashes(filter_input(INPUT_POST, $key));
$insArray[$key] = $key;
Try
$insArray[$key] =stripslashes(filter_input(INPUT_POST, $key));
Then after the foreach loop
extract($insArray);

How can I convert an array of strings to an array of integers?

I'm getting this error with my current PHP code:
Notice: TO id was not an integer: 1, 2. 1) APNS::queueMessage ->
How can I convert to an array of strings to an array of integers like in this other question: ID not integer... EasyAPNS ?
I'm basically trying to pass ids (from my database,) to newMessage() like this Apple example:
// SEND MESSAGE TO MORE THAN ONE USER
// $apns->newMessage(array(1,3,4,5,8,15,16));
// ($destination contain a string with the Ids like "1,2,3")
Here is my code below:
if (isset($destination))
{
//$destination = 1,2,..
$dest = explode(",", $destination);
if (isset($time))
{
$apns->newMessage($dest, $time);
}
else
{
$apns->newMessage($dest);
}
$apns->addMessageAlert($message);
$apns->addMessageBadge($badge);
$apns->addMessageSound('bingbong.aiff');
$apns->queueMessage();
header("location:$url/index.php?success=1");
}
I would create a wrapper function that accepts an array, and then call it.
function newMessageArray($array) {
foreach ($array as $element) {
$apns->newMessage($element);
}
}
This way, you can call newMessageArray() with an array of integers, such as array(1,2,3,4,5), and they will all be sent.
Also, you should change the variable names (from $array and $element) to something more meaningful. I don't know what you're trying to do, so I wasn't sure what names to use.
Your Question is not clear, It's only a guess work.
It seems to be error in convert integer, try
$dest = explode(",", $destination);
$destArray = array();
foreach($dest as $key => $val) {
$destArray[$key] = intval($val);
}
if (isset($time))
{
$apns->newMessage($destArray, $time);
}
else
{
$apns->newMessage($destArray);
}
Convert where the string is not integer using 'intval'.
I believe what you may be looking for is how to do this:
You have ids in your database table, right? And you are trying to get multiple ids into an array so that the array can be used in $apns->newMessage() call, right? (I checked the source for this...) But, the ids are somehow coming over as strings instead of ints.
So, you probably want to just make sure that the new array is made up of ints, like this:
function to_int($x) {
return (int)$x;
}
$dest = array_map("to_int", $dest);
There are probably other ways to do this, but this way, you at least know that you have int variables in that array. Hope that helps!

Extracting Data from JSON Using PHP

Here's a test jason feed
{"MEMBERS":[{"NAME":"Joe Bob","PET":["DOG"]}, {"NAME":"Jack Wu","PET":["CAT","DOG","FISH"]}, {"NAME":"Nancy Frank","PET":["FISH"]}]}
What I'm attempting to do is extract data if PET contains CAT or FISH or both. Another user suggested a filter as such:
$filter = array('CAT', 'FISH');
// curl gets the json data (this part works fine but is not shown for brevity)
$JSONarray=json_decode($JSONdata,true);
foreach($JSONarray['MEMBERS'] as $p) {
if (in_array($p['PET'], $filter)) {
echo $p['NAME'] . '</br>';
}
}
But it's not returning anything.
Note: edited based on comments below
Use strings to access the array and not uninitialized constants.
$p['PET'] is an array. You have to use some other method to compare it against $filter, e.g. array_intersect:
foreach($JSONarray['MEMBERS'] as $p) {
$diff = array_intersect($filter, $p['PET']);
if (!empty($diff)) {
echo $p['NAME'].'</br>';
}
}
DEMO
It should work like this:
foreach($JSONarray['MEMBERS'] as $p) {
if (array_diff($p['PET'], $filter) != $p['PET']) {
echo $p['NAME'].'</br>';
}
}
Remember to always use quotes when you are trying to access an element of an associative array. Without quotes, PHP tries to interpret it as a constant (throwing a Notice on failure). So instead of $a[index] do $a['index']. Please also see Why is $foo[bar] wrong?
In your code, $p['PET'] will be an array of pet names, not one pet name. Testing with in_array() won't be successful, because it will try to find the whole array in $filter. In my code example, I used array_diff() which will find the difference between the two arrays, then I compare it to the original array. If they match, the $filter pets were not found.
First, you need to use quotes on your array keys:
$JSONarray['MEMBERS']
$p['PET']
$p['NAME']
Secondly, you can't use in_array as it assumes 'needle' to be the array('CAT', 'FISH') and not any one of it's values.
(The parameter order was also the other way around)
Here's a method using array_intersect:
foreach($JSONarray['MEMBERS'] as $p) {
$test = array_intersect($filter, $p['PET']);
if (count($test)>0) {
print( $p['NAME'].'</br>' );
}
}

Categories