web-dev-qa-db-ja.com

断続的PHP抽象クラスエラー

私はこれと少し戦っていて、それを理解することができません。おそらく誰か他の人が持っているか、またはSlim、PHP、Apacheなどでより深い問題がここにあるかもしれません。何時間も問題なく動作した後、私のSlimインストールはこれはすべてのルートで:

致命的なエラー:クラスSlim\Collectionには1つの抽象メソッドが含まれているため、F:\ Projects\example\server\vendor\slim\slim\Slim\Collection.phpの抽象メソッドとして宣言するか、残りのメソッド(IteratorAggregate :: getIterator)を実装する必要があります21行目

Apacheを再起動すれば、この問題は解消されます。 (とにかく数時間。)

2年前に誰かが同様の問題を抱えていて、実際にはまったく支援せずにバッジを付けた人がいることがわかりました: https://community.apachefriends.org/viewtopic.php?p=250966&sid=96ef58aaeb7fe142a7dcdfd506a8683f =

composerベンダーディレクトリをクリーンワイプしてインストールしようとしました。これで問題が解決しません。getIteratorがファイルに期待どおりに実装されていることがわかりますエラーメッセージで。

PHPバージョン7.0.12、Windows 7、x86 PHPビルド

数時間後に再び発生しましたが、別の類似したエラーメッセージが表示されました。

致命的なエラー:クラスPimple\Containerには1つの抽象メソッドが含まれているため、F:\ Projects\example\server\vendor\pimple\pimple\src\Pimple\Containerで抽象として宣言するか、残りのメソッド(ArrayAccess :: sqlserver)を実装する必要があります。 34行目のphp

この質問にも同様の問題があり、PHPを再起動することで「解決」しますが、それは明らかに実際の解決策ではなく、opcacheを有効にしていません: PHP 7、Symfony 3:Fatal error 1 abstract method andしたがって、抽象として宣言するか、残りのメソッドを実装する必要があります

推測は?覚えておいてください:このメッセージは私が書いていないファイルにあり、Apacheの再起動時に消えます。これを引き起こすPHP 7のキャッシングはありますか?

編集3/10/17:

はい、スリムでチケットをオープンしました。私はそれをスリムでないファイル(Pimple)でも見たので、スリムな問題ではないと思います。 https://github.com/slimphp/Slim/issues/216

言ったように、私のopcacheはオフです。これがphp.iniファイルとphpinfo()の両方に当てはまることを確認しました。

20
Will Shaver

このopcacheバグ に遭遇したと思います。これはまったく同じ状況ではありませんが、おそらく関連しています。

Opcache_reset()関数を呼び出した後、奇妙なエラーが発生します。サーバー上でランダムに発生します(400サーバーのうち10サーバーが生産)

一部の文字は他の文字に置き換えられ、クラスはすでに宣言されているようです。

Opcache_reset()の後にトリガーされるエラーの例:

  • PHPの致命的なエラー:クラスXXXには1つの抽象メソッドが含まれているため、20行目の/dir/dir/x.phpの抽象メソッドとして宣言するか、残りのメソッド(YYY :: funczzz)を実装する必要があります

開発者にはそれを再現するための十分な情報がないため、チケットはクローズされています。あなたが最小の再現可能なケースを思い付くことができるなら、私はお勧めします それを報告する 。非常に小さなSlimアプリを作成し、JMeterまたは別のツールを使用して多くのリクエストを作成します。調査結果を投稿します。

一方、唯一の回避策は、php.iniでopcacheをオフにすることです。

opcache.enable=0

もちろん、これはパフォーマンスを大幅に低下させます。修正されるまでは、パフォーマンスを選択するか、Apacheを定期的に再起動する必要があります。

キャッシュをオフにしても機能しない場合、考えられる唯一の原因は、オペコードコンパイラーの断続的な問題です。キャッシュされたバージョンまたはコンパイルされていないバージョンでは、エラーが発生する必要があります。 PHP devsまたはPHPソースをデバッグすることで、再現可能なチケットを開くことが、これが原因である場合の唯一の前進方法です。

11
Matt S

CodeIgniterとPHP 7.1.x.

PHP 7.2 にアップグレードしたところ、問題は発生しなくなりました。

1
Robson Piere

Windowsで開発する場合は、XAMPPやWAMPPを使用せず、VMでLinuxを使用して実際の開発サーバーを試すことをお勧めします。

VagrantとVirtualboxをインストールしてから、仮想マシン構成を生成できるpuphpet.comにアクセスしてください。ダウンロードを解凍し、フォルダーにcdして、vagrant upと入力します。次に、ホストをVMに向けます。このエラーがなくなる実際の開発環境が整ったら、私は賭けます。もう1つの選択肢はDockerですが、少し習得する必要があります。

問題は、コード(またはベンダーコード)ではなく、プラットフォームです。

1
delboy1978uk

私はこの正確な動作に遭遇しましたが、それは正確に opcacheのバグではなく、opcacheによってが発生したものでした。

問題は、同じベース名を持ついくつかのクラスがあることでした。

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

今回のインストールでは、デフォルトでopcacheが「最適化」を使用しましたベース名のみを使用をキャッシュキーとして使用。その結果、スクリプトがProtocol2 Dispatcherをクリーンなキャッシュ上でインスタンス化した場合は常に、Protocol1を使用した後続のすべての呼び出しを微妙に妨害しました。使用パターンが原因で、これは他の種類のバグになりすました。

最後に、適切なオプションを有効にしました。

opcache.use_cwdブール値

OPcacheを有効にすると、現在の作業ディレクトリがスクリプトキーに追加されるため、同じベース名を持つファイル間の衝突の可能性がなくなります。このディレクティブを無効にすると、パフォーマンスが向上しますただし、既存のアプリケーションが壊れる可能性があります

破壊状態は次のとおりです:同じベース名を持つクラスが少なくとも2つあります

私たちの次の反復は確かに多くのクラスの名前を変更する予定です

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

use_cwdを再度無効にしてパフォーマンスの数パーセントを圧縮できるようにする(PTBとPHBはそれは価値があると信じています)が、これはすべてのフレームワークで可能ではないことを知っています。

0
LSerni