Samouczek Laravela dla początkujących

Co to jest Laravel?

laravel to framework MVC o otwartym kodzie źródłowym dla PHP. Laravel to solidna platforma zapewniająca łatwe tworzenie aplikacji internetowych PHP z funkcjami takimi jak modułowy system pakowania z dedykowanym menedżerem zależności, dostęp do relacyjnych baz danych i inne narzędzia do wdrażania i konserwacji aplikacji.

Laravel został stworzony przez Taylora Otwella. Od czasu swojej pierwszej wersji w czerwcu 2011 r. (wersja 1) stale zyskuje ona coraz większą popularność w sektorze frameworków PHP w branży tworzenia stron internetowych. Dużą część tej popularności można przypisać wielu funkcjom przeznaczonym dla programistów, które są dostępne w magazynie.

Dlaczego Laravel?

Większość około 2000 roku Kody PHP miał charakter proceduralny i można go było znaleźć w formie „skryptów”, które zawierałyby splątany bałagan w kodzie spaghetti. Nawet najprostsze strony nie miały rozdzielenie obaw, w związku z czym dość łatwo aplikacja szybko przerodziła się w koszmar związany z utrzymaniem. Świat potrzebował czegoś lepszego… Wejdź na PHP w wersji 5 i różnorodne frameworki PHP, próbując zapewnić bardzo potrzebne rozwiązanie i lepsze rozwiązania różnych problemów związanych z aplikacjami internetowymi.

Od tego czasu widzieliśmy wiele wydanych frameworków, które utorowałyby drogę popularnym frameworkom istniejącym i wykorzystywanym obecnie. Dzisiaj, naszym zdaniem, trzema najlepszymi są Zend Framework, Symfony i oczywiście Laravel. Chociaż każdy z tych frameworków został założony na podobnych zasadach i jest ukierunkowany na rozwiązywanie (zasadniczo) tych samych typowych problemów, ich kluczowe różnice leżą w implementacjach. Każdy z nich ma swoje własne dziwactwa dotyczące sposobu rozwiązywania problemów. Kiedy przyjrzysz się kodowi wytworzonemu przez każdy z nich, zobaczysz, że istnieje dość wyraźna granica oddzielająca je od siebie. Naszym skromnym zdaniem, framework Laravel jest najlepszy.

Dowiedz się więcej o: Różnica między Laravelem a CodeIgniterem

Jak pobrać i zainstalować Laravel za pomocą Composera

UWAGA Zakłada się, że masz już zainstalowaną kopię PHP w swoim systemie lokalnym. Jeśli nie, możesz przeczytać, jak go zainstalować tutaj

Composer jest zarówno menedżerem pakietów, jak i zależności. Aby go zainstalować, otwórz terminal i cd do nowego katalogu. Uruchom to polecenie:

curl -Ss getcomposer.org/installer | php

Wyniki tego polecenia będą wyglądać następująco:

Pobierz i zainstaluj Laravel z Composerem

Note Bardziej szczegółowe instrukcje dotyczące konfiguracji Laravela można znaleźć w dokumentacji Laravela tutaj.

Zobaczysz, jak pobiera i kompiluje skrypt composer.phar, którego używamy do instalacji Laravela. Chociaż istnieje wiele sposobów na skonfigurowanie nowej aplikacji Laravel, zrobimy to za pomocą skryptu Laravel composer. Aby zainstalować ten skrypt, uruchom:

composer global require laravel/installer

Które będą wyglądać mniej więcej tak:

Pobierz i zainstaluj Laravel z Composerem

Spowoduje to pobranie i zainstalowanie wszystkich plików frameworka, a także wszystkich wymaganych przez niego zależności. Pakiety zostaną zapisane w katalogu dostawcy. Po pobraniu i zainstalowaniu wystarczy wydać następujące polecenie:

laravel new uploadApp

Zobaczysz coś takiego:

Pobierz i zainstaluj Laravel z Composerem

Composer instaluje wszystkie pakiety, których Laravel potrzebuje do uruchomienia. Może to potrwać kilka minut, więc bądź cierpliwy. Po zakończeniu uruchom polecenie ls -al, aby sprawdzić, co zostało zainstalowane.

Oto krótki opis katalogów w popularnej aplikacji Laravel:

  • aplikacja/ : To jest folder źródłowy, w którym znajduje się kod naszej aplikacji. Wszystkie kontrolery, zasady i modele znajdują się w tym folderze
  • bootstrap/ : Przechowuje skrypt startowy aplikacji i kilka plików map klas
  • konfiguracja/ : Przechowuje pliki konfiguracyjne aplikacji. Zwykle nie są one modyfikowane bezpośrednio, ale zamiast tego opierają się na wartościach skonfigurowanych w pliku .env (środowisko) w katalogu głównym aplikacji
  • Baza danych/ : Zawiera pliki bazy danych, w tym migracje, nasiona i fabryki testowe
  • publiczny/ : Publicznie dostępny folder zawierający skompilowane zasoby i oczywiście plik Index.php
  • zasoby/ : Zawiera zasoby front-end, takie jak pliki javascript, pliki językowe, pliki CSS/SASS i wszystkie szablony używane w aplikacji (zwane szablonami blade)
  • trasy/ : Wszystkie trasy w aplikacji znajdują się tutaj. Istnieje kilka różnych „zakresów” tras, ale skupimy się na pliku web.php
  • składowanie/ : Wszystkie tymczasowe pliki pamięci podręcznej używane przez aplikację, pliki sesji, skrypty widoku skompilowanego i pliki dziennika
  • testy/ : Zawiera pliki testowe aplikacji, takie jak testy jednostkowe i testy funkcjonalne.
  • sprzedawca/ : Wszystkie pakiety zależności zainstalowane za pomocą kompozytora

Teraz zbudujmy resztę aplikacji i uruchommy ją za pomocą specjalnego polecenia rzemieślnika (aby zaoszczędzić sobie kłopotów z instalacją i konfiguracją serwera WWW, takiego jak Apache lub Nginx). Plik .env zawiera wszystkie wartości konfiguracyjne, których pliki w katalogu /config używają do konfigurowania aplikacji. Wewnątrz zauważysz, że wartość konfiguracyjna różnych parametrów jest używana przez elementy wewnętrzne aplikacji.

Projekt aplikacji: Krótkie podsumowanie naszych wymagań

W tym internetowym samouczku Laravel będziemy budować bardzo prostą aplikację, która zrobi tylko dwie rzeczy:

  1. obsługiwać przesyłanie plików z formularza internetowego
  2. wyświetlenie wcześniej przesłanych plików na innej stronie.

W przypadku tego projektu nasza aplikacja będzie przeznaczona tylko do zapisu, co oznacza, że ​​użytkownik będzie mógł jedynie zapisywać pliki i przeglądać listę plików, które przesłał. Ta aplikacja jest niezwykle prosta, ale powinna służyć jako dobra praktyka, abyś mógł zacząć budować swoje umiejętności i wiedzę w Laravel. Pamiętaj, że dla zachowania zwięzłości wykluczyłem wszelkie modelowanie baz danych, migracje i uwierzytelnianie, ale w rzeczywistych aplikacjach są to dodatkowe rzeczy, które warto wziąć pod uwagę.

Oto lista komponentów, które będą nam potrzebne, aby aplikacja działała zgodnie z oczekiwaniami:

  • A trasa który umożliwi światu zewnętrznemu (internetowi) korzystanie z aplikacji oraz określi punkt końcowy, który wskaże, gdzie znajduje się logika zapisująca przesłany plik
  • A kontroler który obsługuje przepływ żądania do odpowiedzi
  • A szablon który zostanie użyty do wyświetlenia listy wcześniej przesłanych plików i samego formularza przesyłania
  • A zażądać za pomocą których administrator będzie sprawdzał poprawność danych przekazanych z formularza internetowego

Co to jest trasa?

Trasa w Laravel to w zasadzie punkt końcowy określony przez URI, który działa jako „wskaźnik” do jakiejś funkcjonalności oferowanej przez aplikację. Najczęściej trasa po prostu wskazuje metodę na kontrolerze, a także określa, które metody HTTP mogą trafić do tego identyfikatora URI. Trasa nie zawsze oznacza metodę kontrolera; może po prostu przekazać wykonanie aplikacji do zdefiniowanego zamknięcia lub funkcji anonimowej.

Dlaczego warto korzystać z trasy?

