【问题标题】:Dirty Methods in Rails equivalent in PHP CodeignitorRails 中的脏方法等效于 PHP Codeigniter
【发布时间】:2019-08-19 04:49:13
【问题描述】:

我是 PHP 和Codeigniter 的新手,但需要在 PHP 中进行某种实现。

下面是dirty methods默认提供在rails框架中,这里person是模型对象,代表persons表中的行。

person.name = 'Bob'
person.changed?       # => true
person.name_changed?  # => true
person.name_changed?(from: nil, to: "Bob") # => true
person.name_was       # => nil
person.name_change    # => [nil, "Bob"]
person.name = 'Bill'
person.name_change    # => [nil, "Bill"]

我对@9​​87654326@和from特别感兴趣,请建议是否可以通过任何方式。

【问题讨论】:

    标签: php mysql codeigniter phpmyadmin


    【解决方案1】:

    如果您考虑使用 Laravel 的 elquent 框架,那么您已经拥有很多这样的功能。

    Laravel Eloquent update just if changes have been made

    它保存模型中“原始”值的数组,如果其中任何一个已更改,它将提交到数据库。

    它们还带有许多可以插入的事件(beforeSave、afterSave、beforeCreate、afterCreate、验证规则等),并且它们可以轻松扩展。它可能是我能想象到的您正在寻找的最兼容的东西。

    但这不是 codeigniter,它依赖于不同的框架。如果您对 codeigniter 没有死心,您可以考虑根据需要切换到 Laravel 或 OctoberCMS 等框架。

    编辑因为你被 codeigniter 卡住了

    您可能希望使用这样的库:https://github.com/yidas/codeigniter-model

    使用一些自定义缓存机制很容易扩展。

    您可以将以下代码用作您自己的模型实现的基础。

    它有一个非常粗略的逻辑基础,但允许您检查脏状态并回滚对模型所做的任何更改。

    请注意,这是非常粗略的,甚至可能包含一些错误,因为我没有运行此代码。它更像是一种概念证明,可帮助您创建适合您需求的模型。

    class User extends CI_Model 
    {
    
         public $table = 'users';
    
         public $primaryKey = 'id';
    
         public $attributes;
    
         public $original;
    
         public $dirty = [];
    
         public $exists = false;
    
         function __construct() 
         {
             parent::Model();
    
         }
    
         public static function find($model_id) 
         {
             $static = new static;
             $query = $static->db->query("SELECT * FROM ' . $static->getTable() . ' WHERE ' . $this->getKeyName() . ' = ?", [$model_id]);
             if($result->num_rows()) {
                $static->fill($query->row_array());
                $static->exists = true;
             }
             else {
                 return null;
             }
             return $static;
         }
    
         public function getKeyName() 
         {
             return $this->primaryKey;   
         }
    
         public function getKey() 
         {
            return $this->getAttribute($this->getKeyName());  
         }
    
         public function getTable()
         {
             return $this->table;
         }
    
         public function fill($attributes) 
         {
             if(is_null($this->original)) {
                 $this->original = $attributes;
                 $this->dirty = $attributes;
             }
             else {
                 foreach($attributes as $key => $value) {
                     if($this->original[$key] != $value) {
                         $this->dirty[$key] = $value;
                     }
                 }
             }
             $this->attributes = $attributes;
         }
    
         public function reset() 
         {
             $this->dirty = [];
             $this->attributes = $this->original;
         }
    
         public function getAttribute($attribute_name) 
         {
            return array_key_exists($attribute_name, $this->attributes) ? $this->attributes[$attribute_name] : null;    
         }
    
         public function __get($key) 
         {
            return $this->getAttribute($key);    
         }
    
         public function __set($key, $value)
         {
             $this->setAttribute($key, $value);
         }
    
         public function setAttribute($key, $value) 
         {
             if(array_key_exists($key, $this->original)) {
                 if($this->original[$key] !== $value) {
                    $this->dirty[$key] = $value;
                 }
             }
             else {
                 $this->original[$key] = $value;
                 $this->dirty[$key] = $value;
             }
    
             $this->attributes[$key] = $value;
         }
    
         public function getDirty() 
         {
            return $this->dirty;    
         }
    
         public function isDirty() 
         {
            return (bool)count($this->dirty);    
         }
    
         public function save() 
         {
             if($this->isDirty()) {
                 if($this->exists) 
                 {
                     $this->db->where($this->getKeyName(), $this->getKey());
                     $this->db->update($this->getTable(), $this->getDirty());
    
                     $this->dirty = [];
                     $this->original = $this->attributes;
                 }
                 else 
                 {
                     $this->db->insert($this->getTable(), $this->getDirty());
    
                     $this->dirty = [];
                     $this->original = $this->attributes;
    
                     $this->attributes[$this->getKeyName()] = $this->db->insert_id();
                     $this->original[$this->getKeyName()] = $this->getKey();
                     $this->exists = true;
                 }
    
             }
         }
     }
    
     if($user = User::find(1)) {
          $user->name = "Johnny Bravo";
          $user->save();
     }
    

    【讨论】:

    • 比起任何 php 框架,我肯定会更喜欢 rails,但我对现有的应用程序有要求,它是在代码点火器上。
    • 除了同情我还能说什么。我将编辑我的答案以添加一些 codeigniter 魔法。
    • 检查是否可能使用start_cachestop_cache 之前和之后在MyModel 中检查$this->db->update,如果可能,以后可能会得到更改..
    • @ray 我更新了我的答案。如果它更适合您的需求,您可以看看它吗?记下脏变量,这将允许您检查自上次从数据库中获取以来模型中的更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 2018-08-29
    • 2011-04-26
    • 2010-11-11
    • 2012-01-14
    • 2023-03-24
    相关资源
    最近更新 更多