有时,根据查看我的页面的用户类型,我需要添加一个JOIN,甚至只是限制结果。是否有更清洁的方式去做?我应该为每种类型的请求单独声明吗?什么更“适当”?
以下是我的代码最终看起来像:
// 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 :(得分:1)
为了清楚起见,可能只需将插入字符串包装到自己的方法中,例如getUserInsertString($user_id)
,并尝试使引用更加一致。
另外,您是否只是通过$user_id
来测试是否定义了$limit
和if ($user_id)
?如果是这样,如果您将错误报告转向所有,则会收到一堆未定义的变量警告。您可能需要考虑使用if (isset($user_id))
。
答案 1 :(得分: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对象表示不同类型的数据库元组,或者在其中一个案例中返回更多行时,我不建议这样做。
我通常做的是创建一个代表(在你的例子中)Document的类。只有一个。我可以插入,删除,选择,修改其字段,并处理一个项目。当我需要(例如)获取更多它们时,我创建了一个新类,例如DocumentList,用于处理文档集合。这个类在获取更多文档对象时会给我一个Document对象数组。