在PHP中为PDO查询创建容器函数
因为我发现PDO执行非常难以记忆,而且我会回顾以前的项目或其他网站,只是为了记住如何从数据库中选择行,所以我决定尝试创建自己的函数,其中包含PDO执行,并插入所需的数据。虽然看起来比实际情况简单得多 到目前为止,我已经成功地创建了一个connect函数,但是现在当我要创建一个select函数时,我遇到了多种原因。在PHP中为PDO查询创建容器函数,php,mysql,function,pdo,simplify,Php,Mysql,Function,Pdo,Simplify,因为我发现PDO执行非常难以记忆,而且我会回顾以前的项目或其他网站,只是为了记住如何从数据库中选择行,所以我决定尝试创建自己的函数,其中包含PDO执行,并插入所需的数据。虽然看起来比实际情况简单得多 到目前为止,我已经成功地创建了一个connect函数,但是现在当我要创建一个select函数时,我遇到了多种原因。 首先,可以传递到函数中的参数数量可能会不断变化,其次,我无法确定应该传递给函数什么以及传递的顺序 到目前为止,函数看起来是这样的。为了让我保持清醒,我在其中添加了“id”部分,这样我可
首先,可以传递到函数中的参数数量可能会不断变化,其次,我无法确定应该传递给函数什么以及传递的顺序 到目前为止,函数看起来是这样的。为了让我保持清醒,我在其中添加了“id”部分,这样我可以看到在最终结果中我需要完成什么,并在我确定如何完成时被相应的变量替换 到目前为止,我已经确定函数需要做的是
- 连接到数据库(使用另一个函数生成$conn变量,已完成)
- 选择表格
- 指定列
- 提供匹配的输入
- 允许使用可能的参数,例如
按“id”描述排序
其他人已经为你做了这项工作。使用他们的工作,而不是专注于你的应用程序所独有的任何令人敬畏的东西。聪明地工作,不要努力等等。哼。。。IMHO我认为您不应该尝试在函数中包装PDO,因为它们已经在方法中“包装”了。事实上,从面向对象到过程似乎是倒退(或者至少是朝着错误的方向迈出了一步)。PDO是一个很好的库,它有很多方法和特性,如果将它们封装在简单的可重用函数中,那么这些方法和特性肯定会丢失 其中一个功能是BeginTransaction/Rollback(请参阅更多) 无论如何,从OOP的角度来看,您可以通过添加一些简单的方法来修饰PDO对象本身 下面是一个基于函数的示例 注意:此代码未经测试强>
class MyPdo
{
public function __construct($conn)
{
$this->conn = $conn;
}
public function pdo()
{
return $this->conn;
}
public function selectAllById($table, $id = null)
{
$query = 'SELECT * FROM :table';
$params = array('table'=>$table);
if (!is_null($id)) {
$query .= ' WHERE id = :id';
$params['id'] = $id;
}
$r = $this->conn->prepare($query)
->execute($params)
->fetchAll();
//More stuff here to manipulate $r (results)
return $r;
}
public function __call($name, $params)
{
call_user_func_array(array($this->conn, $name), $params);
}
}
注意:此代码未经测试强>
class MyPdo
{
public function __construct($conn)
{
$this->conn = $conn;
}
public function pdo()
{
return $this->conn;
}
public function selectAllById($table, $id = null)
{
$query = 'SELECT * FROM :table';
$params = array('table'=>$table);
if (!is_null($id)) {
$query .= ' WHERE id = :id';
$params['id'] = $id;
}
$r = $this->conn->prepare($query)
->execute($params)
->fetchAll();
//More stuff here to manipulate $r (results)
return $r;
}
public function __call($name, $params)
{
call_user_func_array(array($this->conn, $name), $params);
}
}
奥姆 另一个选项是使用,它可以让您直接与模型/实体交互,而无需费心创建/销毁连接、插入/删除等。。。Doctrine2或spreep是PHP的好选择
然而,ORM比直接使用PDO要复杂得多。编写包装器,应该从连接数据库的表单开始,所有可能的方法都可以包装。将连接传递给查询方法看起来不太好 一个非常粗略的例子是下面的代码,我强烈不建议这种混合,但它会给你方向 您应该从构造函数或从构造函数中调用的另一个方法建立连接,您可以使用以下方法:
public function __construct($driver = NULL, $dbname = NULL, $host = NULL, $user = NULL, $pass = NULL, $port = NULL) {
$driver = $driver ?: $this->_driver;
$dbname = $dbname ?: $this->_dbname;
$host = $host ?: $this->_host;
$user = $user ?: $this->_user;
$pass = $pass ?: $this->_password;
$port = $port ?: $this->_port;
try {
$this->_dbh = new PDO("$driver:host=$host;port=$port;dbname=$dbname", $user, $pass);
$this->_dbh->exec("set names utf8");
} catch(PDOException $e) {
echo $e->getMessage();
}
}
因此,您可以在实例化包装器时传递连接凭据,也可以使用默认凭据
现在,您可以创建一个只接收查询的方法。编写整个查询比传递表和列更合适。它不会形成一个完整的ORM,但只会使代码更难阅读
在我第一次处理PDO时,我希望一切都是动态的,所以我实现了,后来我意识到是不成熟的编码风格,但让我们展示一下
public function query($sql, $unset = null) {
$sth = $this->_dbh->prepare($sql);
if($unset != null) {
if(is_array($unset)) {
foreach ($unset as $val) {
unset($_REQUEST[$val]);
}
}
unset($_REQUEST[$unset]);
}
foreach ($_REQUEST as $key => $value) {
if(is_int($value)) {
$param = PDO::PARAM_INT;
} elseif(is_bool($value)) {
$param = PDO::PARAM_BOOL;
} elseif(is_null($value)) {
$param = PDO::PARAM_NULL;
} elseif(is_string($value)) {
$param = PDO::PARAM_STR;
} else {
$param = FALSE;
}
$sth->bindValue(":$key", $value, $param);
}
$sth->execute();
$result = $sth->fetchAll();
return $result;
}
那么这些意大利面条都有什么作用呢
首先,我想我希望所有的post值都作为参数发送,所以如果我有
input name='user'
input name='password'
我可以做$res=$db->查询(“从username=:user和password=:password的用户中选择id”)代码>
还有塔达!我已经获取了这个查询的结果,$res现在是一个包含结果的数组
后来我发现,如果我有
input name='user'
input name='password'
input name='age'
在相同的表单中,但是查询仍然使用:user
和:password
并且我提交表单,被调用的查询将在绑定参数中提供不匹配,因为foreach与$\u请求数组将绑定3个参数,但在查询中我使用2个
因此,我在方法的开头设置了代码,在这里我可以提供要排除的内容。调用方法,如$res=$db->query(“从username=:user和password=:password的用户中选择id”,“age”)代码>给了我这样做的可能性
它起作用了,但还是不行
最好有一个query()
方法来接收两件事:
- 带有参数名称的SQL字符串
- 参数为数组
因此,您可以对bindValue使用foreach()
逻辑,但不能在超全局数组上使用,而是在传递的数组上使用
然后,您可以包装fetch方法
public function fetch($res, $mode = null)
您不应该直接从查询返回fetch,因为它可能是UPDATE、INSERT或DELETE
只需将$res变量传递给fetch()
方法,以及类似PDO::fetch_ASSOC的模式。可以在fetch ASSOC的位置使用默认值,如果传递其他内容,则使用默认值
不要像我开始时那样抽象。它会让你最近填补裂缝。首先,我不知道你从哪里得到10行
是您需要的所有代码,并且
$stmt = $conn->prepare('SELECT * FROM myTable WHERE id = ?');
$stmt->execute(array($id));
$result = $stmt->fetchAll();