Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Zend\Form\FormElementManager not found #71

Closed
adamturcsan opened this issue May 3, 2016 · 11 comments
Closed

Zend\Form\FormElementManager not found #71

adamturcsan opened this issue May 3, 2016 · 11 comments

Comments

@adamturcsan
Copy link

Since zend-form v.2.8.2 I got this fatal error when initializing ZF2 app with PHP 5.6.4. I guess class aliasing during the autoload process doesn't work properly.

It works with PHP 7.0.4.

@weierophinney
Copy link
Member

Can you provide the error message, please?

@adamturcsan
Copy link
Author

Here it is:

junior@juniorPc:~/Munka/Jarkon/JarkonCLH$` php public/index.php check availability --userId=56
PHP Fatal error:  Class 'Zend\Form\FormElementManager' not found in /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-mvc/src/Service/AbstractPluginManagerFactory.php on line 36
PHP Stack trace:
PHP   1. {main}() /home/junior/Munka/Jarkon/JarkonCLH/public/index.php:0
PHP   2. Zend\Mvc\Application::init() /home/junior/Munka/Jarkon/JarkonCLH/public/index.php:12
PHP   3. Zend\ModuleManager\ModuleManager->loadModules() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-mvc/src/Application.php:272
PHP   4. Zend\EventManager\EventManager->triggerEvent() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-modulemanager/src/ModuleManager.php:129
PHP   5. Zend\EventManager\EventManager->triggerListeners() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-eventmanager/src/EventManager.php:251
PHP   6. call_user_func:{/home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-eventmanager/src/EventManager.php:490}() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-eventmanager/src/EventManager.php:490
PHP   7. Zend\ModuleManager\Listener\ServiceListener->onLoadModulesPost() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-eventmanager/src/EventManager.php:490
PHP   8. Zend\ServiceManager\ServiceManager->get() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-modulemanager/src/Listener/ServiceListener.php:208
PHP   9. Zend\ServiceManager\ServiceManager->create() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:530
PHP  10. Zend\ServiceManager\ServiceManager->doCreate() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:597
PHP  11. Zend\ServiceManager\ServiceManager->createFromFactory() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:634
PHP  12. Zend\ServiceManager\ServiceManager->createServiceViaCallback() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:1092
PHP  13. call_user_func:{/home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:934}() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:934
PHP  14. Zend\Mvc\Service\AbstractPluginManagerFactory->createService() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:934
PHP  15. Zend\Mvc\Service\AbstractPluginManagerFactory->__invoke() /home/junior/Munka/Jarkon/JarkonCLH/vendor/zendframework/zend-mvc/src/Service/AbstractPluginManagerFactory.php:49 ```

@Saeven
Copy link
Contributor

Saeven commented May 4, 2016

Confirming break at 2.8.2/3

Exception:

Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Form\FormElementManager\FormElementManagerV2Polyfill

Trace

#0 /Users/Saeven/Documents/Circlical/code/Cloudshare/module/Application/src/Application/Factory/Controller/LazyControllerFactory.php(96): Zend\ServiceManager\ServiceManager->get('Zend\\Form\\FormE...')
#1 [internal function]: Application\Factory\Controller\LazyControllerFactory->createServiceWithName(Object(Zend\Mvc\Controller\ControllerManager), 'applicationcont...', 'Application\\Con...')
#2 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(934): call_user_func(Array, Object(Zend\Mvc\Controller\ControllerManager), 'applicationcont...', 'Application\\Con...')
#3 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php(330): Zend\ServiceManager\ServiceManager->createServiceViaCallback(Array, 'applicationcont...', 'Application\\Con...')
#4 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(1121): Zend\ServiceManager\AbstractPluginManager->createServiceViaCallback(Array, 'applicationcont...', 'Application\\Con...')
#5 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(642): Zend\ServiceManager\ServiceManager->createFromAbstractFactory('applicationcont...', 'Application\\Con...')
#6 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(597): Zend\ServiceManager\ServiceManager->doCreate('Application\\Con...', 'applicationcont...')
#7 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/ServiceManager.php(530): Zend\ServiceManager\ServiceManager->create(Array)
#8 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-servicemanager/src/AbstractPluginManager.php(161): Zend\ServiceManager\ServiceManager->get('Application\\Con...', true)
#9 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-mvc/src/DispatchListener.php(94): Zend\ServiceManager\AbstractPluginManager->get('Application\\Con...')
#10 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#11 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-eventmanager/src/EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#12 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-eventmanager/src/EventManager.php(263): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#13 /Users/Saeven/Documents/Circlical/code/Cloudshare/vendor/zendframework/zend-mvc/src/Application.php(340): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#14 /Users/Saeven/Documents/Circlical/code/Cloudshare/public/index.php(32): Zend\Mvc\Application->run()
#15 {main}

