I've been fighting this for a bit, and can't figure it out, maybe someone else has or maybe there's a deeper issue here with Slim, PHP, Apache etc. After working just fine for hours, my Slim install will start giving this on all routes:
Fatal error: Class Slim\Collection contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (IteratorAggregate::getIterator) in F:\Projects\example\server\vendor\slim\slim\Slim\Collection.php on line 21
Maddeningly this issue goes away if I restart Apache. (For a few hours anyway.)
I found this where someone had a similar problem two years ago, and the person helping badgered them without actually assisting at all: https://community.apachefriends.org/viewtopic.php?p=250966&sid=96ef58aaeb7fe142a7dcdfd506a8683f
I've tried doing a clean wipe and install of my composer vendor directory. This doesn't fix it. I can clearly see that getIterator
is implemented as expected in the file in the error message.
PHP Version 7.0.12, Windows 7, x86 PHP Build
It happened again after a few hours, with a different but similar error message:
Fatal error: Class Pimple\Container contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (ArrayAccess::sqlserver) in F:\Projects\example\server\vendor\pimple\pimple\src\Pimple\Container.php on line 34
This question has a similar problem and "solves" it by restarting PHP, but that clearly isn't an actual solution, and I don't have opcache enabled: PHP 7, Symfony 3: Fatal error 1 abstract method and must therefore be declared abstract or implement the remaining methods
Any guesses? Remember: This message is in files I didn't write, and goes away on Apache restart. Is there some caching with PHP 7 that would cause this?
Edit 3/10/17:
Yes, I've opened a ticket with Slim. I also saw it in a non-slim file (Pimple) so I don't think it is a Slim issue. https://github.com/slimphp/Slim/issues/2160
As I said, my opcache is off. I've confirmed this is true both in the php.ini file and looking at phpinfo().
I think you've run into this opcache bug. This isn't exactly the same situation but probably related.
After calling opcache_reset() function we encounter some weird errors. It happens randomly on servers (10 of 400 servers production)
Some letter a replaced by others, Class seems to be already declared.. etc
Example of errors triggered after opcache_reset():
- PHP Fatal error: Class XXX contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (YYY::funczzz) in /dir/dir/x.php on line 20
The ticket is closed because the developers don't have enough information to reproduce it. If you could come up with the smallest reproducible case I recommend reporting it. Create a very small Slim app and then use JMeter or another tool to make many requests. Post your findings.
Meanwhile the only workaround might be to turn off opcache in php.ini:
opcache.enable=0
Of course this will drastically hurt performance. Until it's fixed you'll have to choose between performance or periodically restarting Apache.
If turning the cache off doesn't work then the only cause I could think of is an intermittent problem with the opcode compiler. Cached or not the compiled version must have an error in it. Opening a reproducible ticket with the PHP devs or debugging the PHP source yourself would be the only way forward if this is the cause.
If you develop on Windows, I would recommend that you DON'T use XAMPP or WAMPP, and try out a real development server using Linux on a VM.
Try installing Vagrant and Virtualbox, then head to puphpet.com, which can generate you a virtual machine configuration. Unzip the download, cd in to the folder, type vagrant up. Then just point your host at the VM. I'll bet once you have a real development environment that this error will go away. Your other option is Docker, but that has a bit of a learning curve.
The problem isn't your code (or your vendor code), but your platform.
I had the same problem using CodeIgniter and PHP 7.1.x.
I upgraded to PHP 7.2 and the problem no longer occurred.
I have encountered this exact behaviour and it was not exactly an opcache bug, even if it was caused by opcache.
The problem was that we had several classes with the same base name, e.g.
Request\GenericProtocol\Dispatcher abstract
Request\Protocol1\Dispatcher
Request\Protocol2\Dispatcher
Now by default on our installation opcache used an "optimization" that used the basename only as cache key. As a result, whenever a script happened to instantiate a Protocol2 Dispatcher on a clean cache, it subtly sabotaged all subsequent calls with Protocol1. Due to usage patterns, this masqueraded as any other kind of bug.
In the end we just activated the appropriate option:
opcache.use_cwd boolean
If enabled, OPcache appends the current working directory to the script key, thereby eliminating possible collisions between files with the same base name. Disabling this directive improves performance, but may break existing applications.
The breaking condition is this: you have at least two classes with the same basename.
Our next iteration indeed is scheduled to rename a lot of classes
Request\Protocol1\Dispatcher ==> Request\Protocol1\Protocol1Dispatcher
to be able to re-disable use_cwd and squeeze a few percents of performance (PTBs and PHBs believe it is worth it), but I know that this may not be possible with every framework out there.
来源:https://stackoverflow.com/questions/42503240/intermittent-php-abstract-class-error