Consultant, Formateur, Contributeur.
2011: Premier commit,
2013: v4.0.0,
2015: v5.0.0,
2019: v5.9.0 ?
… pour les habitués à Symfony 😊
Et une documentation très accessible…
▶ composer.json
▶ .env
▶ ORM (ActiveRecord)
+ Migrations
▶ CLI
▶ Templates
▶ Intégration frontend (Elixir
)
# Création d'un projet vierge composer create-project laravel/laravel
# Démarrage du serveur web intégré à PHP ./artisan serve # Homepage: http://localhost:8000
├── app
│ ├── Console
│ │ └── Kernel.php
│ ├── Exceptions
│ ├── Http
│ │ ├── Controllers
│ │ ├── Middleware
│ │ └── Kernel.php
│ ├── Providers
│ └── User.php
├── bootstrap
├── config
│ ├── app.php
│ └── …
├── database
│ ├── migations
│ ├── seeds
├── routes
│ ├── api.php
│ ├── web.php
│ └── …
├── public
├── resources
└── storages
//routes/api.php
Route::post('/upload', function() {
request('image')->store('images');
});
Route::post('/upload', function() {
...
});
/** @var UploadedFile */
request('image')->store('images');
… not so bad !
use Illuminate\Http\Request;
Route::post('/upload', function(Request $request) {
$request
->file('image')
->store('images');
});
Route::post('/upload', function(Request $request) {
$request->validate([
'image' => 'required|image'
]);
$request->file('image')->store('images');
});
use Illuminate\Contracts\Filesystem\Filesystem;
Route::post(
'/upload',
function(Request $request, Filesystem $filesystem) {
//[...] Validation
$file = $request->file('image');
$filesystem->put(
sprintf('images/%s', $file->hashName()),
$file
);
}
);
Chaque chose à sa place…
…Contrôleur, Route, Service.
namespace App\Http\Controllers\Api\User;
class UploadProfilePicture
{
private $filesystem;
public function __construct(Filesystem $filesystem) {
$this->filesystem = $filesystem;
}
public function __invoke(Request $request) {
// Action…
}
}
namespace App\Http\Controllers\Api\User;
class UploadProfilePicture
{
private $filesystem;
public function __construct(Filesystem $filesystem) {
$this->filesystem = $filesystem;
}
public function __invoke(Request $request) {
// Action…
}
}
namespace App\Http\Controllers\Api\User;
class UploadProfilePicture
{
private $filesystem;
public function __construct(Filesystem $filesystem) {
$this->filesystem = $filesystem;
}
public function __invoke(Request $request) {
// Action…
}
}
Route::post(
'/upload',
'Api\User\UploadProfilePicture'
);
Les services sont des objets…
… construits et gérés par le conteneur …
… injectés à l'exécution.
AppServiceProvider::boot
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Foundation\Application;
$this->app->bind(
Filesystem::class,
function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
}
);
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Foundation\Application;
$this->app->bind(
Filesystem::class,
function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
}
);
use Illuminate\Contracts\Filesystem\Filesystem;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Foundation\Application;
$this->app->bind(
Filesystem::class,
function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
}
);
...
use App\Http\Controllers\Api\User;
$this->app
->when(User\UploadProfilePicture::class)
->needs(Filesystem::class),
->give(function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
});
...
use App\Http\Controllers\Api\User;
$this->app
->when(User\UploadProfilePicture::class)
->needs(Filesystem::class),
->give(function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
});
...
use App\Http\Controllers\Api\User;
$this->app
->when(User\UploadProfilePicture::class)
->needs(Filesystem::class),
->give(function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
});
...
use App\Http\Controllers\Api\User;
$this->app
->when(User\UploadProfilePicture::class)
->needs(Filesystem::class),
->give(function(Application $app) {
return $app
->make(FilesystemManager::class)
->disk('local');
});
Arrêter le processus le plus tôt possible…
… Middlewares
et FormRequest
.
Centraliser les comportements…
./artisan make:request UploadUserProfile
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\UploadedFile;
class UploadUserProfile extends FormRequest
{
public function rules() {
return ['image' => 'required|image'];
}
public function image(): UploadedFile {
return $this->validated()['image'];
}
}
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\UploadedFile;
class UploadUserProfile extends FormRequest
{
public function rules() {
return ['image' => 'required|image'];
}
public function image(): UploadedFile {
return $this->validated()['image'];
}
}
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\UploadedFile;
class UploadUserProfile extends FormRequest
{
public function rules() {
return ['image' => 'required|image'];
}
public function image(): UploadedFile {
return $this->validated()['image'];
}
}
namespace App\Http\Controllers\Api\User;
use App\Http\Requests\UploadUserProfile;
class UploadProfilePicture
{
public function __construct(Filesystem $filesystem)
{
$this->filesystem = $filesystem;
}
public function __invoke(UploadUserProfile $request)
{
$image = $request->image();
$this->filesystem->put('images', $image);
}
}
namespace App\Http\Controllers\Api\User;
use App\Http\Requests\UploadUserProfile;
class UploadProfilePicture
{
public function __construct(Filesystem $filesystem)
{
$this->filesystem = $filesystem;
}
public function __invoke(UploadUserProfile $request)
{
$image = $request->image();
$this->filesystem->put('images', $image);
}
}
Vous pouvez désactiver les facades !
/* config/app.php */
[
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
…
],
]
Une micro application,
Testable, maintenable,
Et surtout pas de magie !
Laravel est un outil et seulement un outil …
Très rapide pour prototyper …
Très riche en fonctionnalités par défaut …
Mais pas adapté à tout les cas !
Ne pas prendre tout les raccourcis possible…
Prendre le temps d'apprendre…
Comprendre l'architecture de votre code.