Strategie zum Überschreiben einer Klasse in einer mit Composer installierten Bibliothek

Lesezeit: 5 Minuten

Benutzer-Avatar
HAKEN

Ich benutze Codeigniter und Composer. Eine der Voraussetzungen ist PHPExcel. Jetzt muss ich eine Funktion in einer der Klassen ändern. Was sollte die beste Strategie dafür sein? Sollte ich den Code im Vendor-Ordner ändern? Wenn ja, wie kann die Änderung über alle Instanzen hinweg beibehalten werden? Wenn nicht, wie überschreibe ich diese bestimmte Klasse. Obwohl ich PHPExcel erwähne, hätte ich gerne eine generische Lösung.

Ich bin mir nicht sicher, ob dies das richtige Forum für diese Frage ist. Wenn nicht werde ich diese entfernen. Bitte lassen Sie mich wissen, wenn weitere Details benötigt werden.

Danke.

  • Oh ja, PHPExcel, der gleiche Grund, hier zu sein.

    – Lukas

    27. September 2017 um 11:03 Uhr

Benutzer-Avatar
Szczepan Holyszewski

In composer.json unter [“autoload”][“psr-4”]fügen Sie einen Eintrag mit Namespace als Schlüssel und Pfad als Wert hinzu:

{
     "autoload": {

         "psr-4": {

             "BuggyVendor\\Namespace\\": "myfixes/BuggyVendor/Namespace"
         }
     }
}

Kopieren Sie Dateien, die Sie überschreiben möchten, unter diesen Pfad (unter Beibehaltung der Verzeichnisstruktur des Unternamensraums) und bearbeiten Sie sie dort. Sie werden dem ursprünglichen “Klassenpfad” des Bibliothekspakets vorgezogen. Es scheint, dass Namespace->Pfad-Zuordnungen, die auf diese Weise zu composer.json hinzugefügt werden, vor denen berücksichtigt werden, die von erforderlichen Paketen hinzugefügt werden. Hinweis: Ich habe es gerade ausprobiert und es hat funktioniert, obwohl ich nicht weiß, ob es sich um eine beabsichtigte Funktion handelt oder welche möglichen Fallstricke es gibt.

EDIT: Habe einen Fehler gefunden. Manchmal, wenn Sie später ein anderes Paket mit benötigen composer require vendor/package, “verlieren” Sie die Überschreibung. In diesem Fall müssen Sie ausstellen composer dump-autoload manuell. Dadurch wird die korrekte Autoload-Reihenfolge unter Berücksichtigung Ihrer Überschreibung wiederhergestellt.

  • Du bist absolut großartig. Ich habe versucht, einen Weg zu finden, den schrecklichen Entitätsgenerator von Doctrine zu überschreiben, und Sie haben mir genau das gegeben, was ich brauchte. Du bist ein Held.

    – Gerald Thibaut

    18. Februar 2016 um 2:40 Uhr

  • Wenn Sie diesen Ansatz verwenden, erhalten Sie wahrscheinlich Folgendes: “` Warnung: Mehrdeutige Klassenauflösung, “Doctrine\Common\Collections\ArrayCollection” wurde sowohl in “vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection. php” und “src\Doctrine\Common\Collections\ArrayCollection.php”, die erste wird verwendet. “` um dieses Problem zu umgehen, fügen Sie die ursprüngliche Klasse zum Ausschluss hinzu: “` “exclude-from-classmap”: [“vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php”] “`, und dann wird der Autoloader Ihre Override-Klasse auflösen.

    – Oleg Andrejew

    9. Juni 2016 um 14:35 Uhr


  • @OlegAndreyev Dies sollte eine eigene Antwort sein. Das war sehr hilfreich und eine Lösung genau für mein Problem. Vielen Dank!

    – Toni Bogdanov

    19. September 2017 um 12:03 Uhr

  • @OlegAndreyev Entfernen Sie einfach die frühere Klasse aus dem Autoloader, um das zu verhindern Ambiguous class resolution Warnung vor dem Geschehen: "autoload": {"exclude-from-classmap": ["vendor/path-to-file-to-ignore.php"]}.

    – Grippe

    5. Dezember 2017 um 15:50 Uhr


  • Es ist wichtig, dass Sie den vollständigen Namensraum Ihrer Überschreibungsklasse in den Autoload-Eintrag aufnehmen, da Composer Autoload zuerst in der nachsieht am spezifischsten Namespace-Verzeichnisse, und der längere Namespace in der Überschreibung wird ihn an den Anfang dieser Liste setzen. Es ist nicht so wichtig, wo sich das physische Verzeichnis befindet, aber wenn Sie es als PSR-4-Verzeichnispfad beibehalten, können Sie es leichter verfolgen, wenn Sie darauf zurückkommen.

    – Jason

    26. August 2021 um 11:39 Uhr

