我正在使用 Codeigniter 3.0 查询生成器,我的问题是每当我的模型返回一个用户时,我都会返回一个数据库行。不是对象 - 它是 stdobject 但不是 try 对象 - 这与 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
对象创建一个抽象类/接口(interface),并在每次获取用户之前将数据库行传递给它,然后再将它们保存到我的 Big ci_model 中?
如果可以,这在 codeigniter 中可行吗?我应该把这个抽象类放在哪里?
最佳答案
我做过这样的事情,是的,我创建了一个 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
的类(如果存在),然后将数据实例化到该类,否则回退到基类 模型行
你的模型还需要一些其他的东西,因为行类将传递给模型,所以你的模型需要一个 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)
,这是因为我定义了一个带有公共(public) setter 的基类:
/**
* 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()
只是检查它是否已设置且不为空..
关于php - codeigniter 正在返回被认为是 oop 的数据库行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22328577/