Laravel

De Banane Atomic
Version datée du 8 avril 2018 à 09:27 par Nicolas (discussion | contributions) (→‎Routing)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigationAller à la recherche

Liens

Description

Framework PHP MVC

Layout

resources/views/layouts/master.blade.php
<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>
    </head>
    <body>
        @yield('content')
    </body>
</html>
resources/views/welcome.blade.php
// utilise le layout du dossier layouts nommé master.blade.php
@extends('layouts.master')

@section('content')
    <h1>Some Content</h1>
@endsection

Partial View

resources/views/partials/header.blade.php
<!-- contenu de ma partial view -->
Php.svg
// incorporation de la partial view header
@include('partials.header')

Routing

Bash.svg
# lister les routes
php artisan route:list
routes/web.php
// route les requêtes get / vers la vue welcome (resources/views/welcome.blade.php)
Route::get('/', function () {
    return view('welcome');
})->name('root');

// route les requêtes get /mycontroller/{id} vers la vue blog/index (resources/views/blog/index.blade.php)
Route::get('/mycontroller/{id}', function ($id) {
    return view('blog.index', ['id' => $id]);
})->name('index');

// group
Route::group(['prefix' => 'mycontroller'], function () {
    Route::get('myaction1/{id}', function ($id) {
        return view('mycontroller.action1');
    })->name('action1');
    Route::get('myaction2/{id}', function ($id) {
        return view('mycontroller.action2');
    })->name('action2');
});

// post request
Route::post('create', function(Request $request) {
    return redirect()->route('index');
});
Html.svg
<a href="/">Root</a>
<a href="/index/1">Index</a>
<!-- même chose avec les nom des routes -->
<a href="{{ route('root') }}">Root</a>
<a href="{{ route('index', ['id' => 1]) }}">Index</a>

Responses

Php.svg
// retourne la vue resources/views/folder/view1.blade.php
// et passe $var1 à la vue
return view('folder.view1', ['var1' => $var1]);
// var1: nom de la variable passé, à utiliser comme $var1 dans la vue
// $var1: valeur passée dans var1

// retourne du texte brut
return "Texte brut";

// retourne du json
return Respounse::json(['key' => 'value']);

// redirection
return redirect()->route('index');

Blade

comments