@weierophinney
Copy link
Member

I've tried to reproduce this by doing the following:

  • Creating a new ZF project based on the skeleton application: composer create-project zendframework/skeleton-application zendframework
  • Entering the new project: cd zendframework
  • Updating the ZF requirement: composer require "zendframework/zendframework:^2.5"
  • Starting up a server: php -S 0:8080 -t public/ public/index.php
  • Browsing to the application: (http://localhost:8080/)

As the FormElementManager is created for every request, the above should be enough to recreate the issue. However, it does not. I've tried with each of PHP 5.5, 5.6, and 7, and the skeleton application works correctly in each case.

To take things further, I did the following:

  • Added the FormAbstractServiceFactory as an abstract factory.
  • Added forms configuration, defining a guests form.
  • Updated my Application\Controller\IndexController to accept a Zend\Form\Form instance to its constructor, and emit the form as part of the view.
  • Updated my Application\Module class to define a factory for my IndexController that injects the form by pulling it from the service manager; I also removed the invokable entry for it from my module.config.php

This, in other words, was a thorough test to ensure that the polyfill must be invoked. I then fired up the server for each of PHP 5.5, 5.6, and 7.0. The code worked perfectly in all cases.

So, I am unable to reproduce with the code that ZF ships. That means the problem is elsewhere. I have a few ideas:

  • First, when you update, are you by any chance running --optimize-autoloader or --classmap-authoritative or --no-autoloader? If so, can you indicate which?
  • Second, @Saeven — I see that it's your LazyControllerFactory that is raising the exception. Is is possible that there is an error in that factory?

@weierophinney
Copy link
Member

I've tested whether or not this is a Composer autoloading issue by issuing each of:

$ composer dump-autoload --optimize-autoloader
$ composer dump-autoload --classmap-authoritative

The code continues to work under both scenarios. In looking through the vendor/composer/ files, I can verify that the polyfill autoload file is being loaded (which makes sense, considering that the code is working).

Just for the record: composer shows the following are installed (partial list, only the relevant packages):

zendframework/zendframework         2.5.3  Zend Framework 2
zendframework/zend-servicemanager   2.7.6
zendframework/zend-form             2.8.3

@Saeven
Copy link
Contributor

Saeven commented May 4, 2016

I'll try to pinpoint a test to reproduce the issue. I basically have a composer set at @stable, I'll try to find the culprit. The issue occurs in my code, whether or not the Lazy Factory is invoked. It's getting FormElementManager on the SM that triggers the failure.

@weierophinney
Copy link
Member

It's getting FormElementManager on the SM that triggers the failure.

Just created a new test by having a controller that accepts FormElementManager to the constructor, and creating a factory that injects it:

return new TestController($container->get('FormElementManager'));

Again, just works in each of PHP 5.5, 5.6, and 7.0.

I also added the following into a template to see what it generates:

Does FormElementManager exist? <b><?= class_exists(Zend\Form\FormElementManager::class) ? 'YES' : 'NO' ?></b>

Each version prints YES.

Do you have a custom factory for FormElementManager, by any chance?

@adamturcsan
Copy link
Author

I don't know why it worked when I changed the zend-form version back to 2.8.1 but as I see, another broken package info blocked the autoload info creation. I managed to fix the other issue and after these test results I tried to reproduce this error, but it vanished. So my bad, I apologize, I cannot reproduce this issue either.
But again, I don't know, why zend-form version changing fixed the error.

The PHP version may have not caused any effect, only it was another composer install.

@weierophinney
Copy link
Member

@adamturcsan This may be a subtle composer bug. If I can figure out a way to reproduce it, I'll report it upstream.

Thanks for following up!

@Estigy
Copy link

Estigy commented May 17, 2016

Just wanted to add my 2 cents:
The way it is done now, using the Polyfill classes and deciding in the autoload/formElementManagerPolyfill.php which of the Polyfill class to autoload, completely breaks IDE's code insight.

@weierophinney
Copy link
Member

@Estigy There is a way around that: add a @var annotation above the variable detailing which polyfill class to hint against:

/** @var Zend\Form\FormElementManager\FormElementManagerV3Polyfill */
$forms = $services->get(FormElementManager::class);

If you have a better suggestion for handling the polyfill, I'd definitely welcome a pull request. This was the best solution I could find that worked consistently.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants