Несколько пространств имен в одном модуле в ZF2
У меня возникли проблемы с настройкой нескольких пространств имен/классов в одном модуле. Например, у меня есть модуль под названием "Учетная запись", в который я хотел бы включить все классы, связанные с учетной записью (компании: "учетные записи", пользователи: "пользователи", внешний api: "api" и т. Д.). Структура модуля выглядит так..
/Account
- Module.php
- /config
- /view
- /src
- /Account
- /Controller (AccountController.php)
- /Form (AccountForm.php)
- /Model (Account.php + AccountTable.php)
- /User
- /Controller (UserController.php)
- /Form (UserForm.php)
- /Model (User.php + UserTable.php)
- /Api
- Api.php (simple class)
Будучи новичком в ZF2, я решил сделать все просто и глупо и не пытаться реализовать сложную маршрутизацию в модуль учетной записи. Итак, для того, чтобы вызвать индексацию для UserController, url-адрес должен быть /user (!)
Вот класс модуля:
namespace Account;
use Account\Model\AccountTable;
use Account\Model\UserTable;
class Module
{
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 getServiceConfig()
{
return array(
'factories' => array(
'Account\Model\AccountTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new AccountTable($dbAdapter);
return $table;
},
'Account\Model\UserTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new UserTable($dbAdapter);
return $table;
},
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
И файл module.config
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
'Account\Controller\User' => 'Account\Controller\UserController',
),
),
'router' => array(
'routes' => array(
'account' => array(
'type' => 'segment',
'options' => array(
'route' => '/account[/:action[/:accountId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'accountId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\Account',
'action' => 'index',
),
),
/*
'may_terminate' => true,
'child_routes' => array(
'user' => array(
'type' => 'literal',
'options' => array(
'route' => '/user[/:action[/:userId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'userId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\User',
'action' => 'index'
)
)
)
),
*/
),
'user' => array(
'type' => 'segment',
'options' => array(
'route' => '/user[/:action[/:userId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'userId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\User',
'action' => 'index',
),
),
)
),
),
'view_manager' => array(
'template_path_stack' => array(
'account' => __DIR__ . '/../view',
'user' => __DIR__ . '/../view',
),
),
);
Но я получаю ошибку: "Класс "Учетная запись\контроллер\пользовательскийконтроллер"не найден". Я уверен, что что-то упустил. Пожалуйста, есть какие-нибудь подсказки?
Спасибо
2 answers
Вы должны сообщить StandardAutoloader
о вашем новом пространстве имен:
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
// This is for the Account namespace
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
// And this is for the User namespace
'User' => __DIR__ . '/src/' . 'User',
),
),
);
}
В module.config.php
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
// The key can be what ever you want, but the value must be a valid
// class name. Your UserController lives in the User namespace,
// not in Account
'Account\Controller\User' => 'User\Controller\UserController',
),
),
/* ... */
);
Стандартный загрузчик должен знать, где найти классы. Вы можете определить его с помощью опции пространства имен, которая представляет собой массив, содержащий абсолютные (или относительные к текущему сценарию) пути. Это должно выглядеть так:
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
__ПРОСТРАНСТВО ИМЕН__ - это имя модуля, а __DIR__ - абсолютный путь к Module.php сценарий
Проверка http://framework.zend.com/manual/2.0/en/modules/zend.loader.standard-autoloader.html
В ClassMapAutoloader используется для повышения производительности: вы определяете ключ класса и его точный путь к файлу, а не папку, в которой zf2 должен просматривать ее содержимое, выполняя операции с файловой системой (способ стандартного загрузчика).
Проверить http://framework.zend.com/manual/2.0/en/modules/zend.loader.class-map-autoloader.html