PHP string comparison with no quotes - php

From what I know about PHP, the following syntax is not legal:
if ($s == Yes)
It should instead be written as:
if ($s == 'Yes')
However, the first example is working just fine. Anyone know why?

Ordinarily, it would be interpreted as a constant, but if PHP can't find a constant by that name, then it assumes it to be a string literal despite the lack of quotes. This will generate an E_NOTICE message (which may not be visible, depending on your error reporting level); something like:
Notice: Use of undefined constant Yes - assumed 'Yes' in script.php on line 3
Basically, PHP is just overly lenient.

In short, PHP is acting as if the quotes were there.
If PHP doesn't recognize something as a reserved token, it treats it as a string literal.
The error log will show a warning about this.

The first one is not a string.
And it is not works fine:
error_reporting(E_ALL);
if ($s == Yes) {}
It's a legacy from the times when PHP were just a "Pretty home page" form interpreter and strongly discouraged nowadays.

You need to have both error_reporting showing notices, and display_errors set on.
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', '1');
if ($s == Yes) {
// foo
}

In PHP that Yes would be treated as a constant. If the constant is undefined it will assume you meant the string 'Yes'. It should generate a notification if you have them turned on.

PHP converts Yes to 'Yes' internally when constant Yes is found not to be defined.
Btw.. If what you want is comparing if $s has "Yes" as value an is a string then you have to
a) use strcmp or
b) use the identity operator "==="

Related

Warn on undefined array write

Let's preface this with an example of a script with typo:
$bc = getBaseConcept();
$bs['key'] = doOtherStuff($bc['key']);
return $bc;
Obviously in the middle line is a typo. It should be $bc instead of $bs. (And yes this was a legit typo of mine just minutes ago before writing this question)
This did not produce a warning.
So my question is: Is there a configuration option that lets this produce a warning?
Specifically: Writing to an array key of a name that was previously undefined.
E_ALL does not seem to help. This should not only generate the warnings for $bar but I want also a warning for $foo.
<?php
ini_set('error_reporting', E_ALL);
echo ini_get('error_reporting'), "\n";
$foo['bar'] = $bar['foo'];
32767
PHP Warning: Undefined variable $bar in Standard input code on line 4
PHP Warning: Trying to access array offset on value of type null in Standard input code on line 4
Unfortunately, php is not like other programming languages. If an unknown variable is used, PHP does the initialisation without complaining. Unfortunately, there is nothing you can do about this.
If you are using an IDE like phpstorm or netbeans the IDE will usually show a hint for uninitisalized variables.
It is not necessary to initialize variables in PHP however it is a
very good practice. Uninitialized variables have a default value of
their type depending on the context in which they are used - booleans
default to false, integers and floats default to zero, strings (e.g.
used in echo) are set as an empty string and arrays become to an empty
array.
https://www.php.net/manual/en/language.variables.basics.php

PHP doesn't give me error when I use a variable name without dollar sign

I am having the following code in a php web page:
if (bInserted) echo "abc";
I would expect PHP to give me a syntax error since I forget to add the dollar sign before the variable name. Howver, the page doesn't produce any errors. Instead, it even echoes the "abc" string. I am not really able to understand this.
Your bInserted is interpreted as a constant and, since is not defined (I presume), it is then treated as the string "bInserted", which evaluates to true hence your "abc" is printed.
Anyway, such implicit conversion from constant to string should raise a notice, see 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 really do not see any message, nor on screen nor in the logs, make sure you have set the correct error reporting level, you could for example try
ini_set('display_errors', 1);
error_reporting(E_ALL);
And, by the way, E_ALL is a defined constant in this case!

Why are all single words in php strings

So I came across this feature/bug today and I'm struggling to wrap my head around what is going on.
so we all know that in php this:
echo 'hello';
print 'world';
echo gettype('test');
will return this:
hello
world
string
However, until today I was unaware that this:
echo hello;
print world;
echo gettype(hello);
will return this:
hello
world
string
What is going on here? What is happening in php's compilation process that it sees any single word as a string? Does this have a name? Does it have any utility?
If PHP can't find a function or constant by the name of hello, then yes, it treats it as a string. However, this is bad practice, and is even warned against:
>php -r 'error_reporting(E_ALL|E_STRICT);echo gettype(blah);'
PHP Notice: Use of undefined constant blah - assumed 'blah' in Command line code on line 1
So, the moral of the story is to always turn on error_reporting in PHP (just like you should always use strict and use warnings in Perl).
If you are not wrapping a piece of "string" inside quotes (be it double or single), the interpreter will try to make a guess and cast that into a String. I believe when you run that piece of PHP in error_reporting(E_ALL) you will see a notice
Notice: Use of undefined constant string - assumed 'string' in Command line code on line 1
A good practice is to always turn on error_reporting to E_ALL in development setups, but remember to turn it to less descriptive in production, you don't want people to have access to sensitive information (such as path) if your php errors out.

Why do undefined constants evaluate to true?

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?';

PHP: getting a "use of undefined constant COOKIE_LOGIN" how do I fix this?

I haven't made any changes to the code affecting the COOKIE's and now I get the following:
Use of undefined constant COOKIE_LOGIN - assumed 'COOKIE_LOGIN'
//Destroy Cookie
if (isset($_COOKIE[COOKIE_LOGIN]) && !empty($_COOKIE[COOKIE_LOGIN]))
setcookie(COOKIE_LOGIN,$objUserSerialized,time() - 86400 );
I'm not sure what I need to do to actually change this since I do not know what chnaged to begin with and so cannot track the problem.
Thanks.
You need to surround the array key by quotes:
if (isset($_COOKIE['COOKIE_LOGIN']) && !empty($_COOKIE['COOKIE_LOGIN']))
setcookie('COOKIE_LOGIN',$objUserSerialized,time() - 86400 );
PHP converts unknown literals to strings and throws a warning. Your php.ini probably had the error reporting level to not display warnings but someone may have updated it or something. In either case, it is bad practice to take advantange of PHP's behavior in this case.
For more information, check out the php documentation:
Always use quotes around a string literal array index. For example, $foo['bar'] is correct, while $foo[bar] is not.
This is wrong, but it works. The reason is that this code has an undefined constant (bar) rather than a string ('bar' - notice the quotes). PHP may in future define constants which, unfortunately for such code, have the same name. It works because PHP automatically converts a bare string (an unquoted string which does not correspond to any known symbol) into a string which contains the bare string. For instance, if there is no defined constant named bar, then PHP will substitute in the string 'bar' and use that.
You can't say $_COOKIE[COOKIE_LOGIN] without error unless COOKIE_LOGIN is an actual constant that you have defined, e.g.:
define("COOKIE_LOGIN", 5);
Some people have habits where they will write code like:
$ary[example] = 5;
echo $ary[example];
Assuming that "example" (as a string) will be the array key. PHP has in the past excused this behavior, if you disable error reporting. It's wrong, though. You should be using $_COOKIE["COOKIE_LOGIN"] unless you have explicitly defined COOKIE_LOGIN as a constant.

Categories