4

What is the best way to define variables from a submitted form instead of having:

$username = $_POST['username'];
$email = $_POST['email'];
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
etc

because it will end up with too many lines of code.

  • 1
    Why do you want to do that in the first place? – PeeHaa Dec 12 '14 at 13:45
  • You *could* venture into the crazy world of XForms and receive all your POST data as an XML document and parse it with DOMDocument - but if *too many lines of code* is something you're trying to avoid... perhaps not. – CD001 Dec 12 '14 at 14:06
  • Just use them directly like `echo $_POST['username'];`. I am still waiting for the day to learn why in the world there are so many code examples that follow the practice you are showing. My current theory is that some developer(s) are trying to stupid-proof their code examples because `$_POST['username']` is information overload for someone who cannot grasp the idea of an array. That is all. It actually upsets me greatly that you are further showing this terrible practice by merely asking this question. I'm not upset with you but rather the fact that this code exists in 3,345,789,349 places. – MonkeyZeus Dec 12 '14 at 14:42
  • 3
    @CD001 I am barely resisting the urge to flag your comment as offensive :P – PeeHaa Dec 12 '14 at 14:53
  • @MonkeyZeus `` ... `= echo $_POST['something']; ?>` ... could result in an undefined index error since empty *textareas* don't propagate the $_POST array (same with checkboxes and radio buttons). In that instance you may want to define `$sSomething = !empty($_POST['something']) ? $_POST['something'] : "";` - then you can safely `= $sSomething; ?>`. Nothing to do with arrays but simply verifying/sanitising your data from userland before using it. – CD001 Dec 12 '14 at 15:19
  • @PeeHaa muwuahahahahaha >:D – CD001 Dec 12 '14 at 15:20
  • Just grab the values you need, each need to be sanitized or validated in a different way anyways and you do not want to manipulate the global array. – Ronni Skansing Dec 12 '14 at 15:30
  • 1
    @CD001 I agree with that specific example but OP's example and the other 3,345,789,349 fail to show such effort. – MonkeyZeus Dec 12 '14 at 15:36

8 Answers8

0

You answered yourself already: the one you mentioned is the best way to declare form variables within pure PHP world.

You can write as many abstractions you want on top of it but you got the point, if you submit with a post you need to pass through the snapshot you just posted...

The Recommendation

People recommended here the usage of extract(). Please, don't. As you can read from the php documentation:

Do not use extract() on untrusted data, like user input (i.e. $_GET, $_FILES, etc.). If you do, for example if you want to run old code that relies on register_globals temporarily, make sure you use one of the non-overwriting extract_type values such as EXTR_SKIP and be aware that you should extract in the same order that's defined in variables_order within the php.ini.

The recommended practice is to use $_POST[<varname>] directly. This way users of your web application can't set variables that should be safe.

The common pattern is something like the following:

