pass FILTER_SANITIZE_STRING

2019-03-04 23:10发布

问题:

I have a this query:

$query="select * from news where news_id = (select max(news_id) from news where news_id< $id)";

for execute I use class. in this class

public function query($query) 
{
  $this->_query = filter_var($query, FILTER_SANITIZE_STRING);
  $stmt = $this->_prepareQuery();
  $stmt->execute();
  $results = $this->_dynamicBindResults($stmt);
  return $results;
}

Is there any way that < signal is not filtered?

回答1:

This is utterly wrong way of running queries.
FILTER_SANITIZE_STRING has absolutely nothing to do with SQL.

You have to use SQL-specific routines when building an SQL query.

First of all, you should be aware of the difference between query and data.
While query should remain intact, data have to be formated according to some rules.

your current implementation of query function is wrong.
if it's general purpose function, to run all types of query, you have to implement some placeholders to represent your data in the query. A function like this

function paraQuery()
{
    $args  = func_get_args();
    $query = array_shift($args);
    $query = str_replace("%s","'%s'",$query); 

    foreach ($args as $key => $val)
    {
        $args[$key] = $this->mysqli->real_escape_string($val);
    }

    $query  = vsprintf($query, $args);
    $result = $this->mysqli->query($query);
    if (!$result)
    {
        throw new Exception($this->mysqli->error()." [$query]");
    }
    return $result;
}

so, you'll be able to run it this way

$query = "select * from news where news_id = (select max(news_id) from news where news_id<%d)";
$result = $db->paraQuery($query, $id);