is there a way to dynamically access $_GET and $_POST in one go? IE, something like:
$do = array('GET', 'POST');
foreach($do AS $type) {
foreach (${'_'.type} AS $var=>$val) {
... # logic
}
}
I understand that there is $_REQUEST, but that doesn't tell me source (get or post) and that there are deprecated HTTP_GET_VARS and HTTP_POST_VARS, but those are deprecated.
Clearly, I can just loop individually. The reason why I'm trying to avoid this is that the logic is a little lengthy but also identical. It would be ideal to not have to have a copy of this logic and open myself up to mistakes.
Or am I completely thinking about this the wrong way and there is some other recommended approach?
Thanks!
Thank you
Thank you for the great feedback everyone. I think #deceze answers the question most objectively, but #charlee (and later deceze as well) alludes to a better solution.
In the end, I created a function with logic and then placed that in my foreach, as such:
foreach($_GET AS $var => $val) {
$_GET[$var] = func($val);
}
I do end up with two foreach()'s, but I appreciate the legibility and increased usability. Thank you again everyone!
foreach (array('get' => $_GET, 'post' => $_POST) as $type => $values) {
foreach ($values as $key => $value) {
...
}
}
If you do care about the source I suggest you loop individually. Its not safe to mash $_POST with $_GET because it would be much easier for hacker to pass data thru GET which is supposed to be POST.
Long logic can always be extracted to a function so you won't have a copy of this logic.
Merge your arrays with array_merge():
$_GET = array('one' => 'foo', 'two' => 'bar');
$_POST = array('three' => 'foo', 'four' => 'bar');
$merged = array('_GET' => $_GET, '_POST' => $_POST);
foreach($merged AS $type => $array) {
foreach ($array AS $var => $val) {
echo "[{$type}] {$var}: {$val}" . PHP_EOL;
}
}
Outputs
[_GET] one: foo
[_GET] two: bar
[_POST] three: foo
[_POST] four: bar
And yes, you shouldn't use $_REQUEST, because
it combines COOKIE as well as GET and POST, and the COOKIE data always takes precedence creating the possibility for dangerous "sticky" variables.
If the logic is identical, you can try using a function. Put your entire code in the function and pass the array that you want to loop through i.e. $_GET or $_POST. If you want to know the source as to whether it is GET or POST, you can try concatenation.
It would help to know what sort of an output you want.
Related
Here is a fairly big object dumped using print_r.
https://docs.google.com/document/d/175RLhWlMQcyhGR6ffGSsoJGS3RyloEqo4EEHCL2H2vg/edit?usp=sharing
I am trying to change the values of the uploaded_files.
Towards the end of that object you'll see something like
[uploaded_files] => Array
(
[attachment] => /home2/magician/public_html/development/testing/wp-content/uploads/wpcf7_uploads/Central-Coast-Montessori-logo.jpg
[attachment2] => /home2/magician/public_html/development/testing/wp-content/uploads/wpcf7_uploads/Andrew.jpg )
My code
// move the attachments to wpcf7ev temp folder
foreach ($cf7ev_object['uploaded_files'] as $key => $uploaded_file_path) {
$new_filepath = WPCF7EV_UPLOADS_DIR . '/' . basename($uploaded_file_path);
wpcf7ev_debug("New file path is {$new_filepath}");
rename($uploaded_file_path, $new_filepath);
wpcf7ev_debug("'{$key}'is the KEY for {$uploaded_file_path}");
wpcf7ev_debug($cf7ev_object['uploaded_files']);
$cf7ev_object['uploaded_files'][$key] = $new_filepath; // this is not updating
}
To loop through it I have been using
foreach ($cf7ev_object->uploaded_files as $key => $uploaded_file_path) {
and this has worked.
But shouldn't it be
foreach ($cf7ev_object['uploaded_files'] as $key => $uploaded_file_path) {
? As '->' is for accessing methods?
And specifically I want to update the values of those uploaded_files, so to do that I need to do
$cf7ev_object['uploaded_files'][$key] = $new_filepath; // this is not updating
? But this doesn't seem to be working.
I think I need to be clear on how to access values in an object.
Thanks.
First of all, regarding the single arrow "->" that is how you reference an objects values. But I won't get into that. Since you say it works, $cf7ev_object is obviously an object.
You say you want to "access the values in the object".
var_dump($cf7ev_object);
This will spit out what is in that object. I gather you are a bit of a newbie, so I will try to help you out best I can with the limited data you provided (you may want to expand your question.
Looping is not a one-shot deal. You can have nested loops and nested loops inside of those. However, it is a resource hog if you're not careful. Here is an exercise that might help you.
$new_array = array();
foreach($cf7ev_object->uploaded_files as $key => $value) {
$new_value = $value;//do something to the $value here
$new_array[$key] = $new_value;
}
//take a look at your work now:
print_r($new_array);
I hope this helps. Note: your google doc is restricted, public can't see it.. And your question is too vague. Let me know if I can help more.
If you want to change the object array values instantly you just set it equal to the above loop result:
$cf7ev_object->uploaded_files = $new_array;
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.
I'm currently using the following format to save a value from an HTML form $item_name=$_POST['item_name'];
This saves the value, but how to I also save the name attribute in a variable?
Thanks in advance!
Assuming you want to store each element of $_POST variable as a key-value pair, then you can try:
$var = array();
foreach($_POST as $key => $val) {
$var[$key] = $val;
}
I'm saving a lot of values and want to avoid typing each one out.
Please, make your mind first.
Global variables are intended to be typed by hand.
If you want some automated processing - just keep them in a form of array.
Looks like rdt.exe's answer is what you're looking for.
maye you noticed you have to use the name to access the $_POST-array and get the value. if you want to store the name in a variable, too, just do:
$item_name_name = 'item_name';
$item_name_value = $_POST[$item_name_name];
you could also use some kind of loop to dynamically create variables with the according names like this:
foreach( $_POST as $name => $value ){
$$name = $value;
}
both ways are some kind of unnecessary and useless in my opinion, but you havn't stated what exactly you're trying to achive - so maybe this helps.
An alternative approach:
$keysarray = array_keys ( $_POST);
print_r( $keysarray);
This will give you all the keys in array
The function you are looking for is called extract.
This will create variables for all the $key=>$val pairs in the array.
$_EXAMPLE = array('bird' => 'chicken', 'dog' => 'greyhound');
export($_EXAMPLE);
echo $bird; # prints "chicken"
echo $dog; # prints "greyhound"
Watch out though - this is a huge security risk. So are the solutions described in some of the other answers.
The problem with doing something like this is that a user can tamper with the POST data, and set parameters other than the ones she is supposed to set. If they set variables that are actually variable names in your application, those variables can be overwritten.
$is_admin = false;
$_EXAMPLE = array('bird' => 'chicken', 'dog' => 'greyhound', 'is_admin' => 'true');
export($_EXAMPLE);
if ($is_admin) { # this will now evaluate to true.
# do sensitive stuff...
}
Is there a better way to search through $_SESSION variables (or any array) for a particular string than:
foreach($_SESSION as $k => $v){
if(strstr($k, 'p_')){
Thanks.
edit: My keys will look similar to:
p_123
p_456
i_123
...
If your $_SESSION structure must stay "as is", IMO it is Ok.
However if all 'p_' elements could go under an array index like $_SESSION['p'] = array('key1' => 'val1', ...), you could retrieve all 'p' elements at once.
BTW this is only micro optimization, go with the structure you're fine with.
EDIT: Just be careful with strstr(): if one day you must store keys like i_123_p_456 into your $_SESSION array, you should switch to if (strpos($k, 'p_') === 0).
I'm adding another answer as I'm taking a completely different approach.
If you're going to do this a lot, you could consider using filters.
function pprefix($var) {
return(strstr($var, 'p_'));
}
$filtered = array_filter(array_keys($_SESSION), "pprefix");
foreach($fildered as $k) {
echo("$k => " . $_SESSION[$k]);
}
try this:
if (array_key_exists('p_', $_SESSION)) {
echo($_SESSION['p_']);
}
Or, if you only knows part of the name of the key (like the beggining), I'd use the array_keys() instead $k => $v, like so:
foreach(array_keys($_SESSION) as $k) {
if(strstr($k, 'p_')){
// do something.
}
}
I want to remove an element from a PHP array (and shrink the array size). Just looking at the PHP docs, it seems this can be done using array_slice() and array_merge()
so I am guessing (off the top of my head) that some combination of array_merge() and array_slice will work. However, array_slice() requires an index (not a key), so I'm not sure how to quickly cobble these functions together for a solution.
Has anyone implemented such a function before?. I'm sure it must be only a few lines long, but I cant somehow get my head around it (its been one of those days) ...
Actually, I just came up with this cheesy hack when writing up this question....
function remove_from_array(array $in, value) {
return array_diff($in, (array)$value);
}
too ugly? or will it work (without any shocking side effects)?
This functionality already exists; take a look at unset.
http://php.net/manual/en/function.unset.php
$a = array('foo' => 'bar', 'bar' => 'gork');
unset($a['bar']);
print_r($a);
output will be:
array(
[foo] => bar
)
There's the array_filter function that uses a callback function to select only wanted values from the array.
you want an unset by value. loop through the array and unset the key by value.
unset($my_array['element']);
Won't work?
This code can be replaced by single array_filter($arr) call
foreach($array as $key => $value) {
if($value == "" || $value == " " || is_null($value)) {
unset($array[$key]);
}
}
/*
and if you want to create a new array with the keys reordered accordingly...
*/
$new_array = array_values($array);