<?php
   if(isset($_POST['submit']) 
   {
      echo("First name: " . htmlentities($_POST['firstname']) . "<br />\n");
      echo("Last name:  " . htmlentities($_POST['lastname'])  . "<br />\n");
   }
?>
<form action="myform.php" method="post">
   <p>First name: <input type="text" name="firstname" /></p>
   <p>Last name: <input type="text" name="firstname" /></p>
   <input type="submit" name="submit" value="Submit" />
</form>
Alex Gidan
  • 2,619
  • 17
  • 29
0

Use extract($_POST) function

it will convert array keys to variables, after that you can directly use as $username, $email, $firstname and $lastname etc.

It extract() function will do variable assigning work.

  • 1
    Not good to recommend an **insecure** solution. As you can read from official doc: "Do not use extract() on untrusted data, like user input (i.e. $_GET, $_FILES, etc.)." – Alex Gidan Dec 12 '14 at 14:18
  • @AlexGidan The recommendation of `extract` is perfectly fine. There should by a warning about overwriting local variables perhaps, but you can use `extract` without any security issues. – PeeHaa Dec 12 '14 at 14:56
  • @PeeHaa sorry but I have to disagree. extract() is insecure and an open door to server side exploits. Even if you use prefixes and so on, you can never forget about your extract() you wrote in your code: you need always to be sure you won't have variable override somewhere, etc... Not really a good practice to be recommended. – Alex Gidan Dec 12 '14 at 15:04
  • Sorry, but I have to call bull shit on that one. `function render($postData) { extract($postData); require __DIR__ . '/../templates/form.php'; }` is perfectly safe – PeeHaa Dec 12 '14 at 15:13
0

You can use extract method but remember read warning related to it to know before what you are dealing with here

one of them is

Warning: Do not use extract() on untrusted data, like user input (i.e. $_GET, $_FILES, etc.). If you do, for example if you want to run old code that relies on register_globals temporarily, make sure you use one of the non-overwriting flags values such as EXTR_SKIP and be aware that you should extract in the same order that's defined in variables_order within the php.ini.

Remember to always perform validation on input data from user or service client to avoid injections. Read more about it here

Mubashar
  • 12,300
  • 11
  • 66
  • 95
  • 2
    POST data is as untrusted as GET, FILES, HEAD, ect. We must assume all user passed data is evil. – a coder Dec 12 '14 at 14:09
0

As others have written you can use extract($_POST) but beware the security implications.

Also, you can optionally define how extract handles existing variables with the same name, or even tell it to prepend a string to the variables.

Assuming you POSTED the following data:

$_POST['id'] => 3, 
$_POST['description'] => "ford pinto"
$_POST['color'] => "mustard yellow"

extract($_POST, EXTR_PREFIX_ALL, 'fd1_');

Would yield the following variables:

$fd1_id
$fd1_description
$fd1_color

Check the documentation for more information on extract options.

Community
  • 1
  • 1
a coder
  • 7,530
  • 20
  • 84
  • 131
0

Ok, after my previous answer got downvoted because of security issues, I will make another attempt.

In one file, say inputs_definitions.php, define, which fields are you expecting:

<?php
$inputsDefinitions = [
  'name' => ['type' => 'text', 'placeholder' => 'Your name'],
  ...
];

Then include this file in your view and generate a dynamic form:

<?php
include("inputs_definitions.php");
for ($inputsDefinitions as $field => $properties) {
  echo '<input type="' . $properties['type'] . '" placeholder="' . $properties['placeholder'] . '" name="' . $field . '" />';
}
?>

In the code, where you process your data, include this file again and do the following:

<?php
include("inputs_definitions.php");
for ($inputsDefinitions as $field => $properties) {
   $$field = $_POST[$field]; 
}
...
?>
Liglo App
  • 3,719
  • 4
  • 30
  • 54
0

There is no silver bullet, it all depends on the usecase.

In some cases you might just use $_POST['foo'] directly, but most of the time, you need to check that the data has been set before trying to use it, also be sure not to directly output it without proper santization. This why the answers that say; just use it directly might imply somehow that the variable is always set and is used in nondangerous context, which in most cases in not the case...

Most of the times you want to do stuff with the data you are retrieving. In such case it is important that you do not directly modify $_POST['foo'] as you should not modify global data but instead incapsulate it.

Sometimes it might be nice to do, what you asked; to avoid: as you would have a place where you transfer all the values you get from the request to specific variable names. This makes it all easier to refactor, if you decide to change the clientside markup. Often you might need to check if the value was even passed before trying to directly use it or assign it.

This might also be a good time to look forward to php7 and https://wiki.php.net/rfc/isset_ternary

Just remember, the more data you send, the code you have to write to properly manage it. And what you are asking not to do, might just be exactly what you want to do... or maybe something like

$foo = isset($_POST['foo']) ? $_POST['foo'] : null;

And I am sure you can easily imaging putting something similar into a function.. What you are looking for in this context, is not less lines of code, but more.

Ronni Skansing
  • 1,494
  • 1
  • 17
  • 33
-1

I don't recommend it, but to have the solution You want, You need to use filter_input() and maybe an array:

$aArray = array_keys($_POST);

foreach($aArray as $sField) {
    ${$sField}= filter_input(INPUT_POST, $sField);
    // and You can make some extra filtering here
    // for example: filter it by previously prepared array of acceptable field keys
}

But, if You just want less secure solution, use extract() function.

Jazi
  • 6,569
  • 13
  • 60
  • 92
-1

I think this will do the trick:

extract($_POST);

(Ref) Simple and effective.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
Liglo App
  • 3,719
  • 4
  • 30
  • 54
  • 3
    This is can cause security issues because an attacker can define any variable by simply passing in that in the POST request. Refer to this question for more information: http://stackoverflow.com/questions/3837789/how-to-demonstrate-an-exploit-of-extract-post – Erik Rothoff Dec 12 '14 at 13:50
  • 2
    You are right. But this is still an answer to OP's question. He may ask another question, how to improve security ... – Liglo App Dec 12 '14 at 13:51
  • While there might be security issues you can cover most of them by parameterizing queries and cleansing the posted data as you would in any best practice situation. If you have a large array this is the most elegant way of handling the variables. – Jay Blanchard Dec 12 '14 at 13:53
  • That is why frameworks exist - we don't have to reinvent the wheel as somebody has already worked on these problems. We can for example define all POST-fields once in an array and use a component to generate the form. Afterwards, we use the same array to validate the data. – Liglo App Dec 12 '14 at 13:54
  • 3
    Not good to recommend an insecure solution. From official doc: _"Do not use extract() on untrusted data, like user input (i.e. $_GET, $_FILES, etc.)."_ – Alex Gidan Dec 12 '14 at 14:10