2

我想在 CakePHP 路由中做以下更改。网站 URL 之后的任何单词或单词组(用连字符分隔),例如example.com/somewordexample.com/some-word应该重定向到controller => posts, action => view. 但我的问题是单词应该是unicode。我已经为 URL 文本尝试了这个正则表达式,但它不起作用。

Router::connect ('/:link', array ('controller' => 'posts', 'action' => 'view'), array ('pass' => array ('link'), 'link' = > '/^['.json_decode('"\u0531"').'-'.json_decode('"\u0587"').'-]+$/u'));

我想提一下,我的正则表达式

'/^['.json_decode('"\u0531"').'-'.json_decode('"\u0587"').'-]+$/u',

如果我要进行一些通常的 preg_match 之类的,那就可以了

$regg = '/^['.json_decode('"\u0531"').'-'.json_decode('"\u0587"').'-]+$/u';
if (preg_match($regg, "my unicode string", $match)) {
  var_dump($match);   // outputs string as expected
}
die;

编辑

我最终得到了这个代码

Router::connect ( '/:link', array ('controller' => 'posts', 'action' => 'view' ), array    ('pass' => array ('link'), 'link' => '((?![a-zA-Z]).)+' ) ); 

就像让我的网址包含除了英文字母之外的所有内容,但这不是我需要的东西,如果我有 2 种或更多不同的语言而不是英语 - 这种方法不起作用。因此,我想将每种语言的单词发送到单独的操作中。

蛋糕版本 2.x

编辑 2

有替代解决方案,如下面的答案,绕过这个问题,但我正在寻找做我需要的确切方法。

谢谢

4

2 回答 2

0

http://en.wikipedia.org/wiki/Query_stringURL encoding段落中,您不能在 url 查询字符串上使用这些字符:

特别是,对查询字符串进行编码使用以下规则:

  • 字母(A-Z 和 a-z)、数字 (0-9) 和字符 '.'、'-'、'~' 和 '_' 保持原样
  • SPACE 编码为 '+' 或 "%20" [8]
  • 所有其他字符都编码为 %HH 十六进制表示,任何非 ASCII 字符首先编码为 UTF-8(或其他指定编码)

如果您有两种(或更多)语言,您可以考虑在帖子表中为每种语言添加一个 slug 字段,例如英语和俄语:

帖子

  • ID
  • title_eng
  • title_rus
  • slug_eng
  • slug_rus

在 Post.php beforeValidate 或 beforeSave 上:

if(isset($this->data['Post']['title_eng'])){
    $this->data['Post']['slug_eng'] = Inflector::slug(strtolower($this->data['Post']['title_eng']), '-');
}
if(isset($this->data['Post']['title_rus'])){
    $this->data['Post']['slug_rus'] = Inflector::slug(strtolower($this->data['Post']['title_rus']), '-');
}

视图内的链接:

echo $this->Html->link($post['Post']['title_eng'], array('controller' => 'posts', 'action' => 'view', 'slug_eng' => $post['Post']['slug_eng']));
echo $this->Html->link($post['Post']['title_rus'], array('controller' => 'posts', 'action' => 'view', 'slug_rus' => $post['Post']['slug_rus']));    

路线:

Router::connect('/posts/:slug_eng', array('controller' => 'posts','action' => 'view', 'eng'), array('pass' => array('slug_eng'), 'slug_eng' => '[a-zA-Z0-9]+'));
Router::connect('/ru/posts/:slug_rus', array('controller' => 'posts','action' => 'view', 'rus'), array('pass' => array('slug_rus'), 'slug_rus' => '[a-zA-Z0-9]+'));

控制器帖子:

public function view($locale, $slug){
    ....
    validate and sanitize here
    ...
    $post = $this->Post->find('first', array('conditions' => array('slug_' . $locale => $slug)));
    ....
}
于 2013-11-19T17:50:33.330 回答
0

我建议使用通配符

Router::connect('/*', array('controller' => 'posts', 'action' => 'view'));

可以在此行之前添加任何其他路线,例如

Router::connect('/:digits', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('digits'), 'digits' => '/d+');
Router::connect('/*', array('controller' => 'posts', 'action' => 'view'));
于 2013-11-19T23:24:16.793 回答