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.
Related
I'm new on the site (hi!) and I had a problem that I can't resolve yet. I look for it, but no results... I think it's a stupid thing, but I can't find the solution.
I'm migrating a system (PHP) to other server (both are CentOS) and I have a problem with the quotes in PHP variables:
Example:
--------
$_GET[var]
$db_reg[assoc]
$array[value]
define(NAME,'value')
etc..
All cases can fix adding quotes to indexes, but I have thousand of PHP files, with millions of lines each one, and I can't check one by one... it will take around two lives and a half.
In the old server, it works normally, but in the new, the variables are not recognized, shows a PHP notice:
"Notice: Use of undefined constant XXXX - assumed 'XXXX in..."
(ej: $_POST[XXXX])
Is there a configuration in Apache or PHP for recognizing or not (indistinct) quotes on variables?
The PHP version on both servers are the same, and I have checked the php.ini file, and they are similar.
I guess you need some information about variables and their usage (when working with arrays) and fixed index concretions.
Usage of variables:
$array = array('hi', 'you', 'there');
$i = 1;
echo $array[$i]; // -> Works and is **fine** (will output 'you')
// --------------------------------
$array = array('a' => 'hi', 'b' => 'you', 'c' => 'there');
echo $array['a']; // -> Works and is **fine**
// Note: in especially that case **NEVER** use barewords like this: echo $array[a] for >> a << here is expected to be a constant which (mostly) does not exist!
// PHP is so fuzzy that it will mostly interpret around like insane and output you the desired value ('hi' in that case), but that was never meant to be! And should always be prevented. That's the reason for you getting that notice...
// So never do this:
echo $array[a];
// ... if >> a << is NOT a valid and available constant
Important (summed up to the point):
Words without quotes and the dollar are considered constants which you perhaps do not use very often. In most cases, you use quotes (like described above) or real variables (identified by $) as index to access data structures/arrays.
Well, you can try editing the php.ini file:
Change
error_reporting=E_ALL
to
error_reporting = E_ALL & ~E_NOTICE
This will disable all notices, but I am not sure sure if this will get your issue resolved. Please try and let us know if this is working or not for you.
The PHP's documentation describes define() function with the constant name as a string. So it should be in quotes:
define('ANY_CONSTANT',1);
However I saw tons of examples with no quotes like this:
define(ANY_CONSTANT,1);
I also tested both ways in online PHP tester and both worked correctly.
Can anyone explain a little bit: is there any difference between those two methods? Is any of those better? In which circumstances?
Short answer: Yes you should.
If you don't, PHP will look for a constant with that name, not find one, and assume it's a string and use it as such. This will generate a notice in the error log, if you set PHP to report notices.
Using
define(ANY_CONSTANT,1);
will cause a warning:
PHP Notice: Use of undefined constant ANY_CONSTANT - assumed
'ANY_CONSTANT'
So you definitely need to use quotes.
(As always) It depends on the context:
define(ANY_CONSTANT,1);
is legal, since passing a literal (such as 'ANY_CONSTANT') is not mandatory - you could also pass a constant (such as PHP_OS aswell). You have to make sure not mixing up literals with constants.
Why it "works" for you is a dangerous approach, since in one case you might have simply forgot the quotation, but in another case you'd definitly wanted to use a constant. Hence the notices PHP will throw.
Why do I get notices when I execute a php file on my local server? Does that mean there is an error in my file? Notices like:
Notice: Use of undefined constant l - assumed 'l' in C:\xampp\htdocs\weekday.php on line 3
Notice: Use of undefined constant Monday - assumed 'Monday' in C:\xampp\htdocs\weekday.php on line 6*
You are likely getting notices because you have debugging turned on. It probably looks something like this:
error_reporting(E_ALL);
ini_set('display_errors', True);
To define a constant you need to do
define("Monday","value");
Also it is a php convention to name constants with all upper case. I suggest you stick to this convention so you can differentiate a constant from a regular string when reading your code.
These notices are there to tell you exactly where the problem is.
Look at line 3 of weekday.php and you'll see a place where you use l and realise that it's an undefined constant (look up constants)
You probably mean it to be a variable (look up variables - they start with a $ like $l in PHP) or a string constant (look up strings - they are surrounded by quotes like "l" or 'l')
going by the mention of "Monday" I'm going to assume you meant it to be a string.
Yes Notice means you have an error. As you can see it explains where the error is
There's a difference between errors and notices. An error will stop your script running; a notice is PHP telling you that there's something up with your script, and it's guessing what you actually meant.
A notice like:
Notice: Use of undefined constant Monday - assumed 'Monday' in C:\xampp\htdocs\weekday.php on line 6*
Means that you're using something like:
if ($day == Monday) .....
PHP is guess that you mean a string with the text of Monday in it, and it's right.
You don't have to fix notices - your code will still run. But it's definitely a good idea to do so - it'll make sure that your script executes exactly as you intend.
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 "==="
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.