6

I'm coding a worksheet app for a printer company. I'm getting flood of forms. For every single input field I have to check if the $_POST variables are set, and if, so echo back the value. (In case of some error, for example after a validation error, the user shouldn't retype the whole form)

Sample code:

if(isset($_POST['time'])&&!empty($_POST['time'])){echo $_POST['time'];}

I had to implement this about a hundred times. So I tried to figure out some kind of function to make this simple and readable.

Something like this:

function if_post_echo($key, $default = "") {
    if(isset($_POST[$key])&&!empty($_POST[$key])){
    echo $_POST[$key];   
    }else{
    echo $default;   
    }
}

But this wont work. I have tried to pass in the $_POST for the $key variable like this:

if_post_echo($_POST['time'])

function if_request_echo($key, $default = "") {
        if(isset($key)&&!empty($key)){
        echo $key;   
        }else{
        echo $default;   
        }
    }

And I also tried this:

function if_request_echo($key, $default = null) {
    return isset($_REQUEST[$key])&&!empty($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
}

Without any reasonable outcome.

The question:

How can I forge a function that looks for the necessary $_POST variable and returns it or if its unset then returns an empty string. And is there a way to do this for $_GET and $_REQUEST, too? (Or simply duplicate?)

das-g
  • 9,718
  • 4
  • 38
  • 80
Kael
  • 565
  • 2
  • 8
  • 18
  • Most of the time, you should avoid $_REQUEST, security matter. Go with $_GET and $_POST depending on the sent data. – David Apr 11 '11 at 15:07
  • Thank you for your comments! @David: I know about the $_REQUEST issue, but this time we are behind protection, the app un availabe from the net. @netcoder: I cant remember why I set this up like this, but I know I used to try the !empty alone without the isset and that dropped some problems. – Kael Apr 11 '11 at 15:13
  • @David how is `$_REQUEST` any less secure than `$_GET` or `$_POST`? They can all be modified by the user to produce values your application might not expect. As can `$_COOKIE` for that matter, which `$_REQUEST` also gets its value from. – Treffynnon Apr 11 '11 at 15:18
  • Have a look at Chris Shiflet [Cross-Site Forgeries](http://shiflett.org/articles/cross-site-request-forgeries) – David Apr 11 '11 at 15:21
  • 1
    Well, it's not actually a security but essential difference between POST and GET methods. – Your Common Sense Apr 11 '11 at 15:26
  • @David: CSRF is a bit of a separate issue. You'll need authorization tokens in any case. Just depending on POST requests is insufficient to prevent exposure of write APIs. -- The $_REQUEST problematic is often blown out of proportion. It's really about cookie fixation rather. Using it allows macious users to cause usability defects rather than security exploits (in the majority of cases). – mario Apr 11 '11 at 15:28
  • @David I don't see anything in Chris' article that describes how merely using `$_REQUEST` opens your PHP scripts up to anything security related. All external data (including headers!) supplied to your application should be mistrusted and validated as a matter of course anyway. – Treffynnon Apr 11 '11 at 15:29
  • Maybe you guys are right and I misunderstood the point, but why would you use $_REQUEST when you know these variable will be in the $_POST and $_GET arrays. Is there something in $_REQUEST you won't find in the two others? – David Apr 11 '11 at 15:43
  • @David see http://php.net/manual/en/reserved.variables.request.php for what is and is not in `$_REQUEST` – Treffynnon Apr 11 '11 at 15:49

8 Answers8

7

Your PHP testing function:

<?php
function test_req($key, $default = '') {
    if(isset($_REQUEST[$key]) and
       !empty($_REQUEST[$key])) {
        return $_REQUEST[$key];
    } else {
        return $default;
    }
}
?>

Then in your form HTML:

<input name="my_field" value="<?php echo htmlentities(test_req('my_field')); ?>" />

$_REQUEST (linked) is a PHP super global that contains both POST ($_POST) and GET ($_GET) request parameters.

If you only want to capture POST request parameters then it would be:

<?php
function test_req($key, $default = '') {
    if(isset($_POST[$key]) and
       !empty($_POST[$key])) {
        return $_POST[$key];
    } else {
        return $default;
    }
}
?>

For example.

Treffynnon
  • 21,365
  • 6
  • 65
  • 98
6

If you have a large amount of fields, I would propose that you also use an array of defaults:

$defaults = array(
    "time" => "default",
    "name" => "enter name here",
    "text..." => "...",
);

$fields = array_filter($_POST) + $defaults;

$fields will then contain a list of form values with either the POST data or a preset default. No isset, see?

array_filter man page particularly: If no callback is supplied, all entries of input equal to FALSE will be removed. Goes some way to explaining the working behind this solution.

Treffynnon
  • 21,365
  • 6
  • 65
  • 98
mario
  • 144,265
  • 20
  • 237
  • 291
2

Just to note, this is redundant:

isset($_POST[$key]) && !empty($_POST[$key])

An unset variable is going to always be "empty", so isset() is implied in your empty() call.

For your logic you can achieve the same result with just:

!empty($_POST[$key])
Farzad
  • 842
  • 2
  • 9
  • 26
Rikaelus
  • 574
  • 1
  • 5
  • 15
2

This should work:

function if_post_echo($key, $default = ''){
    if(isset($_POST[$key]) AND !empty($_POST[$key]){
        echo $_POST[$key];
    }

    echo $default;
}

If you're having problems I recommend that you try var_dump($_POST) or print_r($_POST) to see if everything has been properly posted.

Karl Laurentius Roos
  • 4,360
  • 1
  • 33
  • 42
1

Your first function works perfectly to me.

Why do you think it doesn't work?

However, a better variant would be

function _post($key, $default = "") {
    if(isset($_POST[$key])){
        return $_POST[$key];
    }else{
        return $default;
    }
}

To use it :

echo $_post($key); // You could define the message as a second parameter.
Farzad
  • 842
  • 2
  • 9
  • 26
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
0

This feature is being added in PHP 7 as the "Null Coalesce Operator" using two question marks:

echo ($_GET['message'] ?? 'default-if-not-set');

https://wiki.php.net/rfc/isset_ternary

Adam Albright
  • 5,917
  • 1
  • 21
  • 14
0
function requireArray( $array, $required ) {
    foreach( $required as $k=>$v ) {
        if ( !isset($array[$k]) || empty($array[$k]) )
            return false;
    }
    return true;
}
#call like this:
requireArray($_POST, array('time', 'username', 'foo'));

If you want to know specifically:

function missingFrom( $array, $required ) {
    $r = array();
    foreach( $required as $k ) {
        if ( !isset($array[$k]) || empty($array[$k]) )
            $r[] = $k;
    }
    return $r;
}

Called like previous function.

Treffynnon
  • 21,365
  • 6
  • 65
  • 98
Zirak
  • 38,920
  • 13
  • 81
  • 92
0

Your method seems to work fine here:

function if_post_echo($key, $default = "") {
    if(isset($_POST[$key])&&!empty($_POST[$key])){
        echo $_POST[$key];   
    }else{
        echo $default;   
    }
}

I made a simple input with the name test and the form method is POST and using echo if_post_echo('test');.

It posted on the page what was in the text box.

David
  • 1,101
  • 5
  • 19
  • 38