【问题标题】:ZF2 Zend framework not calling global.php for Album tutorial applicationZF2 Zend 框架没有为专辑教程应用程序调用 global.php
【发布时间】:2013-01-08 04:44:00
【问题描述】:

我收到一个错误:Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raise while creating "Zend\Db\Adapter\Adapter";没有返回实例。

跟踪下来,我发现 Zend\Db\Adapter\Adapter 出现在 global.php 中。但是, global.php 从未被调用过,或者至少在发生错误的 module.php getserviceconfig() 之前没有被调用过。 testconfig.php.dist 和 application.config.php 都将 global.php 呈现给侦听器定义。但是,global.php 永远不会执行。

谁能告诉我为什么?定义如下。

global.php

<?php
echo PHP_EOL . "Global.php executed." . PHP_EOL;
return array(
    'db' => array(
        'driver'         => 'Pdo',
        'dsn'            => 'mysql:dbname=zf2tutorial;host=album.techmate.com',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter'
                    => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
);
?>

testconfig.php.dist

<?php

echo PHP_EOL . "TestConfig.php.dist executed." . PHP_EOL;
return array(
    'modules' => array(
        'Album', // <-- Add this line
    ),
    'module_listener_options' => array(
        'config_glob_paths' => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            './module',
            './vendor',
        ),
    ),
);
?>

应用程序.config.php

<?php
echo PHP_EOL . "Application.config.php executed." . PHP_EOL;
return array(
    'modules' => array(
        'Album',                  // <-- Add this line
    ),
    'module_listener_options' => array(
        'config_glob_paths'    => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            './module',
            './vendor',
        ),
    ),
);
?>

module.php 只是为了完整性...

<?php

namespace Album;

use Album\Model\Album;
use Album\Model\AlbumTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ServiceProviderInterface;
use Zend\Db\Adapter\Adapter as DbAdapter;

class Module implements ServiceProviderInterface {

    public function getAutoloaderConfig() {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getConfig() {
        return include __DIR__ . '/config/module.config.php';
    }

    // Add this method:
    public function getServiceConfig() {
        return array(
            'factories' => array(
/*                'Zend\db\Adapter\Adapter' => function($sm) {
                    echo PHP_EOL . "SM db-adapter executed." . PHP_EOL;
                    $config = $sm->get('config');
                    $config = $config['db'];
                    $dbAdapter = new DbAdapter($config);
                    return $dbAdapter;
                },*/
                'Album\Model\AlbumTable' => function($sm) {
                    echo PHP_EOL . "SM AlbumTable executed." . PHP_EOL;
                    $tableGateway = $sm->get('AlbumTableGateway');
                    $table = new AlbumTable($tableGateway);
                    return $table;
                },
                'AlbumTableGateway' => function ($sm) {
                    echo PHP_EOL . "SM AlbumTableGateway executed." . PHP_EOL;
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $resultSetPrototype = new ResultSet();
                        $resultSetPrototype->setArrayObjectPrototype(new Album());
                        return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }

}

?>

还有错误...

TestConfig.php.dist executed.


Module.config.php executed.
PHPUnit 3.7.10 by Sebastian Bergmann.

Configuration read from D:\PHP\zf2-tutorial\module\Album\test\phpunit.xml.dist

......E
SM AlbumTable executed.

SM AlbumTableGateway executed.


Time: 0 seconds, Memory: 8.50Mb

There was 1 error:

1) AlbumTest\Model\AlbumTableTest::testGetAlbumTableReturnsAnInstanceOfAlbumTable
Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for Zend\Db\Adapter\Adapter

D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:450
D:\PHP\zf2-tutorial\module\Album\Module.php:50
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:44
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\src\Album\Controller\AlbumController.php:33
D:\PHP\zf2-tutorial\module\Album\test\AlbumTest\Model\AlbumTableTest.php:149

FAILURES!
Tests: 7, Assertions: 9, Errors: 1.

【问题讨论】:

    标签: php phpunit zend-framework2


    【解决方案1】:

    根据PHPUnit bootstrapping instructions,看起来TestConfig.php.dist中的以下行可能是错误的:

    'config/autoload/{,*.}{global,local}.php',
    

    将行改为:

    '../../../config/autoload/{,*.}{global,local}.php',
    

    如果您有一个 local.php 配置文件,它也可能不会加载。

    当然,如果目录结构不标准,相应地改行,但你明白了。

    【讨论】:

    • 这完全正确。我刚刚在 Zend 论坛上发布了回复,当我找到你的答案时,我正准备在这里发布。您的答案访问 zf2-tutorial/config/autoload 这可能是最好的情况。但是,本教程将其放入 Album/config/autoload 中。在这种情况下,该行应该读取为 ../config/autoload/{,*.}{global,local}.php 任何一个都可以,只要您了解结构并访问存储它们的文件。另一个注意事项,我必须在 global.php 和 local.php 上放置一个更高级别的节点来匹配这个,即 myconfig.global.php。
    • 我必须这样做:/config/autoload/{,*.}{global,local}.php
    • @DominicWatson;请注意,您列出的文件路径是绝对路径而不是相对路径,并且它引用了一个奇怪的位置。也许是错字?对于那些对路径感兴趣的人:paths explainedwikipedia on paths
    【解决方案2】:

    我认为 global.php 没有被自动加载,因为文件的命名不匹配:

    'config/autoload/{,*.}{global,local}.php',
    

    因此,如果您将文件命名为 myconfig.global.php,则应将其拾取。

    【讨论】:

    • 嗯,这是一个公平的镜头,但是,不,结果是一样的。非常感谢您的回复...RG
    • 我发现这是整个解决方案的必要部分。谢谢。
    【解决方案3】:

    我找到了解决此问题的方法,但我对需要这样做感到非常失望。阅读 ZF2 手册,我发现 global.php 和 local.php 应该由 ModuleManager 与 module.config.php 合并。据我所知,这实际上应该发生在 ModuleManagerFactory 但是......

    无论如何,我手动将 global.php 和 local.php 信息添加到 module.config.php 中。这行得通,但同样,它不应该是必要的。

    与往常一样,我很高兴收到比这更好的答案。

    为了清楚起见,我将手册参考包括在内。它来自第 700 页。请注意,它还包括调用文件 my.global.config.php 和 my.local.config.php 的错误。我确实尝试了这些名称以防万一,但没有奏效。

    154.5 Default Configuration Options
    The following options are available when using the default services configured by the ServiceManagerConfig
    and ViewManager.
    These configuration directives can go to the config/autoload/{,*.}{global,local}.php files, or in the
    module/<module name>/config/module.config.php configuration files. The merging of these configuration
    files is done by the ModuleManager. It first merges each module’s module.config.php file, and then
    the files in config/autoload (first the *.global.php and then the *.local.php files). The order of the
    merge is relevant so you can override a module’s configuration with your application configuration. If you have both
    a config/autoload/my.global.config.php and config/autoload/my.local.config.php, the
    local configuration file overrides the global configuration.
    

    【讨论】:

    • 这也解决了我的问题。但是我不能接受这是一个解决方案。你能找到任何解决方法吗?我们必须找到一个合适的解决方案:)
    • 好的,我想我找到了 :) TestConfig.php.dist 中为 config_glob_paths 编写的路径错误 如果计算父文件夹的数量,结果是四个而不是三个。所以我需要把'config_glob_paths' => array('../../../../config/autoload/{,*.}{global,local}.php', ) 如果这个请告诉我也可以解决您的问题。
    猜你喜欢
    • 2010-11-06
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 2014-01-15
    • 2016-08-25
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    相关资源
    最近更新 更多