我正在编写一个数据库查询管理器类。在我的类表中,前缀的特征是#__
。我想用函数将它们替换为表前缀。
我写的功能运作良好,但速度很慢。我想要一个优化的功能(可能是正则表达式或其他解决方案)。
注意:请记住#__
不应该用引号替换。
示例:
SELECT p.*, m.member_name, m.member_alias
FROM #__posts AS p
LEFT JOIN #__members AS m ON m.member_id=p.post_author
WHERE p.post_approve = '1' AND p.post_date <= '1438252218'
OR
INSERT INTO `#__posts` (`post_title`, `post_text`)
VALUES ('post title (maybe include #__ )' , 'post text. it also can include #__')
我的职能:
protected function replace_prefix($sql, $prefix = '#__')
{
$done = null;
$single = false;
$double = false;
$found = false;
$i = 0;
while (strlen($sql) > 0)
{
if ($sql[$i] == null)
{
return $done.$sql;
}
if (($sql[$i] == "'") && $sql[$i-1] !='\\')
{
$single = !$single;
}
if (($sql[$i] == '"') && $sql[$i-1] !='\\')
{
$double = !$double;
}
if ($sql[$i] == $prefix[0] && !$single && !$double)
{
$found = true;
for ($j=0; $j < strlen($prefix); $j++)
{
if ($sql[$i+$j] != $prefix[$j])
{
$found = false;
break;
}
}
}
if ($found)
{
$done .= substr($sql, 0, $i).$this->prefix;
$sql = substr($sql, $i+$j);
$found = false;
$i = 0;
}
else
{
$i++;
}
if ($i >= strlen($sql))
{
return $done.$sql;
}
}
return $done;
}
答案 0 :(得分:2)
最后我找到了一个好方法!这个功能比旧功能快30倍:
protected function replace_prefix($sql, $prefix = '#__')
{
$array = array();
if($number = preg_match_all( '#((?<![\\\])[\'"])((?:.(?!(?<![\\\])\1))*.?)\1#i', $sql, $matches))
{
for ($i = 0; $i < $number; $i++)
{
if (!empty($matches[0][$i]))
{
$array[$i] = trim($matches[0][$i]);
$sql = str_replace($matches[0][$i], '<#encode:'.$i.':code#>', $sql);
}
}
}
$sql = str_replace($prefix, $this->prefix , $sql);
foreach ($array as $key => $js)
{
$sql = str_replace('<#encode:'.$key.':code#>', $js, $sql);
}
return $sql;
}
答案 1 :(得分:1)
你知道桌子的名字吗?例如,如果您有一个表#__Contacts
,则可以执行以下操作:
$sql2 = str_replace( $prefix . $table, $new_prefix . $table, $sql );
如果您使用replace_prefix()
方法进行琐碎的查询(不是复杂的查询),它应该可以解决问题。