zendframework / zend-modulemanager

ModuleManager component from Zend Framework
BSD 3-Clause "New" or "Revised" License
44 stars 27 forks source link

Packaging a Zend MVC application using zend-modulemanager results in an unloaded configuration #82

Open curtiskelsey opened 6 years ago

curtiskelsey commented 6 years ago

After developing a Zend MVC application with console components, it is desired to package the console components and all services into a phar. After packaging the application into a phar the application ceases to run due to configuration issues. The issues stem from the ModuleManager's use of glob to autoload config files. The glob command does not support stream wrappers. Would it make sense to eliminate the need for glob within the package?

Code to reproduce the issue

The implementation is https://github.com/zfcampus/zf-console on a standard Zend MVC application. To recreate the issue you must have a module that depends on configuration that is only included in the autoloaded config files to execute, such as a custom usage of the Doctrine Migrations package then package the application as a phar. The problem stems from the ConfigListener::addConfigByPath($path, $type) method or, to continue tracing it, The Glob::glob() method in the Zend standard library:

protected function addConfigByPath($path, $type)
    {
        switch ($type) {
            case self::STATIC_PATH:
                $this->addConfig($path, ConfigFactory::fromFile($path));
                break;

            case self::GLOB_PATH:
                // We want to keep track of where each value came from so we don't
                // use ConfigFactory::fromFiles() since it does merging internally.
                foreach (Glob::glob($path, Glob::GLOB_BRACE) as $file) { // FIXME Here is the issue
                    $this->addConfig($file, ConfigFactory::fromFile($file));
                }
                break;
        }

        return $this;
    }

Expected results

$ /usr/bin/php bin/cli.php 
###, version 1.0.0

Available commands:

 autocomplete                 Command autocompletion setup
 build:phar                   Builds a phar of the application
 dbms:database:last-modified  Reports the last time each managed database was modified
 dbms:database:transfer       Transfers a database from an origin server to a destination server
 fixtures                     Manages application data fixtures
 help                         Get help for individual commands
 version                      Display the version of the script

Actual results

$ /usr/bin/php cli.phar

PHP Fatal error:  Uncaught InvalidArgumentException: Cannot load migrations from "data/DoctrineORMModule/Migrations" because it is not a valid directory in phar:///vagrant/cli.phar/vendor/doctrine/migrations/lib/Doctrine/DBAL/Migrations/Finder/AbstractFinder.php:38
Stack trace:
#0 phar:///vagrant/cli.phar/vendor/doctrine/migrations/lib/Doctrine/DBAL/Migrations/Finder/RecursiveRegexFinder.php(36): Doctrine\DBAL\Migrations\Finder\AbstractFinder->getRealPath('data/DoctrineOR...')
#1 phar:///vagrant/cli.phar/vendor/doctrine/migrations/lib/Doctrine/DBAL/Migrations/Configuration/Configuration.php(743): Doctrine\DBAL\Migrations\Finder\RecursiveRegexFinder->findMigrations('data/DoctrineOR...', 'DoctrineORMModu...')
#2 phar:///vagrant/cli.phar/vendor/doctrine/migrations/lib/Doctrine/DBAL/Migrations/Configuration/Configuration.php(385): Doctrine\DBAL\Migrations\Configuration\Configuration->findMigrations('data/DoctrineOR...')
#3 phar:///vagrant/cli.phar/vendor/doctrine/doctrine-orm-module/src/DoctrineORMModule/Service/MigrationsConfigur in phar:///vagrant/cli.phar/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 771

Fatal error: Uncaught InvalidArgumentException: Cannot load migrations from "data/DoctrineORMModule/Migrations" because it is not a valid directory in phar:///vagrant/cli.phar/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 771

Zend\ServiceManager\Exception\ServiceNotCreatedException: Service with name "doctrine.migrations_configuration.orm_default" could not be created. Reason: Cannot load migrations from "data/DoctrineORMModule/Migrations" because it is not a valid directory in phar:///vagrant/cli.phar/vendor/zendframework/zend-servicemanager/src/ServiceManager.php on line 771

Call Stack:
    0.4194    5286560   1. {main}() /vagrant/cli.phar:0
    0.4197    5285680   2. require('phar:///vagrant/cli.phar/bin/cli.php') /vagrant/cli.phar:10
    0.4783    7488880   3. Zend\Mvc\Application::init() phar:///vagrant/cli.phar/bin/cli.php:3
    0.6356   10028752   4. Zend\Mvc\Application->bootstrap() phar:///vagrant/cli.phar/vendor/zendframework/zend-mvc/src/Application.php:273
    0.6531   10362488   5. Zend\ServiceManager\ServiceManager->get() phar:///vagrant/cli.phar/vendor/zendframework/zend-mvc/src/Application.php:158
    0.6531   10362488   6. Zend\ServiceManager\ServiceManager->doCreate() phar:///vagrant/cli.phar/vendor/zendframework/zend-servicemanager/src/ServiceManager.php:200
weierophinney commented 6 years ago

We have deprecated usage of console tooling with zend-mvc.

The recommendation is to instead use something like zf-console or symfony/console for developing console applications.

In terms of getting service definitions to those console applications, you may still end up with similar issues. The best way to combat them: when building your PHAR file, compile the configuration. Once compiled, have the phar use the compiled configuration; this is already built-in in the ConfigListener anyways, and will prevent the need for globbing.

curtiskelsey commented 6 years ago

That is the exact wisdom I needed. Thanks! I will compile the config.

weierophinney commented 4 years ago

This repository has been closed and moved to laminas/laminas-modulemanager; a new issue has been opened at https://github.com/laminas/laminas-modulemanager/issues/1.