Fügen Sie diese letzten 2 Zeilen hinzu zum autoload Abschnitt meiner composer.json hat bei mir funktioniert, als ich nur eine Datei innerhalb der überschreiben wollte vendors Verzeichnis:

"autoload": {        
    "classmap": [
        "database"
    ],
    "psr-4": {
        "App\\": "app/"
    },
    "exclude-from-classmap": ["vendor/somepackagehere/blah/Something.php"],
    "files": ["app/Overrides/Something.php"]
},

Denken Sie daran, dass der Namespace innerhalb app/Overrides/Something.php muss mit dem übereinstimmen, in dem sich das Original befand vendor/somepackagehere/blah/Something.php.

Denken Sie daran zu rennen composer dump-autoload nach Bearbeitung der composer.json.

Dokumente: https://getcomposer.org/doc/04-schema.md#files

  • Funktioniert wie erwartet!

    – Aistis

    1. Juni 2020 um 13:38 Uhr

  • Denken Sie daran zu rennen composer dump-autoload +1

    – jakxnz

    10. März 2021 um 1:51 Uhr

Benutzer-Avatar
Albert Tabak

Es gibt noch eine weitere Möglichkeit. Falls Sie die einzige Klasse, die Sie verwenden können, neu schreiben müssen Dateien in composer.json wie folgt

 "autoload": {
     "files": ["path/to/rewritten/Class.php"]
  }

Also, wenn Sie Klasse umschreiben möchten Some\Namespace\MyClass sag es mal so

#path/to/rewritten/Class.php

namespace Some\Namespace;

class MyClass {
  #do whatever you want here
}

Bei jeder Anfrage lädt Composer diese Datei in den Speicher, also wenn es zur Verwendung kommt Some\Namespace\MyClass – Umsetzung ab path/to/rewritten/Class.php wird verwendet.

  • Dies führt zu einem Ambiguous class resolution Warnung, bei der Verwendung composer dumpautoload -a oder -o und verwendet die Originaldatei anstelle der überschriebenen. Die Lösung von Szczepan gibt diese Warnung ebenfalls aus, wie Oleg oben erwähnt hat, aber sie löst die Verwendung der benutzerdefinierten Klasse anstelle der ursprünglichen auf.

    – Grippe

    5. Dezember 2017 um 13:31 Uhr

Das Ändern einer bestehenden Klasse verstößt gegen die OOP- und SOLID-Prinzipien (speziell das Prinzip Offen für Erweiterungen/Geschlossen für Änderungen). Die Lösung besteht hier also nicht darin, den Code direkt zu ändern, sondern den Code zu erweitern, um Ihre Funktionalität hinzuzufügen.

In einer idealen Welt sollten Sie niemals einen Code ändern, der Ihnen nicht gehört. Mit Composer ist dies tatsächlich nicht möglich, da Ihre Änderung beim Aktualisieren von Abhängigkeiten überschrieben wird.

Eine Lösung in Ihrem Fall besteht darin, eine Klasse auf Anwendungsebene zu erstellen und die zu ändernde Klasse (die sich auf Bibliotheksebene befindet) zu erweitern, um sie mit Ihrem Code zu überschreiben. Bitte sehen Sie sich das Erweitern einer Klasse in PHP an, wenn Sie nicht wissen, wie.

Dann laden Sie normalerweise Ihre Klasse anstelle ihrer Klasse. Auf diese Weise fügen Sie Ihre Funktionalität zusätzlich zu ihrer Funktionalität hinzu, und im Falle eines Updates passiert nichts (im Falle eines Non-Breaking-Updates).

1015000cookie-checkStrategie zum Überschreiben einer Klasse in einer mit Composer installierten Bibliothek

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy