Laravel

Un framework qui rend heureux

Voir cette catégorie
Vers le bas
Laravel 5
Dimanche 21 septembre 2014 23:42

Au 16/01/2015 : article devenu un peu obsolète pour différents points. Pour info J'ai réalisé une application d'exemple pour L5 dans l'optique de futur tutos.

On attendait la version 4.3 mais c'est finalement une version 5.0 qui va nous être donnée .

Il y a pas mal de changements en vue, je vous propose un petit tour d'horizon de tout ça...

Si vous aimez les vidéos et que l'anglais ne vous effraie pas il y a plein d'informations sur le site de Laracasts mais elles ne sont plus toutes à jour.

Une nouvelle structure

On avait commencé à s'habituer à l'organisation de la version 4.0 :

img68

Mais il va nous falloir digérer la nouvelle de la version 5.0 :

img95

Le dossier app

Le dossier app s'est allégé. Il a perdu la configuration, les bases, le stockage, les vues... D'autre part il recèle une nouvelle organisation. Voyons ça de plus près...

  • Console : ici on va mettre toutes nos commandes. Il y en a une comme exemple dans le package :

img70

  • Http : ici on va trouver tout ce qui concerne la communication : contrôleurs, filtres (on parle plus de filtres mais de Middleware) et requêtes.

img96

Le fichier Kernel.php correspond à l'utilisation du composant HttpKernel de symfony. Noua allons en voir aussi la conséquence dans l'utilisation des middlewares.
  • Providers : ici on va mettre tous les services providers, il y en a déjà 4 (ça remplace le fichier app/start)  :

img97

Le dossier app/Http

Voyons de plus près ce dossier. On trouve 3 sous-dossiers :
  • Controllers : ici on placera nos contrôleurs, on trouve au départ le classique HomeController, mais aussi deux contrôleurs déjà présents pour l'authentification :

img98

  • Middleware : la notion de middleware n'est pas très répandue dans le monde PHP. Il faut comprendre ce pattern (pour plus d'infos sur ce pattern c'est ici) comme la "décoration" de la requête dans son cheminement (session, cookies, filtres...). Ces middlewares sont répartis dans plusieurs fichiers (le fichier des filtres a aussi disparu pour le coup) :

img99

  • Requests : ce dossier est vide au départ, nous verrons plus loin son utilité.

Les modèles

Mais où sont passés les modèles qui avaient un joli dossier dans la précédente version ? Maintenant rien de tel...  On trouve juste le modèle User dans le dossier app :

img75

Je pense que cet aspect est laissé à la libre convenance de chacun... La seule précaution à prendre si vous déplacez User.php est de bien renseigner la référence dans app/config/auth.php pour que l'authentification ne vous renvoie pas d'injure .

Les ressources

Les vues et les données de langage ont été regroupées dans un dossier resources :

img01

PSR-4

Lorsqu'on regarde comment tout cela est organisé on se rend compte de deux choses :

  1. Contrairement à la version 4 maintenant le code de l'application est organisé avec des espaces de noms. C'est une bonne chose et de toutes façon il était d'une pratique courante de créer son dossier d'application avec des espaces de noms.
  2. Le chargement automatique est prévu en PSR-4 alors qu'on utilisait en général le PSR-0 :
"autoload": {
	"classmap": [
		"database",
		"tests/TestCase.php"
	],
	"psr-4": {
		"App\\": "app/"
	}
},

Le PSR-4 est moins contraignant au niveau des espaces de noms et de l'organisation des dossiers que le PSR-0. Ici dans Composer on dit que l'espace de noms App se trouve dans le dossier app.

D'autre part on ne va plus avoir à taper composer dumpautoload aussi souvent .

Par contre étant donné qu'on a des espaces de noms de partout il faudra faire des imports corrects pour utiliser les classes qui nous intéressent.

On peut avoir cette route :

Route::get('/', 'HomeController@index');

Sans avoir à préciser l'espace de nom du contrôleur qui est :

<?php namespace App\Http\Controllers;

Sinon on devrait écrire :

Route::get('/', 'App\Http\Controllers\HomeController@index');

Ce qui est quand même plus lourd . Mais on va voir que concernant les routes une petite révolution s'est également produite...

