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

时间:2014-12-11 17:57:00

标签: php oop

我正在尝试重新创建类似于CodeIgniter活动记录的内容。我的目标是:

调用时:

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

它需要创建两个导航(WHERE user = foo和dateadded = today)。但目前我只得到第二个函数的值(WHERE dateadded = 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;

    }

2 个答案:

答案 0 :(得分:1)

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

$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来获得灵感

答案 1 :(得分:0)

这会满足您的需求吗?

 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;

    }