2014-02-03 3 views
3

Я ищу способ сопоставить результаты запросов базы данных Laravel/Eloquent с пользовательскими классами, а не по умолчанию класс Eloquent.Как сопоставить результаты Laravel/Eloquent с пользовательским классом

Имеет ли Laravel/Eloquent какое-либо встроенное средство для этого? Если нет, есть ли подходящее место, чтобы «зацепить» код генерации результата и сделать необходимое сопоставление?

В качестве примера, это примерно то, что я хотел бы достичь:

class User extends Eloquent {} 

class MyUser 
{ 
    protected $name; 

    public function getName() { 
     return $this->name; 
    } 

    public function setName($name) { 
     $this->name = $name; 
     return $this; 
    } 
} 

$users = User::all(); 

// $users should now contain an array of MyUser instances 

Мотивации/Причины вопроса

Мотивации этого вопроса, чтобы найти способ, в котором запрашивает может создавать объекты или массивы объектов, которые полностью независимы от структуры. Это связано с тем, что приложение Laravel, о котором идет речь, должно иметь возможность передавать свои результаты другим системам, отличным от Laravel, поэтому, следовательно, самые обычные объекты PHP (например, MyUser) имеют наибольший смысл.

+0

вы можете получить объекты StdClass путем изменения режима выборки в конфигурации базы данных. Для определенного класса вам придется перезаписать этот класс, из чего я могу сказать '\ vendor \ laravel \ framework \ src \ Illuminate \ Database \ Connection.php' – cecilozaur

ответ

5

Laravel не даст вам что-то подобное, но вы можете сделать с PHP. Внесите свой класс Eloquent User в свой собственный класс, Laravel автоматически добавит его для вас. Используйте объект внутри своего класса по своему усмотрению, и если вам нужно вызвать тот или иной метод Eloquent, вы можете просто предоставить резервные копии объекту «Красноречивый пользователь».

Хороший варианта заключается в использовании хранилища шаблона, где ваш класс будет ожидать, чтобы получить реализацию Репозиторного интерфейса, что вы должны:

Создания интерфейса для хранилища пользователей, всех репозиториев, включая ваша модель Eloquent, должен реализовать этот интерфейс. Это контракт, позволяющий вам переключать реализацию репозитория, когда захотите, без необходимости касаться вашего класса. Это также сделает вашу классовую структуру агностикой.

interface UserRepositoryInterface { 

} 

Ваши реализации этого хранилища может быть:

class EloquentUser extends Eloquent implements UserRepositoryInterface { 

} 

class DoctrineUser extends DoctrineWhatever implements UserRepositoryInterface { 

} 

Создать класс

class User extends Eloquent {} 

class MyUser 
{ 
    protected $name; 

    public function __construct(UserRepositoryInterface $user) 
    { 
     $this->userRepository = $user; 
    } 

    public function __call($name, $arguments) 
    { 
     return call_user_func_array(array($this->userRepository,$name), $arguments); 
    } 

    public static function __callStatic($name, $arguments) 
    { 
     return call_user_func_array(array('User',$name), $arguments); 
    } 

    public function getName() { 
     return $this->userRepository->name; 
    } 

    public function setName($name) { 
     $this->name = $name; 
     return $this; 
    } 
} 

Сейчас в Laravel для выбора реализации вы просто должны

App::bind('UserRepositoryInterface', 'EloquentUser'); 

Чтобы переключиться на учение, вы просто должны

App::bind('UserRepositoryInterface', 'DoctrineUser'); 

И если вам нужно использовать этот класс вне Laravel, вы просто должны создать его экземпляр, передавая все, что реализация хранилища вы хотите:

$user = new MyUser(new DoctrineUser); 

Нет больше связей к Ларавелю.

+1

Я, вероятно, должен был быть более явным, но это важно для этого что класс «MyUser» не должен знать ничего о Laravel или Eloquent. Цель состоит в том, чтобы сделать результаты запросов полностью независимыми от структуры. Полученные объекты должны быть в состоянии свободно передаваться в другие (не-laravel) системы, поэтому по существу они должны быть обычными старыми объектами PHP (POPO!). – coatesap

+0

Получил это. Полностью отредактирован, чтобы показать, как вы это делаете в PHP. –

+0

, вероятно, вы должны отметить это как ответ ... – AndrewMcLagan

0

Я также хотел иметь пользовательский класс для этого предопределенного класса «Пользователь».

class User extends Model implements UserInterface, RemindableInterface { 

к классу UserModel:

class UserModel extends Model implements UserInterface, RemindableInterface { 

Таким образом, вместо взлома через коды и классы, на самом деле есть конфиг для него.

Открыть приложение/Config/auth.php

Убедитесь, что вы измените:

'model' => 'UserModel', // change to UserModel or your custom named class 
'table' => 'User', // change if your table is non default "User" 

Это должно быть хорошо идти.

:)

0

для красноречивых моделей, вы можете воспользоваться ->toArray() методом, то типаж его с помощью (object) получить POPO.

например.

$user = (object) User::find(1)->toArray(); 

print_r($user); 

вы должны получить:

stdClass Object 
(
    [id] => 1 
    [name] => John Doe 
    [email] => [email protected] 
    [active] => 1 
    ... 
    [created_at] => 2017-10-26 17:45:53 
    [updated_at] => 2017-10-26 17:45:53 
    [deleted_at] => 
) 
Смежные вопросы