我已经对此进行了一段时间的斗争,并且无法解决这个问题,也许其他人已经或者可能在这里有更深层次的问题,包括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()并确认这是真的。
答案 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认为值得),但我知道这可能不适用于每个框架。