URIs with german special characters don't work (error 404) in Zend Framework 2

跟風遠走 提交于 2019-11-27 07:22:18

问题


I want to get a list of cities, where each city name is linked and refers a page for this city:

The links (created in the view script) look like this:

http://project.loc/catalog/Berlin (in the HTML source code url-encoded: Berlin)
http://project.loc/catalog/Erlangen (in the HTML source code url-encoded: Erlangen)
http://project.loc/catalog/Nürnberg (in the HTML source code url-encoded: N%C3%BCrnberg)

"Berlin", "Erlangen" etc. work, but if the city name contains a german special character (ä, ö, ü, Ä, Ö, Ü, or ß) like "Nürnberg", a 404 error occurs:

A 404 error occurred Page not found. The requested URL could not be matched by routing. No Exception available

Why? And how to get this working?

Thanks in advance!

EDIT:

My router settings:

'router' => array(
    'routes' => array(
        'catalog' => array(
            'type'  => 'literal',
            'options' => array(
                'route' => '/catalog',
                'defaults' => array(
                    'controller' => 'Catalog\Controller\Catalog',
                    'action'     => 'list-cities',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'city' => array(
                    'type'  => 'segment',
                    'options' => array(
                        'route' => '/:city',
                        'constraints' => array(
                            'city'  => '[a-zA-ZäöüÄÖÜß0-9_-]*',
                        ),
                        'defaults' => array(
                            'controller' => 'Catalog\Controller\Catalog',
                            'action'     => 'list-sports',
                        ),
                    ),
                    'may_terminate' => true,
                    'child_routes' => array(
                    // ...
                    ),
                ),
            ),
        ),
    ),
),

回答1:


You need to change your constraints, you can use a regular expression which will match UTF8 characters, something like this:

'/[\p{L}]+/u'

Notice the /u modifier (unicode).

EDIT:

The problem is resolved.

Explanation:

The RegEx Route maches the URIs with preg_match(...) (line 116 or 118 of Zend\Mvc\Router\Http\Regex). In order to mach a string with "special chars" (128+) one must pass the pattern modifier u to preg_match(...). Like this:

$thisRegex = '/catalog/(?<city>[\p{L}]*)';
$regexStr = '(^' . $thisRegex . '$)u'; // <-- here
$path = '/catalog/Nürnberg';
$matches = array();
preg_match($regexStr, $path, $matches);

And since RegEx Route passes a url-enccoded string to preg_match(...), it's furthermode needed to decode the string first:

$thisRegex = '/catalog/(?<city>[\p{L}]*)';
$regexStr = '(^' . $thisRegex . '$)u';
$path = rawurldecode('/catalog/N%C3%BCrnberg');
$matches = array();
preg_match($regexStr, $path, $matches);

These two steps are not provided in the RegEx Route, so that preg_match(...) gets a steing like '/catalog/N%C3%BCrnberg' and tries to mach it to a regex like '/catalog/(?<city>[\\p{L}]*)/u'

The solution is to use a custom RegEx Route. Here is an example.



来源:https://stackoverflow.com/questions/15634913/uris-with-german-special-characters-dont-work-error-404-in-zend-framework-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!