I am going through the "Head First PHP & MySQL" book right now, and on many parts of the book there are code snippets used to process HTML forms. They start like this:
if (isset($_POST['submit'])){
...
}
The if clause is used to detect if the form has been submitted already or not. Being used to programming in C mostly, I find that construct redundant and annoying (and I also don't think it helps code readability for experienced programmers). I would rather write it as:
if ($_POST['submit']){
...
}
Question: Is there some other reason to use isset() in this context that I might be missing? Would my version of the snippet be considered non-idiomatic PHP? What about in other contexts, can you give me an example of when isset() might be useful?
There are situations where a variable is NULL, 0, or FALSE. They'd fail the if() {} comparison, but they are set.
Using isset() also avoids a notice about an undefined variable if your error_reporting settings include E_NOTICEs.
Check out this page for more information about isset()
http://php.net/manual/en/function.isset.php
Well, if $_SERVER doesn't have the submit key, the second block would throw an E_NOTICE (Undefined index), therefore you should use isset() if you want to check if that key exists and is not null (or, alternatively, array_key_exists(), which just check for the existence).
Additionally, if you also want to check the content of the variable (for example, if it's set to false or 0), I'd suggest to use the !empty() (note the negation with !) function instead of isset().
One of the biggest reasons I can think of is because of PHP's error_reporting and display_errors setting.
Let's say that error_reporting is set to E_ALL and display_errors is turned on.
If you tried to do something like: if ($array['iDontExist'] == false) the code will run as expected, since the variable isn't set, it will evaluate to boolean false. The side effect however, is that PHP will emit a notice saying the variable $array['iDontExist'] does not exist. The more you have this, the more likely random notices will be spammed all over the output.
I find a LOT of production systems have error reporting turned on which would result in this unwanted behavior. If display_errors is turned off, the messages won't show up in the browser, but if error_reporting is set to track notices, the error_log will contain all of the notices about undefined variables, which is also an annoyance.
Related
Sometime ago, I was in a internship, and I was working as a junior web-developer. While working and learning, I noticed that when changing pages, instead of using isset($_POST/GET/REQUEST["var"]) they just used $_POST/GET/REQUEST["var"].
So, later I came home, and tried the same thing. What happens ? Every-time I come across a if() to verify that, I have to use isset(), otherwhise it gives me an error. But notice one thing, my url is this:
?p=sub_artigo&id=2
So, when I do the if() condition:
if(isset($_REQUEST["p"])=="procurar" && $_REQUEST['cont']){
It doesn't show errors, but if I take of the isset(), it gives the usual error that I see in the forums and here.
So my question is, why doesn't show the error for the second variable ?
Note: p->string;id->int
They have error_reporting turned down, which is nice because it means you can do things like
if ($_POST['whatever']) { ... }
instead of
if (isset($_POST['whatever'])) { ... }
but it also stops you from seeing other possibly pertinent errors.
this setting is found in the php.ini file under the variable error_reporting.
More information on the ini file can be found here: http://php.net/manual/en/ini.php
also, isset($_REQUEST["p"])=="procurar" while sytactically correct, is never going to return true, because isset() returns a boolean value.
what you want is isset($_REQUEST['p']) && $_REQUEST['p'] == 'procurar'
RTM: http://php.net/isset
isset() returns a boolean TRUE/FALSE. It will NEVER return a string, so this statement
if(isset($_REQUEST["p"])=="procurar" && $_REQUEST['cont']){
can NEVER succeed, because isset() will never EVER be equal to procurar, so the ['cont'] check will never be evaluated.
When the first statement is false, PHP does not bother triyng the rest of the if statement.
I always use the following check on every $_REQUEST, $_POST or $_GET key:
function ifSet($key) {
return (isset($_REQUEST[$key]) && $_REQUEST[$key])?$_REQUEST[$key]:'';
}
This will never give you any warnings, even if error_reporting is set to E_ALL.
The 'isset' checks if the $key is set and after that it checks if $key has a value.
Is there some fancy syntax I can use within the preg_match_all function to establish the new $matches variable at that time, rather than doing so beforehand as I have done below?
$matches = '';
preg_match_all('/[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}/', file_get_contents($eFetchURL), $matches);
Thanks in advance for your help!
Yes, namely this:
preg_match_all('/[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Za-z]{2,4}/', file_get_contents($eFetchURL), $matches);
Taking the reference of a non-existent variable in PHP is not an error. Rather, PHP automatically declares the variable for you and defines it as NULL.
Not declare variables throws an E_NOTICE. Depending on the php.ini or runtime configuration, using error_reporting function, exception may be omitted or not.
Good practice is to have E_STRICT mode enabled in development environment.
Note:
Enabling E_NOTICE during development has some benefits. For debugging purposes: NOTICE messages will warn you about possible bugs in your code. For example, use of unassigned values is warned. It is extremely useful to find typos and to save time for debugging. NOTICE messages will warn you about bad style. For example, $arr[item] is better to be written as $arr['item'] since PHP tries to treat "item" as constant. If it is not a constant, PHP assumes it is a string index for the array.
Note:
In PHP 5 a new error level E_STRICT is available. As E_STRICT is not included within E_ALL you have to explicitly enable this kind of error level. Enabling E_STRICT during development has some benefits. STRICT messages will help you to use the latest and greatest suggested method of coding, for example warn you about using deprecated functions.
You can find more information in
http://php.net/manual/en/errorfunc.configuration.php
In some conditions, may I use an # character instead of using the longer isset() function?
If not, why not?
I like to use this because in a lot cases I can save several quotation marks, brackets and dots.
I assume you're talking about the error suppression operator when you say # character, but that isn't a replacement for isset().
isset() is used to determine whether or not a given variable already exists within a program, to determine if it's safe to use that variable.
What I suspect you're doing is trying to use the variable regardless of its existance, but supressing any errors that may come from that. Using the # operator at the beginning of a line tells PHP to ignore any errors and not to report it.
The # operator is shorthand for "temporarily set error_reporting(0) for this expression". isset() is a completely different construct.
You shouldn't just use an #. The # suppresses warnings. It doesn't mean the code is correct, and warnings might still get added to your log file depending on your settings. It is much better to use isset to do the check.
As far as I know # is no substitution for isset(). Its an error suppression operator which prevents displaying errors in case they do exist in the script. Its also a pretty bad habit if used in PHP code.
It technically works, but there are a few reasons why I prefer the explicit isset solution when creating output, which I assume is what you're doing:
If I'm a new developer working on your old code, I recognize the isset idiom. I know what you're trying to do. With #, it's not so easy to figure out your intention.
Suppose you want to check if an object's property is set, like $user->name. If you just use error suppression to see if name is set, you will never be notified if $user is undefined. Instead, it's better to run isset($user->name) and be explicit, so that, if $user is undefined, you will be notified of the error.
Error suppression is a bad habit overall. Error notices are good, and you should make it as easy as possible to be notified of errors. Suppressing them when it's not necessary leads to problems in the future.
It depends on what you are trying to do. For instance, if you are performing a var_dump() or other debugging and know that sometimes your value will not be set I'd say in this situation it is ok.
var_dump(#$_REQUEST['sometimesIamSet']);
If you are using it in this case:
if(#$_REQUEST['something']){
// do something
}
else{
// do something else
}
I would strongly advise against it. You should write your code to do explicitly what you want to do.
if(isset($_REQUEST['something'])){
// Hurray I know exactly what is going on!
}
else{
// Not set!
}
The only instance in production I can think about using # is when you want to throw your own error. For example
$database_connection = #db_connect_function();
if($database_connection === false){
throw new Exception("DB connection could not be made");
}
Also, look at PaulPRO's answer. If what he is saying is indeed true, your log files could also be logging warnings that you don't know about. This would result in your log files being less helpful during debugging after release.
If for no other reason, don't use # as a substitute for isset because of this:
Look at this code:
echo (#$test) ?: 'default';
If $test is 'something' then you'll get 'something'.
If $test is empty, null or doesn't exist, then you'll get 'default';
Now here's where the problem comes in:
Suppose '0' or FALSE are valid answers?
If $test is '0' or FALSE then you'll get 'default' NOT '0' as you would want.
The long-format ternary is what you should use:
echo (isset($test)) ? $test : 'default';
Not much more coding, and more reliable when it comes to dealing with arguments that can evaluate as boolean false.
the # operator also makes your code run slower, as pointed out here:
http://php.net/manual/en/language.operators.errorcontrol.php
But as it's been pointed out, the code only runs measurably slower if an error occurs. In that case, code using isset instead of # operator is much faster, as explained here:
http://seanmonstar.com/post/909029460/php-error-suppression-performance
Could somebody help me with this problem. I just trasferred my PHP/MYSQL program to another computer (both are running XAMPP and on localhost) and now I got a massive amount of Undefined index and Undefined variable ERRORS. Could somebody explain me why?
All the variables are checked with isset and all the values should be OK, but I can't get anything to work as it is supposed to and then there are the Undefined index and Undefined variable ERRORS.
Please Help!
Thanks
Take a look here:
error-reporting
You can try something like that (runtime):
<?php
error_reporting(E_ALL ^ E_NOTICE);
?>
Or update php.ini:
error_reporting = E_ALL & ~E_NOTICE
It sounds like your configuration on the first box had a lower error reporting level.
You can set that in php.ini or in your code via ini_set.
php.ini
error_reporting = E_ALL & ~E_NOTICE
php code
error_reporting(E_ALL ^ E_NOTICE);
The other answers help you fix the symptom, not the problem. You are not getting errors, just notices, it's a special error level that warns you of a possible problem, but does not stop execution.
Given php's nature of not needing to declare variables, it is very easy to make a spelling mistake in your code and spend yours tracking it down (I'm sure everyone has did it at least a few times). And there comes E_NOTICE to the rescue: it warns you whenever you're trying to use a variable that did not get set beforehand - helping you spot the typo.
Avoiding it is really easy, suppose you're checking the presence of a submit button in your post array to do form processing:
if ($_POST["submit"] == "submit")
in case it's a regular get request, that line will throw an E_NOTICE for "submit" being an invalid index in $_POST. Avoiding it is really easy:
if (isset($_POST["submit"]) && $_POST["submit"] == "submit")
this checks for the array index existence first. PHP uses lazy evaluation, in this case it means stopping after isset() if it returns false - the check that would throw the notice won't get executed. Also: isset is not a function, but a language construct - thus being fast.
My personal preference is to have error_reporting set to E_ALL | E_STRICT on all developer machines, that way I get notified of every possible problem - including using deprecated language features.
Probably your error_reporting in the PHP configuration file (php.ini) is set differently as on your old XAMPP configuration.
I trying to understand if a isset is required during form processing when i check $_REQUEST["input_name"] if no value is passed it doesn't cry about it and php doesn't throw out an error if you are trying to access a array item which doesn't exist....i can use if($_REQUEST["input_name"])..
what about "empty" even in those cases i can use if()
THnks
I wouldn't recommend using the $_REQUEST superglobal for capturing form input, unless you're testing a form. Use $_GET or $_POST instead, unless you have a really good reason.
Also, isset() and array_key_exists() both do the same trick with regard to array keys, although array_key_exists() is clearer in an arrays context.
I recommend using:
error_reporting(E_ALL); //E_ALL - All errors and warnings
within your development environment, as that can expose where better practices might be applied, such failure to declare variables before they are used, etc.
There are different type of error levels. Checking a variable that is not set only throws a notice. Your error reporting is probably set to ignore those. It is best practice to always use isset when you want to check if a variable has been set, although it does have its gotchas.
Doing only what you are doing above, for example, if $_REQUEST["input_name"] is the string "0", it will evaluate to false. Also it is not a good idea to use $_REQUEST to begin with, as it can be affected by stuff like cookies and such and it's usually a code smell for bad architecture.
using $_REQUEST is pretty much a hack. You should be using $_POST or $_GET (depending on what you are doing) and you should use isset().
Every book I've read on PHP seems to say that.
Generally, at least for testing, set error reporting to E_ALL (all errors and warnings) either in your php.ini or in code using error_reporting(E_ALL); (Look into adding E_STRICT too.) Better to get an obvious notice about an error up front, than to have something subtle go wrong that you don't catch till later.
Avoid using $_REQUEST, which is too vague (it includes GET, POST AND cookie values), and use the $_POST or $_GET if those are what you really mean, and do check with isset($_POST["input_name"])
The short answer is "Yes." :)
if($_REQUEST["input_name"])
will throw a notice (error) if "input_name" doesn't exist, so isset() is recommended.