6

I have several variables coming from an array in $POST_['array'] i wish to make some kind of loop for example foreach that makes, for every value in the variable a variable name of it and assigns the value for it.

For example if i have

$POST_['name'];
$POST_['last'];
$POST_['age'];
$POST_['sex'];

I want the loop to create each variable from the array inside the $_POST with the name of the variable like the following:

$name = 'John';
$last = 'Doe';
$age = '32';
$sex = 'male';

NOTE - The array is coming from a serialized jquery string that puts together all the variables and values in a form into one big string.

Is this possible?

Nicole
  • 32,841
  • 11
  • 75
  • 101
Luis Alvarado
  • 8,837
  • 12
  • 46
  • 60
  • 3
    If you use `extract`, pay attention to the potential security ramifications detailed in the PHP manual. – ceejayoz May 16 '11 at 21:11
  • ?logged_in=True&admin=True&user_id=1 Yeah. Doing what you want to do here is *incredibly* illadvied. – Shayne Jul 04 '23 at 09:12

5 Answers5

17

You don't need a loop, you want extract:

extract($_POST); // But use caution, see below


Cautions and best practices

As noted in the comments this forces all parameters in the $_POST array into the current symbol space.

In global space

<?php
extract($_GET);
var_dump($_SERVER); // Can be overwritten by the GET param
?>

The code above illustrates the problem as shown in this answer — some pretty dangerous things can be overwritten in the global space.

Inside a function

function myFunc() {
    // (Mostly) empty symbol space! (excluding super globals)
    extract($_POST);
}

Inside a function, as the first line, no harm done.

Important note: You might think since $_SERVER is a super global, that this exploit could happen inside a function as well. However, in my testing, on PHP Version 5.3.4, it is safe inside a function — neither $_SERVER, $_POST, $_GET, $_SESSION, or presumably other superglobals, could be overwritten.

With options

You can also use extract with extract_type options that do not overwrite.

The best option to use, in my opinion, is simply to prefix all variables from extract:

// $_GET = test=1&name=Joe

extract($_GET, EXTR_PREFIX_ALL, "request_get");

echo $request_get_test; // 1
echo $request_get_name; // Joe

That way you don't have the overwrite problem, but you also know you got everything from the array.

Alternate - looping w/ conditional

If you wanted to do this manually (but still dynamically), or wanted to conditionally extract only a few of the variables, you can use variable variables:

foreach ($_POST as $key => $value) {
    if (isset($$key)) continue;

    $$key = $value;
}

(The example condition I've used is an overwrite prevention.)

Community
  • 1
  • 1
Nicole
  • 32,841
  • 11
  • 75
  • 101
  • 1
    @jakenoble It's okay if you pay attention to the manual and use an option other than the default behaviour to prevent overwriting variables. – ceejayoz May 16 '11 at 21:13
  • 1
    @jakenoble - It would be helpful to explain why, instead of -1 and a comment on every post. In isolation, for example, if I know what the contents of `$_POST` are, what is the difference? – Nicole May 16 '11 at 21:17
  • 1
    I have added my own answer although that has been down voted with no comments. I can't win. You may overwrite variables you want which will result in unpredictable behaviour. No one could take advantage but it is just an example of something that can be used and then misused by a new user of PHP if it isn't explained properly to start with. This is why PHP has as bad name because of things like `extract()` and their misuse. – Jake N May 16 '11 at 21:19
  • @jakenoble: Just dont use variables, that you dont initialize. Put `extract()` at the beginning of (lets say) a function and there aren't any variables, that can be accidentally overriden. – KingCrunch May 16 '11 at 21:19
  • 1
    @KingCrunch @Renesis All of that is fine, but make sure you write it in your answer, you cannot assume the OP or anyone else will read inbetween the lines or even read the manual and use the function as it should be used. Quick fix is fine, but make sure it is explained as a quick fix. – Jake N May 16 '11 at 21:21
  • 1
    @jakenoble - Of course, you are right. Sadly, I can't advise against every possible problem resulting from a decided course of action in a question, but being aware of the overwriting is a good idea (though you'd have to assume that if they understand order of execution, they would realize that, and if they don't, they have bigger problems). Going to read your answer now... – Nicole May 16 '11 at 21:21
  • 2
    there is a link to the manual in the post, which clearly has options to prevent overwriting, if the method is used properly it's just fine, and if you know whats going to be in the post in the first place, you should have a decent enough naming convention as to NOT overwrite already instantiated variables. I personally believe that this is better than a foreach, just because its cleaner and forces you to have better naming standards . – Ascherer May 16 '11 at 21:40
13

Try not to use extract() when using $_POST. You may overwrite variables you want which will result in unpredictable behaviour. It is a bad habit to get into and while is dynamic may not be the best solution.

You can do something like this:

foreach($_POST as $key => $value)
{
    switch($key)
    {
        case "name":
            $name = $value;
        break;
        case "last":
            $last = $value;
        break;
    }
}
Jake N
  • 10,535
  • 11
  • 66
  • 112
  • 1
    This is excellent advice. The other posts introduce potentially buggy and certainly insecure code. – andrewmitchell May 16 '11 at 21:24
  • @jake I just realized I did -1 this though you'll have to believe me that it was not a revenge downvote, since I didn't even notice who posted it. Apologies for not leaving a comment. The reason is because this isn't dynamic, is very verbose and makes it even harder to update the code with new/changed names. Maybe they don't need that. But if they want a dynamic extraction, there are other ways to avoid overwriting. If you edit your answer (my vote is locked in right now) with a bit of expansion about that, I will certainly remove my downvote, no hard feelings. – Nicole May 16 '11 at 21:26
  • @jakenoble - Done, and I also expanded my answer based on this discussion. Thanks for your input. – Nicole May 16 '11 at 21:41
  • i did a test. its not working.. There are 10 form values posted but this code is returning only the last form values. – logan Feb 27 '14 at 19:11
1

You can actually use the built-in function called extract

Doug Molineux
  • 12,283
  • 25
  • 92
  • 144
  • Really? How could somebody take advantage of it? Perhaps send a post called "loggedIn" => "true" or something like that? – Doug Molineux May 16 '11 at 21:11
  • Not take advantage but it would be a bad habit to get into – Jake N May 16 '11 at 21:13
  • 1
    @Peter: They can do `_POST=haha I nuked your _POST array!`, and ditto for the rest of the superglobals. – Marc B May 16 '11 at 21:18
  • Yep. http: // admin dot mycompany dot com?admin=true&user_id=1&logged_in=true Let someone write too globals and your literally handing them the keys to the kingdom. – Shayne Jul 04 '23 at 09:16
1

Why not use a foreach?

foreach($_POST as $key=>$val){
    ${$key} = $val;
}
Naftali
  • 144,921
  • 39
  • 244
  • 303
0

I just want to mention that you can improve foreach technique because we have in HTML the ability to name one of our form fields using square bracket notation, and if we do that, what HTML will do is it will submit a series of values as an array.

<input name="user[name]">
<input name="user[last]">
<input name="user[age]">
<input name="user[sex]">

Than use just one line of code to assign all values from input fields into local array $args.

$args = $_POST['user'];

So what that means is when we go to process the form, we're looking at an array of values instead of a bunch of single values that we have to go retrieve.

So we can just simply go to the post super global and ask for one item: that is user. And what we get back is an associative array. So instead of having to build up that array by going and retrieving all those values one at a time, we're instantly given an array, just because we named our form fields differently.

Matija Lukic
  • 599
  • 8
  • 28