@sprashivatel

Как доработать проверку?

На данный момент выглядит так:
private $data = []; // тут храним свойства
private $save = []; // тут храним изменённые свойства
public function __set($name, $value)
{
    if ($this->{$name}) {
        $this->save[$name] = $value;
    } else {
        $this->data[$name] = $value;
    }
}

Пример 1:
$unit = Units::findOneById(111);
 $unit->name = 'test';
 var_dump($unit);

private 'data' (core\base\Model) => 
    array (size=9)
      'id' => int 111
      'name' => string 'Гарпун' (length=12)
      'user_lvl' => int 188
      'type' => string 'ground' (length=6)
      'kind' => string 'baks' (length=4)
      'attack' => int 190
      'defense' => int 170
      'maintenance' => int 2600
      'price' => int 310000
  private 'save' (core\base\Model) => 
    array (size=1)
      'name' => string 'test' (length=4)

Изменённое свойство попало в save[].

Пример 2
$unit = new Units();
$unit->name = 'test';
var_dump($unit);

private 'data' (core\base\Model) => 
    array (size=1)
      'name' => string 'test' (length=4)
  private 'save' (core\base\Model) => 
    array (size=0)
      empty

Изменённое (создаваемое) свойство попадает в data[], нужно чтобы попадало в save[].
Что можно сделать, проверка по наличию id не получается что-то:
public function __set($name, $value)
{
    if ($this->{$name} or !$this->id) {
        $this->save[$name] = $value;
    } else {
        $this->data[$name] = $value;
    }
}

Всё всегда в save[] попадает, data[] пустой.
  • Вопрос задан
  • 112 просмотров
Решения вопроса 1
@sprashivatel Автор вопроса
private $data = [];
private $save = [];
public function __set($name, $value)
{
    if ($this->{$name}) {
        $this->save[$name] = $value;
    } else {
        $this->data[$name] = $value;
    }
}

public function save()
{
    $par = [];
    $val = [];
    foreach ($this->id ? $this->save : $this->data as $k => $v) {
        $par[] = $k . ' = ?';
        $val[] = $v;
    }
    if ($this->id) {
        Db::query('update ' . static::table() . ' set ' . implode(', ', $par) . ' where id = ' . $this->id, $val, static::class);
    } else {
        Db::query('insert into ' . static::table() . ' set ' . implode(', ', $par), $val, static::class);
        $this->id = Db::lastInsertId();
    }
}

Гори оно гаром.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
nokimaro
@nokimaro Куратор тега PHP
Жаль что автор не представляет сколько ему ещё предстоит пройти пути, чтобы в итоге написать вменяемый ActiveRecord класс.
Но для понимания масштабов, могу посоветовать ознакомиться с таковым, например в Yii2 -

$changedAttributes
https://github.com/yiisoft/yii2/blob/5ee7fabbf948f...

Там есть все ответы и на текущий вопрос, и на вчерашний про магию __set и на все будущие.

По существу вопроса, изучите класс в частности места где встречается строчка _oldAttributes, changedAttributes, dirtyAttributes
Ответ написан
@FanatPHP
Чебуратор тега PHP
Можно дурацкий вопрос? Если тебе надо чтобы в массив попадали только измененные значения, может быть, так и написать в условии?
if ($this->{$name} !== $value) {
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
09 апр. 2020, в 01:27
1000 руб./за проект
08 апр. 2020, в 22:52
5000 руб./за проект
08 апр. 2020, в 21:19
10000 руб./за проект