【问题标题】:codeigniter is returning database row considered oopcodeigniter 正在返回被视为 oop 的数据库行
【发布时间】:2014-04-15 05:35:51
【问题描述】:

我正在使用 Codeigniter 3.0 查询生成器,我的问题是,当我的模型返回用户时,我正在返回数据库行。不是对象 - 它的标准对象但不是尝试对象 - 这与 oop 实践有关吗?

我的身份验证模型很简单

class user extend CI_MODEL{

funciton attempt($user,$pass){

//do validation and fetch user and compare pass etc...

$query = $this->db->get_where('users',$where);

return $query->result() //now this is my line of question

}

}

所以我认为这与 oop 无关? - 还是我错了? - 它只是使用类进行组织的程序代码!。

那么 oop 方式的正确方法是什么?

我浏览了许多用于 codeigntier 的 auth 库,看看他们是如何做到的,我所看到的只是他们将用户行保存到模型中的数组变量中。然而所有用户仍然只有 1 个用户对象。

我是否应该为user 对象创建一个抽象类/接口,并在每次获取用户之前将数据库行传递给它,然后再将它们保存到我的 Big ci_model 中?

如果是这样,这在 codeigniter 中可行吗?我会把这个抽象类放在哪里?

【问题讨论】:

    标签: php mysql codeigniter database-design crud


    【解决方案1】:

    我做过类似的事情,是的,我创建了一个 model_row 类,以 array_walk 样式传递所有数据:

    if ($qry = $this->db->get()) {
      $res = $qry->result();
    
      return $this->_instantiateRows($res);
    }
    

    函数_instantiateRows():

    /**
       * Get the row class name
       * Checks if a class exists with the model name _Row
       * @return string
       */
      private function _getRowClass() {
        $modelName = get_class($this);
        return class_exists($modelName.'_Row') ? $modelName.'_Row' : 'Model_Row';
      }
    
      /**
       * Formats results into model row classes
       * @param array $results
       * @return array
       */
      protected function _instantiateRows($results) {
        $rowClass = $this->_getRowClass();
        $self = $this;
    
        array_walk($results,function(&$row,$k) use ($rowClass, $self) {
          $row = new $rowClass($row,$self,$k);
        });
    
        return $results;
      }
    

    然后是一个行类:

    /**
     * Model row class
     * Acts as a baseclass and a fallback class for database rows
     * Implements standard methods, for saving, getting the ID, and setting field
     * values.
     * @property $_model MY_Model
     * @property $_key Original Array key
     * @property $_ID_FIELD name of the id field
     */
    class Model_Row
    {
      protected $_isNew = True;
      protected $_model = False;
      protected $_key = False;
      protected $_ID_FIELD = 'id';
      protected $_ID_ORIGINAL = False;
    
      /**
       * C'tor
       * Sets up the object with data from the row
       * @param object $data
       * @param object $model
       * @param int $key
       * @param string $id_field
       */
      public function __construct($data,$model,$key=False) {
        $this->_key = $key;
    
        // If no key is specified then it must be new / Not from database
        if ($this->_key !== False)
          $this->_isNew = False;
    
        $data = (array)$data;
        $this->_model = $model;
        $this->_ID_FIELD = $model->idField;
    
        $this->set($data);
    
        // Ensure ID Field is set.
        $idF = $this->_ID_FIELD;
        if (!isset($this->$idF))
          $this->$idF = null;
      }
    
      /**
       * Get the ID field
       * ID Field could be named differently for each model, this is an easy
       * shortcut to it.
       * @param string $setTo - set the id to this value
       * @return string
       */
      public function id($setTo=False) {
        $idF = $this->_ID_FIELD;
    
        if ($setTo !== False) {
          if ($this->_ID_ORIGINAL === False && !$this->_isNew)
            $this->_ID_ORIGINAL = $this->$idF;
    
          $this->set($idF,$setTo);
        }
    
        return $this->$idF !== null ? (string)$this->$idF : False;
      }
    
      /**
       * Save this row
       * @return bool
       */
      public function save() {
        $wheres = array();
    
        if (!$this->_isNew) {
          $idF = $this->_ID_FIELD;
          $wheres[$idF] = $this->_ID_ORIGINAL ?: $this->id();
        }
    
        $res = $this->_model->set($this,$wheres);
    
        if ($this->id() === False)
          $this->id($this->_model->insertID());
    
        // Reset the original id field
        $this->_ID_ORIGINAL = False;
        $this->_isNew = False;
    
        if ($res)
          return $this;
    
        return False;
      }
    
      /**
       * Set object properties
       * can be passed by array field => value
       * @param mixed $field
       * @param mixed $value
       * @return null
       */
      public function set($field,$value=False) {
        if ((is_array($field) || is_object($field)) && $value === False) {
          if (is_object($field))
            $field = (array)$field;
    
          foreach($field as $f => $v)
            $this->set($f,$v);
        }
        else {
          if (method_exists($this, 'set_'.$field))
            call_user_func(array($this,'set_'.$field), $value);
          else
            $this->$field = $value;
        }
      }
    }
    

    _getRowClass 的重点是检查一个名为 model_name_row 的类是否存在,然后将数据实例化到该类,否则回退到基类 model_row

    你的模型还需要一些其他的东西,因为行类将传递给模型,所以你的模型需要一个 public $idField='id' ,然后这个函数对你的模型很有用:

    /**
       * Create a new record using the model row class
       * @param mixed $data
       * @return Model_Row
       */
      public function newRow($data=array()) {
        $rowClass = $this->_getRowClass();
        return new $rowClass($data,$this);
      }
    

    所以你可以做$newRow = $this->Model->newRow($data)这将创建一个新行,然后可以调用$newRow->save()和其他方法如果设置...

    * 编辑

    还要指出,我在行类上使用$this->_model->set($this, $wheres),这是因为我定义了一个带有公共设置器的基类:

    /**
       * Setter
       * @param mixed $data object or array
       * @param mixed $wheres object or array query
       * @return bool
       */
      public function set($data,$wheres=array()) {
        if (!$this->checkTableSet())
          return False;
    
        if (empty($wheres)) {
          return $this->db->insert($this->table,$data);
        }
        else {
          $this->db->where($wheres);
          return $this->db->update($this->table,$data);
        }
      }
    

    $this->table 是带有表名的模型变量,例如protected $table='users'; 和函数 checkTableSet() 只是检查 this 是否已设置且不为空..

    【讨论】:

      猜你喜欢
      • 2019-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-15
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多