PHP中的链接方法

时间:2014-11-02 19:32:30

标签: php

$db->select("users")->where(array("username", "=", "username"));
$db->update("users", array("username" => "username", "password" => "12345"))->where(array("id", "=", "14"));

好的,我想编写上面的语句,将where()方法链接到select,update和delete。 我的问题是;如何确定我是否在where之前使用了select,update或delete,因此我可以将正确的值绑定到正确的语句中。

我想要这样的事情:

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;
}

2 个答案:

答案 0 :(得分:2)

你必须保持这种状态。这并不是要说明之前的通话是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中存储状态,直到某些最终方法调用实际上是对组合查询进行规避。

答案 1 :(得分:1)

类似的东西:

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([...])都会产生结果,甚至允许扩展语法以使用{{1}多次像:

where()