免责声明:除非我没有看到,这与this topic中描述的不同,我需要一些时间来全面解释这种情况。
很久以前我asked a question关于如何在SQLite语句中使用REGEXP运算符。默认情况下不会实现运算符,但它可以在运行时。
嗯..正如你所看到的那些日期,这对我来说已经有好几年了。不完全是在该主题的帮助下(SQLite邮件列表中的某人向我展示了一个技巧)但它运作良好。
因为preg_match()与ereg()的工作方式不同(正如我所听到的),通过在第一次匹配后立即返回,我采取了额外的预防措施,然后通过排序REGEXES来填充SQLite数据库(我确定这个从最长(更具体)到最短(更通用),不是正确的复数形式。
没什么大不了的,只是使用strlen()的简单uasort()。
考虑到一个虚构的电影管理目录,其中有两个网址,例如management/actors
和management/actors/add
,这种排序技巧使我在访问第一个网址时避免误报并让SQLite以第二个响应结果集只是因为它们都具有相同的不可变部分management/actors
这是当前的实施:
$this -> dbh
-> sqliteCreateFunction(
'REGEXP',
function( $r, $s ) {
return ( preg_match( sprintf( '@^%s$@i', $r ), $s ) != 0 );
},
2
);
$ this - > dbh 使用了PDO实例的class属性。
现在情况有所不同,因为这种排序技巧没有考虑一种可能性:最通用的两条路线也是最长的路线。例如:management/actors/add
和management/actors/overview
。
从概念上讲,第二条路线更通用,因为它指的是一个列出所有演员的简单仪表板,应该放在底部。实际上它只是management/actors
的别名。
第二条路线更具体,因为它路由负责的表格添加新记录,因此应该到顶部
这些路由是根据围绕Controller类的PHP文档注释进行分析的,如下所示:
/**
* Overview
*
* !Route GET, management/actors
* !Route GET, management/actors/overview
*/
final public function overview() {}
/**
* Add
*
* !Route GET, management/actors/add
*/
final public function add() {}
按顺序排列:
management/actors
management/actors/overview
management/actors/add
因为我需要识别Action方法,所以它们在不同的数组索引中构造,并且类方法名称为键:
Array(
'overview' => array(
[0] => management/actors
[1] => management/actors/overview
),
'add' => array(
[0] => 'management/actors/add'
)
)
就像我说排序有效并且可以使这个结构成为:
Array(
'overview' => array(
[0] => management/actors/overview
[1] => management/actors
),
'add' => array(
[0] => 'management/actors/add'
)
)
但由于SQLite REGEX运算符的preg_match()实现,整个组件无法工作。
到目前为止,我设法解决此问题的唯一方法是开发像这样的Controller类:
/**
* Add
*
* !Route GET, management/projects/add
*/
final public function add() {}
/**
* Overview
*
* !Route GET, management/projects
* !Route GET, management/projects/overview
*/
final public function overview() {}
我的意思是,顺序相反。
精细!所有应用程序都以某种方式有其自身的奇怪之处,我可以忍受这种情况,但是,将来,其他人可能会打开这些代码并给它一些维护,可能不会意识到这种限制。
那说(最后)我想知道是否有办法增加preg_match()的暴食并使其不会在第一次正面发生时停止并且像ereg那样匹配最长的可能,或者至少我认为它是的,我从来没有看到它在行动。
或者替代解决方案,当然:p
根据评论中的要求,REGEXES的一些示例,按照它们在SQLite数据库中插入的顺序列出(排序后):
management/projects/overview\b(.*?)
management/projects/add\b(.*?)
management/projects\b(.*?)
他们是非常简单的REGEXES。它们主要匹配Request URI。在REGEX的末尾,我只有一个边界来区分固定字符串文本和可能存在的变量部分(如Xdebug剖析GET参数)