2012-04-05 32 views
1

有时取决于在查看我的页面时使用哪种用户类型,我需要添加一个JOIN,甚至只是限制结果。有没有更简洁的方法去实现它?我应该为每种类型的请求提供单独的语句吗?什么更“适当”?在PDO中使用动态预处理语句

这里是我的代码最终看起来像:

// Prepare statement 
$stmt = $this->db->prepare(' 
    SELECT * 
    FROM Documents 
    LEFT JOIN Notes ON ID = D_ID 
    '.($user_id ? "INNER JOIN Users ON UID = ID AND UID = :userid" : '')." 
    ". ($limit ? 'LIMIT :offset, :limit' : '') 
); 

// Bind optional paramaters 
if ($user_id) $stmt->bindParam(':userid', $user_id, DB::PARAM_INT); 

if ($limit) 
{ 
    $stmt->bindParam(':offset', $limit[0], DB::PARAM_INT); 
    $stmt->bindParam(':limit', $limit[1], DB::PARAM_INT); 
} 

回答

0

我会创建单独的(保护)函数,那些函数返回一个只需要执行的预准备语句。

/** 
* @returns PDOStatement 
*/ 
protected function prepareStatementForCase1(PDO $dbObject,Object $dataToBind){...} 
/** 
* @returns PDOStatement 
*/ 
protected function prepareStatementForCase2(PDO $dbObject,Object $dataToBind){...} 

然后,我会在外面决定,哪一个必须被调用。 您可以更轻松地重建,维护和读取代码。

例子:

class Document{ 
    protected $dbObject; 

    public function __construct(PDO $dbObject){ 
    $this->dbObject=$dbObject; 
    } 
    public function doQuery($paramOne,$paramTwo,...){ 
    $logicalFormulaOne=...; // logical expression here with parameters 
    $logicalFormulaTwo=...; // logical expression here with parameters 
    if($logicalForumlaOne){ 
     $dbStatement=$this->prepareStatementForCase1($dataToBind); 
    }else if($logicalFormuleTwo){ 
     $dbStatement=$this->prepareStatementForCase2($dataToBind); 
    } 
    $dbResult=$dbStatement->execute(); 
    } 
    protected function prepareStatementForCase1(Object $dataToBind){ 
    $dbStatement=$this->dbObject->prepare("query string"); 
    $dbStatement->bindParam(...); 
    return $dbStatement; 
    } 
} 

但我不会建议此,当你PDOResult对象代表不同类型的数据库的元组,或者当你在的情况下,一个返回多个行。

我通常会做的是我创建一个代表(在你的例子中)一个文档的类。只有一个。我可以插入,删除,选择,修改其字段,并处理一个项目。当我需要(例如)获取更多的时候,我创建了一个新的类,例如DocumentList,它处理文档的集合。当这个类获取更多的时候,它会给我一个Document对象的数组。

+0

Dyin的建议,这听起来与dqhendricks所说的类似。你能提供一个例子吗? – 2012-04-06 14:53:40

+0

我改进了我的答案。你应该为这些查询制作单独的类。 – Dyin 2012-04-07 08:24:39

1

也许只是包装插入串到自己的方法为清楚起见,像getUserInsertString($user_id),并尽量使你的引证使用更加一致。

另外,你是否正在测试$user_id$limit只是通过去if ($user_id)定义?如果是这样,如果你有错误报告转向所有,你会得到一堆未定义的变量警告。您可能需要考虑使用if (isset($user_id))

+0

$ user_id和$ limit是函数参数的一部分,我认为这使得isset不必要。我喜欢你关于将连接拼成单独函数 – 2012-04-05 23:54:37