PHP control operator (#) doesn't work - php

The control operator is used to make all warnings/errors silent, no matter what the consequences are. I would like to use this crazy tool, but I guess I've got some strange server configuration and - even though I add # to a function, it still throws warnings/errors:
$ php -a
Interactive shell
php > $f = #file('juzio');
PHP Warning: file(juzio): failed to open stream: No such file or directory in php shell code on line 1
PHP Stack trace:
PHP 1. {main}() php shell code:0
PHP 2. file() php shell code:1
I've been trying to find a setting that is responsibe for this, but found nothing so far. Anybody knows why # isn't working for me? Just in case, I'm running PHP 5.3.6-13ubuntu3.10 with Suhosin-Patch. I've got also xdebug installed (in case it matters).
edit: please don't write about error_reporting. My question is about # operator. Thanks.

The scream.enabled directive in your php.ini configuration file will disable the effects of error suppression operator (#):
Quoting the manual:
The scream extension gives the possibility to disable the silencing error control operator so all errors are being reported. This feature is controlled by an ini setting.
See the example from the documentation to understand how it affects error reporting.
Disabling scream should fix the issue.
Change the directive in your php.ini, like so:
scream.enabled = 0
If you want to disable it during run-time, then you can use ini_set as stated in the manual:
ini_set('scream.enabled', false);

Related

PHP suppress warning with the # character not working on command line

I have an external include file in my php script which triggers a Warning when executing it in the browser. So I put an # character before it and very nice, now the Warning doesn't happen anymore. My problem is that if I now execute the script on the CLI the warning is not suppressed. How can I also suppress the warning for CLI?
This is a new VPS running PHP 7.3.
#include_once('externalsourcefile.php');
Result is:
WARNING : ""continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?" at line xx (externalsourcefile.php)
UPDATE: the point is that die include file is an external source, which I can't edit to resolve the Warning by my own.
You must refer to https://www.php.net/manual/en/function.include-once.php#84108 , It will give you an idea how include_once works. You must remove # soon as possible, bad practice!
if(include_once('externalsourcefile.php') == false) {
} else {
}
# suppresses warnings for that statement, in your case the actual include_once, not the stuff that happens inside it.
I'm writing this as an answer, because it is too long to put in a comment. Saying that # should never be used is wrong. It's using it without thinking that is wrong.
Consider this simple code being run in a busy multi-process environment:
clearstatcache(true, $pathname);
if(is_dir($pathname) && $dh=opendir($pathname)) {
// readdir() loop here
}else{
// error handling here
}
This code has a race condition. It has happened for me numerous times that the directory has disappeared between the is_dir() return and the opendir() call, leading to warnings on the console:
PHP Warning: opendir(/the/path/in/use): failed to open dir: No such file or directory in /path/to/script.php on line 2
So how could this race be worked around without disabling warnings from opendir(), I ask you?
Disabling globally is IMHO worse than doing it on specific statements like the opendir() call above.
As already said, the error is not caused by the include_once statement itself but by the code running inside the included file (you can determine that by reading carefully the error message).
It should work, anyway. There must be something else going on.
I can think of three possibilities:
The CLI interpreter in your VPS is configured to use a custom error handler that doesn't support the error suppression operator:
the standard PHP error handler is completely bypassed for the error types specified by error_types unless the callback function returns FALSE. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the # error-control operator.
The interpreter is configured for debugging and Xdebug has been set up with the xdebug.scream directive:
If this setting is 1, then Xdebug will disable the # (shut-up) operator so that notices, warnings and errors are no longer hidden.
The browser interpreter is running an earlier PHP version then the CLI one. The "continue" targeting switch is equivalent to "break" warning is a backwards-incompatible change in PHP/7.3. It didn't trigger a warning before.
In either case, and as also already noted, the question itself illustrates that suppressing errors can lead to hard-to-diagnose bugs.

Read / Write .gz file with PHP (method="PUT") [duplicate]

This question already has answers here:
How can I get useful error messages in PHP?
(41 answers)
Closed 5 years ago.
This has never happened before. Usually it displays the error, but now it just gives me a 500 internal server error. Of course before, when it displayed the error, it was different servers. Now I'm on a new server (I have full root, so if I need to configure it somewhere in the php.ini, I can.) Or perhaps its something with Apache?
I've been putting up with it by just transferring the file to my other server and running it there to find the error, but that's become too tedious. Is there a way to fix this?
Check the error_reporting, display_errors and display_startup_errors settings in your php.ini file. They should be set to E_ALL and "On" respectively (though you should not use display_errors on a production server, so disable this and use log_errors instead if/when you deploy it). You can also change these settings (except display_startup_errors) at the very beginning of your script to set them at runtime (though you may not catch all errors this way):
error_reporting(E_ALL);
ini_set('display_errors', 'On');
After that, restart server.
Use php -l <filename> (that's an 'L') from the command line to output the syntax error that could be causing PHP to throw the status 500 error. It'll output something like:
PHP Parse error: syntax error, unexpected '}' in <filename> on line 18
It's worth noting that if your error is due to .htaccess, for example a missing rewrite_module, you'll still see the 500 internal server error.
Be careful to check if
display_errors
or
error_reporting
is active (not a comment) somewhere else in the ini file.
My development server refused to display errors after upgrade to
Kubuntu 16.04 - I had checked php.ini numerous times ... turned out that there was a diplay_errors = off; about 100 lines below my
display_errors = on;
So remember the last one counts!
Try not to go
MAMP > conf > [your PHP version] > php.ini
but
MAMP > bin > php > [your PHP version] > conf > php.ini
and change it there, it worked for me...
Enabling error displaying from PHP code doesn't work out for me. In my case, using NGINX and PHP-FMP, I track the log file using grep. For instance, I know the file name mycode.php causes the error 500, but don't know which line. From the console, I use this:
/var/log/php-fpm# cat www-error.log | grep mycode.php
And I have the output:
[04-Apr-2016 06:58:27] PHP Parse error: syntax error, unexpected ';' in /var/www/html/system/mycode.php on line 1458
This helps me find the line where I have the typo.
If all else fails try moving (i.e. in bash) all files and directories "away" and adding them back one by one.
I just found out that way that my .htaccess file was referencing a non-existant .htpasswd file. (#silly)

What is involved in PHP's startup sequence?

Regarding display_startup_errors the PHP manual says that even when display_errors is on, errors that occur during PHP's startup sequence are not displayed. So then what is meant by PHP's startup sequence? What does it involve, and what kind of errors can occur there? Some common examples could help.
The most common types of errors you'll see that would be suppressed by display_startup_errors are going to be related to PHP failing to load modules or modules emitting error messages for various reasons.
For example:
PHP Warning: PHP Startup: Unable to load dynamic library '/path/to/module.so' - /path/to/module.so: cannot open shared object file: No such file or directory in Unknown on line 0
This means PHP is configured to load module.so but it's not found so it cannot be loaded.
A module might also emit a warning due to bad ini configuration values:
PHP Warning: PHP Startup: session.name cannot be a numeric or empty '' in Unknown on line 0
This is one of several warnings the session extension emits, in this case because the configuration value for session.name is numeric or empty.
Most of PHP's startup sequence is going to revolve around configuring itself, loading in dynamic modules, calling each module's GINIT and PHP_MINIT_FUNCTION so they can initialize, then running PHP's startup sequence.
How and when these things happen vary depending on what server API PHP is running under. For Apache, this might be as an Apache module, FPM, CGI/FastCGI.
Some good references that talk about this are:
https://www.slideshare.net/laruence/the-php-life-cycle
http://www.phpinternalsbook.com/php7/extensions_design/php_lifecycle.html
https://wiki.php.net/internals/extensions#extensions_lifetime

Log only real fatal errors from PHP-FPM in Docker container

I'm using NGINX with PHP-FPM in seperated Docker containers. I want to get errors only to stderr, so that I can collect them on a centralized log-server. Problem is: I'm using WP and seems to have some not well written plugins. They work but cause warnings like this:
2017/06/17 01:16:08 [error] 7#7: *1 FastCGI sent in stderr: "PHP
message: PHP Warning: Parameter 1 to wp_default_scripts() expected to
be a reference, value given in /www/wp-includes/plugin.php on line 601
Example script for testing, which should give me a fatal error in the stderr:
<?php
not_existing_func();
PHP-FPM was configured to log errors to stderr like this:
[global]
log_level = error
error_log = /proc/self/fd/2
I'm wondering that this gave me nothing in the script above. Just after I switched the log_level to at least notice, I got the exception on the console of the docker container:
[17-Jun-2017 01:45:35] WARNING: [pool www] child 8 said into stderr:
"NOTICE: PHP message: PHP Fatal error: Uncaught Error: Call to
undefined function not_existing_func() in /www/x.php:2"
Why the hell is this a notice? For me we've clearly a fatal error here like the message indicates, cause the script can't continue (and we get a 500 error in the browser, of course). It can't be true that I have to set log_level to notice so that I don't miss fatal errors which are delcared as warnings. And simultaneously, my logs get filled with trash warnings from wordpress themes, plugins and so on, that I haven't developed and I don't want to fix for update reasons...
I tried a bit and found out that log_errors in php.ini is essential for PHP-FPM to get any information. But the log level from error_reporting seems wired too. For testing purpose, I used the following configuration:
display_errors = Off
log_errors = On
error_log = /proc/self/fd/2
;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
error_reporting = 0
Result: I got notices, but NO info about my fatal error...
First of all, I learned that I was wrong: Wordpress is the root cause for this issue, not PHP directly. It's a known fact that WP manipulates the error_reporting when debugging is enabled, so I tried to define WP_DEBUG as false in my config; BUT even having this set, the documentation says
[...]
Except for 'error_reporting', WordPress will set this to 4983 if WP_DEBUG is defined as false.
[...]
So my settings into php.ini were correct and sufficient. I don't even need the php-fpm settings, when errors are redirected to stdout in the php.ini file.
How to prevent WordPress from manipulating the error reporting?
This is not so easy, too. Although the WordPress documentation says, that the wp-config.php is a good place to set global wide settings like the error reporting, they got overwritten later to 4983. I don't know where; maybe it's not even the Core of Wordpress, but rather some poor developed plugin or theme.
We can handle this by adding error_reporting to the disabled functions:
disable_functions = error_reporting
Now it's not possible to overwrite our error_reporting. I think this is the best solution to make sure that we don't get any other error reporting by external influence from plugins or themes. Also in the future, since PHP allows such chaos, we need to reckon with such things.
Basically, we could criticize that this prevent us from getting more logs by setting WP_DEBUG to true, that's right, but as we're on a production system, it seems wrong for me to do troubleshooting in such a way there. We shouldn't do this on an application base, especially without display_errors! Instead, the workflow to find problems should be to look at the error logs.
Fatal errors should always be logged and checked on a regular basis. If that is not enough, error_reporting could be set on a higher level to get information about possible problems like warnings.

I get a "Deprecated" notice on my page with few of the session functions

I am getting the below message on my sites page there are more than 20 messages like this... pls guide me to rectify the issue... I am using the PHP 5.3.0
Deprecated: Function eregi() is
deprecated in
C:\wamp\www\bannerbuzz\includes\classes\language.php
on line 87
> UPDATE : Is there any way to switch
off this display of error?
The correct answer to your question is: use a different error setting on your site.
You can do that in one of 3 ways.
Change the php.ini file, if you have the right to.
error_reporting = E_ERROR
display_errors = Off
Add an .htaccess file to the root directory of your site
You also have to have the right to do this.
Add the following lines:
php_flag display_errors off
php_value error_reporting E_ERROR
Execute the following statements in the beginning of your script
error_reporting(E_ERROR);
ini_set("display_errors","Off");
However, in concurrence with the other answers given, the errors you get are errors and you should resolve them. Most of the time you want to show errors in your development environment and suppress and log them in your production environment. But you always want to solve them.
Check out the PHP manual for more info on errors.
In PHP 5.3, there are certain things that are deprecated, that is no more supported, however, there exists an alternative for them in php 5.3 for you to use.
See complete list of:
Deprecated features in PHP 5.3.x
Note: The ereg is removed, you can use preg family of functions instead.
Perhaps because the function is deprecated? You can always change the error_reporting settings, but it's better that you stop using deprecated functions!
From PHP.net:
This function has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.
I believe it is also removed as of PHP 6. Why not just use preg_match?
In my case, I'm using a third party library which makes use of the eregi function. In that case, there's an easy solution to hide those warnings. Just place ob_start() and ob_end_clean() at the beginning and the end of the code:
ob_start();
// third party code
// and more code ...
if (eregi("blah", $var)) { // <-- this code is throwing a warning
// ..
}
// and more code ...
ob_end_clean();
And that's all.
Try preg_match or preg_replace, functions that aren't depreciated :)
For changing the error level:
http://php.net/manual/en/function.error-reporting.php

Categories