All over the web[1][2][3], it says that since PHP 5.0.0 "assigning the return value of new by reference" gives a E_DEPRECATED or E_STRICT depending on your php version (E_DEPRECATED didn't exist until 5.3, so it was E_STRICT before that).
As such it is my understanding that this code should give such a warning:
error_reporting(E_ALL | E_STRICT);
class A
{
}
$a =& new A();
However, I have tried this on two completely different servers (one running PHP 5.3 and one running PHP 5.2) and neither is actually giving any message! What's going on? Is my understanding incorrect or is something strange going on on those two servers?
(I do also think it is strange that this is deprecated, seeing that $a = null; $b =& $a; $b = new A(); does not do the same as $a = null; $b =& $a; $b =& new A();, but that's only a part of the question if I misunderstood what is deprecated...)
In response to the OP, this comment pointed him in the right direction:
It wouldn't at all surprise me if the problem here lies elsewhere: try setting E_ALL | E_STRICT in your php.ini directly, don't forget to change the php-cli.ini, too, if you're running this code on the command line.Also double check if the errors aren't hidden by doing an ini_set('display_errors',1);1. If you're running this on a windows box, there have been some bugs with this in the past.
Since the OP also pointed out that the warnings were generated before any code got executed, I had a hunch, that the expected warnings are being raised at compile-time, rather then runtime, so I had another look at the docs. There, I found this big red-box note, which confirmed my suspicions:
Most of E_STRICT errors are evaluated at the compile time thus such errors are not reported in the file where error_reporting is enhanced to include E_STRICT errors (and vice versa).
Since version 5 PHP is effectively a "compiled" language (similar to Java, the code is compiled to Zend Bytecode). When the Zend-engine compiles code with errors that are issued at compiled time, an in-script error_reporting call has no effect on weather or not these errors are reported: the error_reporting call applies only to the runtime errors/warnings.Perhaps this: error_reporting(E_ALL | E_STRICT | E_COMPILE_ERROR); is worth a look, too
Bottom line: Set the error reporting in the php.ini files whenever you can.
Related
I (like a lot of others) am seeing Strict Standards errors with PHP 5.4.???.
Strict Standards: Only variables should be passed by reference in /home/xxxxxx/public_html/xxxxxx/init.php on line 64
There must have been a change between 5.3 and 5.4. All the "wisdom" on the Internet seems to be about turning the error messages off. In this case this is a program (1,000's of lines written by someone else) that I am disinclined to try to resolve.
If I turn off the error reporting then the script does not execute.
I am trying to work the issue with the writer of the script.
Is there any other solution? Is there a setting that can be placed in the .htaccess file that will allow "non strict standards"?
You need to go into your php.ini file and assign the following:
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
This will allow you to show all warnings except deprecated & non-strict standards.
If you want to fix the error rather than ignore it (recomended):
$uri = explode("/",$_SERVER['REQUEST_URI']);
define("INSTALL_URL" , $protocall.$host_name . str_replace("/".array_pop($uri),"/",$_SERVER['REQUEST_URI']));
Sorted out this issue. Problem was the class file (and the folder, actually) was missing. Puzzled why with display_errors = On and E_ALL | E_STRICT defined (and Apache restarted), this would throw a white screen of death and not an error.
phpinfo() shows that the master value and the local value are the same, so I'm assuming that the error settings are not being overwritten somewhere in the code base (in an .htaccess or ini_set() call).
EDIT
The new object instantiation is here:
$type['content_object'] = new $type['handler_class']();
I also tried instantiating it without the variable, i.e. new Foo(); but still gave WSOD.
There might be an alternative error handler activated. Call restore_error_handler() prior to the line with the error (possibly multiple times) to reactivate PHP's default error handler.
I have recently taken over development of a legacy system and want to be able to turn on logging of PHP E_NOTICE's on the deployment environment. The deployment environment ini has the following directives...
error_reporting = E_ALL & ~E_DEPRECATED
display_errors = Off
log_errors = On
I have compared the error_reporting bitmask by using echo (E_ALL & ~E_DEPRECATED).' = '.error_reporting();, and both match, so I know the error_reporting level isn't changed within the system itself, and if I turn display_errors = On notices are displayed, but not logged.
So how can I start logging PHP E_NOTICE's?
Update:
According to #m.p.c in the comments on this answer, errors are being displayed in the browser when display_errors is on, but they aren't appearing in the log. I was assuming errors weren't appearing at all.
Are E_NOTICE errors the only ones that aren't appearing in the log, or are all error types affected? If it's all error types, then the first thing I would check is whether or not error logging is even enabled. Try setting ini_set('log_errors', 'On'); at the top of your script. If that doesn't work, then try setting your log file to something you're sure your server can write to by calling ini_set('error_log', 'your_file_path');. If neither of these work, then I think something is seriously wrong with your PHP install. If either of these fixes work, you can put them into your actual php.ini if you have access.
Original Answer:
Based on the error_reporting level in your question, your PHP install should already be setup to report E_NOTICE errors. If it's not logging these errors, something is wrong. I would suggest turning on display_errors to see if any E_NOTICE errors are displayed. If you can't change the php.ini file, try running ini_set('display_errors', 'On'); at the top of your script. Obviously, these errors will only show up and/or be logged if you trigger one, so you should double check that you're actually doing that somewhere.
One caveat is that the E_DEPRECATED error level was only introduced with PHP 5.3. When I just tested setting E_DEPRECATED on a PHP 5.2 install, PHP responded with errors, and set the error_reporting level to 0, which means it reports no errors at all. While it makes no sense for a pre-5.3 php.ini file to use this setting, I feel it's important to at least raise the possibility that you're using E_DEPRECATED on a server that doesn't support it. If you're not sure of your version, you can run phpinfo() and it will display a page with lots and lots of information, including the version number for your install.
Notwithstanding the above, if I've misunderstood your question and you're only talking about creating your own custom logging, then you need to create a function to run when an error occurs and assign it as the error handler using the set_error_handler() function.
It's important to note that when you use set_error_handler(), you bypass PHP's default error handler entirely. This means that your error_handler level becomes meaningless. All errors, regardless of their severity, will be passed to the error handler function you've created. The first parameter passed to this function by PHP will be the error number, which is the numeric value of the E_xxx constant of the error that was found. You'll need to write custom code to catch only the errors you want.
For example, to catch only E_NOTICE errors, your function would look like this:
function my_error_handler($errno, $errstr, $errfile, $errline) {
if ($errno == E_NOTICE) {
// handle/log the error
}
}
set_error_handler("my_error_handler");
Turns out the system has a custom Apache ErrorLog directive defined, and I have been tail -f ... the default Apache error_log.
Note to self: always check the web server setup first before posting silly questions on SO!
You can create your own handler
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if ($errno == E_USER_NOTICE){
/* log actions here */
}
}
set_error_handler("myErrorHandler");
I've seemingly tried about every different suggestion provided through a couple hours of Google and stackoverflow searching to no avail, and I cannot seem to suppress a large sum of "Deprecated: Assigning the return value of new by reference is deprecated in " errors presented at the top of my application, as well as Many "Warning: the magic method __get() (and __set()) must have public visibility and cannot be static in . Thus far, I have added the following line and many different variations of it to my php.ini file:
error_reporting = E_ALL & ~E_DEPRECATED
error_reporting = E_ALL ^ E_DEPRECATED
I've also attempted a straight suppression of every single error:
error_reporting = ~E_ALL
To no avail either. I've confirmed that it is correctly reading the php.ini file by adjusting other settings successfully.
I've also applied the error_reporting() function (with all different variations of what's provided above) within my scripts with no more luck. Does the location of the reporting have anything to do with the suppression? I've tried posting it at the top of the first file being loaded, also at the top of a required file that is getting called immediately upon executing the main script, no where does it seem to take it.
Try it with a number: http://www.php.net/manual/en/errorfunc.constants.php
Everything but the two deprecateds would be 8191.
PS. It's possible the app/framework/website you're watching/editing/creating sets the error reporting level to E_ALL. If so, it doesn't matter what you set in php.ini, because it's overridden later.
We're moving from php4 to php5, and we get this warning on one of our developers machines, but not in our php5 test setup:
Deprecated: Call-time pass-by-reference has been deprecated in C:\Workspace\Prelive\www\includes\filename etc..
The code seems to be the same in both environments, and the php.ini on the test environment has this setup for errors:
error_reporting = E_STRICT | E_ALL
We could ofcourse just fix the code so the warning will go away, but my main concern is why the test environment is not complaining about it.
There is a php.ini directive called allow_call_time_pass_reference, which may be off in the environment which does not complain about it.
You've probably checked this already, but is
display_errors = On
set in both ini files?