php - 在 Zend Framework 2 中无法正确解析包含特殊字符的路由

标签 php zend-framework2 http-status-code-404 zend-route zend-router

带有德语特殊字符的 URI 不起作用(错误 404)。我已经遇到过这个问题( here ),并且已通过 unicode modifier 解决了和一个custom view helper ,使用它。

现在我对 Segment 有同样的问题子路由,但这次使用 unicode 标识符和自定义 View 助手的方法不起作用。

所有请求如 sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜßsld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123404 结尾错误。

/module/Catalog/config/module.config.php

<?php
return array(
    ...
    'router' => array(
        'routes' => array(
            'catalog' => array(
                ...
            ),
            'city' => array(
                ...
            ),
            // works correctly, if I remove the child route
            'sport' => array(
                'type'  => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
                'options' => array(
                    'regex' => '/catalog/(?<city>[\p{L}\p{Zs}]*)/(?<sport>[\p{L}\p{Zs}]*)',
                    'defaults' => array(
                        'controller' => 'Catalog\Controller\Catalog',
                        'action'     => 'list-courses',
                    ),
                    'spec'  => '/catalog/%city%/%sport%',
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'courses' => array(
                        'type'  => 'segment',
                        'options' => array(
                            'route' => '[/page/:page]',
                            'defaults' => array(
                                'controller' => 'Catalog\Controller\Catalog',
                                'action'     => 'list-courses',
                            ),
                        ),
                        'may_terminate' => true,
                    ),
                )
            ),
        ),
    ),
    ...
);

我也尝试过 UnicodeRegex子路线:

        'sport' => array(
            'type'  => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
            'options' => array(
                'regex' => '/catalog/(?<city>[\p{L}\p{Zs}]*)/(?<sport>[\p{L}\p{Zs}]*)',
                'defaults' => array(
                    'controller' => 'Catalog\Controller\Catalog',
                    'action'     => 'list-courses',
                ),
                'spec'  => '/catalog/%city%/%sport%',
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'courses' => array(
                    'type'  => 'MyNamespace\Mvc\Router\Http\UnicodeRegex',
                    'options' => array(
                        'regex' => '/page/(?<page>[\p{N}]*)',
                        'defaults' => array(
                            'controller' => 'Catalog\Controller\Catalog',
                            'action'     => 'list-courses',
                        ),
                        'spec'  => '/page/%page%',
                    ),
                    'may_terminate' => true,
                ),
            )
        ),

UnicodeRegex

参见here

UnicodeSegment

扩展Zend\Mvc\Router\Http\Segment并完成ALL preg_match(...)的输入调用 u :

如何让它工作?

最佳答案

刚刚看了一下,您需要更改 UnicodeRegex 匹配方法,以便它返回匹配的 url 部分的正确长度,这里尝试修复该问题,这似乎使用您的设置(至少对我来说)

public function match(Request $request, $pathOffset = null)
{
    if (!method_exists($request, 'getUri')) {
        return null;
    }

    $uri  = $request->getUri();
    $path = rawurldecode($uri->getPath());

    if ($pathOffset !== null) {
        $result = preg_match('(\G' . $this->regex . ')u', $path, $matches, null, $pathOffset);
    } else {
        $result = preg_match('(^' . $this->regex . '$)u', $path, $matches);
    }

    if (!$result) {
        return null;
    }

    foreach ($matches as $key => $value) {
        if (is_numeric($key) || is_int($key) || $value === '') {
            unset($matches[$key]);
        } else {
            $matches[$key] = rawurldecode($value);
        }
    }

    // at this point there's a mismatch between the length of the rawurlencoded path
    // that all other route helpers use, so we need to match their expectations
    // to do that we build the matched part from the spec, using the matched params 
    $url = $this->spec;
    $mergedParams = array_merge($this->defaults, $matches);
    foreach ($mergedParams as $key => $value) {
        $spec = '%' . $key . '%';
        if (strpos($url, $spec) !== false) {
            $url = str_replace($spec, rawurlencode($value), $url);
        }
    }
    // make sure the url we built from spec exists in the original uri path
    if (false === strpos($uri->getPath(), $url)) {
        return null;
    }
    // now we can get the matchedLength
    $matchedLength = strlen($url);

    return new RouteMatch($mergedParams, $matchedLength);
} 

关于php - 在 Zend Framework 2 中无法正确解析包含特殊字符的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16097053/

相关文章:

jsf - 自定义错误页面 - 获取最初请求的 URL

javascript - 没有插件的 wordpress 横幅 slider

php - Doctrine2 + ZF2 - 迭代子类别

json - i18next 加载 json 报错(404 Not Found)

php - 跨数据库连接学说

php - 从 Zend Framework 2 在 mysql 中插入 BIT 列

asp.net - 用于错误处理和丢失图像的 HttpModule

php .htaccess url重写不正确的参数

php - 从数据库中提取信息并将其显示在 HTML div 中

PHP - 如何在提交后隐藏表单