在Zend Framework 2中无法正确解析Route Mit特殊字符 [英] Route mit special characters are not parsed correctly in Zend Framework 2

查看:100
本文介绍了在Zend Framework 2中无法正确解析Route Mit特殊字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

带有德语特殊字符的URI不起作用(错误404).我已经遇到了这个问题( unicode修饰符

URIs with german special characters don't work (error 404). I've already had this problem (here) and it has been resolved with the unicode modifier and a custom view helper, that uses it.

现在我对Segment子路由存在相同的问题,但是这次使用unicode标识符和自定义视图助手的方法不起作用.

Now I have the same issue with a Segment child route, but this time the approach with the unicode identifier and a custom view helper isn't working.

Alle请求(例如sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜßsld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123)以404错误结束.

Alle requests like sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß or sld.tld/sport/sportäöüÄÖÜß/cityäöüÄÖÜß/page/123 are ending with a 404 error.

/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子路线:

I've also tried it with a UnicodeRegex 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'  => '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

请参见此处

UnicodeSegment

扩展Zend\Mvc\Router\Http\Segment并使用u完成所有preg_match(...)呼叫的输入:

Extends Zend\Mvc\Router\Http\Segment and completes the input of ALL preg_match(...) calls with u:

  • '((\G(?P<literal>[^:{\[\]]*)(?P<token>[:{\[\]]|$)))u'
  • '(\G\{(?P<name>[^}]+)\}:?)u'
  • '((\G(?P<name>[^:/{\[\]]+)(?:{(?P<delimiters>[^}]+)})?:?))u'
  • '(\G(?P<literal>[^}]+)\})u'
  • '(\G' . $this->regex . ')u'
  • '(^' . $this->regex . '$)u'

如何使其正常工作?

推荐答案

只看了一下,您需要更改UnicodeRegex match方法,以便它为匹配的url部分返回正确的长度,这是一种尝试修复此问题的方法,至少在您的设置中似乎起作用(至少对我而言)

Just had a look at this, you need to change the UnicodeRegex match method so that it returns the correct length for the part of the url it matched, here's an attempt to fix that, which seems to be working (at least for me) with your setup

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);
} 

这篇关于在Zend Framework 2中无法正确解析Route Mit特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