En résumé cette nouvelle structure présente l'avantage de proposer d'emblée un espace de nom, ce que de toutes façons tout le monde faisait dans la version 4. Le premier réflexe était de virer quelque dossier comme les modèles et de créer un dossier pour l'application.

Injection de dépendance

Avec la version 4 on peut injecter une classe dans un contrôleur à partir du constructeur, par exemple :

protected $validation;
protected $gestion;

public function __construct(LoginValidator $validation,	LoginGestion $gestion)
{
	parent::__construct();
	$this->validation = $validation;
	$this->gestion = $gestion;
}

C'est quelque chose de bien pratique qui permet de bien séparer les fonctionnalités et de simplifier les tests. Avec la version 5 apparaît la possibilité d'injecter une classe au niveau d'une méthode :

public function postIndex(LoginValidator $validation, LoginGestion $gestion)
{
	if ($validation->fails()) {
		return Redirect::to('login')
		->withInput()
		->withErrors($validation->errors());
	} 

	$result = $gestion->authenticate();

	if($result === true) {
		return Redirect::intended();
	}
		
	return Redirect::to('login')->withInput()->with('error', $result);
}

Ça épargne un certain nombre de $this . Je n'ai pas fait d'essai en ajoutant la transmission de paramètres mais il paraît que c'est bien géré. Mon exemple avec la validation n'est d'ailleurs plus trop dans l'esprit de la version 5, on va voir bientôt pourquoi...

Vous pouvez aussi faire ce genre d'injection dans les routes.

Les classes Html et Form

Les classes Html et Form ont été retirées de l'installation de base . Si vous tentez cette syntaxe :

echo \Form::label('test', 'Mon petit test');
Vous allez hériter d'une erreur :
Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_ERROR)

Class 'Form' not found

La raison de cette suppression ne me semble pas bien claire mais on peut imaginer que Laravel peut servir à bien d'autres application qu'une classique interface web. Si on veut remettre en route cette fonctionnalité il faut commencer par expliquer à Composer d'aller chercher le code :

"require": {
	"laravel/framework": "~5.0",
	"illuminate/html": "~5.0"
},

Évidemment on doit lancer un petit composer update. Ensuite il faut renseigner le fichier config/app.php pour lancer le service provider et renseigner la façade :

'providers' => [

	...

	'Illuminate\Html\HtmlServiceProvider',

],

'aliases' => [

	...

    'HTML' => 'Illuminate\Html\HtmlFacade'
	'Form' => 'Illuminate\Html\FormFacade'

],      

Pour faire bonne mesure j'ai ajouté la façade pour HTML...

Ainsi on retrouve tout ce qu'il nous faut au niveau helpers et éléments de formulaires . Notez le nouvel helper view() qui permet d'éviter de taper View::make().

Blade

En faisant mes essais je suis tombé sur une petite modification dans Blade : désormais la syntaxe {{ }} du texte brut a disparu au profit de {!! !!}. Si vous entrez cette syntaxe dans un fichier Blade :

{{ Form::label('test', 'Mon petit test') }}

Ça va vous générer ça :

&lt;label for=&quot;test&quot;&gt;Mon petit test&lt;/label&gt;

En fait c'est exactement la même production avec {{{ }}}, on a un échappement.

Si vous utilisez cette syntaxe :

{!! Form::label('test', 'Mon petit test') !!}

Vous aurez le bon code :

<label for="test">Mon petit test</label>

Ma première idée était que la triple accolade ne serait plus utilisée mais en consultant le code j'ai remarqué une différence entre double et simple accolade avec un traitement différent. Mais je n'ai pas encore creusé cette histoire...

Les annotations

Au dernières nouvelles le fichier route.php est réapparu et sera par défaut dans l'installation de base. Par contre les annotations ont disparues. pour les utiliser il faut maintenant utiliser un package. Je trouve ça dommage, j'aime bien cette possibilité, tout autant que je n'aime pas utiliser des packages.

Les annotations sont des renseignements au sujet du code qui est présent dans le DocBlock. PHP peut lire ces renseignements et en faire usage. Le routage pourra être assuré par des annotations. Par exemple dans la méthode index du contrôleur HomeController :

/**
 * @Get("/")
 */
public function index()
{
	return view('hello');
}

Vous remarquez la route mentionnée dans le DocBlock : Get("/").

On peut également prévoir cette mention dans le contrôleur AuthController :

/**
 * @Middleware("guest", except={"logout"})
 */
class AuthController extends Controller {

On trouve cette fois le filtre (Middleware) guest avec une exception pour la méthode logout.

Pour que Laravel scanne ces renseignements il y a une nouvelle commande Artisan :

php artisan route:scan

Le résultat se retrouve dans le fichier storage/framework/routes.scanned.php. Moralité : chaque fois qu'on change une annotation il faut lancer la commande !

Form Request

C'est sans doute l'apport le plus intéressant de cette version 5. La validation a fait couler beaucoup d'encre et les méthodes pour la réaliser se sont multipliées. Que ce soit directement dans une méthode de contrôleur, en injectant une classe, en utilisant un événement, chacun y est allé de son style particulier. Les Form Request vont mettre tout le monde d'accord en apportant une solution simple et élégante à la question de la validation. Pour montrer cette nouvelle possibilité considérons un petit scénario.

Commençons par prévoir un contrôleur :

<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;

class FormController extends Controller {

	/**
	 * @Get("form")
	 */
	public function getForm()
	{
	  return view('test');
	}

	/**
	 * @Post("form", as="response")
	 */
	public function postForm()
	{
	  // ...
	}

}

Pour que ça fonctionne pour les routes il faut aussi que j'informe le fichier app/Providers/RouteServiceProvider.php que le contrôleur existe :

protected $scan = [
	'App\Http\Controllers\HomeController',		
	'App\Http\Controllers\FormController',
	'App\Http\Controllers\Auth\AuthController',
	'App\Http\Controllers\Auth\PasswordController',
];

Il faut ensuite lancer le scan avec php artisan route:scan. La syntaxe d'artisan pour voir les routes a changé. Avec la version 4 on tapait php artisan routes. Maintenant il faut taper php artisan route:list. Voici le résultat dans mon cas :

img02

Maintenant une petite vue pour le formulaire :

{!! Form::open(['route' => 'response']) !!}
   {!! Form::label('nom', 'Nom :') !!}
   {!! Form::text('nom') !!}
   {!! Form::submit('Envoyer') !!}
{!! Form::close() !!}

On place cette vue dans le nouvel emplacement prévu avec la version 5 :

img79

Ce qui nous donne visuellement :

img80

Rien d'extraordinaire mais c'est juste pour illustrer les nouvelles possibilités.

Pour avoir la classe Form il faut ajouter le composant qui n'est plus dans Laravel par défaut.

Maintenant on va créer le fameux Form Request. Artisan a été équipé d'une nouvelle commande pour cela :

img04

Alors je me lance :

img82

Apparemment ça se passe bien :

img03

Et j'obtiens ce code :

<?php namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class TestRequest extends FormRequest {

	/**
	 * Get the validation rules that apply to the request.
	 *
	 * @return array
	 */
	public function rules()
	{
		return [
			//
		];
	}

	/**
	 * Determine if the user is authorized to make this request.
	 *
	 * @return bool
	 */
	public function authorize()
	{
		return false;
	}

}

La méthode authorize doit déterminer si la soumission est valide, par exemple pour vérifier l'identité de celui qui l'envoie. La méthode doit renvoyer un booléen, on voit que par défaut c'est à false. On va commencer à le mettre à true pour que ça fonctionne.

La méthode rules comme son nom l'indique attend les règles de validation. Je vais me contenter de quelque chose de simple. Voici la classe complétée :

<?php namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class TestRequest extends FormRequest {

	/**
	 * Get the validation rules that apply to the request.
	 *
	 * @return array
	 */
	public function rules()
	{
		return ['nom' => 'required|min:6'];
	}

	/**
	 * Determine if the user is authorized to make this request.
	 *
	 * @return bool
	 */
	public function authorize()
	{
		return true;
	}

}

Maintenant il faut injecter cette classe dans la méthode du contrôleur :

<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Http\Requests\TestRequest;

class FormController extends Controller {

	/**
	 * @Get("form")
	 */
	public function getForm()
	{
	  return view('test');
	}

	/**
	 * @Post("form", as="response")
	 */
	public function postForm(TestRequest $request)
	{
	  // ...
	}

}

Quand je fais une saisie correcte tout se passe bien et quand j'en fais une non correcte on me renvoie le formulaire, sans doute avec les message d'erreur mais je n'ai rien prévu pour les afficher, je corrige ça :

@foreach($errors->all() as $error)
	<li> {!! $error !!}</li>
@endforeach
{!! Form::open(['route' => 'response']) !!}
	{!! Form::label('nom', 'Nom :') !!}
	{!! Form::text('nom') !!}
	{!! Form::submit('Envoyer') !!}
{!! Form::close() !!}

Cette fois j'ai bien l'affichage des messages :

img84

Il y aurait encore beaucoup à dire sur ce sujet, il y a plein de propriétés et méthodes qu'on peut surcharger. Par exemple pour avoir un message personnalisé :

public function messages()
{
	return ['nom.required' => 'Faudrait mettre un nom !'];
}

Mais j'ai présenté le principe de base...

Artisan

Artisan a été enrichi de plusieurs commandes en particulier au niveau de la création de classes :

img04

On a déjà vu plus haut l'utilisation de make:request. On voit qu'on peut aussi facilement créer un middleware :

img05

img06

Avec le code tout prêt :
<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Routing\Middleware;

class TestMiddleware implements Middleware {

	/**
	 * Handle an incoming request.
	 *
	 * @param  \Illuminate\Http\Request  $request
	 * @param  \Closure  $next
	 * @return mixed
	 */
	public function handle($request, Closure $next)
	{
		//
	}

}
On peut de la même façon créer un service provider :

img87

img07

Avec ce code :
<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class TestServiceProvider extends ServiceProvider {

	/**
	 * Bootstrap the application services.
	 *
	 * @return void
	 */
	public function boot()
	{
		//
	}

	/**
	 * Register the application services.
	 *
	 * @return void
	 */
	public function register()
	{
		//
	}

}

Systèmes de fichiers

Laravel 5.0 charge par défaut le package flysystem. On peut ainsi accéder à des données issues de diverses origines et non plus seulement le système local, par exemple sur le cloud. Le package est très riche et permet ces accès :

  • Local
  • Amazon Web Services - S3
  • Rackspace Cloud Files
  • Dropbox
  • Copy
  • Ftp
  • Sftp (through phpseclib)
  • Zip (through ZipArchive)
  • WebDAV (through SabreDAV)
  • NullAdapter

Par défaut le fichier config/filesystems ne prend en compte que les 3 premiers mais il doit être facile d'intégrer un des autres.

Contrats

Une nouvelle formalisation de la version 5 apparaît avec un dossier de contrats. En d'autres termes ce sont des interfaces qui fixent le propriétés et méthodes du framework. On retrouve tout ça dans l'installation :

img90

Pour cette partie la vidéo n'est pas très explicite je vais donc un peu développer. Si on veut modifier un peu (ou beaucoup) le fonctionnement du Framework c'est bien pratique. je vais prendre un exemple avec le hashage. Laravel utilise l’algorithme PASSWORD_BCRYPT. Supposons que je veux modifier ce comportement en utilisant la valeur par défaut PASSWORD_DEFAULT pour bénéficier des évolutions futures de PHP sans rien toucher. Je veux aussi augmenter le coût algorithmique qui est fixé à 10 en le montant à 12 étant donné mon architecture serveur. Comment apporter cette modification à Laravel ? Avec les contrats c'est tout simple !

Je trouve le contrat correspondant :

img91

Voici l'interface :

<?php namespace Illuminate\Contracts\Hashing;

interface Hasher {

	/**
	 * Hash the given value.
	 *
	 * @param  string  $value
	 * @param  array   $options
	 * @return string
	 */
	public function make($value, array $options = array());

	/**
	 * Check the given plain value against a hash.
	 *
	 * @param  string  $value
	 * @param  string  $hashedValue
	 * @param  array   $options
	 * @return bool
	 */
	public function check($value, $hashedValue, array $options = array());

	/**
	 * Check if the given hash has been hashed using the given options.
	 *
	 * @param  string  $hashedValue
	 * @param  array   $options
	 * @return bool
	 */
	public function needsRehash($hashedValue, array $options = array());

}

La classe du framework qui implémente cette interface est Illuminate\Hashing\BcryptHasher :

<?php namespace Illuminate\Hashing;

use Illuminate\Contracts\Hashing\Hasher as HasherContract;

class BcryptHasher implements HasherContract {

	/**
	 * Default crypt cost factor.
	 *
	 * @var int
	 */
	protected $rounds = 10;