Trasy są przechowywane w plikach w folderze /routes w katalogu głównym projektu. Domyślnie istnieje kilka różnych plików odpowiadających różnym „stronom” aplikacji („strony” pochodzą z metodologii architektury heksagonalnej). Obejmują one:

  • web.php Publiczne trasy oparte na „przeglądarce”. Są to najczęstsze i to właśnie one są atakowane przez przeglądarkę internetową. Działają one poprzez grupę oprogramowania pośredniego sieci Web i zawierają także udogodnienia dla ochrona CSRF (co pomaga chronić się przed złośliwymi atakami i hackami opartymi na formularzach) i ogólnie zawiera pewien stopień „stanu” (przez to mam na myśli wykorzystanie sesji)
  • api.php Trasy, które odpowiadają grupie API i dlatego mają domyślnie włączone oprogramowanie pośredniczące API. Trasy te są bezstanowe i nie mają sesji ani pamięci między żądaniami (jedno żądanie nie udostępnia danych ani pamięci żadnemu innemu żądaniu — każde z nich jest samokapsułkowane).
  • console.php Te trasy odpowiadają niestandardowym poleceniom rzemieślnika, które utworzyłeś dla swojej aplikacji
  • kanały.php Rejestruje trasy do transmisji wydarzeń

Najważniejszym plikiem, którym należy się w tym momencie zająć, jest plik specyficzny dla przeglądarki, web.php . Domyślnie zdefiniowana jest już jedna trasa, którą wybierasz bezpośrednio podczas przechodzenia do katalogu głównego aplikacji (katalog główny sieci znajduje się w katalogu publicznym). Będziemy potrzebować trzech różnych tras, aby nasza aplikacja do przesyłania mogła działać:

  • /upload To będzie URI strony głównej wyświetlającej nasz formularz internetowy do przesyłania plików.
  • /proces Tutaj formularz znajdujący się pod adresem URI /upload wysyła dane przesłane z formularza do („akcja” formularza)
  • /list Wyświetla listę wszystkich plików przesłanych do serwisu

noty Punkt końcowy /list może nie być potrzebny, jeśli chcielibyśmy umieścić całą logikę wyświetlania formularza przesyłania i listy plików na jednej stronie, jednak na razie trzymaliśmy je oddzielnie, aby dodać trochę więcej uwagi do omawianego tematu .

