routes/web.php*
routes/api.php (URLs with prefix api/)*
Route::get('/greeting', function () {
return 'Hello World';
});
php artisan route:listRoute::get('/', function () {
// show something (e.g. return a blob of HTML)
});
Route::get('/about', function () {
// show something else (e.g. return a blob of HTML)
});
Route::post('/', function () {
// do something (e.g. insert into database, send e-mail)
});
Route::match(['get', 'post'], '/', function () { …
Route::any('/foo', function () { …
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
return 'Post ' . $postId;
});
Route::get('/user/{name?}', function (?string $name = 'John') {
return $name;
});
where method
Route::get('/user/{id}/{name}', function (string $id, string $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-zA-Z]+']);
Route::get('/user/{id}/{name}', function (string $id, string $name) {
//
})->whereNumber('id')->whereAlpha('name');
app/Providers/AppServiceProvider.php)Illuminate\Http\Requestuse Illuminate\Http\Request;
Route::post('/register', function(Request $request) {
$email = $request->input('email', 'not provided');
$name = $request->cookie('name');
$value = $request->header('X-Header-Name');
$iKnowItsTrue = $request->isMethod('post');
$iKnowItsFalse = $request->is('register/*');
$urlWithQueryString = $request->fullUrl();
$ipAddress = $request->ip();
if ($request->has('name')) {
$name = $request->name;
…
});
. to dig into arrays (whether JSON or not)$name = $request->input('products.0.name');
$names = $request->input('products.*.name');
$name = $request->name; // same as: $request->input('name');
if ($request->hasFile('additional_documents')) {
$files = $request->file('additional_documents');
foreach ($files as $file) {
$path = $file->store('users/' . $userId . '/docs'); // folder relative to Filesystem root
// assigns a unique ID as file name
// want to specify file name? $file->storeAs()
}
}
if ($request->has(['name', 'email'])) { ... // if all of the specified parameters are present
if ($request->hasAny(['name', 'email'])) { ... // if any of the specified parameters are present
if ($request->filled('name')) { ... // if the parameter is present and not empty
$input = $request->all(); // array with all parameters
$input = $request->only(['username', 'password']); // same, but only with specified paramters (if present)
$input = $request->except(['credit_card']); // same, without specified paramters
$request->merge(['votes' => 0]); // merge parameters with the request object (will overwrite if present)
$input = $request->collect(); // collection with all parameters
$name = $request->query('name'); // get the name parameter from the query string, not from the payload
$archived = $request->boolean('archived'); // convert to boolean cf. "on" "yes"
$birthday = $request->date('birthday'); // convert to a Carbon date
$name = $request->string('name')->trim(); // convert to a Stringable and trim
Illuminate\Http\Responsereturn 'Hello World';return ['name' => 'Abigail', 'state' => 'CA'];return response($content, $status));return response('Hello World', 200)
->header('Content-Type', 'text/plain')
->cookie('name', 'value');
Illuminate\Http\Responsereturn view('greeting', ['name' => 'James']); — it involves rendering the resources/views/greeting.blade.php templatereturn response()->view('greeting', $data)->…;return response()->json(['name' => 'Abigail', 'state' => 'CA'])->…;json() also sets the HTTP Content-Type headerIlluminate\Http\Responsereturn response()->download($pathToFile);return response()->file($pathToFile);RedirectResponse instance: return redirect('home/dashboard');return back()->withInput();*Controller in the folder app/Http/Controllers
php artisan make:controller TaskController
/routes/web.php (or in /routes/api.php)
use App\Http\Controllers\TaskController;
Route::get('/tasks', [TaskController::class, 'index']);
Route::post('/tasks/create', [TaskController::class, 'store']);
Route::post('/tasks/{task}/delete', [TaskController::class, 'destroy'])->whereNumber('task');
*Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function index(Request $request) : View {
$tasks = DB::select('select * from tasks where user_id = ?',
[$request->user_id]);
return view('tasks.index', ['tasks' => $tasks]);
}
public function destroy(Request $request, string $id) : RedirectResponse
Route::prefix('/admin')->group(function () {
Route::get('/users', [AdminController::class, 'getUsers']); // Matches the "/admin/users" URL
Route::get('/dashboard', [AdminController::class, 'dashboard']); // Matches the "/admin/dashboard" URL
});
Route::controller(OrderController::class)->group(function () {
Route::get('/orders/{id}', 'show');
Route::post('/orders', 'store');
});
Route::domain('{account}.myapp.com')->group(function () {
Route::get('/user/{id}', function (string $account, string $id) {
//
});
});
HttpExceptions describe HTTP error codes from the server
404 (when there is no matching route), internal error (caused by developer) 500, …resources/views/errors/404.blade.php for error code 404 and so on storage/logs/laravel.log)resources/views
resources/views/subdir/greeting.blade.php
<html>
<body>
<h1>Hello, {{ $name }}</h1>
</body>
</html>view helper returns an instance of Illuminate\View\View, to which you can pass variables.
return view('subdir.greeting', ['name' => 'Eddy']);.blade.php.blade.php!) and variable passing: see previous slide (Views).storage/framework/viewsHello, {{ $name }}.
htmlentities to prevent XSS-attacks.${{ time() }} and forget about Twig filters{{ $name or 'Default' }} is syntactic sugar for {{ isset($name) ? $name : 'Default' }}Hello, {!! $name !!}.@if (count($records) === 1)
I have one record!
@elseif (count($records) > 1)
I have multiple records!
@else
I don't have any records!
@endif
@foreach ($events as $event)
<p>This is user {{ $event->id }} ({{ $loop->iteration }} / {{ $loop->count }})</p>
@endforeach
()$event['id']$event->id<html>
<head>
<title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
</body>
</html>
@extends('layouts.master')
@section('title', 'Page Title')
@section('sidebar')
@parent
<p>This is appended to the master sidebar.</p>
@endsection
@section('content')
<p>This is my body content.</p>
@endsection
<div>
@include('shared.errors')
<form>
<!-- Form Contents -->
</form>
</div>
@include('view.name', ['status' => 'complete'])@includeWhen($boolean, 'view.name', ['status' => 'complete'])@each('view.joboffer', $jobs, 'job')@include template, but NOT if you use @each<script>
var app = {{ Js::from($array) }};
</script>
<h1>Laravel</h1>
@@if( condition )
Hello, @{{ name }}.
route/1/ to route/2/ would generate a browser link to route/1/route/2 → helpers
{{ asset('css/common.css') }} to generate a path in your template to an asset in your public folder{{ url('artists/' . $id) }} to generate a path to a route{{ route('admin::dashboard') }} to generate a path to a named routeRoute, ViewIlluminate\Support\Collection) is a convenient wrapper for working with arrays of data
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
return strtoupper($name);
})->reject(function ($name) {
return empty($name);
});$users = DB::select('select * from users where active = ?', [1]);
foreach ($users as $user) {
echo $user->name;
}
DB::select returns an array of StdClass objects with dynamic properties (column name or SQL alias)$results = DB::select('select * from users where id = :id', ['id' => 1]);
$count = DB::scalar('select count(*) from users');
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
DB::statement('drop table users');
database/migrations up (perform migration) and down (reverse).migrations)$ php artisan make:migration create_events_table
database/migrations/<timestamp>_create_events_table.php (auto-guessing it's a table creation)
return new class extends Migration
{
public function up(): void
{
Schema::create('events', function (Blueprint $table) {
$table->id(); // your table has a PK auto-inc unsigned bigint column id
$table->timestamps(); // your table has created_at and updated_at columns
});
}
public function down(): void
{
Schema::dropIfExists('events');
}
}
public function up(): void
{
Schema::create('events', function (Blueprint $table) {
$table->id(); // LEAVE IT HERE
$table->string('title');
$table->text('description');
$table->date('event_date');
// foreign key: column types need to be EXACTLY the same
$table->unsignedBigInteger('location_id');
$table->foreign('location_id')->references('id')->on('locations');
// all at once: $table->foreignId('location_id')->constrained();
$table->timestamps(); // LEAVE IT HERE
});
}
$ php artisan migrate
php artisan migrate
migrate:fresh Drop all tables and re-run all migrations
migrate:install Create the migration repository
migrate:refresh Reset and re-run all migrations
migrate:reset Rollback all database migrations
migrate:rollback Rollback the last database migration (option: --step=2)
migrate:status Show the status of each migration
migrate --pretend Show SQL queries to be executed without running them
migrations table