	/**
	 * Hash the given value.
	 *
	 * @param  string  $value
	 * @param  array   $options
	 * @return string
	 *
	 * @throws \RuntimeException
	 */
	public function make($value, array $options = array())
	{
		$cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds;

		$hash = password_hash($value, PASSWORD_BCRYPT, array('cost' => $cost));

		if ($hash === false)
		{
			throw new \RuntimeException("Bcrypt hashing not supported.");
		}

		return $hash;
	}

	/**
	 * Check the given plain value against a hash.
	 *
	 * @param  string  $value
	 * @param  string  $hashedValue
	 * @param  array   $options
	 * @return bool
	 */
	public function check($value, $hashedValue, array $options = array())
	{
		return password_verify($value, $hashedValue);
	}

	/**
	 * Check if the given hash has been hashed using the given options.
	 *
	 * @param  string  $hashedValue
	 * @param  array   $options
	 * @return bool
	 */
	public function needsRehash($hashedValue, array $options = array())
	{
		$cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds;

		return password_needs_rehash($hashedValue, PASSWORD_BCRYPT, array('cost' => $cost));
	}

}

J'ai juste besoin de modifier la propriété $rounds et la méthode make. Pour alléger mon code je vais hériter de cette classe. Je crée un dossier Services pour loger ma classe que je nomme Hasher :

img92

Je n'ai plus qu'à coder :

<?php namespace App\Services;

class Hasher extends \Illuminate\Hashing\BcryptHasher  {

	/**
	 * Default crypt cost factor.
	 *
	 * @var int
	 */
	protected $rounds = 12;

	/**
	 * Hash the given value.
	 *
	 * @param  string  $value
	 * @param  array   $options
	 * @return string
	 *
	 * @throws \RuntimeException
	 */
	public function make($value, array $options = array())
	{
		$cost = isset($options['rounds']) ? $options['rounds'] : $this->rounds;

		$hash = password_hash($value, PASSWORD_DEFAULT, array('cost' => $cost));

		if ($hash === false)
		{
			throw new \RuntimeException("Default Algorytm hashing not supported.");
		}

		return $hash;
	}

}

Ma classe implémente bien l'interface. Maintenant comment l'utiliser ? Il faut que j'informe le conteneur que je veux utiliser cette classe lorsque j'invoque l'interface. Il suffit de placer ce code dans la méthode register d'un service provider (par exemple AppServiceProvider) :

$this->app->bind('Illuminate\Contracts\Hashing\Hasher', 'App\Services\Hasher');

Et maintenant je peux injecter ma classe dans une méthode de contrôleur facilement :

<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use Illuminate\Contracts\Hashing\Hasher as Hasher;

class TestController extends Controller {

