php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79822 Opcache and get_class_vars() - first output correct, subsequent outputs wrong
Submitted: 2020-07-09 13:42 UTC Modified: 2021-11-30 14:10 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: wadih at systemesmw dot com Assigned: nikic (profile)
Status: Closed Package: opcache
PHP Version: 7.4.3 OS: Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: wadih at systemesmw dot com
New email:
PHP Version: OS:

 

 [2020-07-09 13:42 UTC] wadih at systemesmw dot com
Description:
------------
The same call to get_class_vars() prints different values depending if it's the first time I run it, or if it's subsequent times, when opcache is on which is on by default. (See code in Test script)

First time, e.g. http://localhost/mytest.php, it prints:

7.4.3
Array
(
    [v] => a
)
Array
(
    [v] => b
)

Refresh the page, now prints:

7.4.3
Array
(
    [v] => a
)
Array
(
    [v] => a
)

Any subsequent refreshes prints [v] => a

Now slightly modify the PHP page to trigger a change , and it prints:

7.4.3
Array
(
    [v] => a
)
Array
(
    [v] => b
)

Refresh the page, and goes back to:

7.4.3
Array
(
    [v] => a
)
Array
(
    [v] => a
)

And subsequent refreshes still print [v] => a

SOLUTION: 

Set opcache.enable=0 in php.ini, restart apache2. Bug disappears, and prints [v] => b each time now. 

VERSIONS:

Apache/2.4.41 (Ubuntu)
PHP 7.4.3 (cli)
libapache2-mod-php 2:7.4+75

Test script:
---------------
class MyClass {
    public static $v = 'a';
}

echo '<pre>';
echo phpversion() . "\n";
print_r(get_class_vars('MyClass'));
MyClass::$v = 'b';
print_r(get_class_vars('MyClass'));

Expected result:
----------------
7.4.3
Array
(
    [v] => a
)
Array
(
    [v] => b
)

Actual result:
--------------
7.4.3
Array
(
    [v] => a
)
Array
(
    [v] => a
)

// Note, it is correct only first time it is run, but wrong all subsequent times, when opcache is active

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-09 13:44 UTC] wadih at systemesmw dot com
-Summary: Opcache get_class_vars() - first run successful, subsequent runs wrong +Summary: Opcache and get_class_vars() - first output correct, subsequent outputs wrong -PHP Version: 7.4.7 +PHP Version: 7.4.3
 [2020-07-09 13:44 UTC] wadih at systemesmw dot com
update summary
 [2020-07-09 13:56 UTC] stsalkov at gmail dot com
Can confirm this on a vanilla Ubuntu 20.04LTS install (Apache/2.4.41, PHP 7.4.3).
 [2020-07-09 16:57 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2020-07-09 16:57 UTC] cmb@php.net
With the most recent PHP-7.4 from Git, I get the wrong result on
CLI (Windows) with OPcache enabled right away on the first run.
This may have the same root cause as bug #79487.
 [2020-07-13 08:20 UTC] nikic@php.net
What is the expected behavior here? The docs say:

> Returns an associative array of declared properties visible from the current scope, with their default value. The resulting array elements are in the form of varname => value. In case of an error, it returns FALSE. 

So based on that, and what the implementation does, the intention here was to return the default values, not the current values. However, historically we don't even remember the default values of static properties! In 7.4 we do if opcache is loaded, thus the change in behavior.

ReflectionClass::getDefaultProperties() is probably also affected.
 [2020-07-14 17:46 UTC] stsalkov at gmail dot com
Since this behavior dates back to PHP 4, I think it'd be fair to say "the documentation is wrong" rather than "the implementation is wrong." To me, the culture of not breaking backwards compatibility has always been an important part of PHP.

In any case, it shouldn't behave differently depending on whether opcache is enabled.
 [2021-07-23 08:00 UTC] nikic@php.net
After https://github.com/php/php-src/commit/3eb97a456648c739533d92c81102cb919eab01c9 the behavior will be consistently "a a" as previously with opcache, and in line with the docs.

We could still change the behavior and docs though.
 [2021-11-30 14:10 UTC] nikic@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: nikic
 [2021-11-30 14:10 UTC] nikic@php.net
Closing as fixed in 8.1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 08:01:28 2024 UTC