链接方法 - 如果函数被调用多次,则不要覆盖值


Chaining method - don't override value if the function is called more then once

我正在尝试重新创建类似于CodeIgniter活动记录的东西。我的目标如下:

当这被称为:

echo $messages->select()->from()->where('user', 'foo')->where('dateadded', 'today');

它需要创建两个 where 传导(WHERE 用户 = foo 和日期添加 = 今天)。但目前我只得到第二个函数的值,称为(WHERE dateadd = today)。我该怎么做?

这是我到目前为止的代码:

abstract class DatabaseQuery extends Database
{
    protected $_tablename;
    protected $_primary_key = 'id';
    protected $_dbSelect    = '';
    protected $_dbFrom      = '';
    protected $_dbJoin      = '';
    protected $_dbWhere     = '';
    function __construct()
    {
        parent::__construct();
    }
    public function __toString()
    {
        $query = '';
        $query .= $this->_dbSelect . PHP_EOL;
        $query .= $this->_dbFrom . PHP_EOL;
        $query .= $this->_dbJoin . PHP_EOL;
        $query .= $this->_dbWhere . PHP_EOL;
        return $query;
    }
    public function select($select = null)
    {
        if($select === null):
            $this->_dbSelect = "SELECT *";
        else:
            $this->_dbSelect = "SELECT {$select}";
        endif;
        return $this;
    }
    public function from($from = null)
    {
        if($from === null):
            $this->_dbFrom = "FROM {$this->_tablename}";
        else:
            $this->_dbFrom = "FROM {$from}";
        endif;
        return $this;
    }
    public function join($table, $on)
    {
        if(is_string($join))
            $this->_dbJoin = "JOIN {$table} ON {$on}";
        return $this;
    }
    public function where($field, $value = null)
    {
        if(!is_array($field)):
            $this->_dbWhere = "WHERE " . $field . ' = :' . $value;
        else:
            $where = 'WHERE ';
            foreach($field as $key => $value):
                $where .= $key . ' = :' . $key . ' AND ';
            endforeach;
            $this->_dbWhere = rtrim($where, ' AND ');
        endif;
        return $this;
    }

你需要某种触发器来在最后运行查询

$messages->select()->from()->where('user', 'foo')->where('dateadded', 'today')->get();

例如,您可以在触发器中平滑事情

<?php
class QueryBuilder{
    private $_dbWhere;
    public function where($field, $value = null)
    {
        if(!is_array($field)):
            $this->_dbWhere .= $field . ' = :' . $value . ' AND ';
        else:
            foreach($field as $key => $value):
                $this->_dbWhere .= $key . ' = :' . $key . ' AND ';
            endforeach;
        endif;
        return $this;
    }
    // your trigger this will get the result for the class user
    public function get()
    {
        // smooth things up (remove last AND ) 
        $this->_dbWhere = " WHERE " . rtrim($this->_dbWhere, ' AND ');
        // build the query select . from . where
        // and return the result (in this case print _dbWhere)
        echo $this->_dbWhere;
    }
}

这将起作用

$db = new QueryBuilder;
$db->where('user', 'foo')->where('dateadded', 'today')->get();  

但是,您试图重新发明轮子,那里有大量漂亮的查询构建器,请查看Laravel's Query Builder以获得一些灵感

这会满足您的需求吗?

 public function where($field, $value = null)
    {
        if(this->_dbWhere == ''){
              $this->_dbWhere .= "WHERE ";
        } else {
               $this->_dbWhere .= " AND ";
        }
        if(!is_array($field)){
            $this->_dbWhere =  . $field . ' = :' . $value;
        }else{
            foreach($field as $key => $value):
                $where .= $key . ' = :' . $key . ' AND ';
            endforeach;
            $this->_dbWhere = rtrim($where, ' AND ');
        }
        return $this;
    }