php / php/php-src

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

Offen
#16,668 4 Kommentare 3 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Extension: opcache Status: Verified
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, den Reproducer compile-test.php des Issues mit opcache_compile_file() unter PHP 8.3.13 auszuführen, und vergleiche ihn anschließend mit den separaten Requests compile-v1.php und compile-v2.php. Verfolge den Einstiegspunkt opcache_compile_file() und seine Verarbeitung kompilierter Dateien, die doppelte Funktionen enthalten; abgeschlossen ist die Aufgabe, wenn beide Dateien in einem Request erfolgreich kompiliert werden, ohne ihren Code auszuführen oder einen redeclare-Fehler zu erzeugen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
php
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
52/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.