2

ドイツ語の特殊文字を含む URI は機能しません (エラー 404)。私はすでにこの問題 ( here ) を抱えており、それを使用するunicode 修飾子カスタム ビュー ヘルパーで解決されました。

現在、子ルートで同じ問題が発生していますSegmentが、今回は、Unicode 識別子とカスタム ビュー ヘルパーを使用したアプローチが機能していません。

sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜßなどのすべてのリクエストがエラーsld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123で終了してい404ます。

/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,
                ),
            )
        ),

Unicode正規表現

ここを参照

Unicodeセグメント

Zend\Mvc\Router\Http\SegmentALLpreg_match(...)呼び出しの入力を次のように拡張して完成させuます。

それを機能させる方法は?

4

1 に答える 1

3

これを見ただけで、一致したURLの部分の正しい長さを返すように一致メソッドを変更する必要があります。UnicodeRegexこれを修正する試みがあり、(少なくとも私にとっては)あなたの設定

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);
} 
于 2013-04-19T09:31:04.270 に答える