//inside routes/web.php
Route::get('/upload', 'UploadController@upload')->name('upload');
Route::get('/download, 'UploadController@download)->name(‘download');
Route::post('/process', 'UploadController@process')->name('process');
Route::get('/list', 'UploadController@list')->name('list');

W tym samouczku dotyczącym frameworka Laravel dla każdej żądanej trasy umieścimy ją jawnie w pliku tras web.php przy użyciu jednej z dostępnych metod żądania specyficznych dla protokołu HTTP (get(), post(), put() , Delete(), patch() lub opcje() ). Aby zapoznać się z podziałem każdego z nich, sprawdź to na zewnątrz. Metody te określają, które czasowniki HTTP mogą uzyskać dostęp do danej trasy. Jeśli potrzebujesz trasy, która będzie w stanie zaakceptować więcej niż jeden czasownik HTTP (co może mieć miejsce, jeśli używasz jednej strony do wyświetlania danych początkowych i danych przesłanych do formularza), możesz użyć Route::any( ) metoda.

Drugim argumentem metody Route::get() i Route::post() (oraz dowolnej innej metody opartej na poleceniach HTTP na fasadzie Route) jest nazwa określonego kontrolera i metoda umieszczona w tym kontrolerze, która zostaje wykonana po dotarciu do punktu końcowego trasy za pomocą dozwolonego żądania HTTP (GET, POST, PATCH itd.). Używamy kontrolera UploadController dla wszystkich trzech tras i określiliśmy je w następujący sposób:

Co to jest trasa

Ostatnią metodą, którą wywołujemy na każdej trasie, jest jej funkcja name(), która przyjmuje pojedynczy ciąg znaków jako argument i służy do mniej więcej „oznaczenia” konkretnej trasy łatwą do zapamiętania nazwą (w naszym przypadku jest to przesyłanie, przetwarzanie i wyświetlanie listy). Zdaję sobie sprawę, że nadawanie każdej trasie własnej nazwy, gdy adres URL ma dokładnie taką samą nazwę, nie wydaje się zbyt świetną funkcją, ale naprawdę przydaje się, gdy masz konkretną trasę, taką jak /users/profile/dashboard/config, który byłby łatwiejszy do zapamiętania jako profile-admin lub user-config.

Uwaga dotycząca fasad:

  • Fasady zapewniają „statyczny” interfejs dla klas dostępnych w kontenerze usług aplikacji.
  • Zapewniają zwięzłą, zapadającą w pamięć składnię, która pozwala korzystać z funkcji Laravela bez zapamiętywania długich nazw klas, które należy wprowadzić lub skonfigurować ręcznie.

Powyższe definicje tras w tym samouczku frameworka Laravel, używamy fasady Route zamiast ręcznego tworzenia nowego obiektu Illuminate/Routing/Router i wywoływania odpowiednich metod na tym obiekcie. To po prostu skrót, który oszczędza pisanie. Fasady są często używane w całym środowisku Laravel — możesz i powinieneś się z nimi lepiej zapoznać. Dokumentację Fasady można znaleźć tutaj.

Co to jest kontroler?

Kontroler to „C” w architekturze „MVC” (Model-View-Controller), na której opiera się Laravel. Zadanie kontrolera można sprowadzić do tej prostej definicji: Otrzymuje żądanie od klienta i zwraca mu odpowiedź. Jest to podstawowa definicja, a także minimalne wymagania dowolnego kontrolera. To, co robi pomiędzy tymi dwoma rzeczami, jest ogólnie uważane za „akcję” kontrolera (lub „implementację trasy”). Pełni rolę drugiego punktu wejścia do aplikacji (pierwszym jest żądanie) dla klienta, który wysyła ładunek żądania (do którego przejdziemy dalej) do aplikacji, oczekując pewnego rodzaju odpowiedzi (w postaci strona sukcesu, przekierowanie, strona błędu lub jakikolwiek inny rodzaj odpowiedzi HTTP).

Kontroler robi (w zasadzie) to samo, co definicja trasy z anonimową funkcją ustawioną jako „akcja” w przypadku trafienia na tę trasę. Różnica polega na tym, że kontroler dobrze radzi sobie z rozdzielaniem obaw, podczas gdy trasa jest definiowana bezpośrednio w rzeczywistej definicji adresu URL, co w zasadzie oznacza, że ​​łączymy przypisany URI trasy z implementacją trasy lub kodem wykonywanym, gdy ta trasa jest uderzyć.

Na przykład poniższe dwa fragmenty kodu osiągną ten sam cel:

Przykład nr 1: Definicja i implementacja trasy w pojedynczym wywołaniu metody (w pliku tras web.php)

//inside routes/web.php
<?php
Route::get('/hello-world', function(Request $request) {
   $name = $request->name;
   return response()->make("<h1>Hello World! This is ".$name, 200);
});

Przykład nr 2: Definicja trasy znajduje się w Routes/web.php, ale jej implementacja znajduje się w klasie /app/Http/Controllers/HelloWorldController

//inside routes/web.php
<?php

Route::get('/hello-world', 'HelloWorldController@index')->name('hello-world');

------------------------------------------------------------------------------------
//inside app/Http/Controllers/HelloWorldController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloWorldController extends Controller
{
   public function index(Request $request)
   {
       $name = $request->name;
       return response()->make("<h1>Hello World! This is ".$name, 200);
   }
}

Chociaż przykład Laravela nr 2 wydaje się wymagać dużo więcej pracy (co nie jest prawdą – wystarczy tylko trochę więcej kodu), spójrz na korzyści, jakie zyskujemy, umieszczając zamiast tego naszą logikę akcji dla danej trasy „hello-world” wewnątrz kontrolera of z definicją trasy jako funkcją zwrotną:

  1. Nasza logika jest wyraźnie podzielona na własną klasę (oddzielenie problemów)
  2. Nasz kontroler jest skonfigurowany do późniejszego rozszerzenia, jeśli zajdzie potrzeba dodania do niego dodatkowych możliwości... Powiedzmy, że chcielibyśmy dodać funkcję „pożegnania świata”... W takim przypadku zmienilibyśmy nazwę kontrolera na bardziej ogólną „HelloController”, a następnie zdefiniowali dwie oddzielne metody, Witam() i do widzenia(). Musielibyśmy także zdefiniować dwie oddzielne trasy, które wyznaczałyby mapę /Witam i /do widzenia URI do odpowiedniej metody na kontrolerze. Jest to pożądane w porównaniu do zagęszczania pliku tras z implementacją każdej trasy zdefiniowaną jako funkcja wywołania zwrotnego.
  3. Laravel posiada wbudowaną możliwość buforowania wszystkich definicji tras w aplikacji, dzięki czemu przyspiesza czas znalezienia danej trasy (zwiększa wydajność aplikacji); Jednak będziesz mógł z tego skorzystać tylko wtedy, gdy wszystkie zdefiniowane przez Ciebie trasy w aplikacji zostaną skonfigurowane przy użyciu mapowań specyficznych dla kontrolera (patrz przykład nr 2 powyżej)

Uruchommy to polecenie, które wygeneruje dla nas nowy kontroler.

// ...inside the project's root directory:
php artisan make:controller UploadController   

Zasadniczo polecenie to generuje kod pośredniczący dla kontrolera o nazwie „UploadController” w głównym katalogu kontrolera pod adresem /app/Http/Controllers/UploadController.php. Możesz otworzyć ten plik i rzucić okiem. Jest to bardzo proste, ponieważ jest to tylko wycięta wersja kontrolera, z poprawną ścieżką do przestrzeni nazw i wymaganymi klasami, z których się rozciąga.

Generowanie żądania

Zanim przejdziemy dalej w tym samouczku PHP Laravel i wprowadzimy kilka zmian do wygenerowanego stubu UploadController, myślę, że bardziej sensowne będzie najpierw utworzenie klasy request. Wynika to z faktu, że metoda kontrolera, która obsługuje żądanie, musi zawierać wskazówkę typu obiektu request w swoim podpisie, co pozwala jej automatycznie walidować przychodzące dane formularza (zgodnie ze specyfikacją w metodzie rules(). Więcej na ten temat później…) Na razie użyjmy ponownie polecenia artisan, aby wygenerować nasz stub request:

php artisan make:request UploadFileRequest

To polecenie wygeneruje plik o nazwie UploadFileRequest w pliku app/Http/Requests/UploadFileRequest. Otwórz kod pośredniczący i zerknij… Przekonasz się, że jest to bardzo proste i zawiera tylko dwie metody: Authorize() i Rules.

Tworzenie logiki walidacji

Zmodyfikujmy fragment żądania, aby spełniał potrzeby naszej aplikacji. Zmodyfikuj plik tak, aby wyglądał następująco:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

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

   /**
    * Get the validation rules that apply to the request.
    *
    * @return array
    */
   public function rules()
   {
       return [
           'fileName' => 'required|string',
           'userFile' => 'required|file'
       ];
   }
}

