间歇性的PHP抽象类错误

时间:2017-02-28 08:03:53

标签: php apache slim

我已经对此进行了一段时间的斗争,并且无法解决这个问题,也许其他人已经或者可能在这里有更深层次的问题,包括Slim,PHP,Apache等。好几个小时,我的Slim安装将开始在所有路线上提供:

  

致命错误:类Slim \ Collection包含1个抽象方法,因此必须在F:\ Projects \ example \ server \ vendor \ slim \ slim \ Slim \ Collection中声明为抽象或实现其余方法(IteratorAggregate :: getIterator)第21行的.php

如果我重新启动Apache,这个问题就会消失。 (无论如何都要几个小时。)

我发现这是两年前有人遇到过类似问题的地方,而且这个人在没有实际帮助的情况下帮助他们做了::https://community.apachefriends.org/viewtopic.php?p=250966&sid=96ef58aaeb7fe142a7dcdfd506a8683f

我尝试过干净的擦除并安装我的作曲家供应商目录。这并没有解决它。我可以清楚地看到getIterator在错误消息中的文件中按预期实现。

PHP Version 7.0.12,Windows 7,x86 PHP Build

几个小时后又发生了一次,但有一个不同但相似的错误信息:

  

致命错误:类Pimple \ Container包含1个抽象方法,因此必须在F:\ Projects \ example \ server \ vendor \ pimple \ pimple \ src \ Pimple中声明为抽象或实现其余方法(ArrayAccess :: sqlserver)第34行的Container.php

这个问题有一个类似的问题,"解决了"它通过重新启动PHP,但这显然不是一个真正的解决方案,我没有启用opcache: PHP 7, Symfony 3: Fatal error 1 abstract method and must therefore be declared abstract or implement the remaining methods

任何猜测?请记住:此消息位于我没有编写的文件中,并且在Apache重新启动时消失。是否有一些PHP 7的缓存会导致这种情况?

编辑3/10/17:

是的,我已经用Slim打开了一张票。我也看到它是一个非苗条的文件(疙瘩),所以我不认为这是一个苗条的问题。 https://github.com/slimphp/Slim/issues/2160

正如我所说,我的opcache已关闭。我已经在php.ini文件中查看了phpinfo()并确认这是真的。

4 个答案:

答案 0 :(得分:11)

我认为你遇到了this opcache bug。这种情况并非完全相同,但可能相关。

  

调用opcache_reset()函数后,我们遇到了一些奇怪的错误。   它在服务器上随机发生(400台服务器生产中的10台)

     

有些字母被其他人取代,Class似乎已经宣布了......   等

     

opcache_reset()之后触发的错误示例:

     
      
  • PHP致命错误:类XXX包含1个抽象方法,因此必须声明为抽象方法或实现其余方法   第20行/dir/dir/x.php中的(YYY :: funczzz)
  •   

故障单已关闭,因为开发人员没有足够的信息来重现故障。如果您能想出最小的可重复的案例,我建议reporting it。创建一个非常小的Slim应用程序,然后使用JMeter或其他工具发出许多请求。发表你的发现。

同时唯一的解决方法可能是关闭php.ini中的opcache:

opcache.enable=0

当然这会严重影响性能。在修复之前,您必须在性能之间进行选择或定期重新启动Apache。

如果关闭缓存不起作用,那么我能想到的唯一原因是操作码编译器的间歇性问题。是否缓存编译版本必须有错误。如果这是原因,那么使用PHP开发人员打开可重现的票证或自己调试PHP源代码将是唯一的方法。

答案 1 :(得分:1)

如果您在Windows上开发,我建议您不要使用XAMPP或WAMPP,并在VM上使用Linux试用一个真正的开发服务器。

尝试安装Vagrant和Virtualbox,然后前往puphpet.com,它可以为您生成虚拟机配置。解压下载,cd进入文件夹,输入vagrant up。然后将主机指向VM。一旦你有一个真正的开发环境,我就会打赌这个错误会消失。你的另一个选择是Docker,但这有一点学习曲线。

问题不在于您的代码(或您的供应商代码),而在于您的平台。

答案 2 :(得分:1)

使用CodeIgniter和PHP 7.1.x我遇到了同样的问题。

我已升级到PHP 7.2,问题不再发生。

答案 3 :(得分:0)

我遇到了这种确切的行为,并且它不是完全一个opcache错误,即使 由opcache引起。

问题是我们有几个具有相同基本名称的类,例如

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

现在默认情况下,我们的安装opcache使用了“优化”,仅使用基本名称作为缓存键。因此,每当脚本碰巧在干净缓存上实例化Protocol2 Dispatcher时,它就会巧妙地破坏所有后续使用Protocol1的调用。由于使用模式,这伪装成任何其他类型的错误。

最后我们刚刚激活了相应的选项:

  

opcache.use_cwd boolean

     

如果启用,OPcache会将当前工作目录附加到脚本键,从而消除具有相同基本名称的文件之间可能发生的冲突。禁用此指令可提高性能,但可能会破坏现有应用程序

突破条件是:您至少有两个具有相同基本名称的类

我们的下一次迭代确实计划重命名很多类

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

能够重新禁用use_cwd并挤压几个百分点的性能(PTB和PHB认为值得),但我知道这可能不适用于每个框架。