webentwicklung-frage-antwort-db.com.de

Wechselnd PHP Abstrakter Klassenfehler

Ich habe das ein bisschen gekämpft und kann es nicht herausfinden, vielleicht hat jemand anderes es, oder vielleicht gibt es hier ein tieferes Problem mit Slim, PHP, Apache usw. Nachdem ich stundenlang gut gearbeitet habe, wird meine Slim-Installation anfangen zu geben dies auf allen Strecken:

Schwerwiegender Fehler: Die Klasse Slim\Collection enthält 1 abstrakte Methode und muss daher als abstrakt deklariert werden oder die verbleibenden Methoden (IteratorAggregate :: getIterator) in F:\Projekte\Beispiel\Server\Vendor\Slim\Slim\Slim\Collection.php verwenden Zeile 21

Das Problem verschwindet leider, wenn ich Apache neu starte. (Für ein paar Stunden trotzdem.)

Ich habe das gefunden, wo jemand vor zwei Jahren ein ähnliches Problem hatte, und die Helferin, die sie bedrängte, ohne sie überhaupt zu unterstützen: https://community.apachefriends.org/viewtopic.php?p=250966&sid=96ef58aaeb7fe142a7dcdfd506a8683f

Ich habe versucht, ein sauberes Löschen und Installieren meines Composer-Herstellerverzeichnisses durchzuführen. Das behebt das nicht. Ich kann deutlich sehen, dass getIterator erwartungsgemäß in der Datei in der Fehlermeldung implementiert ist.

PHP Version 7.0.12, Windows 7, x86 PHP Build

Nach einigen Stunden passierte es erneut mit einer anderen, aber ähnlichen Fehlermeldung:

Schwerwiegender Fehler: Die Klasse Pimple\Container enthält eine abstrakte Methode und muss daher als abstrakt deklariert werden oder die restlichen Methoden (ArrayAccess :: sqlserver) in F:\Projects\example\server\vendor\pimple\pimple\src\Pimple\Container implementieren. php in Zeile 34

Diese Frage hat ein ähnliches Problem und löst dieses Problem durch einen Neustart von PHP. Dies ist jedoch keine wirkliche Lösung, und ich habe Opcache nicht aktiviert: PHP 7, Symfony 3: Fatal Fehler 1 abstrakte Methode und muss daher als abstrakt deklariert werden oder die übrigen Methoden implementieren

Irgendwelche Ideen? Denken Sie daran: Diese Nachricht befindet sich in Dateien, die ich nicht geschrieben habe, und geht beim Neustart von Apache verloren. Gibt es ein Zwischenspeichern mit PHP 7, das dies verursachen würde?

Edit 10.03.17:

Ja, ich habe mit Slim ein Ticket eröffnet. Ich habe es auch in einer nicht schlanken Datei (Pimple) gesehen, daher glaube ich nicht, dass es sich um ein Slim-Problem handelt https://github.com/slimphp/Slim/issues/2160

Wie gesagt, mein Opcache ist aus. Ich habe bestätigt, dass dies sowohl in der php.ini-Datei als auch beim Betrachten von phpinfo () zutrifft.

18
Will Shaver

Ich glaube, du hast diesen Fehler in der Odecache getroffen. Dies ist nicht genau die gleiche Situation, die aber wahrscheinlich damit zusammenhängt.

Nach dem Aufruf der Funktion opcache_reset () treten einige seltsame Fehler auf. Es geschieht zufällig auf Servern (10 von 400 Server-Produktion)

Einige Buchstaben werden durch andere ersetzt. Die Klasse scheint bereits deklariert zu sein .. usw

Beispiel für Fehler, die nach opcache_reset () ausgelöst wurden:

  • PHP Schwerwiegender Fehler: Die Klasse XXX enthält eine abstrakte Methode und muss daher als abstrakt deklariert werden oder die übrigen Methoden implementieren (YYY :: funczzz) in /dir/dir/x.php in Zeile 20

