Jump to content

prevent undefined index


Toomas_99

Recommended Posts

What is best way to avoid Undefined index?

Is this good approach?

<?php

$defaults = [
    'first_name' => null,
    'last_name' => null,
    'username' => null,
    'password' => null,
    /* -------------- */
];

# Any missing elements get the default value.
$_post = array_merge( $defaults, array_intersect_key( $_POST, $defaults ) );

if ( $_SERVER[ 'REQUEST_METHOD' ] == 'POST' ) 
{
    var_dump( $_post );
}

?>

<!DOCTYPE html>
<html>
<body>

<form action="" method="post">
    First name:<br>
    <input type="text" name="first_name" value="<?=$_post['first_name'];?>">
    <br>
    Last name:<br>
    <input type="text" name="last_name" value="<?=$_post['last_name'];?>">
    <br>
    Username:<br>
    <input type="text" name="username" value="<?=$_post['username'];?>">
    <br>
    Password:<br>
    <input type="password" name="password" value="<?=$_post['password'];?>">
    <br><br>
    <input type="submit" name="submit_form" value="Submit">
</form> 

</body>
</html>
Link to comment
Share on other sites

No, this is not a good approach.

 

First off, your code is wide open to cross-site scripting attacks. You can't just insert user input straight into your HTML document, because this allows anybody to inject malicious scripts, manipulate the page content or do anything they like with your markup. All dynamic HTML data must be HTML-escaped.

 

Secondly, if the client hasn't sent you the required parameters, that's a fundamental problem (possibly even a bug). Trying to cover this up with fantasy defaults makes no sense. The proper reaction is to show an error message, set the appropriate HTTP status code (e. g. 400) and terminate the script.

 

If you want to use the $_post array solely for your form defaults, well, that's at least possible. But it's still confusing and not really worth it. Just write proper code with checks, then you won't run into undefined indexes.

<input type="text" name="username" value="<?= isset($_POST['username']) ? html_escape($_POST['username']): '' ?>">

If you don't like to write down the same stuff over and over again, use a proper template engine like Twig. This will also help you with your XSS vulnerabilities.

Link to comment
Share on other sites

"What is best way to avoid Undefined index?"

 

To actually answer your question, I like this approach:

if( isset($_POST['name']) && !empty($_POST['name']) ) {
  // Safety $_POST['name'] and process the value as appropriate
}

The way I understand how PHP evaluates the expression is that if isset() returns false, the other arguments are ignored as there is no longer any point.

 

The function isset() doesn't trigger an undefined index error because that's it job to determine that.

 

And, you could iterate $_POST through foreach() testing for the elements in the array $defaults, as these are what you are expecting to process.

Edited by bsmither
Link to comment
Share on other sites

The empty() function is usually a bad idea, because it's triggered by all kinds of values: The integer 0, the float 0.0, the string "0" and much more. It's easy to see how this can lead to all kinds of nasty bugs.

 

A missing parameter is also something entirely different than a value which just happens to be falsy. Missing parameters indicate serious bugs (probably server-side, possibly client-side), so they should be logged and clearly indicated to the user. Falsy values are perfectly normal.

Link to comment
Share on other sites

isnt this

$defaults = [
    'first_name' => null,
    'last_name' => null,
    'username' => null,
    'password' => null,
    /* -------------- */
];

# Any missing elements get the default value.
$_post = array_merge( $defaults, array_intersect_key( $_POST, $defaults ) );

basically same thing like this without html escape.

<input type="text" name="username" value="<?= isset($_POST['username']) ? html_escape($_POST['username']): '' ?>">

So now when shomeone should remove (when editing template) <?= isset($_POST['username']) ? html_escape($_POST['username']): '' ?> and replace this line with <?=$_POST['username'];?>

Link to comment
Share on other sites

I have no idea what you're saying.

 

The equivalent of

<input type="text" name="username" value="<?= isset($_POST['username']) ? html_escape($_POST['username']): '' ?>">

using your default value stuff would be

$defaults = [
    'first_name' => '',
    'last_name' => '',
    'username' => '',
    'password' => '',
];

# Any missing elements get the default value.
$_post = array_merge( $defaults, array_intersect_key( $_POST, $defaults ) );
<input type="text" name="username" value="<?= html_escape($_post['username']) ?>">

That's more code, it's more complicated, and it's just confusing. So why on earth would you do that?

 

You've tried your idea for two weeks now. I think it's time to give up.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.