Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
716 views
in Technique[技术] by (71.8m points)

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

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

enter image description here

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' => 'CatalogControllerCatalog',
                    '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' => 'CatalogControllerCatalog',
                            'action'     => 'list-sports',
                        ),
                    ),
                    'may_terminate' => true,
                    'child_routes' => array(
                    // ...
                    ),
                ),
            ),
        ),
    ),
),
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 ZendMvcRouterHttpRegex). 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...