如果您是 ZF2/3 的新手,这是一个合理的问题。
您应该知道的一件事是所有配置(application.config.php、modules.config.php 和每个模块 module.config.php 以及您定义的任何其他配置文件都应该包含在 Module.php 类中),它们都被合并到一个单个配置数组。
因此,如果您在每个模块中都有以下位,则如果您使用array_merge_recursive 合并,则只有最后一个有效,如果您使用array_merge,则只有第一个有效。
'view_manager' => [
// ... others
'template_map' => [
'layout/layout' => _DIR__ . '/../view/layout/sam_layout.phtml',
// ... others
],
],
因此,请确保:
- 定义关联数组键仅一次!
- 确保您要覆盖扩展模块中的值出于某种原因!
就我个人而言,我同时使用这两条规则。定义一次并在需要时覆盖。但是,要小心后者,很容易出错。
一个这样的错误是在您的Application 模块中定义layout/layout,然后在您的User 模块中再次定义它,然后在另一个模块中再次定义它。 永远不要这样做 ;)
首先修复你的配置问题
为了给你一些清理的配置,这样你就不会迷路,使用AbstractModule.php 类。我从某人的 sn-p 中复制了我的(不记得是谁的,否则会记入)。
namespace Your\Core\Or\Mvc\Module\Namespace;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
/**
* Class AbstractModule
* @package Your\Core\Or\Mvc\Module\Namespace
*/
abstract class AbstractModule implements ConfigProviderInterface, AutoloaderProviderInterface
{
/**
* @var String Path of current module
*/
protected $path;
/**
* @var String Namespace of current module
*/
protected $namespace;
/**
* This is to be called by descendant classes with:
* parent::__construct(__DIR__, __NAMESPACE__)
*
* @param $path string Module path
* @param $namespace string Module namespace
*/
public function __construct($path, $namespace)
{
$this->path = $path;
$this->namespace = $namespace;
}
/**
* @return array
*/
public function getConfig()
{
$config = [];
foreach (glob($this->path . '/config/*.php') as $filename) {
$config = array_merge_recursive($config, include $filename);
}
return $config;
}
/**
* @return array
*/
public function getAutoloaderConfig()
{
return [
'Zend\Loader\StandardAutoloader' => [
'namespaces' => [
$this->namespace => $this->path . DIRECTORY_SEPARATOR . 'src',
],
],
];
}
}
在每个模块中使用以下 Module.php
namespace Your\Module\Namespace;
use Your\Core\Or\Mvc\Module\Namespace\AbstractModule;
/**
* Class Module
* @package Your\Module\Namespace
*/
class Module extends AbstractModule
{
/**
* Module constructor.
*/
public function __construct()
{
parent::__construct(__DIR__, __NAMESPACE__);
}
}
我为什么要使用所有这些 OO 垃圾?
好吧,如果您有此代码,您可以按主题将模块中的所有配置文件分开。因此,在 APP_DIR/module/MODULE_NAME/config/ 文件夹中,您现在可以放置一堆配置文件,例如:
- module.config.php
- routes.config.php
- custom.config.php
所有这些都会被加载。
注意:这并没有解决您遇到的布局被其他人覆盖的问题。这是因为您的所有配置都使用了相同的配置键名称 (layout/layout)。
第二次设置配置以允许不同的布局
接下来,您想为每个模块使用不同的布局。这没问题,但是,您需要确保允许设置它的配置。因此,我们使用了一些 sn-p 代码。
如果您有专门用于主题的模块,请将此功能添加到其Module.php。否则,您可能希望将其添加到 Application 模块中的 Module.php 类中。
/**
* @param MvcEvent $e
*/
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
/**
* Source: https://github.com/Hounddog/HdRouteLayouts/blob/master/Module.php
* Add below AND route_layouts => [ %route% => %template/layout% ] to a module to allow route based layout
*
* Below example applies layout in [layout/admin => [ %path/to/layout.phtml% ] to all routes starting with
* "admin*" as defined in the "route_layouts => []" array.
*
* 'view_manager' => [
* 'template_map' => [
* 'layout/admin' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'view'
* . DIRECTORY_SEPARATOR . 'layout' . DIRECTORY_SEPARATOR . 'layout.phtml',
* ],
* ],
*
* 'route_layouts' => [
* 'admin*' => 'layout/admin',
* ],
*/
$e->getApplication()->getEventManager()->getSharedManager()
->attach(AbstractActionController::class, MvcEvent::EVENT_DISPATCH, function (MvcEvent $e) {
$controller = $e->getTarget();
$routeName = $e->getRouteMatch()->getMatchedRouteName();
$config = $e->getApplication()->getServiceManager()->get('config');
$layoutConfig = isset($config['route_layouts']) ? $config['route_layouts'] : [];
if (isset($layoutConfig) && count($layoutConfig) > 0) {
if (isset($layoutConfig[$routeName])) {
$controller->layout($layoutConfig[$routeName]);
} else {
$rules = array_keys($layoutConfig);
foreach ($rules as $routeRule) {
if (fnmatch($routeRule, $routeName, FNM_CASEFOLD)) {
$controller->layout($layoutConfig[$routeRule]);
break;
}
}
}
}
}, 100);
}
我们现在可以添加特定的路线布局!
我们通过在配置中注册它们来添加新布局。在我的一个项目中,我们添加了一些布局,这是添加的配置,以根据路线使用不同的布局。
// 'route_layouts' is a new "top-level" config array key
// Here you define: route -> template_name
'route_layouts' => [
'*' => 'layout/layout',
'login' => 'layout/login',
'register' => 'layout/login',
'error*' => 'error/error',
'error/404' => 'error/404',
'error/index' => 'error/index',
],
'view_manager' => [
'template_map' => [
// Here you define: template_name -> location
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'layout/login' => __DIR__ . '/../view/layout/login.phtml',
'layout/register' => __DIR__ . '/../view/layout/register.phtml',
'error/error' => __DIR__ . '/../view/error/error.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
// ... other config
],
希望这可以为您解决很多关于配置和布局的问题。如果您无法使用这些示例解决相关问题,请随时发表评论。