php - codeigniter 正在返回被认为是 oop 的数据库行

标签 php mysql codeigniter database-design crud

我正在使用 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/

相关文章:

php - PHP 中的 MySQL 位值不起作用

php - 如何将PHP排序替换为SQL?

mysql - 为快速导入而调整的数据库转储

php - 使用 Codeigniter 上传多张图片,仅将一个文件路径保存到 MySQL 数据库

php - zend 验证多选框

php - Symfony2 FOSUserBundle 无法更新 Doctrine 数据库模式或清除缓存

mysql - 如何保持数据库中某些实体的更新(差异)

mysql - 在这种情况下如何更新多列

codeigniter - 登山扣 : cache path does not exist. 请在 config/carabiner.php 中设置缓存路径

php - Bootstrap 完整日历不适用于日选项卡