Unable to define variables as empty in foreach loop - php

I'm trying to define three empty variables through a foreach loop to make my code cleaner. This is what I've tried, however I see the error:
Notice: Undefined variable: hi
foreach(['$hi','$bye','$hello'] as $key) {
$key = "";
}
$hi .= "hello";
When I remove the foreach loop and simply define each empty variable one by one, like this, it works:
$hi = "";
$bye = "";
$hello = "";

You're assigning to $key, not to the variable that's named by it. To indirect through a variable, you need to use $$key. But the value of the variable shouldn't include the $, just the variable name.
foreach (['hi', 'bye', 'hello'] as $key) {
$$key = "";
}
$hi .= "hello";
However, if you ever find yourself using variable variables like this, you're almost certainly doing something wrong. You should probably be using an associative array instead.

You have strings which are saved in $key. So the value of $key is a string and you set it to "".
Later you want to append something to a variable you never used.
Try to remove the ' and write
foreach([$hi, $bye, $hello] as $key) {
Generally thats not the best way to initialise multiple variables. Try this
Initializing Multiple PHP Variables Simultaneously

Easier way:
list($hi, $bye, $hello) = "";

foreach creates a new array variable in memory, so you only clear these values inside the array in memory which is useless out of the foreach sentence. the best way is:
$h1=$bye=$hello="";
I didn't think that a foreach process will work more fast than a Simple equal (=), foreach function uses more CPU resources than a simple =. That's because the math CPU exists.

Related

Reset variables inside a 'foreach' loop

As I have really many variables inside my foreach loop, it would be great if I could reset them all at once instead of:
$variable_one = ''; // Reset to: It is blank for each loop
$variable_two = '';
...
$variable_hundred = '';
If I were you and had these number of variables which should be set to some value in a loop, I would use an array instead:
$arr = ['first value', 'second value','hundred value'];
Then you can access what you want by index in your loop, so instead of using:
$variable_one
You will use:
$arr[0]
And now you want to reset them all, so you can use array_map() like this:
$arr = array_map(function($val){ return '';}, $arr);
If you have such a high number of variables in your loop, you probably should refactor it to make it simpler. If you are sure that having 100 variables inside a loop is a way to go, you can use the following expression:
$variable_one = $variable_two = $variable_hundred = '';
This will set each variable to '' in one very long line.
Another option is to unset() all these variables in a single function call:
unset($variable_one, $variable_two, $variable_hundred);
But this will not set their value to '', but unset the variable itself.

undefined variable and undefined index php errors

I've been given the task to remove undefined variable and undefined index errors, which i know how to
$value = isset($_POST['value']) ? $_POST['value'] : '';
The problem is this is way too time consuming, I predict over 2000 variables, $_GET, $_POST hasn't been set. So is there a regular expression i can use to set these variables quickly?
How do i do regex to change this $category = $_GET['c'] to this
$category = isset($_GET['c']) ? $_GET['c'] : ''?
And how do i do regex to change if($page or $category or $profile) to this
if(isset($page) or isset($category) or isset($profile))?
This is the best method i can think of by using regex find & replace in Notepad++. I assume over 2000 PHP variable/index undefined errors. How do i solve this without turning off errors?
you should not use regex because it's kind of heavy :)
if i'm understanding your question right, you can do this like this,
with this approach, it does not matter how many parameters contains POST or GET, you simply filter them through foreach loop and getting clean arrays with parameters, also you can make it a function that returning array.and then you just need to check if_array_key_exests() and do your things.
$_POST = ["user"=>"1", "num"=>2];
$_GET = ["user" => '', "num"=>1];
//function method
function filter($array)
{
$arr = array();
foreach ($array as $key => $val) {
if (!empty($val)) {
$arr[$key] = $val;
}
}
return $arr;
}
without function
$post = array();
foreach ($_POST as $key => $val) {
if (!empty($val)) {
$post[$key] = $val;
}
}
$get = array();
foreach ($_GET as $key => $val) {
if (!empty($val)) {
$get[$key] = $val;
}
}
For your first problem, replacing something like
(\$\w+)\s*=\s*\$_GET\[['"]?(\w+)['"]?\]\s*;
by
$1 = isset($_GET['$2']) ? $_GET['$2'] : '';
should work.
Regarding the second, I don't know if this is possible with a variable number of variables. This one works for 3 variables, replace
if\s*\(\s*\s*(\$\w+)\s+or\s+(\$\w+)\s+or\s+(\$\w+)\s*\)
by
if (isset($1) or isset($2) or isset($3))
You can add another \s+or\s+(\$\w+) before the last \s* in the search, and add another or isset($4) in the replacement for 4 variables etc.
I recommend you to replace them one by one instead of replacing all at once ;-)
Also note that if ($a) is not the same as if (isset($a)). Consider something like this:
// query string is a=0
$a = $_GET['a'];
if ($a) // will be false
if (isset($a)) // will be true
if (!empty($a)) // will be false
So, perhaps you want to use !empty() instead of isset(). This should work without notices, too.
resove first issue:
define a function like:
function global_get($key){
return isset($_GET[$key])?$_GET[$key]:'';
}
then use sed(linux tool) to replace all parts like this(it will modify all the $_GET[.*] of php extension files in your project,so be careful to use this):
find /yourproject -name "*.php" -exec sed -i "s/\$_GET\[\([^]]*\)\]/global_get(\1)/" \;
you may modify this command to apply your own demand.
The second issue could be harmful if you use the regex expression because it is hard to make a role rule.so I recommend you to replace manually.

Naming variables automatically from $_POST array.

My PHP script processes some POST variables.
Instead of manually naming each variable
$name = $_POST['name'];
$email = $_POST['account'];
I'd like my script to grab all the variable names from the $_POST array and automatically create variables with those names, e.g. (not code, just illustrating the principle)
foreach ($_POST as $name => $value) {
$[$name] = $value;
}
Is something like that possible?
You can use the extract function for this. But there is a risk, because you cannot know what data is posted, and it will create or overwrite variables in the scope in which you call it, possibly leading to unexpected behaviour.
You can partially counter this, using one of the flags for extract, for instance:
extract($_POST, EXTR_SKIP);
Anyway, make sure to read the two warnings (red block) on the documentation page of this function. And of course, the same warning applies when you do this using your own foreach loop, so answers suggesting that are no more secure.
There is extract function in php:
extract($_POST);
This is a very bad idea because it allows a user to create any variable in your PHP script (within the scope that it this code is used). Take for example if you have a $debugging flag:
$debugging = false;
foreach ($_POST as $name => $value) {
$$name = $value;
}
// some time later, we do a query and output the SQL if debugging
if($debugging){
echo $sql;
}
What if a malicious user submitted an input called debugging with a value of 1? Your debugging flag would be changed and the user could see sensitive debug data.
Try this (which is a bad practice):
foreach ($_POST as $name => $value) {
$$name = $value;
}
You can do this with variable variables as follows:
foreach ($_POST as $name => $value) {
$$name = $value;
}
You can also use the following format if you want to muck about with the variable names some more:
foreach ($_POST as $name => $value) {
${$name.'_1'} = $value;
}
There are comments here saying don't use variable variables - mainly because they are hard as heck to troubleshoot, make it damn hard for others to read your code and will (for the most part) create more headaches than they solve.

PHP get array() value to become $variable

ok, So I have this array:
$choices = array($_POST['choices']);
and this outputs, when using var_dump():
array(1) { [0]=> string(5) "apple,pear,banana" }
What I need is the value of those to become variables as well as adding in value as the string.
so, I need the output to be:
$apple = "apple";
$pear = "pear";
$banana = "banana";
The value of the array could change so the variables have to be created depending on what is in that array.
I would appreciate all help. Cheers
Mark
How about
$choices = explode(',', $_POST['choices']);
foreach ($choices as $choice){
$$choice = $choice;
}
$str = "apple,pear,pineapple";
$strArr = explode(',' , $str);
foreach ($strArr as $val) {
$$val = $val;
}
var_dump($apple);
This would satisfy your requirement. However, here comes the problem, since you could not predefine how many variables are there and what are they, it's hard for you to use them correctly. Test "isset($VAR)" before using $VAR seems to be the only safe way.
You'd better just split the source string in just one array and just operate the elements of the specific array.
I have to concur with all the other answers that this is a very bad idea, but each of the existing answers uses a somewhat roundabout method to achieve it.
PHP provides a function, extract, to extract variables from an array into the current scope. You can use that in this case like so (using explode and array_combine to turn your input into an associative array first):
$choices = $_POST['choices'] ?: ""; // The ?: "" makes this safe even if there's no input
$choiceArr = explode(',', $choices); // Break the string down to a simple array
$choiceAssoc = array_combine($choiceArr, $choiceArr); // Then convert that to an associative array, with the keys being the same as the values
extract($choiceAssoc, EXTR_SKIP); // Extract the variables to the current scope - using EXTR_SKIP tells the function *not* to overwrite any variables that already exist, as a security measure
echo $banana; // You now have direct access to those variables
For more information on why this is a bad approach to take, see the discussion on the now deprecated register_globals setting. In short though, it makes it much, much easier to write insecure code.
Often called "split" in other langauges, in PHP, you'd want to use explode.
EDIT: ACTUALLY, what you want to do sounds... dangerous. It's possible (and was an old "feature" of PHP) but it's strongly discourage. I'd suggest just exploding them and making their values the keys of an associative array instead:
$choices_assoc = explode(',', $_POST['choices']);
foreach ($choices as $choice) {
$choices_assoc[$choice] = $choice;
}

Put all parameters from a session into variables

I have the following code:
if(isset($_SESSION["spgrund"])) {
$spgrund = $_SESSION["spgrund"];
}else{
$spgrund = '';
}
This code is repeated about 20 times for each session variable. How can I make a loop out of it?
foreach($_SESSION as $key => $value){
$$key = $value;
}
I think that should work. But I get undefined variable error messages. Can't I use such a loop?
What you actually try to achieve is already available in PHP, the extract­Docs function:
extract($_SESSION);
From it's documentation:
Import variables from an array into the current symbol table.
Checks each key to see whether it has a valid variable name. It also checks for collisions with existing variables in the symbol table.
You would still need look for undefined variables however. Probably you should define them first?
foreach($_SESSION as $key => $value)
{
$$key = $value;
}
you missed the $ for value

Categories