Niewiele zmian, ale zauważ, że metodaauthorize() zwraca teraz wartość true zamiast false. Ta metoda decyduje, czy zezwolić żądaniu na przejście do aplikacji. Jeśli jest ustawiona na wartość false, uniemożliwia wprowadzenie żądania do systemu (co normalnie byłoby metodą na kontrolerze). Byłoby to bardzo przydatne miejsce do sprawdzenia autoryzacji użytkownika lub dowolnej innej logiki, która może zdecydować, czy żądanie może zostać przekazane dalej do kontrolera. Na razie po prostu zwracamy tutaj wartość true, aby umożliwić wszystkim korzystanie z żądania.

Druga metoda, Rules(), polega na tym, że w grę wchodzi cała magia związana z walidacją. Pomysł jest prosty: zwróć tablicę zawierającą zestaw reguł w postaci:

'formFieldName' => 'constraints this field has separated by pipe characters (|)'

Istnieje wiele różnych ograniczeń walidacyjnych, które są obsługiwane przez Laravel od razu po wyjęciu z pudełka. Aby uzyskać pełną listę, sprawdź dokumentację online tutaj. W przypadku naszej aplikacji do przesyłania danych będą dwa pola przekazywane za pośrednictwem żądania POST z formularza na froncie. Parametr fileName musi być zawarty w treści formularza (tj. wymagany) i jest używany jako nazwa pliku, pod którą będziemy przechowywać plik w magazynie (robi się to w kontrolerze – przejdziemy do tego nieco później). Określamy również, że nazwa pliku musi być ciągiem znaków, dodając znak pionowej kreski (|) i słowo „ciąg znaków”. Ograniczenia są zawsze ograniczone pionowymi kreskami, co pozwala określić wszelkie dodatkowe kryteria dla danego pola w jednym wierszu! Jaka moc!

