CakePHP为unicode路由正则表达式

时间:2012-11-17 18:45:25

标签: regex cakephp unicode routes

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

  

Router :: connect('/:link',array('controller'=&gt;'posts','action'=&gt;'view'),array('pass'=&gt; array('link') ),'link'=&gt;'/^ ['。json_decode('\\ 05205​​'')。' - '。json_decode('\¥05. *')。' - '+ $ / u')); < / p>

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

'/^['.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]).)+' ) ); 

喜欢让我的网址包含所有内容,但包含英文字母,但这不是我需要的东西,如果我有两种或更多不同的语言而不是英文 - 这种方法不起作用。所以,我希望将每种语言的单词分别发送到单独的行动中。

cake version 2.x

编辑2

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

由于

2 个答案:

答案 0 :(得分:0)

http://en.wikipedia.org/wiki/Query_string 网址编码段落中,您无法在网址查询字符串中使用这些字符:

  

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

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

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

帖子

  • ID
  • title_eng
  • title_rus
  • slug_eng
  • slug_rus

在AfterValidate之前的Post.php或之前保存:

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

答案 1 :(得分: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'));