Toomas_99 Posted December 11, 2016 Share Posted December 11, 2016 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> Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 11, 2016 Share Posted December 11, 2016 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. Quote Link to comment Share on other sites More sharing options...
Toomas_99 Posted December 12, 2016 Author Share Posted December 12, 2016 Because this code is just testing purpose. I have not write any error checking and xss preventing stuff. Like if ( empty( $_post[ 'username' ] ) ) { $errors[] = 'Please enter your username.'; } Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 12, 2016 Share Posted December 12, 2016 I suggest you finish your work and then show us the real script, not some fantasy code. Like I said, the default parameter stuff is completely unnecessary if you write proper code, so the undefined index problem should actually go away as soon you add the missing parts. Quote Link to comment Share on other sites More sharing options...
bsmither Posted December 15, 2016 Share Posted December 15, 2016 (edited) "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 December 15, 2016 by bsmither Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 15, 2016 Share Posted December 15, 2016 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. Quote Link to comment Share on other sites More sharing options...
Toomas_99 Posted December 22, 2016 Author Share Posted December 22, 2016 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'];?> Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 22, 2016 Share Posted December 22, 2016 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. Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 22, 2016 Share Posted December 22, 2016 (edited) If you are initializing a lot of variables with the same value, you could consider using array_fill(). More information can be found here: http://php.net/manual/en/function.array-fill.php Wrong function. See the post below. Edited December 22, 2016 by cyberRobot Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 22, 2016 Share Posted December 22, 2016 Sorry, I meant array_fill_keys(). And it would only replace the part where you initialize $defaults. Here's a quick example: <?php $defaults = array_fill_keys(array('first_name', 'last_name', 'username', 'password'), NULL); print '<pre>' . print_r($defaults, true) . '</pre>'; ?> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.