Zend Framework 路由器主机名和多语言支持

问题描述 投票:0回答:1

这两天我一直在和 Zend Framework Router 进行斗争,但仍然没有找到解决方案。

现有项目有 2 个不同的模块,它们适用于同一域,例如www.domain1.com:

  • default - 包含公共信息,可以通过 www.domain1.com
  • 访问
  • admin - 管理员界面,可以通过 www.domain1.com/admin
  • 访问

项目是多语言的,为了保留语言代码,它作为每个 URL 的第一个参数进行传输,例如www.domain1.com/en/ www.domain1.com/en/admin

需要处理的部分代码是下一个插件:

class Foo_Plugin_Language extends Zend_Controller_Plugin_Abstract
{

const LANGUAGE_KEY = 'lang';

 public function routeStartup(Zend_Controller_Request_Abstract $request)
{


    $languagesRegexp = implode('|', array_map('preg_quote', $this->_bootstrap->getLanguages()));

    $routeLang = new Zend_Controller_Router_Route(
        ':' . self::LANGUAGE_KEY,
        array(self::LANGUAGE_KEY => $this->_bootstrap->getLanguage()->toString()),
        array(self::LANGUAGE_KEY => $languagesRegexp)
    );

    $router = $this->getFrontController()->getRouter();

    $router->addDefaultRoutes();

    $chainSeparator = '/';

    foreach ($router->getRoutes() as $name => $route) {

        $chain = new Zend_Controller_Router_Route_Chain();
        $chain
            ->chain($routeLang, $chainSeparator)
            ->chain($route, $chainSeparator);

        $new_name = $this->_formatLanguageRoute($name);

        $router->addRoute($new_name, $chain);
    }

    protected function _formatLanguageRoute($name)
    {
        $suffix = '_' . self::LANGUAGE_KEY;
        if (substr($name, -strlen($suffix)) == $suffix) return $name;
        return $name . '_' . self::LANGUAGE_KEY;
    }

public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
    $lang = $request->getParam(self::LANGUAGE_KEY, null);

    $this->_bootstrap->setLanguage($lang);
    $actual_lang = $this->_bootstrap->getLanguage()->toString();

    $router = $this->getFrontController()->getRouter();
    $router->setGlobalParam(self::LANGUAGE_KEY, $lang);

    // Do not redirect image resize requests OR get js, css files
    if (preg_match('/.*\.(jpg|jpeg|gif|png|bmp|js|css)$/i', $request->getPathInfo())) {
        return true;
    }

    // redirect to appropriate language
    if ($lang != $actual_lang) {

        $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');

        $params = array(self::LANGUAGE_KEY => $actual_lang);
        $route = $this->_formatLanguageRoute($router->getCurrentRouteName());

        return $redirector->gotoRouteAndExit($params, $route, false);
    }
}

}

第一个问题是您如何看待这种提供多语言支持的方式。我注意到,所有这些链极大地降低了服务器的运行速度,服务器的响应时间约为 4 秒......

主要问题是:目前我必须实现这样的功能:我有域名 www.domain2.com ,它应该只适用于单个模块,例如“foobar”...它应该可以通过第二个网址访问...或者,当然,默认情况下它应该像 www.domain1.com/en/foobar 一样工作...

为了在 Bootstrap 类中提供此功能,我实现了这部分代码

// Instantiate default module route
$routeDefault = new Zend_Controller_Router_Route_Module(
    array(),
    $front->getDispatcher(),
    $front->getRequest()
);

$foobarHostname = new Zend_Controller_Router_Route_Hostname(
        'www.domain2.com',
        array(
            'module' => 'foobar'
        )
    );

$router->addRoute("foobarHostname", $foobarHostname->chain($routeDefault));

这是行不通的,因为我发现routeDefault总是重写找到正确的模型名称“foobar”,值为“default”

然后我实现了这样的默认路由器:

new Zend_Controller_Router_Route(
        ':controller/:action/*',
        array(
            'controller' => 'index',
            'action' => 'index'
        );

    );

但这仍然不起作用,只有当我在 Foo_Plugin_Language 中评论“routeStartup”方法时才开始没有语言的工作,但是我需要语言支持,我已经玩了很多可能的代码组合,最后使它提供默认语言支持:

class Project_Controller_Router_Route extends Zend_Controller_Router_Route_Module

{ /** * @参数字符串$路径 * @param bool $partial * @返回数组 */ 公共函数匹配($path,$partial = false) { $结果=数组();

    $languageRegexp = '%^\/([a-z]{2})(/.*)%i';

    if (preg_match($languageRegexp, $path, $matches)) {
        $result['lang'] = $matches[1];
        $path = $matches[2];
    }

    $parentMatch = parent::match($path);

    if (is_array($parentMatch)) {
        $result = array_merge($result, $parentMatch);
    }

    return $result;
}

}

因此语言参数像往常一样从路径和常规处理的左侧部分中仔细提取......

但是当我执行下一个代码时,我无法通过 www.domain2.com url 访问 foobar 模块,因为请求中的模块名称始终是“默认”

$front = Zend_Controller_Front::getInstance();

    /** @var Zend_Controller_Router_Rewrite $router */
    $router = $front->getRouter();

    $dispatcher = $front->getDispatcher();
    $request = $front->getRequest();
    $routerDefault = new Project_Controller_Router_Route(array(), $dispatcher, $request);

    $router->removeDefaultRoutes();

    $router->addRoute('default', $routerDefault); 

    $foobarHostname = new Zend_Controller_Router_Route_Hostname(
        'www.domain2.com',
        array(
            'module' => 'foobar'
        )
    );

$router->addRoute("foobar", $foobarHostname->chain($routerDefault));

而不是总结

  • 问题是我应该实现为辅助域提供对 ZendFramework 特定模块的访问的功能,并且我应该保留多语言支持。我找不到办法,如何管理这一切......
  • 第二个问题是关于链式路由器的性能,它使站点工作非常非常慢......
php zend-framework router hostname chain
1个回答
0
投票

我解决多语言页面问题的方法是在这个线程中: 在 Zend 中使用多语言路由器(最后一篇文章)。

当然,我的解决方案需要一些缓存,但我认为它可以解决您的问题。

干杯。

© www.soinside.com 2019 - 2024. All rights reserved.