WordPress.org

Make WordPress Core

Opened 7 years ago

Closed 6 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)

8701.diff (578 bytes) - added by jacobsantos 7 years ago.
Fix based on trunk.
8701.2.diff (693 bytes) - added by jacobsantos 7 years ago.
Correct fix for E_STRICT on PHP < 5.3 and check for E_DEPRECATED ON PHP 5.3.0+
8701.3.diff (691 bytes) - added by jacobsantos 7 years ago.
Ensure that the bit operators correctly remove the constants.
8701.fix.diff (612 bytes) - added by Denis-de-Bernardy 7 years ago.
8701.correct.diff (973 bytes) - added by jacobsantos 7 years ago.
Fix error reporting for PHP 6 and PHP 5.3
conditional_code.diff (7.1 KB) - added by sojweb 6 years ago.
conditional_code.zip (9.5 KB) - added by sojweb 6 years ago.
8701.4.diff (1.6 KB) - added by Denis-de-Bernardy 6 years ago.
See: http://fr2.php.net/manual/en/errorfunc.constants.php

Download all attachments as: .zip

Change History (66)

comment:1 @jacobsantos7 years ago

You know, I made a patch for this a long, long time ago.

@jacobsantos7 years ago

Fix based on trunk.

comment:2 @jacobsantos7 years ago

  • Keywords has-patch tested commit added

comment:3 @jacobsantos7 years ago

  • Keywords needs-patch added; has-patch tested commit removed

@jacobsantos7 years ago

Correct fix for E_STRICT on PHP < 5.3 and check for E_DEPRECATED ON PHP 5.3.0+

comment:4 @jacobsantos7 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.

@jacobsantos7 years ago

Ensure that the bit operators correctly remove the constants.

comment:5 @jacobsantos7 years ago

8701.3.diff appears to be the correct bitwise calculation to prevent notices from appearing.

comment:6 @mrmist7 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.

comment:7 @Denis-de-Bernardy7 years ago

looks like we're not the only ones with the issue:

http://doc.php.net/wiki/

lol!

comment:8 @westi7 years ago

  • Resolution set to fixed
  • Status changed from new to closed

(In [10405]) Update error_reporting configuration for newer version of PHP. Fixes #8701 props jacobsantos

comment:9 @westi7 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

2.7.1 candidate still

comment:10 @westi7 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [10406]) Update error_reporting configuration for newer version of PHP. Fixes #8701 for 2.7.x props jacobsantos

comment:11 @westi7 years ago

See also [10407] and [10409].

Why did that make it that difficult to config in 5.0.0!

comment:12 @jacobsantos7 years ago

You wanted 8701.3.diff instead of 8701.2.diff

@Denis-de-Bernardy7 years ago

comment:13 @Denis-de-Bernardy7 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.

comment:14 @westi7 years ago

(In [10419]) More Error Reporting stuff. For 2.7.x, See #8701 props Denis-de-Bernardy

comment:15 @westi7 years ago

See also [10418]

comment:16 @jacobsantos7 years ago

Line 205 needs to be corrected also.

comment:17 @Denis-de-Bernardy7 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.

comment:18 follow-up: @jacobsantos7 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.

comment:19 in reply to: ↑ 18 @westi7 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.

comment:20 @westi7 years ago

(In [10420]) Sort out the error_reporting for PHP 5.3. See #8701.

comment:21 @westi7 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...

comment:22 @westi7 years ago

(In [10421]) Sort out the error_reporting for PHP 5.3. See #8701 for 2.7.x.

comment:23 @Denis-de-Bernardy7 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.

comment:24 @jacobsantos7 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.

comment:25 @jacobsantos7 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) );

comment:26 @Denis-de-Bernardy7 years ago

In php6, I think E_ALL E_DEPRECIATED E_STRICT E_WARNING E_NOTICE will be correct.

comment:27 @Denis-de-Bernardy7 years ago

E_ALL ^ E_DEPRECIATED ^ E_STRICT ^ E_WARNING ^ E_NOTICE

... even

comment:28 follow-up: @Denis-de-Bernardy7 years ago

err... silly copy pasting :-)

E_ALL ^ E_DEPRECATED ^ ~E_STRICT ^ E_NOTICE ^ E_USER_NOTICE

comment:29 in reply to: ↑ 28 @jacobsantos7 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.

comment:30 @jacobsantos7 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

comment:31 @jacobsantos7 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

comment:32 follow-up: @Denis-de-Bernardy7 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

comment:33 in reply to: ↑ 32 @jacobsantos7 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

comment:34 follow-up: @jacobsantos7 years ago

Well, I mean PHP 6.0 shows nothing.

comment:35 in reply to: ↑ 34 ; follow-up: @jacobsantos7 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

comment:36 @jacobsantos7 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);

comment:37 in reply to: ↑ 35 @Denis-de-Bernardy7 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

comment:38 follow-up: @Denis-de-Bernardy7 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

comment:39 in reply to: ↑ 38 @jacobsantos7 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.

@jacobsantos7 years ago

Fix error reporting for PHP 6 and PHP 5.3

comment:40 @jacobsantos7 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+).

comment:41 @westi7 years ago

(In [10431]) Error reporting (again\!) See #8701 props jacobsantos.

comment:42 @westi7 years ago

(In [10432]) Error reporting (again). For 2.7.x, See #8701 props jacobsantos.

comment:43 @westi7 years ago

Ooops scratch that. committed from the wrong checkout

comment:44 @westi7 years ago

(In [10434]) Use the correct PHP6 check. See #8701 for 2.7.x

comment:45 follow-up: @ryan6 years ago

Fixed?

comment:46 @jacobsantos6 years ago

[10434] need to be reverted back to version_compare().

comment:47 in reply to: ↑ 45 @westi6 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

comment:48 @westi6 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

comment:49 @westi6 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?

comment:50 @sojweb6 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.

@sojweb6 years ago

@sojweb6 years ago

comment:51 @azaozz6 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.

comment:52 @Denis-de-Bernardy6 years ago

  • Milestone changed from 2.7.2 to 2.8

comment:53 @Denis-de-Bernardy6 years ago

  • Keywords reporter-feedback added; has-patch tested commit removed

isn't this one fixed now?

comment:54 @ryan6 years ago

  • Component changed from General to Warnings/Notices

comment:55 @Denis-de-Bernardy6 years ago

  • Keywords dev-feedback added; reporter-feedback removed

comment:56 @Denis-de-Bernardy6 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

comment:57 @Denis-de-Bernardy6 years ago

  • Keywords has-patch added

comment:58 @ryan6 years ago

  • Resolution set to fixed
  • Status changed from reopened to closed

(In [11128]) Error reporting fixes. Props Denis-de-Bernardy, jacobsantos. fixes #9639 #8701

Note: See TracTickets for help on using tickets.