Bug #68765 [Com]: Optimisation of constant definitions can cause incorrect output.

From: Date: Fri, 13 Mar 2015 11:39:23 +0000
Subject: Bug #68765 [Com]: Optimisation of constant definitions can cause incorrect output.
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-191371@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68765&edit=1

 ID:                 68765
 Comment by:         v dot leborgne at shop-application dot com
 Reported by:        axel dot ml at warenform dot net
 Summary:            Optimisation of constant definitions can cause
                     incorrect output.
 Status:             Re-Opened
 Type:               Bug
 Package:            opcache
 Operating System:   Linux x86_64
 PHP Version:        5.6.4
 Block user comment: N
 Private report:     N

 New Comment:

I experience the same issue with php 5.6.6 : 

myscript.php :
define('FOO','hello');
include('somefile.php');
echo ANOTHER_FOO;

somefile.php :
define('FOO','hi');
define('ANOTHER_FOO',FOO.' world');


myscript.php prints :

    in PHP<5.6 : "hello world"
    in PHP5.6 : "hi world"


Previous Comments:
------------------------------------------------------------------------
[2015-01-07 19:23:54] leigh@php.net

Apologies I didn't read properly.

It seems to me this is unrelated to the @ operator at all then (yes the current bug title is
misleading - I'll try and think of something more appropriate), as you state yourself, if you
omit all of the @ operators the problem persists.

I suspect there is some kind of optimisation being performed, and OpCache noticing that the include
file has not changed, simply spits out the optimised output even though the execution conditions
have changed.

------------------------------------------------------------------------
[2015-01-07 18:52:34] axel dot ml at warenform dot net

I admit using an "@" here is misleading. But if you omit all "@"s the problem is
still the same: The code behaves different, when turning opcache on. The seems to be a bug for me.

------------------------------------------------------------------------
[2015-01-07 15:58:08] leigh@php.net

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php

The @ operator is not a conditional construct. It prevents any error from being displayed, it does
not prevent the statement from executing.

Checking the constant with if (!defined(...)) is the correct way to handle this
situation.

------------------------------------------------------------------------
[2015-01-07 12:01:12] axel dot ml at warenform dot net

Description:
------------
With active opcache following problems occurs:

If constants.php is called first the output is:
1
1
1
1
1
which is correct.
If constants-include.php is called the output is:
4
which is also correct.
If constants.php is called afterwards the output is:
1
1
1
4
1
which is wrong.

The line is @define('SOME_CONSTANT', 4) is conditionally because of the "@" and
must not be evaluated by opcache but on runtime.

If the line is rewritten as:
if (!defined('SOME_CONSTANT')) define('SOME_CONSTANT', 4);
everything works as expected.

Thank you for fixing this issue.

Test script:
---------------
FILE: constants-include.php
@define('SOME_CONSTANT', 4);
echo SOME_CONSTANT.'<br>'.PHP_EOL;

FILE: constants.php
define('SOME_CONSTANT', 1);
echo SOME_CONSTANT.'<br>'.PHP_EOL;
@define('SOME_CONSTANT', 2);
echo SOME_CONSTANT.'<br>'.PHP_EOL;
@define('SOME_CONSTANT', 3);
echo SOME_CONSTANT.'<br>'.PHP_EOL;
include('./constants-include.php');
echo SOME_CONSTANT.'<br>'.PHP_EOL;

Expected result:
----------------
1
1
1
1
1


Actual result:
--------------
1
1
1
4
1



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=68765&edit=1


Thread (8 messages)

« previous php.bugs (#191371) next »