$db->select("users")->where(array("username", "=", "username"));
$db->update("users", array("username" => "username", "password" => "12345"))->where(array("id", "=", "14"));
好的,我想通过将where((方法链接到选择,更新和删除来编写像上面这样的语句。我的问题是;如何确定我是否在 where 之前使用了选择、更新或删除,以便我可以将正确的值绑定到正确的语句上。
我想要这样的东西:
public function where() {
if($this->select()) {
// so if $db->select("users")->where(array("username", "=", "username"));
// save the where data in the select variable.
}
elseif($this->update()) {
// so if $db->update("users", array("username" => "username", "password" => "12345"))->where(array("id", "=", "14"));
// save the where data in the update variable.
}
elseif($this->delete()) {
// so if $db->delete("users")->where(array("username", "=", "username"));
// save the where data in the delete variable.
}
}
但是上面的代码当然是无效的,而且我没有使用任何框架。
public function select($table, $what = null) {
$what == null ? $what = "*" : $what;
$this->_select = "SELECT {$what} FROM {$table}";
return $this;
}
您必须保持该状态。这不是要判断之前的电话是select()
还是update()
,这是思考问题的错误方式。你只需要select
/update
/delete
中的每一个来修改$this
,这样$this
,总是知道它正在构建什么样的查询。
一个死的简单例子:
public function select() {
$this->kind == 'select';
return $this;
}
public function where() {
if ($this->kind == 'select') {
...
return $this;
}
链式方法共享的唯一内容是它们各自返回$this
,以便后续方法可以链接到末尾。这一切都是关于在$this
中存储状态,直到某个最终方法调用实际评估建立的查询。
像这样:
public function select($table, $fields = '*')
{
$this->query = "SELECT {$fields} FROM `{$table}`";
return $this;
}
public function where($conditions = [])
{
if ($this->query)
{
if ($conditions)
{
foreach ($conditions as $key => &$val)
$val = "`{$key}` = '{$val}'";
$this->query .= ' WHERE ' . implode(' AND ', $conditions);
}
$db->query($this->query);
$this->query = '';
return $this;
}
}
这将起作用,但是,您必须注意,此结构将允许您执行以下操作:
$db->where();
这是完全有效的,即使直接在数据库中调用where()
也没有意义。
此外,不需要 WHERE
子句的查询不会运行,因为只有where()
实际进行调用。
如何解决这个问题?
我们实际上可以使用一个非常有趣的 OOP 机制:析构函数方法。PHP 在对象不再使用后立即销毁它们,我们可以在这里探索此功能作为运行查询的触发器。我们只需要将查询分离到一个新对象。
class dbQuery
{
private $db;
private $conditions = [];
function where($conditions = [])
{
$this->conditions = array_merge($this->conditions, $conditions);
return $this;
}
function __construct($db, $query)
{
$this->db = $db;
$this->query = $query;
}
function __destruct()
{
if ($this->conditions)
{
foreach ($this->conditions as $key => &$val)
$val = "`{$key}` = '{$val}'";
$this->query .= ' WHERE ' . implode(' AND ', $this->conditions);
}
$this->db->result = $db->query($this->query);
}
}
class Database
{
public $result = null;
protected static $instance;
function __construct()
{
if (!self::$instance)
self::$instance = new mysqli('localhost', 'user', 'password', 'dbname');
}
public function query($query)
{
return self::$instance->query($query);
}
public function select($table, $fields = '*')
{
return new dbQuery($this, "SELECT {$fields} FROM `{$table}`");
}
}
这样$db->where()
就不起作用,因为它不存在,使用 $db->select('table')
或 $db->select('table')->where([...])
都会给出结果,甚至允许扩展语法以多次使用 where()
,例如:
$db->select('table')->where(['id' => 100])->where(['price' => 1.99]);