0

I'd like to pull all the names of fields from a submitted form, and create variables from them automatically. Not much of a problem as my code1 below shows. BUT I'd now like to put the code in a function that I can call from many PHP form processors, and have the newly created variables be accessible in the CALLING context. My code2 below is the best I can do; is there a safer, better way???

CODE1:

foreach($_POST as $key => $value){
   $$key = filter_var($value, FILTER_SANITIZE_STRING);
}
unset($key,$value);

CODE2: (resides in included file)

function test(){
        foreach($_POST as $key => $value){
            global $$key; <<<------ my best attempt
            $$key = filter_var($value, FILTER_SANITIZE_STRING);
        }
        unset($key,$value);
}
URi613
  • 27
  • 2
  • 3
    This is similar to what [extract](https://www.php.net/manual/en/function.extract.php) does and is risky, as that documentation says - someone could submit a value which overwrites another important variable in your script, and could thus inject something bad where it shouldn't be. See also https://stackoverflow.com/a/11907393/5947043 and similar. So my advice would be, don't create variable names from this (uncontrollable) client-side input. And why do you need to anyway? Just access the data directly from $_POST as and when you need it. – ADyson Jun 30 '23 at 14:48
  • 2
    P.S. `global $$key; <<<------ my best attempt`...this is the opposite of your ask. This brings a global variable into the local function scope, not the reverse. AFAIK you can't directly do the reverse. Even if this was a good idea (which it really really isn't...see above), there's not really anything you can do except just return the values from the function in an array. But that would effectively just be something with the same structure as $_POST, and since $_POST is a superglobal to begin with, it's already accessible from anywhere, so you should just use it. – ADyson Jun 30 '23 at 14:57
  • You would rather want to return an associative array and process it further. – nice_dev Jun 30 '23 at 16:23
  • Apologies there were things I left out which I'm now cause confusion. Rest assured I was aware of the old super globals method, and the risk of using user input without checks. In the example I gave, there would definitely be checks and balances before the variables made it to any other location! The point to my question was, without making the variables global from a function, is there a way to get them usable in my calling code without returning them explicitly? – URi613 Jul 02 '23 at 12:43
  • Well the simple answer so that is, no there isn't – ADyson Jul 02 '23 at 16:00
  • `there would definitely be checks and balances before the variables made it to any other location`...how exactly would you enforce that, out of interest? – ADyson Jul 02 '23 at 16:01

2 Answers2

3

I'd like to pull all the names of fields from a submitted form, and create variables from them automatically.

That was actually a PHP bultin feature from the beginning, that was eventually removed from the language given how troublesome it was.

If you're happy with variables popping up from nowhere and the excitement of being able to be hacked, you need to add your variables to the $GLOBALS superglobal array. That will make them available in global scope.

function test() {
    foreach ($_POST as $key => $value){
        $GLOBALS[$key] = filter_var($value, FILTER_SANITIZE_STRING);
    }
}

is there a safer, better way???

The simplest way to handle variable lists of variables is to use an array. It's also safer because site visitors cannot overwrite random variables:

function test(): array {
    $sanitized = [];
    foreach ($_POST as $key => $value) {
        $sanitized[$key] = filter_var($value, FILTER_SANITIZE_STRING);
    }
    return $sanitized;
}

But I think you should reconsider what you're even trying to accomplish here. FILTER_SANITIZE_STRING doesn't do anything useful, and it's unclear why you can't know in advance what variables to expect from your form. If you look for simplicity and security, I'd vote for this:

$foo = $_POST['foo'] ?? null;
$bar = $_POST['bar'] ?? null;

... for every variable. Replace null with any other default value you prefer.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
1

have the newly created variables be accessible in the CALLING context.

This is easy. And a very common feature: the return value of that function.

So within the function build the variable table in form of a PHP array, then return the array.

In the calling context receive it then and have all form variables accessible by their name as array keys.

hakre
  • 193,403
  • 52
  • 435
  • 836