Drugi parametr, userFile , to rzeczywisty plik, który użytkownik przesyła z formularza na stronie internetowej. Wymagany jest również plik UserFile i musi być plikiem. Uwaga: Gdybyśmy oczekiwali, że przesłany plik będzie obrazem, zamiast tego użylibyśmy ograniczenia obrazu, które ograniczyłoby typy plików akceptowane jako jeden z popularnych typów obrazów (jpeg, png, bmp, gif lub svg). Ponieważ chcemy umożliwić użytkownikowi przesyłanie dowolnego typu pliku, pozostaniemy przy ograniczeniu dotyczącym sprawdzania poprawności pliku.

To właściwie wszystko, co dotyczy obiektu żądania. Jego głównym zadaniem jest po prostu przechowywanie akceptowalnego zestawu kryteriów (ograniczeń), które muszą spełniać parametry treści formularza, aby móc przejść głębiej do aplikacji. Kolejną rzeczą wartą odnotowania jest to, że te dwa pola (userFile i filename) muszą być również określone w kodzie HTML w formie pól wejściowych (z nazwą pola odpowiadającą nazwie wewnątrz obiektu żądania).

Możesz zapytać: z pewnością definiuje to, co powinno zawierać żądanie formularza, ale gdzie przeprowadza się faktyczną kontrolę tych ograniczeń? Zajmiemy się tym dalej.

Modyfikowanie kontrolera

Otwórz app/Http/Controllers/UploadController i wprowadź następujące zmiany:

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use App\Http\Requests\UploadFileRequest; //our new request class
use Illuminate\Support\Facades\Storage; 

class UploadController extends Controller
{
   /**
    * This is the method that will simply list all the files uploaded by name and provide a
    * link to each one so they may be downloaded
    *
    * @param $request : A standard form request object
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    * @throws BindingResolutionException
    */
   public function list(Request $request)
   {
       $uploads = Storage::allFiles('uploads');

       return view('list', ['files' => $uploads]);
   }

   /**
    * @param $file
    * @return \Symfony\Component\HttpFoundation\BinaryFileResponse
    * @throws BindingResolutionException
    */
   public function download($file)
   {
       return response()->download(storage_path('app/'.$file));
   }

   /**
    * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
    * @throws BindingResolutionException
    */
   public function upload()
   {
       return view('upload');
   }

   /**
    * This method will handle the file uploads. Notice that the parameter's typehint
    * is the exact request class we generated in the last step. There is a reason for this!
    *
    * @param $request : The special form request for our upload application
    * @return array|\Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|null
    * @throws BindingResolutionException
    */
   public function store(UploadFileRequest $request)
   {
       //At this point, the parameters passed into the $request (from form) are
       //valid--they satisfy each of the conditions inside the rules() method

       $filename = $request->fileName;    //parameters have already been validated
       $file = $request->file('userFile'); //that we don't need any additional isset()

       $extension = $file->getClientOriginalExtension(); //grab the file extension
       $saveAs = $filename . "." . $extension; //filename to save file under

       $file->storeAs('uploads', $saveAs, 'local'); //save the file to local folder

       return response()->json(['success' => true]); //return a success message
   }
}

Jest to więc dość proste podejście do zapisywania przesłanych plików na dysk. Oto opis metody upload() powyżej:

  • Wpisz wskazówkę dotyczącą klasy żądania w metodzie kontrolera, która wykonuje funkcję „mięso i ziemniaki”, abyśmy mogli automatycznie zweryfikować przychodzące dane
  • Pobieramy plik z (teraz sprawdzonego) obiektu żądania wewnątrz metody kontrolera (w tym przypadku nazwaliśmy go upload(), ale można go było również nazwać bardziej standardową nazwą, np. store()).
  • Pobierz nazwę pliku z żądania
  • Wygeneruj ostateczną nazwę pliku, pod którą zostanie zapisany plik. Metoda getClientOriginalExtension() po prostu pobiera oryginalne rozszerzenie przesłanego pliku.
  • Zapisz plik w lokalnym systemie plików, używając metody storeAs(), przekazując nazwaną ścieżkę wewnątrz katalogu /storage jako pierwszy argument i nazwę pliku, pod którym ma zostać zapisany, jako drugi.
  • Zwróć odpowiedź JSON wskazującą, że żądanie powiodło się

