简体   繁体   中英

Laravel: Avoid to create instance of a model with a constructor in the controller

I'm following a course for Laravel 4 and the teacher did a code refactoring and introduced a magic method constructor in the controller

class UtentiController extends BaseController {

    protected $utente;

    public function __construct(Utenti $obj) {  
        $this->utente = $obj;
    }

    public function index() {
        $utenti = $this->utente->all();
        return View::make('utenti.index', ["utenti" => $utenti]);
    }

    public function show($username) {
        $utenti = $this->utente->whereusername($username)->first(); //select * from utenti where username = *;
        return View::make('utenti.singolo', ["utenti" => $utenti]);
    }

    public function create() {
        return View::make('utenti.create');
    }


    public function store() {
        if (! $this->utente->Valido( $input = Input::all() ) ) {
            return Redirect::back()->withInput()->withErrors($this->utente->messaggio);
        }

        $this->utente->save();
        return Redirect::route('utenti.index');
    }

}

Thanks to this code I don't have to create a new instance of the Utenti model every time:

protected $utente;
public function __construct(Utenti $obj) {

    $this->utente = $obj;

}

Now I can access the database with this simple approach:

$this->utente->all();

Whereas before, I had to do this:

$utente = new Utente;
$utente::all();

Does this type of technique have a name? (is it a pattern?).

My understanding is that every time the controller is invoked it automatically generates an instance of the User class (model) and applies an alias (reference) attribute $utente

Is that correct?

Also, here is the code for the Utenti model:

class Utenti extends Eloquent {

    public static $regole = [
        "utente" => "required",
        "password" => "required"
    ];

    public $messaggio;

    public $timestamps = false;

    protected $fillable = ['username','password'];

    protected $table = "utenti";

    public function Valido($data) { 
        $validazione = Validator::make($data,static::$regole);

        if ($validazione->passes()) return true;

        $this->messaggio = $validazione->messages();

        return false;
    }
}

This is called dependency injection or short DI. When creating a new instance of the Controller, Laravel checks the constructor for type hinted parameters (The ones that have a type defined like __construct(Utenti $obj){ ) If your controller has any of these Laravel tries to create an instance of the class and injects it into the constructor.

The reason why this is done is that it's becoming very clear what the dependencies of a class (in this case your controller) are. It gets especially interesting if you type hint an Interface instead of a concrete class. You then have to tell Laravel with a binding which implementation of the interface it should inject but you can also easily swap an implementation or mock it for unit testing.

Here are a few links where you can get more information:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM