Opened 16 years ago
Closed 15 years ago
#8701 closed defect (bug) (fixed)
WordPress throws E_DEPRECATED notices all over the place with newer PHP 5 installs
Reported by: | Otto42 | Owned by: | |
---|---|---|---|
Milestone: | 2.8 | Priority: | high |
Severity: | blocker | Version: | 2.7 |
Component: | Warnings/Notices | Keywords: | has-patch dev-feedback |
Focuses: | Cc: |
Description
On PHP 5.3 and up installs, there's lots of deprecated messages popping up everywhere.
As reported here:
http://wordpress.org/support/topic/227914
PHP Deprecated: Assigning the return value of new by reference is deprecated in C:\Inetpub\wwwroot\wordpress\wp-settings.php on line 512
PHP Deprecated: Assigning the return value of new by reference is deprecated in C:\Inetpub\wwwroot\wordpress\wp-settings.php on line 527
...
PHP Deprecated: Assigning the return value of new by reference is deprecated in C:\Inetpub\wwwroot\wordpress\wp-includes\cache.php on line 103
PHP Deprecated: Assigning the return value of new by reference is deprecated in C:\Inetpub\wwwroot\wordpress\wp-includes\query.php on line 61
PHP Deprecated: Assigning the return value of new by reference is deprecated in C:\Inetpub\wwwroot\wordpress\wp-includes\theme.php on line 1109
And so on.
There's no real good fix for this, since WP is still trying to maintain backward compatibility all the way to PHP 4, however since wp-settings is already setting the error_reporting() level, it might be a good idea to stick some extra code in there to make it ignore E_DEPRECATED for the cases where E_DEPRECATED is defined. That might prevent these spurious errors in at least some cases.
Attachments (8)
Change History (66)
#4
@
16 years ago
- Keywords has-patch needs-testing tested commit added; needs-patch removed
Patch works on PHP 5.2.6. Needs to be tested on PHP 5.3.
#5
@
16 years ago
8701.3.diff appears to be the correct bitwise calculation to prevent notices from appearing.
#6
@
16 years ago
- Keywords needs-testing removed
- Milestone changed from 2.8 to 2.7.1
- Severity changed from normal to major
This could probably do with being bumped up the priority list.
I couldn't access a local test site admin dashboard at all due to this warning, and I'm surprised that there aren't more people mentioning it. I suppose one reason why is because most hosting providers don't take up PHP versions very quickly. 8701.3 works for me.
#9
@
16 years ago
- Resolution fixed deleted
- Status changed from closed to reopened
2.7.1 candidate still
#13
@
16 years ago
- Priority changed from normal to high
- Resolution fixed deleted
- Severity changed from major to blocker
- Status changed from closed to reopened
using php 5.2, I get tons of notices due. the patch I just attached fixes the issue.
#17
@
16 years ago
Might be... I have yet to try php 5.3. To test though, install a plugin that doesn't bother using isset() before using an undefined variable.
While we're on this ticket, there might be an upcoming bug once php 6.0 is around: E_STRICT then becomes part of E_ALL.
#18
follow-up:
↓ 19
@
16 years ago
I have already tested it and the .3.diff patch works. Therefore, yes it does need to fixed, and the patch 8701.3.diff will fix it.
#19
in reply to:
↑ 18
@
16 years ago
Replying to jacobsantos:
I have already tested it and the .3.diff patch works. Therefore, yes it does need to fixed, and the patch 8701.3.diff will fix it.
But it doesn't make sense based on the values of the defines:
PHP 5.3 defines.
We want E_ALL and not E_NOTICE and not E_USER_NOTICE which this gives us:
E_ALL ^ E_NOTICE ^ E_USER_NOTICE
Then depending on which ver of PHP5 we want to add E_STRICT (not part of E_ALL) and possibly remove E_DEPRECATED.
The one for php 5.3 is still wrong at the moment but will be corrected shortly.
#21
@
16 years ago
That works fine for me on PHP 5.2.6 and PHP 5.2.0.
It should work fine on PHP 5.3 as well with the E_DEPRECATED in there too.
I don't have a PHP 5.3 install to test with though...
#23
@
16 years ago
there probably is an issue in php6 though. for that one we'd need to check if both E_DEPRECIATED and E_STRICT are defined, and deactivate E_STRICT (part of E_ALL in php6) accordingly.
#24
@
16 years ago
<?php // int(6143) var_dump(E_ALL); // int(2048) var_dump(E_STRICT); // int(-8182) var_dump(((E_ALL ^ ~E_STRICT ^ E_WARNING ^ E_NOTICE) )); // int(0) var_dump( ( E_ALL & E_STRICT & E_WARNING & E_NOTICE ) ); // int(0) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) & E_STRICT) ); // int(7159) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) ^ E_STRICT) ); // int(7159) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) | E_STRICT) ); // int(5111) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) & ~E_STRICT) ); // int(5111) var_dump( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) ); ?>
It appears the reason my patch worked was because it evaluated to '0', which would have disabled the error reporting.
#25
@
16 years ago
PHP 6:
<?php // int(32767) var_dump(E_ALL); // int(2048) var_dump(E_STRICT); // int(31735) var_dump( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) ); // int(30709) var_dump((E_ALL ^ E_STRICT ^ E_WARNING ^ E_NOTICE)); // int(0) var_dump( ( E_ALL & E_STRICT & E_WARNING & E_NOTICE ) ); // int(2048) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) & E_STRICT) ); // int(29687) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) ^ E_STRICT) ); // int(31735) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) | E_STRICT) ); // int(29687) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) & ~E_STRICT) ); // int(-1) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) | ~E_STRICT) ); // int(8192) var_dump(E_DEPRECATED); // int(23543) var_dump( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) ); // int(22517) var_dump((E_ALL ^ E_DEPRECATED ^ E_STRICT ^ E_WARNING ^ E_NOTICE)); // int(32767) var_dump( ( E_ALL ^ E_DEPRECATED & E_STRICT & E_WARNING & E_NOTICE ) ); // int(2048) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) & E_STRICT) ); // int(21495) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) ^ E_STRICT) ); // int(23543) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) | E_STRICT) ); // int(21495) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) & ~E_STRICT) ); // int(-1) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) | ~E_STRICT) );
PHP 5.3:
<?php // int(30719) var_dump(E_ALL); // int(2048) var_dump(E_STRICT); // int(29687) var_dump( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) ); // int(32757) var_dump((E_ALL ^ E_STRICT ^ E_WARNING ^ E_NOTICE)); // int(0) var_dump( ( E_ALL & E_STRICT & E_WARNING & E_NOTICE ) ); // int(0) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) & E_STRICT) ); // int(31735) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) ^ E_STRICT) ); // int(31735) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) | E_STRICT) ); // int(29687) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) & ~E_STRICT) ); // int(-2049) var_dump( ( (E_ALL ^ E_NOTICE ^ E_USER_NOTICE) | ~E_STRICT) ); // int(8192) var_dump(E_DEPRECATED); // int(21495) var_dump( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) ); // int(24565) var_dump((E_ALL ^ E_DEPRECATED ^ E_STRICT ^ E_WARNING ^ E_NOTICE)); // int(30719) var_dump( ( E_ALL ^ E_DEPRECATED & E_STRICT & E_WARNING & E_NOTICE ) ); // int(0) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) & E_STRICT) ); // int(23543) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) ^ E_STRICT) ); // int(23543) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) | E_STRICT) ); // int(21495) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) & ~E_STRICT) ); // int(-2049) var_dump( ( (E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE) | ~E_STRICT) );
#26
@
16 years ago
In php6, I think E_ALL E_DEPRECIATED E_STRICT E_WARNING E_NOTICE will be correct.
#28
follow-up:
↓ 29
@
16 years ago
err... silly copy pasting :-)
E_ALL ^ E_DEPRECATED ^ ~E_STRICT ^ E_NOTICE ^ E_USER_NOTICE
#29
in reply to:
↑ 28
@
16 years ago
Replying to Denis-de-Bernardy:
err... silly copy pasting :-)
E_ALL ^ E_DEPRECATED ^ ~E_STRICT ^ E_NOTICE ^ E_USER_NOTICE
I'll try it.
#30
@
16 years ago
PHP 5.2.6:
<?php error_reporting( E_ALL ^ E_STRICT ^ E_NOTICE ^ E_WARNING); echo $notsetbefore; mktime();
Results:
Strict Standards: mktime() [function.mktime]: It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Chicago' for '-6.0/no DST' instead in C:\wamp \www\testerrors.php on line 9 Strict Standards: mktime() [function.mktime]: You should be using the time() function instead in C:\wamp\www\testerrors.php on line 9
<?php error_reporting( E_ALL ^ ~E_STRICT ^ E_NOTICE ^ E_WARNING); echo $notsetbefore; mktime();
Results:
Notice: Undefined variable: notsetbefore in C:\wamp\www\testerrors.php on line 7
#31
@
16 years ago
Had to include warnings:
Notice: Undefined variable: notsetbefore in C:\wamp\www\testerrors.php on line 7 Warning: include(nonexistantfile.php) [function.include]: failed to open stream: No such file or directory in C:\wamp\www\testerrors.php on line 11 Warning: include() [function.include]: Failed opening 'nonexistantfile.php' for inclusion (include_path='.;C:\wamp\bin\php\php5.2.6\pear') in C:\wamp\www\testerrors.php on line 11
#32
follow-up:
↓ 33
@
16 years ago
sometimes, I wish it was simpler to install apache on a Mac :-)
what does this result in?
E_ALL ^ E_DEPRECATED ^ E_STRICT ^ E_NOTICE ^ E_USER_NOTICE
#33
in reply to:
↑ 32
@
16 years ago
Replying to Denis-de-Bernardy:
sometimes, I wish it was simpler to install apache on a Mac :-)
what does this result in?
E_ALL ^ E_DEPRECATED ^ E_STRICT ^ E_NOTICE ^ E_USER_NOTICE
I'd say that based on PHP 6.0 results:
PHP 6.0: Nothing.
PHP 5.3: Shows Strict
PHP 5.2.x: Shows Strict
#35
in reply to:
↑ 34
;
follow-up:
↓ 37
@
16 years ago
Replying to jacobsantos:
Well, I mean PHP 6.0 shows nothing.
Confirmed:
error_reporting( E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_WARNING ^ E_STRICT);
Works on PHP 6.0 but not PHP 5.3 or PHP 5.2.x
#36
@
16 years ago
Okay, basically this works on PHP 5.2.x and PHP 5.3:
error_reporting( E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_WARNING);
This works on PHP 6.0
error_reporting( E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_WARNING ^ E_STRICT);
#37
in reply to:
↑ 35
@
16 years ago
Replying to jacobsantos:
Replying to jacobsantos:
Well, I mean PHP 6.0 shows nothing.
Confirmed:
error_reporting( E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_WARNING ^ E_STRICT);Works on PHP 6.0 but not PHP 5.3 or PHP 5.2.x
that would be the expected behavior: E_STRICT is part of E_ALL starting with php6
#38
follow-up:
↓ 39
@
16 years ago
you still need the test for E_DEPRECATED though -- else, you end up with an undefined constant (and bugs) prior to php5.3
#39
in reply to:
↑ 38
@
16 years ago
Replying to Denis-de-Bernardy:
you still need the test for E_DEPRECATED though -- else, you end up with an undefined constant (and bugs) prior to php5.3
Yeah, it is strange to me too. It "works" in php 5.2.6 and the constant doesn't exist in that version. You are right, which is why it is strange how it would work. I think the behavior is still unexpected, so even though it works on mine, it may not work on yours for example.
#40
@
16 years ago
Latest patch has been fully tested, it bases the PHP 6 version check off the PHP 6 only function (Unicode hopefully won't be backported to PHP 5.4+).
#47
in reply to:
↑ 45
@
16 years ago
Replying to ryan:
Fixed?
Yes and no ;-)
I believe it can be simplified anyway.
E_ALL pre PHP v6.0 is the same as E_ALL E_STRICT in v6.0 and E_STRICT has existed longer than E_DEPRECATED so we can just add E_STRICT if E_DEPRECATED is defined and then not have to check for PHP 6 in anyway
#48
@
16 years ago
Hmm that went a bit messy.
E_ALL pre PHP v6.0 is the same as E_ALL ^ E_STRICT in v6.0 and E_STRICT
has existed longer than E_DEPRECATED so we can just add ^ E_STRICT if
E_DEPRECATED is defined and then not have to check for PHP 6 in anyway
#49
@
16 years ago
Right as far as I can tell on PHP 5 this works fine:
error_reporting( E_ALL ^ E_DEPRECATED ^ E_NOTICE ^ E_USER_NOTICE & ~E_STRICT );
That means we don't need a PHP6 section.
Could someone test that with PHP6?
#50
@
16 years ago
I think I have a solution that will solve this problem, as well as #9394, #3293, #3292, #667, and allow for further backwards compatibility as PHP evolves. I've written some conditional code into wp-settings.php, wp-db.php, and install.php, and added two files, wp-adjust.php and wp-adjust-functions.php to the wp-admin directory that will read wp-settings.php and wp-db.php during install and rewrite them to fix the deprecated errors, as well as check for mysqli functionality.
It works a bit like the IE conditional code we all use for CSS. For example, to deal with the problem in #9394, this code is in the wp-settings.php file:
if ( function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < abs(intval(WP_MEMORY_LIMIT)) ) ) @ini_set('memory_limit', WP_MEMORY_LIMIT); /** PHP **/ /** >4.4.9 **/ /** <=5.2.9 set_magic_quotes_runtime(0); **/ set_magic_quotes_runtime(0); /** /PHP **/ @ini_set('magic_quotes_sybase', 0);
During install, this tells wordpress to rewrite that block as a blank line for PHP versions higher than 4.4.9, to use set_magic_quotes_runtime(0) for versions less than 5.3. After install, the section (for me) looks like this:
if ( function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < abs(intval(WP_MEMORY_LIMIT)) ) ) @ini_set('memory_limit', WP_MEMORY_LIMIT); @ini_set('magic_quotes_sybase', 0);
All this conditional stuff is in comments, so if WordPress doesn't have write privileges, the patch doesn't bother trying to rewrite the files, and they behave as usual.
The only catch is that, to install, you have to visit /wp-admin/install.php directly. You can't count on redirects to take you there. On my test server I have PHP 5.3RC1 with strict error reporting on, and only mysqli installed, and WordPress fails before it gets to redirect. If I visit install.php directly, however, it works fine. Of course, there are a million different ways around that problem, but I thought I put this up for discussion first. Patch file attached as conditional_code.diff, additional files uploaded in conditional_code.zip.
I haven't done extensive tests on this, so any feedback is welcome.
#51
@
16 years ago
When setting error_reporting shouldn't we be turning bits off instead of flipping them? Something like this
if ( defined( 'E_DEPRECATED' ) ) // Introduced in PHP 5.3, missing in early 6.x error_reporting( E_ALL & ~E_DEPRECATED & ~E_NOTICE & ~E_USER_NOTICE & ~E_STRICT ); else error_reporting( E_ALL & ~E_NOTICE & ~E_USER_NOTICE & ~E_STRICT );
would work for all versions of php including 6.x.
#53
@
15 years ago
- Keywords reporter-feedback added; has-patch tested commit removed
isn't this one fixed now?
#56
@
15 years ago
added a new patch, based on the idea outlined here:
http://core.trac.wordpress.org/ticket/9639#comment:3
The patch fixes #9639 too
You know, I made a patch for this a long, long time ago.