SamC Posted February 11, 2019 Share Posted February 11, 2019 Still not sure whether 'dev talk' means talk about just PW or anything else?! Anyway, been working with Laravel for a bit now but still a bit confused about a certain thing. For example: namespace App\Http\Controllers; // Bring Project model into namepsace use App\Project; class ProjectsController extends Controller { /** * Save new project */ public function store() { $project = new Project(); // <<<<<< NEW OBJECT $project->title = request('title'); $project->description = request('description'); $project->save(); // A GET request by default return redirect('/projects'); } } ... but I've since found out that you don't need to instantiate a new object in a method, you can type hint like so: /** * Update existing project */ public function update(Project $project) { // Update and save $project->title = request('title'); // <<<<<< OBJECT IS AVAILABLE LIKE MAGIC $project->description = request('description'); $project->save(); // A GET request by default return redirect('/projects/' . $project->id); } What I'm confused with is how type hinting creates a Project object that is then available in the update() method. Isn't type hinting simply saying "this method expects param 1 to be an Object of type Project"? i.e. nothing to do with dependency injection. Any hints would be awesome, thanks. Link to comment Share on other sites More sharing options...
LostKobrakai Posted February 11, 2019 Share Posted February 11, 2019 I'm mostly guessing. I've seen quite a bunch of tutorials using laravel, but never actually used it, so I try: I'm expecting that laravel uses reflection to know the type hint you put for the parameter and depending on the result do some boilerplate code you could've written on your own to retrieve the project and call the controller action with it. 1 Link to comment Share on other sites More sharing options...
Wanze Posted February 11, 2019 Share Posted February 11, 2019 LostKobrakai is right. Laravel's dependency injection container automagically resolves type-hinted objects, see: https://laravel.com/docs/5.7/container#automatic-injection 1 Link to comment Share on other sites More sharing options...
SamC Posted February 11, 2019 Author Share Posted February 11, 2019 Ah, ok, thanks guys. I did wonder one other thing, there seems to be numerous ways to achieve something, like, which approach would you use, inject into a method, or into the constructor? Both work in my case here (only showing one method, there are more, but they do not ALL need the Project class, create() for example just returns a view). So would you (the Laracasts showing me how to do this way): namespace App\Http\Controllers; use Illuminate\Http\Request; // Bring Project model into namepsace use App\Project; class ProjectsController extends Controller { public function show(Project $project) { return view('projects.show', compact('project')); } } ...OR (the way shown in @Wanze's link above from Laravel docs): namespace App\Http\Controllers; use Illuminate\Http\Request; // Bring Project model into namepsace use App\Project; class ProjectsController extends Controller { protected $project; // Inject Project model here instead of on multiple methods public function __construct(Project $project) { $this->project = $project; } public function show($id) { $project = $this->project->findOrFail($id); return view('projects.show', compact('project')); } } Would one way be considered 'better' than the other way? Does it just depend on how many methods actually need the other class? i.e. what's the point of instantiating in the constructor if 3 methods need it, and 3 methods don't. That kind of thing? Not sure I like compact() either, it's not obvious to me (lack of experience?) what's actually being passed to the view. I know there are other ways. If you use artisan to set this up automagically: php artisan make:controller ProjectsController -r -m Project ...it results with the former i.e. no constructor, which seems weird seeing as their docs say: Quote In practice, this is how most of your objects should be resolved by the container. i.e. using a constructor: https://laravel.com/docs/5.7/container#automatic-injection Link to comment Share on other sites More sharing options...
Recommended Posts