Szablon ostrza

Ostatnim ważnym elementem tej układanki jest szablon blade, który będzie zawierał cały kod HTML, CSS i javascript dla naszej prostej aplikacji. Oto kod – wyjaśnimy go później.

<body>
   <h1>Upload a file</h1>
   <form id="uploadForm" name="uploadForm" action="{{route('upload')}}" enctype="multipart/form-data">
       @csrf
       <label for="fileName">File Name:</label>
       <input type="text" name="fileName" id="fileName" required /><br />
       <label for="userFile">Select a File</label>
       <input type="file" name="userFile" id="userFile" required />
       <button type="submit" name="submit">Submit</button>
   </form>
   <h2 id="success" style="color:green;display:none">Successfully uploaded file</h2>
   <h2 id="error" style="color:red;display:none">Error Submitting File</h2>
   <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
   <script>
        $('#uploadForm').on('submit', function(e) {
            e.preventDefault();
            var form = $(this);
            var url = form.attr('action');
            $.ajax({
                url: url,
                type: "POST",
                data: new FormData(this),
                processData: false,
                contentType: false,
                dataType: "JSON",
                success: function(data) {
                    $("#fileName").val("");
                    $("#userFile").val("");
                }
            }).done(function() {
                $('#success').css('display', 'block');
                window.setTimeout(()=>($("#success").css('display', 'none')), 5000);
            }).fail(function() {
                $('#error').css('display', 'block');
                window.setTimeout(()=>($("#error").css('display', 'none')), 5000);
            });
        });
   </script>
</body>
</html>

Oto, co nasze / Przekazać plik strona wygląda następująco:

Szablon ostrza

To bardzo typowy przykład pliku blade zawierającego formularz HTML i javascript/jQuery do dodawania asynchronicznej funkcjonalności (aby strona się nie odświeżała). Istnieje podstawowy tag bez atrybutu metody (który wyjaśnię za chwilę) i z ciekawym atrybutem akcji o wartości {{route('file.upload')}}. W blade jest to znane jako Dyrektywa. Dyrektywa to po prostu wymyślna nazwa funkcji – są to funkcje specyficzne dla szablonów blade, które wykonują różne operacje typowe dla tworzenia stron internetowych i aplikacji internetowych. Aby lepiej zrozumieć wszystkie fajne rzeczy, które blade potrafi zrobić, sprawdź dokumentację tutaj. W powyższym przypadku używamy dyrektywy Route do wygenerowania adresu URL do przesłania formularza.

Pamiętaj, że nasze trasy zdefiniowaliśmy wcześniej w aplikacji w pliku web.php, podając dla każdej z nich łatwą do zapamiętania nazwę. Dyrektywa {{route()}} akceptuje nazwę trasy, wyszukuje ją na wewnętrznie buforowanej liście tras i generuje pełny adres URL w oparciu o definicję tej trasy w pliku web.php. W tym pierwszym przypadku określamy, że chcemy, aby formularz wysyłał przesłane dane na adres URL /proces naszej aplikacji, który jest zdefiniowany jako POST trasa.

Następną dziwną rzeczą, którą mogłeś zauważyć, jest tag @csrf tuż pod tagiem formularza otwierającego. W bloku ten tag generuje parametr _token w formularzu, który jest sprawdzany w aplikacji, zanim dane formularza będą mogły zostać przetworzone. Gwarantuje to, że dane w formularzu mają prawidłowe pochodzenie i zapobiega atakom polegającym na fałszowaniu żądań między witrynami. Więcej informacji na ten temat znajdziesz w docs.

Następnie definiujemy nasz formularz jako normalny, jednak należy pamiętać, że nazwy naszych parametrów formularza, userFile i fileName, są dokładnie to samo zgodnie z definicją wewnątrz naszego obiektu żądania. Jeśli zapomnimy podać dane wejściowe dla danego parametru, który został zdefiniowany w obiekcie żądania (lub zostanie on błędnie napisany), żądanie zakończy się niepowodzeniem i zwrócony zostanie błąd, uniemożliwiając trafienie pierwotnego żądania formularza do metody kontrolera znajdującej się pod adresem UploadController@ proces .

