php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73665 set_error_handler cant't listen E_Deprecated when opcache loaded
Submitted: 2016-12-06 09:36 UTC Modified: 2020-01-30 10:23 UTC
Votes:7
Avg. Score:4.0 ± 0.5
Reproduced:6 of 6 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (16.7%)
From: lcx165 at gmail dot com Assigned:
Status: Verified Package: opcache
PHP Version: 7.0.13 OS: Linux 64bit NTS
Private report: No CVE-ID: None
 [2016-12-06 09:36 UTC] lcx165 at gmail dot com
Description:
------------
When opcache.so loaded,use set_error_handler function listen all error.
When E_Deprecated happened, can't call error_handler function, use php system error display.

Test script:
---------------
//a.php
<?php

class A {
    //E_Deprecated 
    function a() {

    }   
}


//error.php
<?php

error_reporting(E_ALL);

set_error_handler(function($code, $msg, $file, $line) {
	echo  "[{$code}] {$msg}\r\n";
});

//NOTICE
echo $a;

//E_Deprecated 
include 'a.php';

//run as cli: php error.php

Expected result:
----------------
[8] Undefined variable: a
PHP Deprecated:  Methods with the same name as their class will not be constructors in a future version of PHP; A has a deprecated constructor in /root/a.php on line 3

Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; A has a deprecated constructor in /root/a.php on line 3


Actual result:
--------------
[8] Undefined variable: a
[8192] Methods with the same name as their class will not be constructors in a future version of PHP; A has a deprecated constructor

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-02-19 10:41 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2017-02-19 10:42 UTC] cmb@php.net
The expected and actual results above are swapped, but otherwise I can reproduce this at least for the first page request.
 [2019-08-27 21:55 UTC] dwilks at intacct dot com
I just ran into this as well and tracked it down to opcache running in Apache.  Yes, it only happens once, while the script is compiling the first time before being cached.

I assume it has something to do with opcache explicitly disabling the user_error_handler while compiling the script in opcache_compile_file.
 [2020-01-30 10:20 UTC] rasmus at mindplay dot dk
Has this been fixed in PHP 7.4?

I was expecting to catch deprecations in my test-suite, and as you can see here, a deprecation from PHP 7.1 was not caught in my 7.2 environment:

https://3v4l.org/SsL0q

The deprecation can't be caught until 7.4, apparently.

Now, this could be either because the issue has been resolved - or just because this particular method was flagged in documentation as deprecated in 7.1 but wasn't actually triggering a deprecation notice until 7.4.

Any idea which it is?
 [2020-01-30 10:23 UTC] nikic@php.net
@rasmus at mindplay dot dk: Only triggers deprecation since 7.4. Was blocked on https://wiki.php.net/rfc/tostring_exceptions.
 [2021-09-15 21:03 UTC] rkaiser at gmail dot com
This is still an issue in PHP 8.0.10.  The first time a deprecation error is raised with opcache enabled, it doesn't trigger custom error handlers.  Subsequent loads of the script, however, do.  https://bugs.php.net/bug.php?id=81442 has an example using a different deprecation case.
 [2023-01-13 13:44 UTC] jochem dot blok at fasterforward dot nl
Tested this in php 8.2.1 with the code below:


jochem.php
-----------
error_reporting(E_ALL);
ini_set('display_errors', 1);
//header('Content-type: text/plain; charset=windows-1252');
header('Content-type: text/plain; charset=utf-8');


function shutdown()
{
    $error = error_get_last();
    if ($error) {
        echo "\n\n--------------- SHUTDOWN ---------------------\n\n";
        var_dump($error);
        echo "\n--------------- EO: SHUTDOWN ---------------------\n\n";
    }
}

register_shutdown_function('shutdown');

function myErrorHandler($errno, $errstr, $errfile, $errline)
{
    echo "\n\n--------------- ERROR ---------------------\n\n";
    var_dump(error_reporting());
    echo "\n" . 'errno = ';
    print_r($errno);
    echo "\n" . 'errstr = ';
    print_r($errstr);
    echo "\n" . 'errfile = ';
    print_r($errfile);
    echo "\n" . 'errline = ';
    print_r($errline);
    echo "\n--------------- EO: ERROR ---------------------\n\n";

//    die();
    return true;
//    return false;
}


set_error_handler("myErrorHandler");


function exception_handler($exception)
{
    echo "\n\n--------------- EXCEPTION ---------------------\n\n";
    echo "class: ", get_class($exception), "\n";
    echo "message: ", $exception->getMessage(), "\n";
    echo "regel: ", $exception->getLine(), "\n";
    echo "\n--------------- EO: EXCEPTION ---------------------\n\n";
}

set_exception_handler('exception_handler');


require 'jochem2.php';


echo "\nEOF";

-----------

jochem2.php
-----------
<?php
class A {
    final private function iets() {

    }

}


$a2 =new A();

-----------
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 14:01:29 2024 UTC