Welcome Guest, Not a member yet? Register   Sign In
Codeigniter 4 Model set() returns error
#1

Input: Entity Object 
Error returned: "Illegal offset type" on line 685 in \codeigniter4\framework\system\Model.php.

Example:
PHP Code:
        if ((new EquipmentModel)->where('order_id'$order_id)->first()) {
            (new EquipmentModel)->where('order_id'$order_id)->set($equipment)->update();
        } else {
            $equipmentModel->insert($equipment);
        
Reply
#2

Where is the line 685? What is the Entity Object?

The error message shows you are doing wrong to the array key.
Reply
#3

(This post was last modified: 03-27-2024, 11:30 PM by MZahov.)

If I use array not entity it works fine.

This function is inside "vendor\codeigniter4\framework\system\Model.php"

PHP Code:
    /**
    * Captures the builder's set() method so that we can validate the
    * data here. This allows it to be used with any of the other
    * builder methods and still get validated data, like replace.
    *
    * @param array|object|string              $key    Field name, or an array of field/value pairs
    * @param bool|float|int|object|string|null $value  Field value, if $key is a single field
    * @param bool|null                        $escape Whether to escape values
    *
    * @return $this
    */
    public function set($key$value '', ?bool $escape null)
    {
        $data is_array($key) ? $key : [$key => $value]; // This line

        foreach (array_keys($data) as $k) {
            $this->tempData['escape'][$k] = $escape;
        }

        $this->tempData['data'] = array_merge($this->tempData['data'] ?? [], $data);

        return $this;
    
Reply
#4

As you see the first parameter of set() method is:

PHP Code:
@param array|object|string              $key    Field name, or an array of field/value pairs 

So you cannot pass an entity to the set() method.
Reply
#5

(03-28-2024, 12:58 AM)kenjis Wrote: As you see the first parameter of set() method is:

PHP Code:
@param array|object|string              $key    Field name, or an array of field/value pairs 

So you cannot pass an entity to the set() method.

Shouldn't it be the same as BaseBuilder set() function ?

PHP Code:
/**
    * Allows key/value pairs to be set for insert(), update() or replace().
    *
    * @param array|object|string $key    Field name, or an array of field/value pairs
    * @param mixed              $value  Field value, if $key is a single field
    * @param bool|null          $escape Whether to escape values
    *
    * @return $this
    */
    public function set($key$value '', ?bool $escape null)
    {
        $key $this->objectToArray($key); // Object to Array?

        if (! is_array($key)) {
            $key = [$key => $value];
        }

        $escape is_bool($escape) ? $escape $this->db->protectIdentifiers;

        foreach ($key as $k => $v) {
            if ($escape) {
                $bind $this->setBind($k$v$escape);

                $this->QBSet[$this->db->protectIdentifiers($kfalse)] = ":{$bind}:";
            } else {
                $this->QBSet[$this->db->protectIdentifiers($kfalse)] = $v;
            }
        }

        return $this;
    
Reply
#6

Oh, good point! I overlooked "@param object".

If it accept an object, the description "Field name, or an array of field/value pairs" is not correct.
But the current code does not accept an object.
Reply
#7

For other people who encounter use of OBJECT in update() function based on foreign key.

Solution/Transform object to array and use set($array): 

PHP Code:
model()->where('foreign'$foreign)->update(null$entity); 
Reply
#8

I concluded this is a bug.

I sent a PR to fix this bug.
https://github.com/codeigniter4/CodeIgniter4/pull/8670
Reply




Theme © iAndrew 2016 - Forum software by © MyBB