Php 我怎样才能消除过去的一切;“限制”;从一个问题?(内载详情)

Php 我怎样才能消除过去的一切;“限制”;从一个问题?(内载详情),php,Php,我得到了一些由脚本动态生成的查询。它们通常符合以下模板: SELECT ... FROM ... JOIN ... WHERE ... (lots of filters, search conditions, etc. here) ... ORDER BY (optional) ... LIMIT (optional) ... OFFSET (optional) 我想从查询中删除限制和偏移部分。我曾经 $sql_entitati = implode("LIMIT", explode(

我得到了一些由脚本动态生成的查询。它们通常符合以下模板:

SELECT ... 
FROM ... 
JOIN ... 
WHERE ... (lots of filters, search conditions, etc. here) ... 
ORDER BY (optional) ... 
LIMIT (optional) ... OFFSET (optional)
我想从查询中删除限制和偏移部分。我曾经

$sql_entitati = implode("LIMIT", explode("LIMIT", $sql_entitati, -1));
但是我突然想到:如果查询中没有限制,如果唯一的限制是where子句中的某个地方,该怎么办

所以我的问题是:如果where子句中没有限制和/或某个地方有“限制”,我如何安全地删除LIMIT关键字之后的所有内容而不把它搞砸?所有这些都是在php中完成的

为了清晰起见,进行了一些编辑:

我使用的算法是:

$sql = implode("LIMIT", explode("LIMIT", $sql, -1));
将处理99%的案例。当末尾的“LIMIT”关键字丢失,并且条件中的某个地方写有“LIMIT”时,就会出现问题。例如:

 SELECT * FROM table WHERE bla = 'SPEED LIMIT' ORDER BY table.a
这是我需要解决的问题

使用以下算法求解(归功于techfoobar):


获取限制的位置,检查它是否存在==FALSE然后是子字符串

$str = "SELECT X FROM Y JOIN WHERE CONDITIONS ORDER BY ORDERS LIMIT OFFSET";

$pos = strrpos($str,"LIMIT");
if ($pos!==false)
{
$newStr = substr($str,0,$pos);
echo $newStr;
}

获取限制的位置,检查它是否存在==FALSE然后是子字符串

$str = "SELECT X FROM Y JOIN WHERE CONDITIONS ORDER BY ORDERS LIMIT OFFSET";

$pos = strrpos($str,"LIMIT");
if ($pos!==false)
{
$newStr = substr($str,0,$pos);
echo $newStr;
}
试试这个

$query = '';
$query .= 'SELECT...';
$query .= 'FROM ...';
$query .= 'JOIN ...';
$query .= 'WHERE...';
if ($limit)
{
    $query .= " LIMIT $limit";
}
试试这个

$query = '';
$query .= 'SELECT...';
$query .= 'FROM ...';
$query .= 'JOIN ...';
$query .= 'WHERE...';
if ($limit)
{
    $query .= " LIMIT $limit";
}

你应该这样做:

  • 获取最后一个“限制”的位置-将此位置存储在例如,
    p
  • 确保在
    p
    之后没有
    ””
    字符-如果是,则它是条件等内部查询的一部分
  • 确保在
    p
    之后没有
    “'”
    字符-如果是,则它是某些用户输入字符串的一部分
  • 如果第2步和第3步通过,则去掉
    p
  • 更多提示:

    • 对于步骤1-使用
      strrpos
      查看上次出现的
      LIMIT
    • 对于步骤2和步骤3,使用
      strpos
      p
      作为搜索开始偏移量
    • 对于步骤4,使用
      substr
      去除
      p

    您应该执行以下操作:

  • 获取最后一个“限制”的位置-将此位置存储在例如,
    p
  • 确保在
    p
    之后没有
    ””
    字符-如果是,则它是条件等内部查询的一部分
  • 确保在
    p
    之后没有
    “'”
    字符-如果是,则它是某些用户输入字符串的一部分
  • 如果第2步和第3步通过,则去掉
    p
  • 更多提示:

    • 对于步骤1-使用
      strrpos
      查看上次出现的
      LIMIT
    • 对于步骤2和步骤3,使用
      strpos
      p
      作为搜索开始偏移量
    • 对于步骤4,使用
      substr
      去除
      p
      • 这可能会帮助您

        $str = " SELECT * FROM table WHERE bla = 'SPEED LIMIT' ORDER BY table.a";
        
        $pos = strrpos($str,"LIMIT");
        if ($pos!==false)
        {
            $ok = 1;
            if(substr_count($str, '"', $pos) % 2 != 0)
            {
                $ok = 0;
            }
            if(substr_count($str, "'", $pos) % 2 != 0)
            {
                $ok = 0;
            }
        
            if(substr_count($str, ")", $pos) > 0)
            {
                $ok = 0;
            }
        
        
        
            if($ok == 1)
            $str = substr($str,0,$pos);
        }
        
        echo $str;
        
        这可能会帮助你

        $str = " SELECT * FROM table WHERE bla = 'SPEED LIMIT' ORDER BY table.a";
        
        $pos = strrpos($str,"LIMIT");
        if ($pos!==false)
        {
            $ok = 1;
            if(substr_count($str, '"', $pos) % 2 != 0)
            {
                $ok = 0;
            }
            if(substr_count($str, "'", $pos) % 2 != 0)
            {
                $ok = 0;
            }
        
            if(substr_count($str, ")", $pos) > 0)
            {
                $ok = 0;
            }
        
        
        
            if($ok == 1)
            $str = substr($str,0,$pos);
        }
        
        echo $str;
        

        我确实想到了这一点(我现在就是这样实现的),但它不是100%防错的。问题是“条件”可以包含用户输入,并且可能包含单词限制。这就是我使用内爆/爆炸结构的原因,因为这样我可以抓住所有东西直到最后一个极限。但是,如果查询不包含LIMIT关键字,并且条件确实包含“LIMIT”,则算法将失败,查询将变得不可用。抱歉,是的,使用strrpos将查找LIMITEDIT的最后一次出现:抱歉,没有看到您的上一次注释。我将使用您的strrpos想法,因为它比我正在使用的内爆/爆炸更快。另一种方法可能是更改您的动态查询,以便它们总是向查询添加限制,对于那些您不希望有任何限制的查询,您可以将限制设置为0,我确实想到了这一点(我现在就是这样实现的),但它不是100%防错的。问题是“条件”可以包含用户输入,并且可能包含单词限制。这就是我使用内爆/爆炸结构的原因,因为这样我可以抓住所有东西直到最后一个极限。但是,如果查询不包含LIMIT关键字,并且条件确实包含“LIMIT”,则算法将失败,查询将变得不可用。抱歉,是的,使用strrpos将查找LIMITEDIT的最后一次出现:抱歉,没有看到您的上一次注释。我将使用您的strrpos想法,因为它比我正在使用的内爆/爆炸更快。另一种方法可能是更改您的动态查询,以便它们总是向查询添加限制,对于那些您不希望有任何限制的查询,您可以将限制设置为0,是的,这就是我正在寻找的。“我没想过要找“)”和“”,一直在想关键词,但没有一个有效,因为WHERE之后的所有内容都是可选的。你还应该在“.”的同时检查“.”是的,这就是我要找的。我没想过要找“)”和“.”“,一直在考虑关键词,但都不起作用,因为WHERE之后的所有内容都是可选的。您还应该检查“%”和“%”。