2016-01-14 16 views
5

DomandaPHP Tipo Hinting Attuazione del metodo astratto - Pattern Repository

E 'possibile ottenere il completamento del codice fila all'interno PhpStorm utilizzando un modello/modello repository?

mio Setup

Sto usando laravel e attuazione del modello di repository, come descritto in un video Laracasts.

Il Codice

Ecco un esempio di base di come i modelli funzionano all'interno laravel e come sembra impossibile per ottenere il completamento del codice per gli attributi del modello.

Questo codice funziona e stampa "billy" come dovrebbe, tuttavia l'attributo $ name non è di tipo suggerito e non verrà completato dal codice all'interno di PhpStorm. Il tipo di suggerimento sta dando la priorità al tipo di definizione dell'attributo padre piuttosto che al bambino, il che mi sembra strano.

<?php 

// Models 
abstract class Model { 
    public $sqlTableName; 

    public function findFromDatabase($id) 
    { 
     $model = new $this; 

     // This would be grabbed using table name and $id 
     $fakeDatabaseRow = ['name' => 'billy', 'job' => 'engineer']; 

     foreach ($fakeDatabaseRow as $column => $value) { 
      $model->$column = $value; 
     } 

     return $model; 
    } 
} 

class User extends Model { 
    public $name; 
    public $job; 

    public $sqlTableName = 'users'; 
} 

// Repositories 
abstract class RepositoryBase { 
    /** 
    * @var Model 
    */ 
    public $model; 

    public function find($id) 
    { 
     $this->model = $this->model->findFromDatabase(1); 

     return $this->model; 
    } 
} 

class UserRepository extends RepositoryBase { 
    /** 
    * @var User 
    */ 
    public $model; 

    public function __construct(User $model) 
    { 
     $this->model = $model; 
    } 
} 

// Run 
$model = new User(); 

$userRepository = new UserRepository($model); 

echo $userRepository->find(1)->name; 

una correzione Ugly

L'unico realmente per ottenere il completamento del codice sembra essere a ri-definire la funzione bambino con un nuovo blocco php doc:

class UserRepository extends RepositoryBase { 
    /** 
    * @var User 
    */ 
    public $model; 

    public function __construct(User $model) 
    { 
     $this->model = $model; 
    } 

    // I need to replace this function for every different repository 
    // even though they are all the same 
    /** 
    * @param $id 
    * @return User 
    */ 
    public function find($id) 
    { 
     return parent::find($id); 
    } 
} 

Tuttavia ho centinaia di modelli, repository e funzioni di repository. Sarebbe un enorme lavoro riscrivere tutte le funzioni all'interno di ciascuna implementazione.

C'è un modo per far sì che PhpStorm usi la dichiarazione di tipo hint del bambino piuttosto che i genitori senza dover ripetere il metodo?

+0

Prova '@ method' in PHPDoc per la classe. – LazyOne

+0

@LazyOne - Funziona se aggiungo '@method User find ($ id)' al docblock UserRepository. Tuttavia, ciò significa che avrei bisogno di farlo per ogni repository e per ogni funzione che restituisce un modello. – magnito

+0

'¯ \\ _ (ツ) _/¯' 1) almeno non lo dichiari nuovamente 2) Non conosco altro modo 3) forse il plugin di supporto di Laravel può farlo (nel caso non lo avessi ancora installato) – LazyOne

risposta

2

Non sono riuscito a trovare una soluzione per ottenere il suggerimento di tipo corretto con il modello e gli archivi nel contesto in cui ho inserito questa domanda in origine.


compromessa Soluzione

Dopo ulteriore studio dei repository e modelli php MVC sono arrivato alla conclusione di utilizzare le funzioni più specifiche e dettagliate repository.


il modo sbagliato

Per esempio, stavo usando funzioni base del repository dentro i miei controllori/classi di logica come questo:

$users = 
    $userRepository->where('created_at', '<', '2016-01-18 19:21:20')->where(
      'permission_level', 
      'admin' 
     )->orderBy('created_at')->get('id'); 

$posts = 
    $postRepository->where('posted_on', '<', '2016-01-18 19:21:20') 
     ->where('content', '!=', 'null') 
     ->chunk(
      function ($posts) { 
       // do things 
      } 
     ); 

nel modo giusto

Ora codice funzioni logiche database separato per tutti i miei bisogni all'interno dei repository specifici, quindi le mie classi di base/controller finire per assomigliare a questo:

$users = $userRepository->getAdminIdsCreatedBeforeDate('2016-01-18 19:21:20'); 
$posts = $postRepository->chunkFilledPostsBeforeDate('2016-01-18 19:21:20', function() {}); 

In questo modo tutta la logica del database viene spostato nella repository specifico e posso digitare suggerimento per i suoi modelli restituiti. Questa metodologia si traduce anche in un codice di lettura più semplice e più pulito e separa ulteriormente la logica di base da Eloquent.

0

È possibile utilizzare la parola chiave abstract per scaricare l'implementazione di un metodo.

abstract class Model { 
    abstract public function find($id); 
} 

che forza qualsiasi modello che estende l'oggetto a implementare tale funzione.

Spero che abbia senso.

Problemi correlati