使用foreach进行动态表选择

时间:2011-06-13 15:20:33

标签: php mysql pdo kohana

我使用kohana并且我有这个模型使用PDO从数据库中检索搜索结果:

class Model_Crud extends Model_Database {

  private $tables=array('articles','comments','pages');

  public function get_search_results()
  {
    $query = DB::query(Database::SELECT, 'SELECT * FROM :table WHERE ( title LIKE :search OR body LIKE :search OR tag LIKE :search)');
    $query->param(':search', $_POST['search'] );
    $query->bind(':table', $table );

    foreach($this->tables as $table)
    {
       //echo $query;
       $result[] = $query->execute();
    }

    return $result;
  }
} 

这不会起作用,因为sql语句将以最终形式出现:

SELECT * FROM 'articles' WHERE ( title LIKE 'a random string' OR body LIKE 'a random string' OR tag LIKE 'a random string')

并且自然会失败,因为文章应该超出'

可以这样做吗? 或者我需要写3个不同的查询,每个表一个?

2 个答案:

答案 0 :(得分:1)

是的,只需将表名直接放入字符串中,而不是作为参数:

class Model_Crud extends Model_Database {

  private $tables=array('articles','comments','pages');

  public function get_search_results()
  {
    foreach($this->tables as $table)
    {
       $query = DB::query(Database::SELECT, 'SELECT * FROM ' . $table . ' WHERE ( title LIKE :search OR body LIKE :search OR tag LIKE :search)');
       $query->param(':search', $_POST['search'] );

       //echo $query;
       $result[] = $query->execute();
    }

    return $result;
  }
} 

正常情况下,由于SQL注入,这不是一个好主意,但由于表的列表已编码到您的程序中,因此在这种情况下您不必担心这一点。

答案 1 :(得分:1)

看一下Database_Query类,看起来你不能在不为每个表创建单独的查询的情况下完成所需的工作。

可以使用set_table方法扩展Database_Query类,该方法可翻译:table

更好的是,您可以稍微抽象一下这个概念,并添加新的方法来翻译的参数进行消毒。看看Database_Query::compile,了解它是如何完成的。 (这一点都不难。)