Avoid using isset in PHP when accessing $_POST, $_GET, and other variables? - php

how can I prevent PHP from returning an Undefined variable error every time I try to check a variable if it has contents and that certain variable hasn't been used yet? In my previous setup, I can check $_POST['email'] even if I haven't put anything into it yet. It simply returns a blank or empty result. That's how I want my PHP setup to work but for the life of me, I can't seem to find figure out how to configure it. :(
Example:
<?php
if ($_POST['info'] != '') {
// do some stuff
}
?>
<form method="post">
<input type="text" name="info" />
<input type="submit" />
</form>
When you use the above script in a single PHP page and run it on my current setup, it returns an Undefined variable error. On my previous setup, that script worked like a charm. Can anyone share some light into this problem of mine. If you need further details, just say so and I will try to add more details to this post.
I know about the isset() checking but I don't want to use it on all of my scripts. I want it to not be that restrictive about variables.

You could use the empty function, which returns true if the variable is either unset or empty (i.e. a zero-length string, 0, NULL, FALSE and so on):
if(!empty($_POST['variable'])){
/* ... */
}
This is pretty much the same test as the one you're doing now, except that it will also return false (not run the block), without warnings, when the variable is unset.

Most likely it's not an error, but a Warning. You can set PHP not to display errors/warnings if you want. Just add this to the begining of your code:
ini_set('display_errors', 0);
Altough, I recommend you not to be lazy and have your code not display any errors, warnings, notices whatsoever, better safe than sorry.
And the preferred way to do what you want to do is
<?php
if (isset($_POST['info'])) {
// do some stuff
}
?>
<form method="post">
<input type="text" name="info" />
<input type="submit" />
</form>

I have sometimes done the following to do a comparison and avoid the warning about an unset variable:
if( #$_POST['variable'] == 'value' )
{
...
}
Although PHP would still call custom error handlers, so perhaps I need to reconsider this strategy.

Are you using your own Server? If so you can change the error_reporting via PHP.INI. Above the line
"error_reporting = E_ALL;" (might not be E_ALL) There will be a small documentation explaining which type of errors you can show.
If you're using a shared server from a webhosting company, I believe some may offer quick PHP management under your Webhosting account CP.
I hope I helped ;/
ps- If you do have your own server, you'll have to restart Apache. I'm not sure how it's done in Ubunto (if that's what you're using) but for CentOS it's:
/sbin/service httpd restart

The variable will be always SET as long as you sent the form .
So its better to check of the variable is not empty.
if(!empty($_POST['var']))

If you want to set $_POST vars, having a whole lot of these statements really clutters your code:
if (isset($_POST['info']))
$info = $_POST['info'];
... etc....
How about this?
function setPostVar( &$v ) {
$trace = debug_backtrace();
$vLine = file( __FILE__ );
$fLine = $vLine[ $trace[0]['line'] - 1 ];
preg_match( "#\\$(\w+)#", $fLine, $match );
eval("\$v = isset(\$_POST[\"$match[1]\"])?\$_POST[\"$match[1]\"]:'';");
}
Now, as long as you are happy naming variables similar to your POST vars
ie. $Foo = $_POST['Foo'];
you can just do this:
setPostVar($Foo); // equivalent to if(isset($_POST['Foo']) $Foo = $_POST['Foo'];
setPostVar($Bar); // ditto
setPostVar($Baz); // ditto

Related

First timer PHP edit to update html, some errors

this is my first time using PHP in a real project environment. The project is pretty simple, take an existing, working PHP site and update the HTML to be consistent with HTML5. After designing the HTML, I am inserting the PHP from the previous site. This works most of the time, but I get a few errors. For instance:
<?
$sec = $_GET['sec'];
if ($sec == "1") {
echo ('Success!');
}
?>
Is causing the error:
Notice: Undefined index: sec in /file_that_holds_site_build.
Of course that is only if the url doesn't include the append tag (=1) that alerts the message.
So the question is this, what am I missing that causes the $GET when there is no $sec? How do I eliminate this error on first page load?
You're getting that notice because you're trying to access an array index that doesn't exist in some scenarios. Here's how you should be getting the data out of the request.
$sec = array_key_exists('sec', $_GET) ? $_GET['sec'] : null;
Thanks to everyone who provided possible answers to this question. It was Daniel that came up with the easiest fix. Again, I am just adjusting someone else's code to work, so a universal solve would involve too much of my own writing. To the point, the final code looks like this:
<?
if (isset($_GET["sec"])){
$sec = $_GET['sec'];
if ($sec == "1") {
echo ('Success! Your username and password have been sent via email.');
}}
?>
Notice the added if statement. As I said in a comment to Daniel, SO SIMPLE!
Thanks again for everyone's help. I hope to be likewise of service to you all soon.
Simple just use isset($_GET['sec']) to check for the parameter 'sec' before using it in the php code. That should eliminate the error. This is quite trivial I suppose.
I often simply extract() the wohle $_GET super global and then either get the desired variable or not. As a kind of "declaration" I initialize each expected variable first with false. This way I find it much easier to handle than individually doing a check like if(isset($_GET['element'])) ...
$var1=$var2=$var3=false; // my desired variables
extract($_GET); // everything I get from the form
// or: extract($_REQUEST);
if ($var1) { /* do something with it */ }
Possible security risk:
Of course you should be aware that everybody could simply include their own variable as an argument to he page ...

Is there another way to assign PHP variables that I don't know about?

I'm debugging some client PHP code that has me stumped. As this pseudo-example illustrates, there is code on the receiving end of a form submission that processes the form values, but without ever apparently assigning those values:
(On form submission, where form has fields 'name' and 'position'):
echo "The name is = ". $name;
echo "The position is = ". $position;
This code is part of a large app, and code from other files is called before this. BUT the crucial point is that if I do a search for '$name = ' across the entire codebase it never shows up. How then is it possible that the request variable gets assigned to $name? Is there another way to assign value to a variable in PHP other than $var = value??
My only other clue is that this project uses Smarty, which I don't know anything about.
It may be that the person that created the code was working on a server with register_globals on. What that does, for example, is create regular global variables as the result of a form submission rather than populating the $_POST or $_GET arrays.
If the register_globals directive has been set to true in php.ini, then all POST attributes will also show up as individual variables, in the way you describe. Note that this directive is false by default, and that use of this directive is deprecated.
When you look at the smarty documentation you can see that variables are assigned like this (copied from the linked page):
<?php
$smarty = new Smarty();
$smarty->assign('firstname', 'Doug');
$smarty->assign('lastname', 'Evans');
$smarty->assign('meetingPlace', 'New York');
$smarty->display('index.tpl');
?>
Technically yes there is.
$x = 'name';
$$x = 'harry';
echo 'Yer a wizard '.$name;
(I would be surprised if this was the reason)
I guess your server has register_globals setting on, which automatically generates variables from posted items:
$_POST['foo'] === $foo
Maybe this is another outbreak of the register_globals disease?
This has been thought to have died out, but surfaces again and again!
Sounds to me like someone included those variables with the intention of doing more with them, but never got around to doing so. Unless an include php page is assigning values to those variables, nothing will go in them.
Try turning your error reporting level up, if these variables are being used but haven't been initialised, a warning will be shown

What's the best way to get rid of notices about undefined variables?

I use codeigniter, one of the main issues i have with the views is undefined variables that may or may not exist.
I know that it's easy to get rid of the notices when using something like:
<?=html($this->input->post('name'))?>
By adding if(isset(..){ html($this->input->post('name')); }
But it's very annoying and it makes the code look ugly, I also don't want to disable notice reporting.
Is there any advice about that?
The "best" way? I still say it's isset. It's nice to be explicit, and it would help me, as someone maintaining your code later, to realize that you are okay with that variable not existing and that it wasn't just a mistake. Unless the isset check were there, I'd assume you just didn't realize it was possible for it not to be set, and would wonder what you actually meant to do.
Additionally, I'd assert that one of the main reasons it looks ugly is because all the code is being crammed into one line. There are two things you're trying to do: check if it's set, and print it if so. Maybe spacing them out would look nicer, even if it's a bit more verbose:
<?php if( isset($this->input->post('name')) ): ?>
<?= $this->input->post('name') ?>
<?php endif ?>
This also makes the snippet easier to manage later, in case you later decide to, say, wrap the output in an HTML tag, or add an else case.
Plus, since, according to the question, we can't mess with the error reporting settings, checking for the variable's existence is the only option. Sorry. Either you check if it's set, or disable the error messages saying it's not. No middle road.
I guess you'll find the error reporting() php function located at the top of your main index.php file.
Then have a look to the php manual that says for your question :
error_reporting(E_ALL ^ E_WARNING);
The best way is to define your variables always. If the variable is an input (i.e. You don't know whether it is defined or not) then using isset() required. Personally I use a wrapper function to get data from input variables:
function get($key, $default = null) {
return isset($_GET[$key]) ? $_GET[$key] : $default);
}
Then instead of using $_GET['some_key'] you can use get('some_key').
You can also suppress errors using at sign (#) which I do not recommend.
Just put this in your controller in function __construct() part.
function __construct() {
parent::__construct();
error_reporting(E_ALL ^ (E_NOTICE));
}

PHP Function 'return' not returning

This is a bit of an oddity for me. PHP is my forte, and I can normally figure out any issue I encounter.
I have a custom framework that I have been using for years. I have taken it upon myself to rewrite it, and I'm doing everything essentially the same that I was before. The problem lies in the following construct:
function ModPages_GetPage() {
$page = ModPages_GetPageByName($_GET['page_name']);
if($page != false) {
include(TPL_DIR.'pages/pages.view.php');
} else {
ErrorMessage('Invalid Page', 'The selected page could not be found.');
}
}
function ModPages_GetPageByName($page_name = null) {
$db = new Database;
$query = '
SELECT *
FROM pages
WHERE page_name = "'.CleanStr($page_name).'"
AND page_enabled = "yes"
LIMIT 1
';
$page = $db->GetRow($query);
return $page;
}
This code is being called with 'home' for the value of $_GET['page_name']. The call to ModPages_GetPageByName() is working fine, but the value of $page in ModPages_GetPage() isn't getting set. Matter of fact, any debugging statements thrown in after that call are failing to display anything.
I have display_errors set to on, and error_reporting set to E_ALL. I get a couple notices from my Database class, but that's it.
Running the script at a shell fails to produce any errors. When using strace, I do see the process spits out an 'exit_group(255)'.
This one has me quite baffled. I could sure use some direction on this.
I would think it's your query, shouldn't you just return the page name instead of star? as star (*) would return an array which is probably being passed back as the value? just my guess.
$query = '
SELECT *
FROM pages
WHERE page_name = "'.CleanStr($page_name).'"
AND page_enabled = "yes"
LIMIT 1
';
if you do a print_r on the $page return I would think it should be an array
$page = $db->GetRow($query);
echo "Page:<pre>".print_r($page,true)."</pre><br />\n";
Then maybe return something like this
return $page['page_name_field'];
ok before we get to a solution can we first make sure that before setting the $page variable, first just echo $_GET['page_name'] to see if there is a value being received.
PK
Does your script stop right after your database call, or just doesn't display any output?
If the first is true, then it looks like a fatal error. With E_ALL, it should be displayed, are you sure both display_errors and error_reporting are as you say at that point, and that the GetRow function doesn't alter them in any way? If so, maybe there's something in the Apache error log (PHP errors are sometimes logged there).
If the latter is true I'm thinking about an exception being thrown in a method that is being called, and caught in a higher level function. To check this you can put the database call (ie: the point where things go wrong) inside a try/catch block and see if you reach the catch block.
I would try following:
replace $_GET with $_REQUEST (maybe your form is using POST?)
do a print_r to check contents of your variables.
use mysql_error to view any errors, or print your mysql query in your browser, copy/paste it in phpmyadmin, is it returning anything? error.. data?
something similar happend to me once, my framework was encoded in ANSI and my calling php file was UTF8+BOM... I changed everything to UTF8+BOM and it worked.
try also different browser, I know it might not be a browser problem, but it might be that your script is cached somewhere.
are you using some caching? like eaccelerator?
Are those functions in a class? If so, you will need $page = $this->ModPages_GetPageByName().
Also I would echo out the argument and the sql statment in ModPages_GetPageByName(). This way you can verify that it isn't a SQL error.
I can't say for sure why your code isn't working, but I can make some suggestions that might help in locating the error.
The first thing I notice is you don't check that $db actually contains a valid database. I don't know the details of your Database object but I'm assuming there's some mechanism in there for checking if it's actually connected to the database. You should use that to determine if the database is connected before running queries on it.
$db = new Database ();
if ($db -> isConnected ())
{
$query = 'SELECT * (etc etc etc)';
// ...
}
else
{
// Put some kind of DB connection error notification or throw an exception here
}
Just on a stylistic note, you don't need to store the results of your DB lookup before returning it, unless you're planning on doing some processing on the result before returning it. You can just return the lookup directly. Of course that's just a stylistic choice, but it saves a line or two :)
return ($db->GetRow($query));
After you run your getpage function, I'd strongly recommend var_dump()ing the result. Even if your function returned NULL, you'll still see this in the var_dump. If in doubt, dump it out :). I'd also recommend installing xdebug to make the var_dump output more readable.
$page = ModPages_GetPageByName($_GET['page_name']);
var_dump ($page);
I would also strongly recommending var_dumping your query before you execute just to make absolutely sure that you're running the query you think you're running. Copy and paste the outputted query into sqlyog or phpmyadmin or whatever you use for interactive access to your database and make sure it returns what you think it should return.
Other things to check, is the page you're trying to return actually set page_enabled='yes'? Does the page_enabled column actually store the value as 'yes', or is it a bool or an integer or something else? Is magic quotes enabled or disabled? If they're in one state when you think they're in the other they can cause confusion. Are errors actually being reported to the browser? Add a line at the top of your script that's guaranteed to fail just to make sure, like an attempted foreach on an integer. If you don't see an error, then maybe error reporting isn't configured properly. I know those are obvious questions but I also know how easy it is to overlook the obvious if you're not getting what you expect out of a query.
Are you sure $page is not set, or is it just that your debug instructions don't print anything? Try logging to a file or a database instead; maybe your code triggered output buffering or something like that.
Also, you are calling ModPages_GetPageByName before declaring it. That is usually okay, but might not be in special circumstances (e.g. when the code is wrapped in an if block). Try swapping the two.
Also, check your environment and disable opcode caching and other possible error sources. APC for example can call the old version of the script long after you changed the PHP file.
While some of you have put extra effort into responding to this, nobody has been able to see the full picture, even given the details I have provided. I have been unable to trace the issue back to its source, but have moved on to a different project.

check box stops my Jquery script

I my login form if I dont check remember me check box in php script it gives <b>Notice</b>: Undefined index: autologin in error. in my .php file I have
$check_autologin = $_POST['autologin']; And I am checking is user checked it
if($check_autologin == 1)
{
$password_hash = $encrypted_mypassword;
setcookie ($cookie_name, 'usr='.$username.'&hash='.$password_hash, time() + $cookie_time);
}
and this is my check box field <input type="checkbox" name="autologin" value="1">Remember Me<br />
How could check box can return any default value if it is not checked?
I suspect the problem is when your checkbox is not checked the value doesn't exist in the $_POST array.
Try insulating your value check by using
isset( $_POST['autologin'] )
thusly:
$check_autologin = false;
if( isset( $_POST['autologin'] ) ) {
$check_autologin = $_POST['autologin'];
}
Undefined Index means that you're asking PHP to tell you the value of an array element that doesn't exist.
It is a 'Notice', which means it isn't a fatal error and doesn't stop the program from running, but is a good idea to fix. (it is also possible to set PHP so it doesn't report Notice-level events, but again, better just to fix the problem)
How to fix it?
a) As already suggested, check whether it's been set before you check what the value is.
So rather than just saying if($_POST['x']) say if(isset($_POST['x]) && $_POST['x'])
b) Explicitly supress the warning. PHP allows you to do this with the # symbol.
So you would say if(#$_POST['x'])
c) Ensure that you only ever make reference to variables that you know have been set. This would mean a different approach to your code, but could be a start toward making it more robust in general.
For example, rather than looking directly at the $_POST values you're expecting, you could write a foreach($_POST) loop which allows you to inspect everything in $_POST. This would also allow you to spot when someone posts values you're not expecting to receive.

Categories