php / php/php-src

opcache_compile_file() fails with Cannot redeclare function error when compiling multiple files with the same function

Open
#16,668 4 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Extension: opcache Status: Verified
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

The following code:

compile-test.php

<?php
var_dump(opcache_compile_file(__DIR__ . '/releases/v1/functions.php'));

// expecting `bool(false)` since opcache_compile_file() shouldn't have executed the compiled file.
var_dump(in_array('foo', get_defined_functions()['user']));

// expecting successful compilation: `bool(true)`
var_dump(opcache_compile_file(__DIR__ . '/releases/v2/functions.php'));

releases/v1/functions.php

<?php
function foo(): string {
    return 'foo_v1';
}

releases/v2/functions.php

<?php
function foo(): string {
    return 'foo_v2';
}

Resulted in this output:

bool(true)
bool(true)
PHP Fatal error:  Cannot redeclare foo() (previously declared in /private/tmp/opcache/releases/v1/functions.php:4) in /private/tmp/opcache/releases/v2/functions.php on line 4

Fatal error: Cannot redeclare foo() (previously declared in /private/tmp/opcache/releases/v1/functions.php:4) in /private/tmp/opcache/releases/v2/functions.php on line 4
PHP Warning:  Zend OPcache could not compile file /private/tmp/opcache/releases/v2/functions.php in /private/tmp/opcache/compile-test.php on line 4

Warning: Zend OPcache could not compile file /private/tmp/opcache/releases/v2/functions.php in /private/tmp/opcache/compile-test.php on line 4
bool(false)

But I expected this output instead:

bool(true)
bool(false)
bool(true)

Additional Context:
The issue happens on both cli and php-fpm. It seems to be similar to https://bugs.php.net/bug.php?id=66066 . While the use case in bug 66066 might be less common in the real world and probably should be avoided, it's a perfectly valid use case to run multiple releases with similar files under the same php-fpm instance.

Workaround
Our current workaround is to compile different releases with different requests, i.e. PHP will happily process the following logics in two different requests.

compile-v1.php

<?php
var_dump(opcache_compile_file(__DIR__ . '/releases/v1/functions.php'));

compile-v2.php

<?php
var_dump(opcache_compile_file(__DIR__ . '/releases/v2/functions.php'));

opcache_get_status()['scripts'] shows that the two files have been compiled successfully.

    [/var/www/html/releases/v2/functions.php] => Array
        (
            [full_path] => /var/www/html/releases/v2/functions.php
            [hits] => 0
            [memory_consumption] => 992
            [last_used] => Fri Nov  1 11:32:01 2024
            [last_used_timestamp] => 1730460721
            [timestamp] => 1730458160
            [revalidate] => 1730460723
        )

    [/var/www/html/releases/v1/functions.php] => Array
        (
            [full_path] => /var/www/html/releases/v1/functions.php
            [hits] => 5
            [memory_consumption] => 992
            [last_used] => Fri Nov  1 11:31:58 2024
            [last_used_timestamp] => 1730460718
            [timestamp] => 1730458130
            [revalidate] => 1730460720
        )
PHP Version

PHP 8.3.13

Operating System

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the issue's compile-test.php reproducer with opcache_compile_file() on PHP 8.3.13, then compare it with the separate compile-v1.php and compile-v2.php requests. Trace the opcache_compile_file() entry point and its handling of compiled files containing duplicate functions; done means both files compile successfully in one request without executing their code or producing a redeclare error.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.