Maison  >  Questions et réponses  >  le corps du texte

Étendre les classes PHP utilisées en interne sans modifier les dépendances

Je souhaite remplacer une classe PHP dans Laravel, mais elle est étendue par plusieurs autres classes avec lesquelles je ne veux pas m'embêter. La structure globale est la suivante

class A extends R { }
class B extends R { }
class C extends R { }
class D extends R { }

Où A/B/C/D/R se trouvent toutes les classes du package externe.

Je souhaite étendre A/B/C/D à la P 而不更改任何这些文件(这将成为维护负担),这样 P 类扩展了 R。因此,我可以对 P classe à ajouter.

J'ai fait des recherchesclass_alias(),它允许我连接到自动加载器。这会正确加载类 P.

Le code que j'ai utilisé est :

// Some bootstrap file:
class_alias(
    P::class,
    R::class
);
// My modification:
class P extends R
{
    // ...
}

Mais j'ai eu l'erreur :

ErrorException : Impossible de déclarer la classe R car le nom est déjà utilisé

Je recherche une solution capable d'étendre une classe PHP interne tout en empêchant la copie du contenu complet du fichier de la classe. Je ne sais même pas si c'est réalisable. La classe que je souhaite étendre ne rentre pas dans le conteneur de services Laravel, il n'existe donc aucun moyen propriétaire d'ajouter des fonctionnalités.

P粉278379495P粉278379495306 Il y a quelques jours337

répondre à tous(1)je répondrai

  • P粉189606269

    P粉1896062692024-01-11 00:08:07

    class_alias en soi ne suffit pas, car pour que P étende R, les deux classes doivent exister. Et class_alias n'a rien à voir avec le chargement automatique, il déclare simplement une classe avec deux noms.

    Ce dont vous avez réellement besoin est de définir une vraie classe R avec un nouveau nom, puis de définir votre propre classe avec le nom R (vous n'avez pas réellement besoin de class_alias).

    Une solution consiste à réécrire dynamiquement le code source de la classe cible puis à charger la copie modifiée, comme ceci (non testé) :

    $code = file_get_contents(__DIR__ . '/vendor/path/to/R.php');
    $code = str_replace('class R', 'class R_original', $code);
    eval($code);
    
    class R extends R_original {
       // Your code here
    }

    Il est important de noter que cela doit être exécuté avant que le chargeur automatique normal ne tente de définir la classe. Par exemple, vous pouvez utiliser l'option spl_autoload_register,其中 $prepend définie sur true.

    répondre
    0
  • Annulerrépondre