I have theses errors in php v7.2 but don't see any E_WARNING when using php v7.1.
How can I resolve following errors?
/web13/web/boutique/includes/Sites/Shop/NavigationHistory.php on line 39
[12-Jan-2018 22:44:20 America/Toronto] PHP Warning: Use of undefined constant MODULE_HEADER_SELECT_TEMPLATE_STATUS - assumed 'MODULE_HEADER_SELECT_TEMPLATE_STATUS' (this will throw an Error in a future version of PHP) in /var/www/clients/client1/web13/web/boutique/includes/Sites/Shop/Template.php on line 356
This is a common warning that occurs whenever PHP has detected the usage of an undefined constant.
Here is an example of constant being defined in PHP:
define('PI', 3.14);
Below is a list of some cases that might cause the issue:
Forgetting to use a $ symbol at the start of a variable name.
$name = "Aniket";
echo name; // forgot to add $ before name
The above code will throw: Notice: Use of undefined constant name – assumed ‘name’. Because there is no dollar sign in front of the variable “name”, PHP assumes that I was trying to reference a constant variable called “name”.
Forgetting to place quotes around strings.
echo $_POST[email];
In the example above, I failed to place quotes around the $_POST variable “email”. This code will throw: Notice: Use of undefined constant name – assumed ’email’.
To fix this, I’d obviously have to do the following:
echo $_POST["email"];
According to Deprecated features in PHP 7.2.x you should not use undefined constants because:
Unquoted strings that are non-existent global constants are taken to be strings of themselves.
This behaviour used to emit an E_NOTICE, but will now emit an E_WARNING. In the next major version of PHP, an Error exception will be thrown instead.
You can prevent this E_WARNING only if you declare the constant value before using it.
In the above question, MODULE_HEADER_SELECT_TEMPLATE_STATUS is not defined.
In addition, for those who are new to wordpress Plugin development and cant seem to figure out what it means to define "Constant" before its used...
Here is an example of what will throw an error:
add_action('wp_enqueue_scripts', myprefix_load_styles);
Declaring a function directly like that in a hook is one way to generate an error like this.
Instead:
add_action('wp_enqueue_scripts', 'myprefix_load_styles');
Note, the function name is now inside the quotes.
And that should work, if thats your scenario.
I've just created a PHP job to recursively clean up all files in a PHP project and automatically quote all strings which are undefined constants used inside square brackets for the array syntax.
Observation: this fix only targets array usage like $a[key1] which will be automatically transformed into $a['key1']. The clean up process DOES NOT parse and compute a list of defined constants in your project, in order to white-list them for usage without quotes in all possible contexts.
It's recommended to run it for your project on DEV first, check functionality and then push to LIVE.
QUICK USAGE:
git clone https://github.com/eyroot/lx-utils lx-utils
cd lx-utils && composer install --no-dev
php run/cleanUpSquareBrackets.php /path/you/want/to/clean/up
The complete usage instructions and source code are on the page:
https://github.com/eyroot/lx-utils
Short hand Search replace Regex for Notepad++
for array(test=>'bla')
Search: ([ (\t])([aA-zZ]+)([\t ]*=>)
Replace: \1'\2'\3
for [test]
Search \[([aA-Zz]+)\]
Replace:['\1']
I had a similar error in WordPress using PHP version 7.3:
The error: [23-Dec-2022 21:53:48 UTC] PHP Warning: Use of undefined constant ‘xmlrpc_enabled’ - assumed '‘xmlrpc_enabled’' (this will throw an Error in a future version of PHP) in functions.php in a child theme
The code:
add_filter( ‘xmlrpc_enabled’, ‘__return_false’ );
as you can see, there were quotes that in my editor (gedit) look like inverted commas. These do not work.
After I changed the quotes to:
add_filter( 'xmlrpc_enabled', '__return_false' );
the errors went away.
Thank you #wale for the pointer on where to look.
Related
Can anyone help me understand what is happening here?
How do the double and single quotes affect the behaviour of the associative array keys?
Is this behaviour different to php 7, why?
<?php
// php version 8.0.2
echo "$assoc_array[key]"; // OK
echo $assoc_array[key]; // error undefined constant "key"
echo $assoc_array['key']; // OK
echo "$assoc_array['key']"; // error - unexpected string content ""
// this behaviour seems inconsistent
?>
Let's take a look at each line...
echo $assoc_array[key];
Anything string that isn't preceded with certain characters (e.g. $|->), terminated with certain characters (e.g. (), or inside of quotes (or heredoc etc.) is assumed to be a constant.
Which means key is usually assumed to be a constant. But you haven't set a constant value for key and therefore PHP has to do something with it...
Before PHP 8.x that would mean assume it was supposed to be a string and try the look up again; this would generate a warning.
This behaviour changed in PHP 8.x and now it throws an Error. Which, if not handled, ends the script.
echo "$assoc_array[key]";
In this case key is enclosed in quotes and thus, treated as a string. Arguably I'd suggest that this should throw an error as well; it would seem more consistent.
However, it's the same behaviour across PHP 7 & 8.
echo $assoc_array['key'];
This is just the standard way to access an associative array; single or double quotes would be fine. Again, this behaviour is consistent across PHP versions.
echo "$assoc_array['key']";
This one's a bit trickier. What it comes down to is that using double quotes and variables is a tricky business. PHP has to try and decide what parts are meant literally and what parts are identifiers and the current process is that quotes around keys is not allowed.
This is consistent across PHP versions.
Effectively PHP provides two ways of defining variables inside of double quotes:
simple
This means a variable preceded with a $. Which can be used like:
echo "$variable";
echo "$array[key]";
Complex
This means almost any variable you can think of in PHP. Which is used like:
echo "{$variable}";
echo "${variable}
echo "{$array['key']}";
echo "${array['key']}";
echo "{$array["key"]}";
echo "${array["key"]}";
echo "{$object->property}";
See the PHP 7 >> 8 migration manual for further information on the backwards compatibility:
https://www.php.net/manual/en/migration80.incompatible.php
N.B. The key difference, for your purposes, is that the way undefined constants is handled has changed (as above) from a Warning to an Error Exception
Based on your code example, I used the following code to test:
<?php
$assoc_array = ['key' => 'okay'];
echo "$assoc_array[key]"; // OK
echo $assoc_array[key]; // error undefined constant "key"
echo $assoc_array['key']; // OK
#echo "$assoc_array['key']"; // error - unexpected string content ""
Using PHP 7.2.34, I get the following results:
okayPHP Warning: Use of undefined constant key - assumed 'key' (this will throw an Error in a future version of PHP) in /home/summea/example.php on line 6
okayokay
When I uncomment the last line from the above code, I get something like:
PHP Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in ...
Then, when running the above code in a PHP 8.0.0 editor online, I get:
okay<br />
<b>Fatal error</b>: Uncaught Error: Undefined constant "key" in [...][...]:6
Stack trace:
#0 {main}
thrown in <b>[...][...]</b> on line <b>6</b><br />
So, it appears that this PHP Warning: Use of undefined constant key warning from PHP 7.2.34 was changed into an Error at least by PHP 8.0.0.
When I uncomment the last line in the above code and run in PHP 8.0.0, I get:
<br />
<b>Parse error</b>: syntax error, unexpected string content "", expecting "-" or identifier or variable or number in <b>[...][...]</b> on line <b>8</b><br />
From these tests, I would recommend using the two general ideas below for this (for PHP 7.x.x and 8.0.0):
When dealing with an array_name[key] (without outer quotes), it seems safe to use this format: $array_name['key'].
When dealing with an "array_name[key]" (within outer quotes), it seems safe to use this format: "{$array_name['key']}".
Hopefully in answer to part of your questions, the "undefined constant key" error appears to happen because of a change between PHP 7.2.34 and PHP 8.0.0.
The "unexpected string content" error happens because I think you need to have {...} braces around an array with a key with single quotes when inside an outer double-quoted string in order to make it work. This particular behavior seems to be similar in both PHP 7.2.34 and PHP 8.0.0.
If, for example, you were to try using outer single quotes instead of double quotes, like this:
echo '{$assoc_array["key"]}';
In PHP 7.2.34 and PHP 8.0.0, the result should be:
{$assoc_array["key"]}
which is not quite what you want (it appears to be printing a literal version of your string). Thus, I would still recommend using the "{$array_name['key']}" format.
I have a plugin in my forum which throws a warning.
I want to fix the problem, but firstly, I want to hide the warning message to the users.
I know I can change it globally, but I just want to do it for some lines.
How can I do this?
$bbcode_parser =& new vB_BbCodeParser($vbulletin, fetch_tag_list());
gives the error:
Warnung: Assigning the return value of new by reference is deprecated in ..../includes/garage_func_var.php (Zeile 6411)
I already know I need to use # but where do I put this?
# can be used to suppress warnings, notices and errors.
Fatal errors are displayed in PHP 7 which breaks the script.
# can be used before variables, functions, include calls, constants and so forth but cannot be prepended to function or class definitions, conditionals, loops and so forth.
So for example, to hide an undefined property error:
Class Cars{
}
$obj = new Cars();
echo #$obj->idontexist;
As to your specific problem:
#$bbcode_parser =& new vB_BbCodeParser($vbulletin, fetch_tag_list());
should fix it.
While the mentioned deprecated warning message is displayed in PHP 5, the following will be displayed in PHP 7 since it was deprecated in the upgrade.
PHP 7 Note:
Parse error: syntax error, unexpected 'new' (T_NEW)
Use # only as an absolute last resort. It is considered bad coding to use # as slows things down and moreover creates headaches for programmers (including yourself) in the future when trying to debug. This is really frowned upon.
You should:
Hide warnings only for that call using a function using set_ini
Use "try" in php to manage errors.
Notice: Use of undefined constant test - assumed 'test'.
I am not sure where this error came from. I am using the Widget Logic Plugin and is fully updated, but I can't seem to find where this issue is. Has anyone had this issue and know how to resolve it?
The most likely answer is that you have missed a $ on a variable called $test and used test in your code somewhere.
This is hard to verify without your code, but the error message you are referring to is what generally happens when a variable is written without the $ at the start - PHP tries to assume it is a constant of the same name.
The second option is that there is an array index 'test' with the missing quotes, i.e. $array[test] instead of $array['test'].
Edit: If you are not writing any code yourself, and using only using plug-ins, you might want to do two things:
See if you can find the error in their code (search for a variable called test without a $ in front of it
Raise a bug on their site, so that they can update it
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.
Is it somehow possible to identify unused variables in a PHP file in Emacs?
With other languages, this is possible by using tools such as Flymake.
I've already enabled Flymake to show syntax errors for my PHP files on the fly, but still it's frustrating that PHP logic errors are sometimes due to situations like:
<?php
$foo = whatever();
$bar = something($fo);
...
Note the typo on $foo that will contribute to the developer's headache and to his/her exorbitant use of coffee.
After the hints by Pascal and viam0Zah, I set this in my php.ini file:
error_reporting = E_ALL | E_STRICT
When I run php from the command line, I'm now able to see the notice about the undefined variable (with or without the -l option):
php -r '$foo = 3; echo $fo;'
PHP Notice: Undefined variable: fo in Command line code on line 1
php -r '$foo = 3; echo $fo;' -l
PHP Notice: Undefined variable: fo in Command line code on line 1
This is what I'm currently using in my .emacs file. It works perfectly fine with parse errors, but I'm still not able to match on the notices, though :(
;; Flymake for PHP
(require 'flymake)
(defun flymake-php-init ()
"Use php to check the syntax of the current file."
(let* ((temp (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace))
(local (file-relative-name temp (file-name-directory buffer-file-name))))
(list "php" (list "-f" local "-l"))))
(add-to-list 'flymake-err-line-patterns
'("\\(Parse\\|Fatal\\) error: +\\(.*?\\) in \\(.*?\\) on line \\([0-9]+\\)$" 3 4 nil 2))
(add-to-list 'flymake-err-line-patterns
'("Notice: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)" 2 3 nil 1))
(add-to-list 'flymake-allowed-file-name-masks '("\\.php$" flymake-php-init))
I've also tried Gabor's configuration, but with the same result. It is fine with errors, but bad with notices.
Please note that from the command line, parse errors look like:
php -r '$fo o = 3; echo $fo;' -l
PHP Parse error: syntax error, unexpected T_STRING in Command line code on line 1
I don't get why Notices are not matched. I've tried the regular expression separately and it seems to match correctly:
(search-forward-regexp "Notice: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)")
PHP Notice: Undefined variable: fo in Command line code on line 1
(C-x C-e will jump to the end of the lines).
Finally, I disabled Xdebug for now, since the notices were originally reported as:
PHP Notice: Undefined variable: fo in Command line code on line 1
PHP Stack trace:
PHP 1. {main}() Command line code:0
So, I guess I should slightly change the regexp to match the multiline errors. Any hint about this?
It's not really an answer to your question, as it's not working in Emacs, but PHP can raise notices, when you are trying to read from a variable that's not been initialized.
For more informations, see:
error_reporting, which should include E_NOTICE
display_errors to have those notices (and other errors) displayed
which is useful when developing,
but it should not be enabled on a production server.
For example, with error_reporting set to report E_NOTICE (and others), the following portion of code:
$aa = 'glop';
echo strlen($a);
Raises this notice:
Notice: Undefined variable: a in /.../temp/temp.php on line 5
It's not as simple as getting it in your editor, I admit -- but it will still help finding out why something doesn't work ;-)
Since Flymake uses the php binary's syntax check option (-l) for highlighting parse errors, there is no obvious way to catch notices and other errors without running or lexical parsing the code. If it's not a problem to not only lint but execute your script, then you can do the following.
Unfortunately, flymake-php defines error line patterns as constant (at least in the bundle shipped with Emacs Starter Kit), and even the flymake command is hard-coded. There is a few ways to achieve our goal and each is a pain. May be it's a quick and not so dirty solution to define our flymake-php-init function based on the original one.
(defun my-flymake-php-init ()
;; add a new error pattern to catch notices
(add-to-list 'flymake-err-line-patterns
'("\\(Notice\\): \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)"
3 4 nil 2))
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
;; here we removed the "-l" switch
(list "php" (list "-f" local-file))))
Then customize flymake-allowed-php-file-name-masks to use my-flymake-php-init function for initializing flymake-php instead of the original one. And so it works:
(source: flickr.com)
Decent IDE's will give you the names of the variables in the current scope when you are typing them via Intellisense.
This should severely cut down on the number of times you misspell a variable name. It also allows your variable names to be more descriptive than $foo
Furthermore, you should always pay attention to undefined variable warnings, as they immediately tell you when you have made a misspelling.