3

我想保留在生产和开发环境中不同的端口号,但是基于我的 zend 路由调用 url 助手会忘记端口号。

我的路由是一堆正则表达式路由,与默认主机名路由链接,主要用于多域配置上的多语言(下面的简短概述)。

<?php
    $routecateg = new Zend_Controller_Router_Route_Regex('cat/(\w+)_([^_]+)(?:_page_(\d+))?(?:_par_(\d+))?(?:.html)?',
    array(1 =>'',2=>'',3=>'1',4=>'20','controller' =>'list','action'=>'categ'),
    array(1 =>'categid',2=>'categname',3=>'page',4=>'par'),
    'cat/%s_%s_page_%d_par_%d.html'
);

$routeindex= new Zend_Controller_Router_Route_Regex('(index|home)?',
    array('controller' =>'index','action'=>'home'),
    array(),
    'index'
);    

$hostRouteRepository = new Zend_Controller_Router_Route_Hostname(
    ':lang.'.$config->serverurl
);
$router ->addRoute('index',$hostRouteRepository->chain($routeindex));
$router ->addRoute('categ',$hostRouteRepository->chain($routecateg));
?>

其中 $config->serverurl 只是取决于环境并在我的 application.ini 文件中配置的域名。

在我的生产服务器上,没关系,因为我在默认端口 80 上运行,但是在开发网中,我需要在不同的端口上运行,并且每次我调用我的 url 助手时,端口号都被遗忘了。

我知道我可以通过更好地配置我的 apache 服务器来解决问题,但我很惊讶没有找到任何解决此问题的方法。

4

1 回答 1

2

这是我发现的:

如果你将类似 ':lang.example.com:8888' 或 ':lang.example.com:port' 的内容传递给 Zend_Controller_Router_Route_Hostname 的构造函数,端口部分将不会被正确解析(com:8888 或 com:port) . 这是因为字符串以 '.' 展开。字符并且 hostVariable 字符 (':') 仅在构造中分解的部分的第一个字符上检查:

foreach (explode('.', $route) as $pos => $part) {
            if (substr($part, 0, 1) == $this->_hostVariable) {
                $name = substr($part, 1);
                $this->_parts[$pos] = (isset($reqs[$name]) ? $reqs[$name]
                                       : $this->_defaultRegex);
                $this->_variables[$pos] = $name;
            } else {
                $this->_parts[$pos] = $part;
                $this->_staticCount++;
            }
        }

现在,在路由匹配函数(function match($request))中,端口号从请求中被丢弃,这将阻止有效请求匹配路由:

// Get the host and remove unnecessary port information
    $host = $request->getHttpHost();
    if (preg_match('#:\d+$#', $host, $result) === 1) {
        $host = substr($host, 0, -strlen($result[0]));
    }

我相信有 3 种不同的方法可以解决您的问题:

  1. 在 config.ini 文件中添加一个端口号选项并将其注册到 Zend_Registry,如下所示: Zend_Registry::set('PORT_NUMBER', $this->getOption('portnumber'));
  2. 修复函数 match($request) 中的代码以保留端口号(注释掉上面显示的代码应该可以)
  3. 修复构造函数中的代码以允许路由的 ':port' 参数化(您可能希望在设置路由时使用必需值或默认值)

注意:解决方案 2 似乎比 3 更容易,但需要一些额外的工作,因为端口号将由 assemble 函数进行 urlencoded:

foreach (array_reverse($host, true) as $key => $value) {
        if ($flag || !isset($this->_variables[$key]) || $value !== $this->getDefault($this->_variables[$key]) || $partial) {
            if ($encode) $value = urlencode($value);
            $return = '.' . $value . $return;

            $flag = true;
        }
    }

解决方案 3 不应该发生这种情况,因为端口号是一个变量。

希望有帮助。

于 2010-02-12T02:37:13.700 回答