php / php/php-src

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

Ouverte
#16,668 4 commentaires 3 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Extension: opcache Status: Verified
Langage dominant
C
Étoiles
40.4k
Forks
8.2k
Merge moyen
2 j 13 h
PR mergées (30 j)
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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter le reproducer compile-test.php de l’issue avec opcache_compile_file() sur PHP 8.3.13, puis comparez-le aux requêtes séparées compile-v1.php et compile-v2.php. Suivez le point d’entrée opcache_compile_file() et son traitement des fichiers compilés contenant des fonctions en double ; la tâche est terminée lorsque les deux fichiers se compilent correctement dans une seule requête sans exécuter leur code ni produire une erreur de redeclare.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
php
Domaine
backend
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
52/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.