Śmiało, wypróbuj i prześlij kilka plików do aplikacji za pomocą tego formularza. Następnie przejdź do /lista stronę, na której możesz zobaczyć zawartość folderu przesyłania, wraz z listą przesłanych plików w tabeli:

Szablon ostrza

Szerszy

Cofnijmy się o krok i przyjrzyjmy się, co zrobiliśmy w tym samouczku Laravel.

Na tym diagramie przedstawiono aplikację w jej obecnym stanie (bez szczegółów ogólnych):

Schemat tutoriala Laravela

Powinieneś pamiętać, że obiekt żądania, który skonstruowaliśmy na początku tego samouczka Laravel, powinien mieć te same parametry zdefiniowane w metodzie reguł, co w formularzu w szablonie bloku (jeśli nie, przeczytaj ponownie sekcję „Tworzenie logiki walidacji”) . Użytkownik wprowadza formularz na stronie internetowej renderowanej za pomocą silnika szablonów typu blade (proces ten odbywa się oczywiście na autopilocie, więc nie musimy nawet o tym myśleć) i przesyła formularz. Kod jQuery szablonu na dole zatrzymuje domyślne przesyłanie (które automatycznie przekierowuje na osobną stronę), tworzy żądanie ajax, ładuje żądanie danymi formularza i przesyła plik, a następnie wysyła całość do pierwszej warstwy naszego wniosek: prośba.

Obiekt żądania zostaje zapełniony poprzez powiązanie parametrów metody Rules() z parametrami przesłanego formularza, a następnie sprawdza poprawność danych zgodnie z każdą określoną regułą. Jeśli wszystkie reguły są spełnione, żądanie jest przekazywane do dowolnej metody kontrolera, która odpowiada wartościom zdefiniowanym w pliku trasy web.php. W tym przypadku działa metoda Process() kontrolera UploadController. Gdy trafimy na kontroler, wiemy już, że żądanie przeszło weryfikację, więc nie musimy ponownie testować, czy podana nazwa pliku jest w rzeczywistości ciągiem znaków lub parametr userFile faktycznie zawiera jakiś typ pliku… Możemy kontynuować normalna.

Następnie metoda kontrolera pobiera sprawdzone parametry z obiektu żądania, generuje pełną nazwę pliku poprzez połączenie przekazanego parametru fileName z oryginalnym rozszerzeniem userFile, przechowuje plik w katalogu w naszej aplikacji, a następnie zwraca prosty kod zakodowany w formacie JSON odpowiedź weryfikująca, czy żądanie powiodło się. Odpowiedź jest odbierana przez logikę jQuery, która wykonuje kilka dodatkowych zadań związanych z interfejsem użytkownika, takich jak wyświetlanie komunikatu o powodzeniu (lub błędzie) przez 5 sekund, a następnie ukrywanie go i usuwanie poprzednich wpisów formularza… o tym użytkownik wie upewnij się, że żądanie powiodło się i jeśli chcesz, możesz przesłać kolejny plik.

Zwróć również uwagę na diagram powyżej, gdzie dokładnie przebiega linia między klientem a serwerem. Ta koncepcja jest absolutnie krytyczna, abyś ją zrozumiał i pomoże ci rozwiązać problemy i kwestie, które możesz mieć w przyszłości, na przykład żonglując wieloma asynchronicznymi żądaniami, które mogą wystąpić w dowolnym momencie. Separacja znajduje się tuż na granicy obiektu żądania. Sam obiekt żądania można postrzegać jako „bramę” do reszty aplikacji… Wykonuje on początkową walidację i rejestrację wartości formularza przekazanych z przeglądarki internetowej. Jeśli zostaną uznane za prawidłowe, kontynuuje działanie do kontrolera. Wszystko, co było przed tym, znajduje się na froncie („klient” dosłownie oznacza „na komputerze użytkownika”). Odpowiedź jest zwracana z aplikacji z powrotem do strony klienta, gdzie nasz kod jQuery cierpliwie nasłuchuje jej nadejścia i wykonuje kilka prostych zadań interfejsu użytkownika po jej otrzymaniu.

Omówiliśmy prawie 90+ ważnych, często zadawanych pytań Pytania do rozmowy kwalifikacyjnej związane z Laravelem i PHP zarówno nowicjuszom, jak i doświadczonym kandydatom na znalezienie właściwej pracy.