Php.svg
{{-- Don't put the closing PHP comment */ in your comment --}}

if

Php.svg
@if($myVar == 0)
    <p>Zéro!</p>
@elseif($myVar == 1)
    <p>Un!</p>
@else
    <p>Autre!</p>
@endif

foreach

Php.svg
@foreach($myCollection as $item)
    <li>{{ $item }}</li>
@endforeach

for

Php.svg
@for($i = 0; $i < 5; $i++)
    <li>{{ $i }}</li>
@endfor

XSS

Php.svg
// affiché comme du texte
{{ "<script>alert('XSS');</script>" }}
// exécuté comme un script
{!! "<script>alert('XSS');</script>" !!}

CSS

public/css/myStyles.css
/* my css */
Html.svg
<link rel="stylesheet" href="css/myStyles.css">

Controller

Bash.svg
php artisan make:controller MyController
app/Http/Controllers/MyController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Session\Store;

class MyController extends Controller
{
    private $model;
    function __construct()
    {
        $this->model = new Model();
    }

    public function getAllItems(Store $session)
    {
        $items = $this->myModel->getAllItems($session);
        return view('index', ['items' => $items]);
    }

    public function editItem($id, Store $session)
    {
        $item = $this->model->getItem($id, $session);
        return view('edit', ['item' => $item]);
    }

    public function updateItem($id, Store $session, Request $request)
    {
        $item = $this->model->getItem($id, $session);
        $item->name = $request->input('name');
        return redirect(route('home'));
    }
}
routes/web.php
Route::get('/', [
    'uses' => 'MyController@getAllItems',
    'as' => 'home'
]);

// autre écriture
Route::get('/', 'MyController@getAllItems')->name('home');

Route::get('/edit/{id}', [
    'uses' => 'MyController@editItem',
    'as' => 'edit'
]);

Route::post('/edit/{id}', [
    'uses' => 'MyController@updateItem',
    'as' => 'update'
]);

Model

apps/MyModel.php
<?php

namespace App;

class MyModel
{
    public function getItems($session)
    {
        if (!$session->has('items')) {
            $this->fillData($session);
        }
        return $session->get('items');
    }

    private function fillData($session)
    {
        $items = [ 'item1', 'item2' ];
        $session->put('items', $items);
    }
}

Mix

Bash.svg
# Run all Mix tasks...
npm run dev

# Run all Mix tasks and minify output...
npm run production

# Watching Assets For Changes
# The npm run watch command will continue running in your terminal and watch all relevant files for changes.
# Webpack will then automatically recompile your assets when it detects a change:
npm run watch
webpack.mix.js
let mix = require('laravel-mix');

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');

Elixir

Bash.svg
# installer gulp en global pour qu'il soit accessible en ligne de commande
npm install -g gulp

# installer les packets nodejs listés dans le fichier package.json
npm install
# installer laravel-elixir
npm install --save-dev laravel-elixir

# exécuter les taches gulp
gulp

# exécute les taches gulp si un fichier de resources/* change
gulp watch
gulpfile.js
var elixir = require('laravel-elixir');

// resources/assets/css
elixir(function(mix) {
    mix.sass("app.scss");
});
Html.svg
<!-- inclure l'asset css/app.css -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" >
resources/assets/sass/app.scss
// Fonts
@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");

// Variables
@import "variables";

// Bootstrap
//@import '~bootstrap/scss/bootstrap';
@import 'node_modules/bootstrap/scss/bootstrap';

.navbar-laravel {
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
}

/* My scss code */

Font Awesome

Bash.svg
npm install font-awesome --save
resources/assets/sass/app.scss
@import "node_modules/font-awesome/scss/font-awesome";
Bash.svg
npm run dev
# copie node_modules/font-awesome/fonts dans public/fonts/vendor/font-awesome
# agrège les fichiers node_modules/font-awesome/scss/*.scss dans public/css/app.css

MSBUILD : error MSB3428: Could not load the Visual C++ component "VCBuild.exe"

Powershell.svg
# dans un terminal en administrateur
npm install --global --production windows-build-tools

Eloquent ORM

Data Validation

Html.svg
@if(count($errors->all()))
    <div class="row">
        <div class="col-md-12">
            <div class="alert alert-danger">
                <ul>
                    @foreach($errors->all() as $error)
                        <li>{{ $error }}</li>
                    @endforeach
app/Http/Controllers/MyController.php
public function postCreate(Store $session, Request $request)
{
    $this->validate($request, [
        // input id => builtin rules
        'login' => 'required|min:3'
    ]);
}
routes/web.php
Route::post('create', function(Request $request, Factory $validator)) {
    $validation = $validator->make($request->all(), [
        // input id => builtin rules
        'login' => 'required|min:3'
    ]);
    
    if ($validation->fails()) {
        return redirect()->back()->withErrors($validation);
    }
}

Session

Php.svg
// Store $session
// $request->session()

// ajouter un élément
$session->put('key', $item);
// obtenir un élément à partir de sa clé
$item = $session->get('key');
// supprimer un élément à partir de sa clé
$session->forget('key');

// si l'élément est un tableau
$items = [ new Item(1, 'item1'), new Item(2, 'item2') ];
$session->put('main_key', $items);
// supprimer un élément du tableau
if(($array_key = array_search($item, $items, true)) !== FALSE) {
    $session->forget('main_key.' . $array_key);
}
// ajouter un élément au tableau
$session->push('key', $item);
routes/web.php
Route::post('edit', function(Request $request) {
    return redirect()
        ->route('index')
        // ajoute à la session la variable info
        // $request->input('value1'): récupère la valeur du champs value1
        ->with('info', 'My value: ' . $request->input('value1'));
})->name('update');
Php.svg
@if(Session::has('info'))
    // disponible au premier affichage de la page
    {{ Session::get('info') }}
@endif

form

Classe Form

Retiré de core mais disponible dans laravelcollective
Bash.svg
composer require "laravelcollective/html"
Php.svg
// Post par défaut
{{ Form::open(['route' => ['myroute', $var1]]) }}
{{ Form::open(['action' => ['MyController@myaction', $var1]]) }}

{{ Form::text('name', $value = $var2) }}
{{ Form::submit('Yes', ['name' => 'yes', 'class' => 'btn btn-danger btn-xs']) }}
{{ Form::submit('No', ['name' => 'no', 'class' => 'btn btn-danger btn-xs']) }}

{{ Form::close() }}
Php.svg
if ($request->input('yes')) {
    // ...
}

CSRF Protection

Mécanisme de protection contre les urls malicieuses fabriquées.

Html.svg
<form>
    <input type="text" name="field1">
    <input type="hidden" name="_token" value="{{csrf_token()}}">
    <!-- Ou -->
    {{ csrf_field() }}
    <button type="submit">
</form>

Visual Studio Code

  • Pas de Formatting pour le code PHP

Extensions:

  • Laravel Extension Pack
    • Laravel Blade Snippets
    • Laravel 5 Snippets
    • Laravel Artisan
    • PHP Extensions
      • PHP Debug
      • PHP Intellisense
    • EditorConfig for VS Code
  • phpfmt, formatter code PHP avec Alt + Shift + F

IDE

Visual Studio Code gratuit
Netbeans gratuit
Atom gratuit
PHP Storm payant
Sublime Text payant
Codelobster

Erreurs

Missing required parameters

Missing required parameters for [Route: myroute] [URI: myaction/{id}]. (View: /resources/views/myview.blade.php)
/resources/views/myview.blade.php
{{ Form::open(['action' => 'MyController@myaction']) }}
// spécifier le paramètre
{{ Form::open(['action' => ['MyController@myaction', 'id='.$item->id]]) }}
routes/web.php
Route::post('/myaction/{id}', [
    'uses' => 'MyController@myaction',
    'as' => 'myroute'
]);

Action App\Http\Controllers\MyController@MyAction not defined

Vérifier que le fichier routes/web.php contienne bien une route qui utilise MyController@MyAction

routes/web.php
Route::post('/MyController/MyAction', [
    'uses' => 'MyController@MyAction',
    'as' => 'MyRoute'
]);

Class 'Form' not found

Bash.svg
composer require "laravelcollective/html"

404 Not Found

Vérifier la config Nginx

unexpected '?' in helpers.php on line 233

Parse error: syntax error, unexpected '?' in C:\wamp64\www\laravel\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php on line 233

Passer à PHP 7

Installation

Archlinux

Bash.svg
# installer composer: Dependency Manager for PHP
pacman -S composer

#### LARAVEL INSTALLER
# télécharger l'installeur Laravel dans ~/.composer
composer global require "laravel/installer"
# créer un projet laravel dans MonDossier
laravel new MonDossier

#### COMPOSER
# créer un projet laravel dans MonDossier, l'installeur Laravel sera téléchargé dans ../.composer
composer create-project --prefer-dist laravel/laravel MyLaravelProject
# sans utiliser root
sudo -u http composer create-project laravel/laravel MyLaravelProject
sudo chown root:root MyLaravelProject

# droits d'écriture
chown -R http:http storage/
#find storage/* -type d -print0 | xargs -0 chown http:http
#chown http:http bootstrap/cache
/etc/nginx/laravel.conf
server {
    listen      80;
    server_name laravel.my-domain.fr;
    root        /srv/http/laravel/public;
    index       index.php;

    location / {
        # $is_args = ? if a request line has arguments, or an empty string otherwise
        try_files $uri $uri/ /index.php$is_args$args;
    }
    
    # uwsgi
    location = /index.php {
        include         uwsgi_params;
        uwsgi_modifier1 14;
        uwsgi_pass      unix:/run/uwsgi/laravel.sock;
    }

    # ou php-fpm
    location = /index.php {
        fastcgi_pass    unix:/var/run/php-fpm/php-fpm.sock;
        include         /etc/nginx/fastcgi.conf;
    }
}
/etc/uwsgi/laravel.ini
[uwsgi]
; maximum number of worker processes
processes = 4
; the user and group id of the process once it’s started
uid = http
gid = http
socket = /run/uwsgi/%n.sock
master = true
chdir = /srv/http/%n/public
; php
plugins = php
php-sapi-name = apache
php-docroot = /srv/http/%n/public
php-index = index.php
; clear environment on exit
vacuum = true

Windows

Powershell.svg
mkdir C:\wamp64\www\laravel
cd C:\wamp64\www\laravel

# créer le dossier MyLaravelProject et le projet laravel
composer create-project laravel/laravel MyLaravelProject --prefer-dist
# supprimer prefer-dist si ca ne fonctionne pas
C:\wamp64\bin\apache\apache2.x.x\conf\extra\httpd-vhosts.conf
<VirtualHost *:8080>
    ServerName laravel
    DocumentRoot "c:/wamp64/www/laravel/public"
    <Directory  "c:/wamp64/www/laravel/public/">
        Options +Indexes +Includes +FollowSymLinks +MultiViews
        AllowOverride All
        Require local
    </Directory>
</VirtualHost>