-
Using Routes with Controller
-
Resource Controllers
-
Constructor Injection
-
Method Injection
Controllers are essentially classes that organize the logic of one or more routes together in one place.
A controller’s primary job is to capture the intent of an HTTP Request and pass it onto the rest of the application. So, you can create the logic for the routes of all the pages in a single class.
Creating a Controller
To create a controller you can use the 'artisan' command in CLI. In Command Line Interface navigate to the folder with your Laravel project, and execute this command:
php artisan make:controller MyController
This will create a new file named "
MyController.php" in
app/Http/Controllers/ folder, with some basic code (that extends the base Controller class included with Laravel):
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MyController extends Controller {
//
}
- Alternatively, you can create manually the file "
MyController.php" (in
app/Http/Controllers/ folder) with the code above.
To see a list with available "artisan" commands, type in Command Line Interface:
php artisan –list
Using Routes with Controller
In the
MyController class we can create methods that can be used in routes (in "web.php").
1. Create a public method called
index() that receives the Request objet, and returns a view page with data for template.
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MyController extends Controller {
//receives the request objet; returns a simple page using view
public function index(Request $req){
//set array with keys to be passed to view() for template
$data =[
'uri'=>$req->path(),
'url'=>$req->url(),
'method'=>$req->method()
];
return view('index', $data);
}
}
2. In the "
resources/views/" folder create a "
index.blade.php" file with some content, for example:
<!doctype html>
<html lang="{{app()->getLocale()}}">
<head>
<meta charset="utf-8">
<title>Home Page</title>
</head>
<body>
<h1>Home page</h1>
URI: {{$uri}}<br>
URL: {{$url}}<br>
METHOD: {{$method}}
</body>
</html>
3. Use the MyController index() method in the route for home page (in "routes/web.php", delete the existing get() route for '/'), add:
Route::name('home')->get('/', 'MyController@index');
4. Open the php built-in server (in CLI navigate to the folder with your Laravel project, and initiate: "
php artisan serve"), and access in browser: "
//localhost:8000/".
- It will display the content created in "index.blade.php", a page like in this image:
Resource Controllers
Resource Controllers is an automatically created class that extends Controller, which provide all the methods to perform CRUD operations (
Create, Read, Update, Delete).
To create a "resource controller" use this command in CLI:
php artisan make:controller ControllerName --resource
For example, lets create a controller that handles all HTTP requests for "photos" stored by a Laravel application.
1. Just type this command in CLI:
php artisan make:controller PhotoController --resource
This will create a "
PhotoController.php" file in
app/Http/Controllers/ folder, with a class that extends the base Controller, and a empty method for each of the available resource operations.
Of Course, you can create manually the PhotoController.php file with the class code presented below.
2. Lets add simple 'return' string in each method of the PhotoController class to make some tests.
Copy this code in the "
PhotoController.php" file:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PhotoController extends Controller {
//Display a listing of the resource.
//@return \Illuminate\Http\Response
public function index(){
return 'index';
}
//Show the form for creating a new resource.
//@return \Illuminate\Http\Response
public function create(){
return 'create';
}
//Store a newly created resource in storage.
//@param \Illuminate\Http\Request $request
//@return \Illuminate\Http\Response
public function store(Request $request){
return 'store, uri: '. $request->path();
}
//Display the specified resource.
//@param int $id
//@return \Illuminate\Http\Response
public function show($id){
return 'show, id: '. $id;
}
//Show the form for editing the specified resource.
//@param int $id
//@return \Illuminate\Http\Response
public function edit($id){
return 'edit, id: '. $id;
}
//Update the specified resource in storage.
//@param \Illuminate\Http\Request $request
//@param int $id
//@return \Illuminate\Http\Response
public function update(Request $request, $id){
return 'update, uri: '. $request->path() .' - id: '. $id;
}
//Remove the specified resource from storage.
//@param int $id
//@return \Illuminate\Http\Response
public function destroy($id){
return 'destroy, id: '. $id;
}
}
3. Now, just add the following line of code in routes/web.php file.
Route::resource('photo', 'PhotoController');
- This single route declaration creates multiple routes to handle a variety of actions on the resource.
Request Type |
URI |
Action |
Route Name |
GET |
/photo |
index |
photo.index |
GET |
/photo/create |
create |
photo.create |
POST |
/photo |
store |
photo.store |
GET |
/photo/{photo} |
show |
photo.show |
GET |
/photo/{photo}/edit |
edit |
photo.edit |
PUT/PATCH |
/photo/{photo} |
update |
photo.update |
DELETE |
/photo/{photo} |
destroy |
photo.destroy |
4. Try executing the URLs shown in the following table.
URL |
Description |
Output |
http://localhost:8000/photo |
Executes index() method of PhotoController.php |
index |
http://localhost:8000/photo/create |
Executes create() method of PhotoController.php |
create |
http://localhost:8000/photo/1 |
Executes show() method of PhotoController.php |
show |
http://localhost:8000/photo/1/edit |
Executes edit() method of PhotoController.php |
edit |
Since HTML forms can't make PUT, PATCH (for update), or DELETE (for destroy) requests, you will need to add a hidden
name='method_' field to spoof these HTTP verbs. The
method_field helper can create this field for you:
{{method_field('PUT')}}
If you want to know what routes your current application has available, from the command line, run:
php artisan route:list
- and you’ll get a listing of all of the available routes.
By default, all resource controller actions have a route name.
To get the current route name, use:
$request->route()->getName()
Or, with Route facade:
use Illuminate\Support\Facades\Route;
$route = Route::current();
$name = Route::currentRouteName();
$action = Route::currentRouteAction();
Constructor Injection
Constructor Injection means that you are able to type-hint any dependencies your controller may need in its constructor. The dependencies will automatically be resolved and injected into the controller instance.
- Lets test an example.
1. Create a "
TestController.php" file in the "
app/Http/Controllers/", and add this code:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller {
private $myclass;
//automatically inject instance of MyClass
public function __construct(\MyClass $myclass){
$this->myclass = $myclass;
}
//Responds to requests to /test
public function index(){
echo $this->myclass->prop1;
dd($this->myclass); //to see properties of myclass instance
}
}
2. Add the following code to
routes/web.php file, to route the '/test' request to specified controller:
class MyClass{
public $prop1 ='value 1';
public $prop_2 ='value 2';
}
Route::get('test', 'TestController@index');
3. Now, if you access this URL in your browser:
//localhost:8000/test/, it will display a page as shown in the following image:
Method Injection
In addition to constructor injection, you may also type-hint dependencies in the action methods of your controller.
- Example.
1. Create a "
TestController.php" file in the "
app/Http/Controllers/", and add this code:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller {
//Responds to requests to /test
//automatically inject instance of MyClass
public function index(\MyClass $myclass){
echo $myclass->prop1;
dd($myclass); //to see properties of myclass instance
}
}
2. In the
routes/web.php file let the code used in the previous example for constructor injection.
3. Now, if you access this URL in your browser:
//localhost:8000/test/, it will display a page as shown in the following image:
- Documentation:
Laravel - Controllers