	public function index(Hasher $hasher) 
	{
		echo $hasher->make('toto');
	}
}

Etant donné que j'indique une interface comme type du paramètre le conteneur va gentiment créer pour moi une instance de ma classe . Je peux à l'avenir modifier mon hashage sans toucher mon code du contrôleur. Je peux aussi créer une façade.

Mise en cache des routes

Une nouvelle fonctionnalité : on peut mettre en cache les routes pour accélérer le chargement des pages. Il suffit d'utiliser la commande php artisan route:cache :

img93

Dans un premier temps le cache existant, s'il existe, est supprimé et un nouveau cache est créé. Où est-il ? Ici :

img94

Le fichier des routes est sérialisé pour être mémorisé et on trouve très logiquement ici une méthode pour faire l'opération inverse :

app('router')->setRoutes(
	unserialize(base64_decode('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ZXN0L3Rlc3Qve29uZT99L3t0d28/fS97dGhyZWU/fS97Zm91cj99L3tmaXZlP30iO086MjQ6IklsbHVtaW5hdGVcUm91dGluZ1xSb3V0ZSI6Nzp7czo2OiIAKgB1cmkiO3M6NDg6InRlc3QvdGVzdC97b25lP30ve3R3bz99L3t0aHJlZT99L3tmb3VyP30ve2ZpdmU/fSI7czoxMDoiACoAbWV0aG9kcyI7YToxOntpOjA7czo0OiJQT1NUIjt9czo5OiIAKgBhY3Rpb24iO2E6Njp7czo0OiJ1c2VzIjtzOjQ0OiJBcHBcSHR0cFxDb250cm9sbGVyc1xUZXN0Q29udHJvbGxlckBwb3N0VGVzdCI7czoyOiJhcyI7czo4OiJyZXNwb25zZSI7czoxMDoiY29udHJvbGxlciI7czo0NDoiQXBwXEh0dHBcQ29udHJvbGxlcnNcVGVzdENvbnRyb2xsZXJAcG9zdFRlc3QiO3M6OToibmFtZXNwYWNlIjtzOjIwOiJBcHBcSHR0cFxDb250cm9sbGVycyI7czo2OiJwcmVmaXgiO047czo1OiJ3aGVyZSI7YTowOnt9fXM6MTE6IgAqAGRlZmF1bHRzIjthOjA6e31zOjk6IgAqAHdoZXJlcyI7YTowOnt9czoxMzoiACoAcGFyYW1ldGVycyI7TjtzOjE3OiIAKgBwYXJhbWV0ZXJOYW1lcyI7Tjt9czoxNToidGVzdC97X21pc3Npbmd9IjtyOjM1O31zOjM6IlBVVCI7YToxOntzOjE1OiJ0ZXN0L3tfbWlzc2luZ30iO3I6MzU7fXM6NToiUEFUQ0giO2E6MTp7czoxNToidGVzdC97X21pc3Npbmd9IjtyOjM1O31zOjY6IkRFTEVURSI7YToxOntzOjE1OiJ0ZXN0L3tfbWlzc2luZ30iO3I6MzU7fX1zOjEyOiIAKgBhbGxSb3V0ZXMiO2E6NDp7czo1OiJIRUFELyI7cjo0O3M6NTI6IkhFQUR0ZXN0L3Rlc3Qve29uZT99L3t0d28/fS97dGhyZWU/fS97Zm91cj99L3tmaXZlP30iO3I6MTk7czo1MjoiUE9TVHRlc3QvdGVzdC97b25lP30ve3R3bz99L3t0aHJlZT99L3tmb3VyP30ve2ZpdmU/fSI7cjo2MDtzOjIxOiJERUxFVEV0ZXN0L3tfbWlzc2luZ30iO3I6MzU7fXM6MTE6IgAqAG5hbWVMaXN0IjthOjI6e3M6NDoiZm9ybSI7cjoxOTtzOjg6InJlc3BvbnNlIjtyOjYwO31zOjEzOiIAKgBhY3Rpb25MaXN0IjthOjQ6e3M6NDE6IkFwcFxIdHRwXENvbnRyb2xsZXJzXFRlc3RDb250cm9sbGVyQGluZGV4IjtyOjQ7czo0MzoiQXBwXEh0dHBcQ29udHJvbGxlcnNcVGVzdENvbnRyb2xsZXJAZ2V0VGVzdCI7cjoxOTtzOjQ0OiJBcHBcSHR0cFxDb250cm9sbGVyc1xUZXN0Q29udHJvbGxlckBwb3N0VGVzdCI7cjo2MDtzOjQ5OiJBcHBcSHR0cFxDb250cm9sbGVyc1xUZXN0Q29udHJvbGxlckBtaXNzaW5nTWV0aG9kIjtyOjM1O319'))
);

Il y a quelques inconvénients : les fonctions anonymes ne sont pas prises en compte (vous ne gérez pas tout dans des contrôleurs ? ) et tout changement ultérieur dans le fichier des routes n'est pas pris en compte dans le cache. Donc en cas de changement il faut relancer la commande. On peut imaginer ne lancer cette commande que sur le serveur de production sans oublier qu'on l'a fait . On peut aussi juste vider le cache avec php artisan route:clear.

Conclusion

Tout ce que je vous ai dit ici est évidemment susceptible d'évoluer jusqu'à la sortie définitive prévue en novembre mais les grandes lignes seront présentes. Il va falloir revoir nos habitudes et rénover les tutoriels ! Je prévois de lancer une rubrique Laravel 5 pour présenter cette nouvelle version avec un souci didactique comme je l'avais fait pour la version 4.

Si vous avez des attentes particulières concernant cette version dépêchez-vous de faire un pull request sur Github ! Au moment où j'écris ces lignes il y en a encore 8 ouverts pour cette version mais qui portent sur des détails du code, ce qui me fait penser qu'on en est arrivés à une certaine stabilité.



Par bestmomo

Nombre de commentaires : 13