Путаница с объектом-компаньоном после использования Laravel factory () -> create () - PullRequest
0 голосов
/ 30 августа 2018

Я получаю странные результаты при сравнении объекта, возвращенного методом factory () -> create (). Приведенный ниже php artinan tinker paste показывает, что я испытываю.

>>> $game1 = factory(App\Game::class)->create();
=> App\Game {#2909
     title: "Macey Rogahn",
     image_location: "Julio Hoppe/fake/path/image.img",
     updated_at: "2018-08-29 02:45:40",
     created_at: "2018-08-29 02:45:40",
     id: 10,
   }
>>> $game2 = App\Game::first();
=> App\Game {#2906
     id: 10,
     created_at: "2018-08-29 02:45:40",
     updated_at: "2018-08-29 02:45:40",
     title: "Macey Rogahn",
     image_location: "Julio Hoppe/fake/path/image.img",
   }
>>> $game1 == $game2
=> false

Я не понимаю, почему этот результат неверен. Значения равны, но php возвращает false при сравнении. Это также вызывает у меня проблемы с использованием Collection-> diff () во время тестирования. Я только средний в PHP, кто-нибудь может объяснить это поведение?

1 Ответ

0 голосов
/ 30 августа 2018

Даже оба объекта ссылаются на одну и ту же модель предметной области, в которой они создаются по-разному, и поэтому, с точки зрения PHP, они являются разными объектами.

Вы можете легко заметить это, посмотрев на выход тинкера. Даже у обоих есть свойство id со значением 10, они имеют разные идентификаторы объектов PHP (# 2909 и # 2906)

Когда вы звоните App\Game::first(), Eloquent подключается к базе данных, извлекает данные, создает новый объект , а затем гидратирует (заполняет) свойства объекта значениями базы данных. Поскольку вы (ну, в общем, Eloquent) создаете новый объект, это не тот же экземпляр.

Когда вы сравниваете объекты (==), PHP не знает, что они являются моделями Eloquent, а просто обычными объектами PHP, и они не указывают на одну и ту же область памяти.

Если вы хотите сравнить равенство моделей, вы должны сравнить их ID или создать определенную логику в вашей базовой модели, например

// file: App/Model.php
abstract class Model extends Eloquent {

    public function isSameAs(\App\Model $model):bool {
        return $this->id !== null and $this->id === $model->id;
    }
}

// file: App/Game.php
class Game extends Model {

}

Вы могли бы сделать

$game1->isSameAs($game2);

Обратите внимание, что я использовал isSameAs() вместо isEqualTo() намеренно, потому что вы не сравниваете каждое свойство моделей и, следовательно, даже если они имеют одинаковый идентификатор, они могут быть не равными моделям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...