CodeIgniter Forums
Custom Result Objects & Setter - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: CodeIgniter 4 (https://forum.codeigniter.com/forumdisplay.php?fid=28)
+--- Forum: CodeIgniter 4 Support (https://forum.codeigniter.com/forumdisplay.php?fid=30)
+--- Thread: Custom Result Objects & Setter (/showthread.php?tid=88770)



Custom Result Objects & Setter - Fabien72 - 11-03-2023

Hi, I started to use CI4 three days ago and today I'm facing a problem with "Custom Result Objects". Here is the class of my custom object :

PHP Code:
class Transaction
{
    protected int $id;
    protected string $name;
    protected float $amount;

    public function __get($key)
    {
        if (property_exists($this$key)) {
            return $this->{$key};
        }
    }

    public function __set($key$value)
    {
        if (property_exists($this$key)) {
            $this->{$key} = $value;
        }
    }


The problem is when I'm using the function "getCustomResultObject" the "__set" method is never called, attributes are directly updated. Indeed, I tried to modify the setter to update my attributes using the $key & $value variables to do some operations, but the setter is never called. That is strange because I saw in the documentation :

Quote:The object will have all values returned from the database set as properties. If these have been declared and are non-public then you should provide a __set() method to allow them to be set.

And indeed if I remove the "__set" method, I get a error message "Cannot access protected property App\Entities\Transaction::$name". So the __set method is necessary to update the "protected" attributes, but the method is never used. So is it a bug, or I missed something ?

Thanks for your help.


RE: Custom Result Objects & Setter - kenjis - 11-03-2023

Why do you think __set() is not called?


RE: Custom Result Objects & Setter - ozornick - 11-03-2023

If you have "protected $name" properties declared, they are automatically filled with values. 
When there is no property, __set() is executed. BUT, you re-check the declaration of the property (they are already filled in). property_exists() is unnecessary.

PHP Code:
// Class
class Notify {
    protected $id$user_id$title$is_read;

    public function __set($name$value)
    {
        $this->{$name} = $value;

        return $this;
    }
}
// Select result
$notify $model->builder()->limit(1)->get()->getCustomResultObject(Notify::class);
// Output
array:[
  0 
=> App\Controllers\Notify {#199 ▼
    #id: "5"
    #user_id: "1"
    #title: "New Message"
    #is_read: "yes"
    +"body""New post created!"
    +"created_at""2023-11-01 20:18:43"
  }




RE: Custom Result Objects & Setter - kenjis - 11-03-2023

(11-03-2023, 10:26 PM)ozornick Wrote: If you have "protected $name" properties declared, they are automatically filled with values. 

What do you mean by automatically? How?
See https://3v4l.org/FZSap


RE: Custom Result Objects & Setter - ozornick - 11-04-2023

See https://www.php.net/manual/en/mysqli-result.fetch-object.php
Mysqli creates an object a little differently. As Reflection?
Props id, user_id, title, is_read not calling __set(). body, created_at run __set(). What did I say wrong?

PHP Code:
    // Setter
    public function __set($name$value)
    {
        echo $name PHP_EOL;

        $this->{$name} = $value;

        return $this;
    }
    
    
// Contains row: id, user_id, title, is_read, body, created_at
    $notify model(NotificationModel::class)->builder()->limit(1)->get()->getCustomResultObject(Notify::class);

    // Output
    body created_at

 
array:[
  0 
=> App\Controllers\Notify {#199 ▼
    #id: "5"
    #user_id: "1"
    #title: "New Message"
    #is_read: "yes"
    +"body""New post created!"
    +"created_at""2023-11-01 20:18:43"
  }




RE: Custom Result Objects & Setter - Fabien72 - 11-05-2023

Thanks guys