In a piece of code I found the following conditional statement:
if ( !defined('MY_CONSTANT') || MY_CONSTANT !== false )
and I am wondering what this may achieve that is not achieved by simply stating:
if ( MY_CONSTANT !== false )
..
is it not so, that in case MY_CONSTANT !== false then it MUST also be defined, making the first argument of the first example superfluous, or am I missing something?
If the constant may be undefined at that point, trying to access it will produce a warning on properly configured servers. You don't want those filling up your error logs, hence the defined() check.
The or conditional stops evaluating as soon as one of the conditions is true.
Since the conditions are evaluated left to right, and trying to check an undefined constant yelds an exception, you first check if it is defined, and then for its value.
If the constant is not defined, the if statement exits, and doesn't try to check the value.
Your version and the first version are not the same:
If it is not defined, the first condition of the first version will be true, and it will 'trigger'.
If it is not defined, your version will be false. (well, at least raise an error ;) )
no, because if MY_CONSTANT is not defined, PHP will give you an error message :
Notice: Use of undefined constant MY_CONSTANT
If MY_CONSTANT is not defined, PHP will do two things:
Log and/or display an error when you try to use it
Interpret MY_CONSTANT as if it were the literal string "MY_CONSTANT"
Related
I would have expected $x->p never to be resolved as the first condition !$x=getIt() is true, yet this is not the case for the first two examples.
When are parenthesis required in IF clause?
<?php
if(!$x=getIt() || ($x->p) ){echo('yes1');}
else {echo('no1');}
if(!$x=getIt() || $x->p ){echo('yes2');}
else {echo('no2');}
if(!($x=getIt()) || ($x->p) ){echo('yes3');}
else {echo('no3');}
if(!($x=getIt()) || $x->p ){echo('yes4');}
else {echo('no4');}
function getIt(){return false;}
?>
OUTPUT
Notice: Undefined variable: x in /var/www/html/test.php on line 3
Notice: Trying to get property of non-object in /var/www/html/test.php on line 3
yes1
Notice: Trying to get property of non-object in /var/www/html/test.php on line 6
yes2yes3yes4
The logical operator || has higher precedence than the assignment operator =. So
!$x = getIt() || $x->p
is treated like:
!$x = (getIt() || $x->p)
When getIt() returns a falsy value, this will access the property of $x before the variable is assigned, and before the result is inverted by !.
You need parentheses to override this precedence. You could also use or instead of ||, because it has lower precedence.
if (!$x = getIt() or $x->p)
I'd say that it is good habit to always use it. You definitely will thank yourself as soon as you get into using languages with preprocessor.
I use the braces for the following reason
They reduce the work required to understand the code.
They provide confirmation of the developer's intent.
As said by Marcin, it is a good habit to use them always.
But in php, if the the IF statement body is single line, then it is not necessary to use parenthesis. See below example:
if(your condition)
some php code here;
The above example is fine and will work.
Now if the body of IF statement has multiple lines of code, then you have to use parenthesis. Check below example.
if(your condition) {
some php code here;
some more code here;
....
}
Now in above case, parenthesis are required.
If parenthesis are not used in above, you wont get your expected results or you will get an error.
Thanks
Notice is no error.
The first notice says variable x is not declared (So you never assigned it before)
The others just inform you nicely that $x->p does nothing, because $x is no object and therefore has no properties
For the brackets question see other answers
I'm running into this error when loading up my view:
ErrorException [ Notice ]: Undefined variable: errors
APPPATH\views\admin\category\add.php [ 2 ]
<h3>Add</h3>
<?php if( $errors ): ?>
<p><?=$errors?></p>
<?php endif; ?>
How is my checking not valid?
You might want to give this one a try:
isset Manual
or you can actually show the controller code in which you're failing to set the errors to the View object (probably inside of a condition).
As Kemo said you should use isset. What you are actually doing there is checking if the variable $errors has a value that evaluates to true/false. The non-existence of the variable does not equate to false and you wouldn't want it to, you want spelling mistakes etc... to throw errors rather than any variable just being considered null regardless of whether it's actually been declared. isset is specifically designed to check for the existence of the variable. As you still want to check if it also evaluates to true you should be doing:
if(isset($errors) && $errors)
An undefined variable means it does not exists. You can just wrap it inside isset() to do what you want to do:
<?php if( isset( $errors ) ): ?>
Isset is one of the few language constructs that work on unset variables without giving a warning / error. Another one is empty().
PHP is throwing an error because the error reporting includes the E_STRICT constant, which throws an exception if an undefined variable is pointed to.
Use isset() instead - It's good practice to check if your variable even exists (if there's a chance that it doesn't).
Stupid question - I'm surprised this one has bitten me. Why do undefined constants in PHP evaluate to true?
Test case:
<?php
if(WHATEVER_THIS_ISNT_DEFINED)
echo 'Huh?';
?>
The above example prints 'Huh?'
Thanks so much for your help! :)
Try defined('WHATEVER_THIS_ISNT_DEFINED')
When PHP encounters a constant that is not defined, it throws an E_NOTICE, and uses the constant name you've tried to use as a string. That's why your snippet prints Huh!, because a non-empty string (which is not "0") will evaluate to true.
From the manual:
If you use an undefined constant, PHP
assumes that you mean the name of the
constant itself, just as if you called
it as a string (CONSTANT vs
"CONSTANT"). An error of level
E_NOTICE will be issued when this
happens.
If you set your error reporting level to report E_NOTICEs, which is a good practice during development, you will also see the notice thrown.
PHP Constant Syntax
defined()
Casting to Boolean
error_reporting
error_reporting() function
From the manual:
If you use an undefined constant, PHP assumes that you mean the name of the constant itself, just as if you called it as a string (CONSTANT vs "CONSTANT").
Basically, if WHATEVER_THIS_ISNT_DEFINED isn't defined, PHP interprets it as "WHATEVER_THIS_ISNT_DEFINED". Non-empty strings evaluate to true, so your expression will always pass (unless WHATEVER_THIS_ISNT_DEFINED is defined and set to a falsey value.)
This is, frankly, stupid behaviour. It was implemented, I believe, to allow things like $foo[bar] to work when the programmer should have used $foo['bar']. It's illogical behaviour like this that makes people think PHP isn't a real programming language.
The way to test whether a constant is defined is with defined.
Undefined constants are treated as strings by PHP: docs. Taking that fact, think it through in English language:
If "WHATEVER_THIS_ISNT_DEFINED", then do something.
... it is logical that it is "true" - you aren't comparing anything to anything else.
That is why, when doing if statements, it is best practice to include a specific evaluation. If you're checking for false, put it in the code: if (something === false) vs if (something). If you're checking to see if it is set, use isset, and so on.
Also, this highlights the importance of developing with notices and warnings enabled. Your server will throw a notice for this issue:
Notice: Use of undefined constant
MY_CONST - assumed 'MY_CONST' in
some_script.php on line 5
Turn on notices and warnings to develop, turn them off for production. Can only help!
Try defined(). If it's not defined then the constant assumes it's simply text.
Note that constant name must always be quoted when defined.
e.g.
define('MY_CONST','blah') - correct
define(MY_CONST,'blah') - incorrect
also
<?php
if (DEBUG) {
// echo some sensitive data.
}
?>
and saw this warning:
"Use of undefined constant DEBUG - assumed 'DEBUG'"
A clearer workaround is to use
<?php
if (defined('DEBUG')) {
// echo some sensitive data.
}
?>
See http://php.net/manual/en/language.constants.php
It's not just constants, it is a much broader issue with PHP's parsing engine. (You ought to see warnings in your logs.)
In PHP, "bare words" that it doesn't recognize are generally treated as strings that happen to be missing their quotes, and strings with a non-zero length tend to evaluate to true.
Try this:
$x = thisisatest ;
$y = "thisisatest";
if($x == $y){
echo("They are the same");
}
You should see "They are the same".
Old question, but in addition to defined() you can also use strict type checking using ===
<?php
if(WHATEVER_THIS_ISNT_DEFINED === true) // Or whatever type/value you are trying to check
echo 'Huh?';
I want to use such code:
$arr=array('a'=>$a);
but $a is not defined, so I get error. But if I write this code before
if (!isset($a))
$a=null;
all works. Why? In the beginning $a is not defined , so $a=null. or underfined!=NULL ?
When you write
array("a"=>$a)
it means that you want the key "a" refers to a variable reference named $a which does not exist in the first place thus you are getting an error; but when you add
$a=null;
before hand, although you are setting $a to null but actually you are creating a variable reference named $a that's known by PHP so there will be no errors.
Yes, in truth undefined != null, although the difference is only in the eyes of PHP when it decides whether to throw an error or not. Otherwise it's the same thing.
As you already discovered undefined is different from null.
Undefined means that the name $a in not yet into the scope of your function/code.
$a=null is a (no)value assigned to a variable.
By the way you should get a Notice, not an error as using undefined variables as right-values php warns you about a probable typo and proceed with the script execution.
As a rule of thumb, if you address an undefined variable on the left of the assignment (=) simbol (a left-value name) then php create a new variables name and bind it into the current scope, if the reference is on the right (are you using the value contained instead than the variable itself) php warns you and keep going. You can change this behaviour by the error_reporting function.
see the manual of isset
Returns TRUE if var exists and has
value other than NULL, FALSE
otherwise.
In PHP if I define a constant like this:
define('FOO', true);
if(FOO) do_something();
The method do_something gets executed as expected.
But if I don't define the BOO constant below:
if(BOO) do_something();
Then do_something also gets executed. What's going on here?
// BOO has not been defined
if(BOO) do_something();
BOO will be coerced into the string BOO, which is not empty, so it is truthy.
This is why some people who don't know better access an array member with $something[a].
You should code with error_reporting(E_ALL) which will then give you...
Notice: Use of undefined constant HELLO - assumed 'HELLO' in /t.php on line 5
You can see if it is defined with defined(). A lot of people use the following line so a PHP file accessed outside of its environment won't run...
<?php defined('APP') OR die('No direct access');
This exploits short circuit evaluation - if the left hand side is true, then it doesn't need to run the right hand side.
If you enable error logging, you'll see an error like the following:
PHP Notice: Use of undefined constant BOO - assumed 'BOO' in file at line N
What's happening is that PHP is just arbitrarily assuming that you meant to use 'BOO' and just forgot the quotes. And since strings other than '' and '0' are considered "true", the condition passes.
If it's not the existance of the constant you want to test, but if you want to test the value of the constant you defined, this might be a better way: if(BOO === true) or if(BOO === false)
if($FOO) do_something();
Just using FOO takes it as a value rather than the variable you defined. Better to use PHP's defined.
PHP is dynamically typed. You can achieve what you're trying to do with a function such as this:
function consttrue($const) {
return !defined($const) ? false : constant($const);
}
PHP will automatically make the guess that you meant the string format, which a string will return true.
However you should use the defined method:
bool defined ( string $name )
So it would be:
if(defined('BOO')) {\\code }
Another option is to use php's constant() function, as in:
if (constant('BOO')) doSomething();
Remember to enclose the constant's name in quotes.
Here is a PHP replit demonstrating the examples below.
Ap per the php docs, if the constant is defined, its value is returned; otherwise, null is returned.
Since null is falsey, this will behave as expected.
This can be used in cases where you need to know if something is explicitly defined as true (or at lease a truthy value) vs either not defined, or defined with a falsey value. This works particularly well when having a variable defined is the exception, or having it undefined could be a security risk.
if (constant('IS_DEV')) {
// *Remember to enclose the constant's name in quotes.*
// do stuff that should only happen in a dev environment
// By Default, if it didn't get defined it is, as though, 'false'
}
Using constant() when checking against variables is a good practice to mitigate against security risks in certain situations. For example, printing out php info only if a certain constant is (defined and) TRUE.
As your question shows, PHP's string conversion would expose details if somehow the constant did not get defined.
Alternately, you could:
if (defined('IS_DEV') && (IS_DEV)) {
// *Remember to enclose the constant's name in quotes for the FIRST operator.*
// do stuff that should only happen in a dev environment
}
Another method that would work is to use === or !==, which tests exact equality (including type), without performing typecast a conversion.
if (IS_DEV === true)) {
// do stuff that should only happen in a dev environment
}