Das Ticket ist geschlossen, da die Entwickler nicht über ausreichende Informationen verfügen, um es zu reproduzieren. Wenn Sie den kleinsten reproduzierbaren Fall finden können, empfehle ich reporting . Erstellen Sie eine sehr kleine Slim-App und verwenden Sie dann JMeter oder ein anderes Tool, um viele Anfragen zu stellen. Posten Sie Ihre Erkenntnisse.

In der Zwischenzeit besteht die einzige Möglichkeit darin, Opcache in php.ini zu deaktivieren:

opcache.enable=0

Natürlich wird dies die Leistung drastisch beeinträchtigen. Bis es behoben ist, müssen Sie zwischen Performance oder periodischem Neustart von Apache wählen.

Wenn das Deaktivieren des Cache nicht funktioniert, kann ich nur an ein intermittierendes Problem mit dem Opcode-Compiler denken. Die zwischengespeicherte oder nicht kompilierte Version muss einen Fehler enthalten. Das Öffnen eines reproduzierbaren Tickets mit den Entwicklern von PHP oder das Debuggen der Quelle PHP selbst wäre der einzige Weg, wenn dies die Ursache ist.

10
Matt S

Ich hatte das gleiche Problem mit CodeIgniter und PHP 7.1.x.

Ich habe ein Upgrade auf PHP 7.2 durchgeführt und das Problem ist nicht mehr aufgetreten.

1
Robson Piere

Wenn Sie unter Windows entwickeln, würde ich Ihnen empfehlen, dass Sie NICHT XAMPP oder WAMPP verwenden und einen echten Entwicklungsserver mit Linux auf einer VM ausprobieren. 

Installieren Sie Vagrant und Virtualbox, und besuchen Sie puphpet.com. Dort können Sie eine Konfiguration für eine virtuelle Maschine erstellen. Entpacken Sie den Download, cd in den Ordner und geben Sie vagrant ein. Dann richten Sie Ihren Host einfach auf die VM. Ich wette, sobald Sie eine echte Entwicklungsumgebung haben, wird dieser Fehler verschwinden. Ihre andere Option ist Docker, aber das hat eine gewisse Lernkurve.

Das Problem ist nicht Ihr Code (oder Ihr Herstellercode), sondern Ihre Plattform.

1
delboy1978uk

Ich bin genau diesem Verhalten begegnet und es war nicht genau ein Opcache-Fehler, auch wenn er durch opcache verursacht wurde.

Das Problem war, dass wir mehrere Klassen mit demselben Basisnamen hatten, z.

Request\GenericProtocol\Dispatcher     abstract
Request\Protocol1\Dispatcher
Request\Protocol2\Dispatcher

In unserer Installation hat opcache standardmäßig eine "Optimierung" verwendet, die nur den Basisnamen als Cache-Schlüssel verwendet. Jedes Mal, wenn ein Skript einen Protocol2 Dispatcher in einem leeren Cache instanziierte, sabotierte es daher alle nachfolgenden Aufrufe mit Protocol1. Aufgrund von Verwendungsmustern wurde dieses Maskerade wie jeder andere Fehler maskiert.

Am Ende haben wir gerade die entsprechende Option aktiviert:

opcache.use_cwd boolean

Wenn aktiviert, hängt OPcache das aktuelle Arbeitsverzeichnis an den Skriptschlüssel an, wodurch mögliche Kollisionen zwischen Dateien mit demselben Basisnamen vermieden werden. Durch das Deaktivieren dieser Anweisung wird die Leistung verbessert, aber möglicherweise werden vorhandene Anwendungen beschädigt .

Die Bruchbedingung lautet: Sie haben mindestens zwei Klassen mit demselben Basisnamen .

Bei der nächsten Iteration werden tatsächlich viele Klassen umbenannt

 Request\Protocol1\Dispatcher   ==> Request\Protocol1\Protocol1Dispatcher

use_cwd wieder deaktivieren zu können und ein paar Prozent der Leistung zu quetschen (PTBs und PHBs glauben, dass es sich lohnt), aber ich weiß, dass dies nicht mit jedem Framework draußen möglich ist.

0
LSerni