Laravel Tutorial για αρχάριους

Τι είναι η Laravel;

Laravel είναι ένα πλαίσιο MVC web ανοιχτού κώδικα για PHP. Το Laravel είναι ένα ισχυρό πλαίσιο που παρέχει εύκολη ανάπτυξη διαδικτυακών εφαρμογών PHP με χαρακτηριστικά όπως ένα αρθρωτό σύστημα συσκευασίας με έναν αποκλειστικό διαχειριστή εξαρτήσεων, πρόσβαση σε σχεσιακές βάσεις δεδομένων και άλλα βοηθητικά προγράμματα για ανάπτυξη και συντήρηση εφαρμογών.

Η Laravel δημιουργήθηκε από τον Taylor Otwell. Από την αρχική του κυκλοφορία τον Ιούνιο του 2011 (έκδοση 1), γίνεται σταθερά όλο και πιο δημοφιλής στον τομέα PHP-πλαισίων της βιομηχανίας ανάπτυξης ιστού. Μεγάλο μέρος αυτής της δημοτικότητας μπορεί να αποδοθεί στα πολλά χαρακτηριστικά που έχουν την πρώτη ματιά στους προγραμματιστές που συνοδεύει το απόθεμα.

Γιατί Laravel;

Περίπου το 2000, τα περισσότερα Κώδικες PHP ήταν διαδικαστικό και θα μπορούσε να βρεθεί με τη μορφή «σεναρίων» που θα είχαν ένα μπλεγμένο χάος από κώδικα σπαγγέτι. Ακόμα και οι πιο απλές σελίδες δεν είχαν διαχωρισμός των ανησυχιών, και έτσι ήταν αρκετά εύκολο για μια εφαρμογή να εξελιχθεί γρήγορα σε εφιάλτη συντήρησης. Ο κόσμος χρειαζόταν κάτι καλύτερο…Εισαγάγετε την έκδοση 5 της PHP και μια ποικιλία πλαισίων PHP, προσπαθώντας να φέρετε κάποια αναγκαία ανάλυση και καλύτερες λύσεις σε διάφορα προβλήματα εφαρμογών ιστού.

Από τότε έχουμε δει πολλά πλαίσια να κυκλοφορούν που θα άνοιξαν το δρόμο για τα δημοφιλή πλαίσια που υπάρχουν και χρησιμοποιούνται σήμερα. Σήμερα, οι τρεις πρώτες θα ήταν (κατά τη γνώμη μας) οι Zend Framework, Symfony και φυσικά η Laravel. Αν και καθένα από αυτά τα πλαίσια βασίστηκε σε παρόμοιες αρχές και είναι προσανατολισμένο στην επίλυση (βασικά) των ίδιων κοινών προβλημάτων, οι βασικές διαφορές τους έγκεινται στις υλοποιήσεις τους. Ο καθένας έχει τις δικές του ιδιορρυθμίες σχετικά με το πώς να επιλύσει προβλήματα. Όταν κοιτάξετε τον κώδικα που παράγεται από καθένα από αυτά, θα δείτε ότι υπάρχει μια αρκετά σταθερή γραμμή που τα χωρίζει το ένα από το άλλο. Κατά την ταπεινή μας γνώμη, το πλαίσιο Laravel είναι το καλύτερο.

Μάθετε περισσότερα σχετικά με Διαφορά μεταξύ Laravel και CodeIgniter

Πώς να κατεβάσετε και να εγκαταστήσετε το Laravel με το Composer

ΣΗΜΕΊΩΣΗ Υποτίθεται ότι έχετε ήδη ένα αντίγραφο της PHP εγκατεστημένο στο τοπικό σας σύστημα. Εάν όχι, μπορείτε να διαβάσετε πώς να το εγκαταστήσετε εδώ

Το Composer είναι ταυτόχρονα διαχειριστής πακέτων και εξαρτήσεων. Για να το εγκαταστήσετε, ανοίξτε ένα τερματικό και ένα cd σε έναν νέο κατάλογο. Εκτελέστε αυτήν την εντολή:

curl -Ss getcomposer.org/installer | php

Τα αποτελέσματα αυτής της εντολής θα μοιάζουν με αυτό:

Κατεβάστε και εγκαταστήστε το Laravel με το Composer

Σημείωση Για πιο εκτενείς οδηγίες σχετικά με τη ρύθμιση του Laravel, ανατρέξτε στην τεκμηρίωση Laravel εδώ.

Θα το δείτε να κατεβάζει και να μεταγλωττίζει το σενάριο composer.phar, το οποίο χρησιμοποιούμε για την εγκατάσταση του Laravel. Αν και υπάρχουν πολλοί τρόποι για να ρυθμίσετε μια νέα εφαρμογή Laravel, θα το κάνουμε μέσω του σεναρίου συνθέτη Laravel. Για να εγκαταστήσετε αυτό το σενάριο, εκτελέστε:

composer global require laravel/installer

Το οποίο θα μοιάζει κάπως έτσι:

Κατεβάστε και εγκαταστήστε το Laravel με το Composer

Αυτό θα κατεβάσει και θα εγκαταστήσει όλα τα ίδια τα αρχεία πλαισίου καθώς και όλες τις εξαρτήσεις που απαιτεί. Τα πακέτα θα αποθηκευτούν στον κατάλογο του προμηθευτή. Μόλις γίνει λήψη και εγκατάσταση, είναι τόσο εύκολο όσο η έκδοση της ακόλουθης εντολής:

laravel new uploadApp

Θα δείτε κάτι σαν την ακόλουθη έξοδο:

Κατεβάστε και εγκαταστήστε το Laravel με το Composer

Ο Composer εγκαθιστά όλα τα πακέτα που χρειάζεται η Laravel για να τρέξει. Μπορεί να χρειαστούν μερικά λεπτά, οπότε να είστε υπομονετικοί. Αφού τελειώσει, εκτελέστε μια εντολή ls -al για να ρίξετε μια ματιά σε αυτό που εγκαταστάθηκε.

Ακολουθεί μια σύντομη ανάλυση των καταλόγων σε μια κοινή εφαρμογή Laravel:

  • app/ : Αυτός είναι ο πηγαίος φάκελος όπου βρίσκεται ο κώδικας της εφαρμογής μας. Όλοι οι ελεγκτές, οι πολιτικές και τα μοντέλα βρίσκονται μέσα σε αυτόν τον φάκελο
  • bootstrap/ : Κρατάει το σενάριο εκκίνησης της εφαρμογής και μερικά αρχεία χάρτη τάξης
  • config/ : Διατηρεί τα αρχεία διαμόρφωσης της εφαρμογής. Συνήθως δεν τροποποιούνται απευθείας, αλλά βασίζονται στις τιμές που έχουν ρυθμιστεί στο αρχείο .env (περιβάλλον) στη ρίζα της εφαρμογής
  • βάση δεδομένων/ : Στεγάζει τα αρχεία της βάσης δεδομένων, συμπεριλαμβανομένων των μεταναστεύσεων, των σπόρων και των εργοστασίων δοκιμών
  • δημόσιο/ : Φάκελος προσβάσιμος από το κοινό που περιέχει μεταγλωττισμένα στοιχεία και φυσικά ένα αρχείο index.php
  • πόροι/ : Περιέχει στοιχεία διεπαφής όπως αρχεία javascript, αρχεία γλώσσας, αρχεία CSS/SASS και όλα τα πρότυπα που χρησιμοποιούνται στην εφαρμογή (που ονομάζονται πρότυπα blade)
  • διαδρομές/ : Όλες οι διαδρομές στην εφαρμογή είναι μέσα εδώ. Υπάρχουν μερικά διαφορετικά «πεδία» διαδρομών, αλλά αυτό στο οποίο θα επικεντρωθούμε είναι το αρχείο web.php
  • αποθήκευση/ : Όλα τα προσωρινά αρχεία κρυφής μνήμης που χρησιμοποιούνται από την εφαρμογή, αρχεία συνεδρίας, μεταγλωττισμένα σενάρια προβολής και αρχεία καταγραφής
  • τεστ/ : Περιέχει αρχεία δοκιμών για την εφαρμογή, όπως δοκιμές μονάδας και λειτουργικές δοκιμές.
  • Προμηθευτή/ : Όλα τα πακέτα εξάρτησης έχουν εγκατασταθεί με το composer

Τώρα, λοιπόν, ας δημιουργήσουμε την υπόλοιπη εφαρμογή και ας την εκτελέσουμε με μια ειδική εντολή artisan (για να γλυτώσουμε από την ταλαιπωρία εγκατάστασης και διαμόρφωσης ενός διακομιστή ιστού όπως ο Apache ή το nginx). Το αρχείο .env περιέχει όλες τις τιμές διαμόρφωσης που χρησιμοποιούν τα αρχεία στον κατάλογο /config για τη διαμόρφωση της εφαρμογής. Μέσα σε αυτό, θα παρατηρήσετε ότι η τιμή διαμόρφωσης για διάφορες παραμέτρους χρησιμοποιείται από τα εσωτερικά της εφαρμογής.

Σχεδιασμός εφαρμογής: Μια γρήγορη ανάλυση των απαιτήσεών μας

Σε αυτό το διαδικτυακό σεμινάριο Laravel, θα δημιουργήσουμε μια πολύ απλή εφαρμογή που θα κάνει μόνο δύο πράγματα:

  1. χειρίζονται μεταφορτώσεις αρχείων από μια φόρμα ιστού
  2. εμφάνιση των αρχείων που έχουν μεταφορτωθεί προηγουμένως σε διαφορετική σελίδα.

Για αυτό το έργο, η εφαρμογή μας θα είναι μόνο εγγραφή, που σημαίνει ότι ο χρήστης μπορεί να γράψει μόνο αρχεία και να δει τη λίστα των αρχείων που έχει ανεβάσει. Αυτή η εφαρμογή είναι εξαιρετικά βασική, αλλά θα πρέπει να χρησιμεύσει ως καλή πρακτική για να αρχίσετε να χτίζετε τις δεξιότητες και τις γνώσεις σας στο Laravel. Σημειώστε ότι για λόγους συντομίας, έχω αποκλείσει οποιαδήποτε μοντελοποίηση βάσης δεδομένων, μετεγκατάσταση και έλεγχο ταυτότητας, αλλά, σε μια εφαρμογή πραγματικού κόσμου, αυτά είναι πρόσθετα πράγματα που θα θέλατε να εξετάσετε.

Ακολουθεί μια λίστα με τα στοιχεία που θα χρειαστούμε για να λειτουργήσει η εφαρμογή όπως αναμένεται:

  • A Διαδρομή που θα επιτρέψει στον έξω κόσμο (διαδίκτυο) να χρησιμοποιήσει την εφαρμογή καθώς και θα καθορίσει το τελικό σημείο που θα δείχνει πού βρίσκεται η λογική για την αποθήκευση του μεταφορτωμένου αρχείου
  • A ελεγκτής που χειρίζεται τη ροή αιτήματος απόκρισης
  • A πρότυπο που θα χρησιμοποιηθεί για την εμφάνιση μιας λίστας αρχείων που έχουν μεταφορτωθεί προηγουμένως και της ίδιας της φόρμας μεταφόρτωσης
  • A ζητήσει που θα χρησιμοποιήσει ο ελεγκτής για την επικύρωση των δεδομένων που διαβιβάζονται από τη φόρμα Ιστού

Τι είναι μια διαδρομή;

Μια διαδρομή στο Laravel είναι βασικά ένα τελικό σημείο που καθορίζεται από ένα URI που λειτουργεί ως «δείκτης» σε κάποιο κομμάτι της λειτουργικότητας που προσφέρει η εφαρμογή. Συνηθέστερα, μια διαδρομή απλώς οδηγεί σε μια μέθοδο σε έναν ελεγκτή και επίσης υπαγορεύει ποιες μέθοδοι HTTP μπορούν να χτυπήσουν αυτό το URI. Μια διαδρομή δεν σημαίνει πάντα μέθοδος ελεγκτή. θα μπορούσε απλώς να περάσει την εκτέλεση της εφαρμογής σε ένα καθορισμένο κλείσιμο ή ανώνυμη συνάρτηση επίσης.

Γιατί να χρησιμοποιήσετε το Route;

Οι διαδρομές αποθηκεύονται μέσα σε αρχεία κάτω από το φάκελο /routes μέσα στον ριζικό κατάλογο του έργου. Από προεπιλογή, υπάρχουν μερικά διαφορετικά αρχεία που αντιστοιχούν στις διαφορετικές "πλευρές" της εφαρμογής (οι "πλευρές" προέρχονται από τη μεθοδολογία της εξαγωνικής αρχιτεκτονικής). Περιλαμβάνουν:

  • web.php Το κοινό που αντιμετωπίζει διαδρομές που βασίζονται σε πρόγραμμα περιήγησης. Αυτά είναι τα πιο συνηθισμένα και είναι αυτό που χτυπιέται από το πρόγραμμα περιήγησης ιστού. Εκτελούνται μέσω της ομάδας web middleware και περιέχουν επίσης εγκαταστάσεις για προστασία csrf (που βοηθά στην άμυνα ενάντια σε κακόβουλες επιθέσεις και εισβολές που βασίζονται σε φόρμες) και γενικά περιέχει έναν βαθμό "κατάστασης" (με αυτό εννοώ ότι χρησιμοποιούν συνεδρίες)
  • api.php Διαδρομές που αντιστοιχούν σε μια ομάδα API και επομένως έχουν ενεργοποιημένο το ενδιάμεσο λογισμικό API από προεπιλογή. Αυτές οι διαδρομές είναι ανιθαγενείς και δεν έχουν περιόδους σύνδεσης ή μνήμη πολλαπλών αιτημάτων (ένα αίτημα δεν μοιράζεται δεδομένα ή μνήμη με οποιοδήποτε άλλο αίτημα - καθεμία είναι αυτο-ενθυλακωμένη).
  • console.php Αυτές οι διαδρομές αντιστοιχούν σε προσαρμοσμένες εντολές artisan που έχετε δημιουργήσει για την εφαρμογή σας
  • channels.php Καταγράφει διαδρομές για μετάδοση συμβάντων

Το βασικό αρχείο που πρέπει να ασχοληθεί αυτή τη στιγμή είναι το ειδικό για το πρόγραμμα περιήγησης, web.php . Υπάρχει ήδη μια διαδρομή που ορίζεται από προεπιλογή, η οποία είναι αυτή που πατάτε δεξιά κατά την πλοήγηση στη ρίζα web της εφαρμογής σας (η ρίζα web βρίσκεται στον δημόσιο κατάλογο). Θα χρειαστούμε τρεις διαφορετικές διαδρομές για να λειτουργήσει η εφαρμογή μεταφόρτωσης:

  • /upload Αυτό θα είναι το URI της κύριας σελίδας που εμφανίζει τη φόρμα ιστού μας για τη μεταφόρτωση αρχείων.
  • /process Αυτό θα είναι όπου η φόρμα που βρίσκεται στο /upload URI δημοσιεύει τα δεδομένα που υποβλήθηκαν από τη φόρμα (η «ενέργεια» της φόρμας)
  • /list Αυτό θα εμφανίσει όλα τα αρχεία που έχουν μεταφορτωθεί στον ιστότοπο

σημείωση Το τελικό σημείο /list μπορεί να μην χρειάζεται αν θέλαμε να βάλουμε όλη τη λογική για την εμφάνιση της φόρμας μεταφόρτωσης και της λίστας των αρχείων σε μία μόνο σελίδα, ωστόσο, τα κρατήσαμε ξεχωριστά προς το παρόν για να προσθέσουμε λίγο περισσότερο θέμα στο θέμα. .

//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');

Σε αυτό το σεμινάριο πλαισίου Laravel, για κάθε επιθυμητή διαδρομή, θα την απαριθμήσουμε ρητά στο αρχείο διαδρομών web.php χρησιμοποιώντας μία από τις διαθέσιμες μεθόδους αιτήματος ειδικά για το HTTP (get(), post(), put() , delete(), patch() ή options() ). Για μια ανάλυση καθενός από αυτά, ελέγξτε αυτό έξω. Αυτό που κάνουν αυτές οι μέθοδοι είναι να καθορίσουν ποια ρήματα HTTP επιτρέπεται να έχουν πρόσβαση σε αυτήν τη δεδομένη διαδρομή. Εάν χρειάζεστε μια διαδρομή για να μπορέσετε να αποδεχτείτε περισσότερα από ένα ρήματα HTTP (κάτι που θα μπορούσε να συμβεί αν χρησιμοποιείτε μία σελίδα για να εμφανίσετε τα αρχικά δεδομένα και να δημοσιεύσετε δεδομένα φόρμας που υποβλήθηκαν), μπορείτε να χρησιμοποιήσετε το Route:: any( ) μέθοδος.

Το δεύτερο όρισμα τόσο για τη μέθοδο Route::get() όσο και για τη μέθοδο Route::post() (και οποιαδήποτε από τις άλλες μεθόδους που σχετίζονται με το ρήμα HTTP στην πρόσοψη της διαδρομής), είναι το όνομα ενός συγκεκριμένου ελεγκτή και μιας μεθόδου που στεγάζεται σε αυτό ελεγκτής που εκτελείται μόλις φτάσει στο τελικό σημείο της διαδρομής με το επιτρεπόμενο αίτημα HTTP (GET, POST, PATCH, κ.λπ.) Χρησιμοποιούμε το UploadController και για τις τρεις διαδρομές και τις έχουμε καθορίσει με τον ακόλουθο τρόπο:

Τι είναι μια διαδρομή

Η τελευταία μέθοδος που καλούμε σε κάθε διαδρομή είναι η συνάρτηση name() της, η οποία δέχεται μια μεμονωμένη συμβολοσειρά ως όρισμα και χρησιμοποιείται για να "επισημάνει" λίγο-πολύ μια συγκεκριμένη διαδρομή με εύκολη απομνημόνευση του ονόματος (στην περίπτωση μας, μεταφόρτωση, επεξεργασία και λίστα). Αντιλαμβάνομαι ότι δεν είναι τόσο σπουδαίο να δίνετε σε κάθε διαδρομή το δικό της όνομα όταν η διεύθυνση URL ονομάζεται ακριβώς το ίδιο, αλλά είναι πραγματικά χρήσιμο όταν έχετε μια συγκεκριμένη διαδρομή όπως /users/profile/dashboard/config, που θα ήταν πιο εύκολο να θυμάστε ως προφίλ-διαχειριστής ή διαμόρφωση χρήστη.

Σημείωση για τις προσόψεις:

  • Οι προσόψεις παρέχουν μια «στατική» διεπαφή σε κλάσεις που είναι διαθέσιμες στο κοντέινερ υπηρεσιών της εφαρμογής».
  • Παρέχουν μια συνοπτική, αξιομνημόνευτη σύνταξη που σας επιτρέπει να χρησιμοποιείτε τις δυνατότητες του Laravel χωρίς να θυμάστε μεγάλα ονόματα κλάσεων που πρέπει να εγχυθούν ή να ρυθμιστούν με μη αυτόματο τρόπο.

Οι παραπάνω ορισμοί διαδρομής σε αυτό το σεμινάριο πλαισίου Laravel, χρησιμοποιούμε την πρόσοψη διαδρομής αντί να δημιουργούμε με μη αυτόματο τρόπο ένα νέο αντικείμενο Illuminate/Routing/Router και να καλούμε τις αντίστοιχες μεθόδους σε αυτό το αντικείμενο. Είναι απλώς μια συντόμευση που εξοικονομεί την πληκτρολόγηση. Οι προσόψεις χρησιμοποιούνται σε μεγάλο βαθμό σε όλο το πλαίσιο Laravel – μπορείτε και πρέπει να εξοικειωθείτε περισσότερο με αυτές. Μπορείτε να βρείτε τα έγγραφα για τις προσόψεις εδώ.

Τι είναι ο ελεγκτής;

Ένας ελεγκτής είναι το "C" στην αρχιτεκτονική "MVC" (Model-View-Controller), στο οποίο βασίζεται η Laravel. Η δουλειά ενός ελεγκτή μπορεί να συνοψιστεί σε αυτόν τον απλό ορισμό: Λαμβάνει το αίτημα από τον πελάτη και επιστρέφει μια απάντηση στον πελάτη. Αυτός είναι ο ορισμός των bare-bones και είναι επίσης οι ελάχιστες απαιτήσεις κάθε δεδομένου ελεγκτή. Αυτό που κάνει μεταξύ αυτών των δύο πραγμάτων θεωρείται γενικά ως η «δράση» του ελεγκτή (ή η «υλοποίηση της διαδρομής»). Λειτουργεί ως το δεύτερο σημείο εισόδου στην εφαρμογή (το πρώτο είναι το αίτημα) στον πελάτη, ο οποίος στέλνει το ωφέλιμο φορτίο αιτήματος (στο οποίο θα φτάσουμε στη συνέχεια) στην εφαρμογή, αναμένοντας κάποιο είδος απάντησης (με τη μορφή σελίδα επιτυχίας, ανακατεύθυνση, σελίδα σφάλματος ή οποιοδήποτε άλλο είδος απόκρισης HTTP).

Ένας ελεγκτής κάνει (βασικά) το ίδιο πράγμα με έναν ορισμό διαδρομής με μια ανώνυμη συνάρτηση που έχει οριστεί ως «ενέργεια» όταν χτυπηθεί αυτή η διαδρομή. Η διαφορά είναι ότι ένας ελεγκτής αντέχει καλά στον διαχωρισμό των ανησυχιών ενώ μια διαδρομή ορίζεται ενσωματωμένα στον πραγματικό ορισμό της διεύθυνσης url, πράγμα που ουσιαστικά σημαίνει ότι συνδέουμε το URI που έχει εκχωρηθεί στη διαδρομή με την υλοποίηση της διαδρομής ή τον κώδικα που εκτελείται όταν αυτή η διαδρομή είναι Κτύπημα.

Για παράδειγμα, τα ακόλουθα δύο κομμάτια κώδικα θα επιτύχουν το ίδιο πράγμα:

Παράδειγμα #1: Ορισμός και υλοποίηση διαδρομής μέσα σε μια κλήση μεμονωμένης μεθόδου (στο αρχείο διαδρομών 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);
});

Παράδειγμα #2: Ο ορισμός της διαδρομής είναι μέσα σε routes/web.php, αλλά η εφαρμογή της βρίσκεται μέσα στην κλάση /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);
   }
}

Αν και το παράδειγμα #2 της Laravel φαίνεται να έχει πολύ περισσότερη δουλειά (κάτι που δεν είναι – απλώς λίγο περισσότερος κώδικας είναι όλο), κοιτάξτε τα οφέλη που αποκομίζουμε βάζοντας τη λογική δράσης μας για τη δεδομένη διαδρομή "hello-world" μέσα σε έναν ελεγκτή με τον ορισμό της διαδρομής ως συνάρτηση επανάκλησης:

  1. Η λογική μας χωρίζεται καθαρά στη δική της κατηγορία (διαχωρισμός ανησυχιών)
  2. Ο ελεγκτής μας έχει ρυθμιστεί για επέκταση αργότερα, εάν χρειαζόταν να του προσθέσουμε πρόσθετες δυνατότητες… Ας πούμε ότι ίσως θέλαμε να προσθέσουμε μια λειτουργία "αντίο-κόσμος"... Σε αυτήν την περίπτωση θα μετονομάζαμε τον ελεγκτή σε ένα πιο γενικό "HelloController" και στη συνέχεια θα ορίσουμε δύο ξεχωριστές μεθόδους, Γειά σου() και αντιο σας(). Θα χρειαστεί επίσης να ορίσουμε δύο ξεχωριστές διαδρομές που χαρτογράφησαν το /Γειά σου και / αντιο σας URI στην κατάλληλη μέθοδο τους στον ελεγκτή. Αυτό είναι επιθυμητό σε σύγκριση με το πάχυνση ενός αρχείου διαδρομών με την υλοποίηση κάθε διαδρομής να ορίζεται ως συναρτήσεις επανάκλησης.
  3. Η Laravel έχει την ενσωματωμένη δυνατότητα να αποθηκεύει προσωρινά όλους τους ορισμούς διαδρομής στην εφαρμογή, έτσι ώστε να επιταχύνει το χρόνο που χρειάζεται για να βρεθεί μια δεδομένη διαδρομή (αυξάνει την απόδοση της εφαρμογής). ωστόσο, θα μπορείτε να το εκμεταλλευτείτε μόνο εάν όλες οι καθορισμένες διαδρομές σας εντός της εφαρμογής έχουν ρυθμιστεί χρησιμοποιώντας αντιστοιχίσεις ειδικών για τον ελεγκτή (βλ. Παράδειγμα #2 παραπάνω)

Ας εκτελέσουμε αυτήν την εντολή που θα δημιουργήσει έναν νέο ελεγκτή για εμάς.

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

Ουσιαστικά, αυτό που κάνει αυτή η εντολή είναι να δημιουργεί ένα στέλεχος για έναν ελεγκτή που ονομάζεται "UploadController" μέσα στον κύριο κατάλογο του ελεγκτή στο /app/Http/Controllers/UploadController.php. Ανοίξτε αυτό το αρχείο και ρίξτε μια ματιά. Είναι πολύ απλό γιατί είναι μόνο μια αποκομμένη έκδοση του ελεγκτή, με τη σωστή διαδρομή χώρου ονομάτων και τις απαιτούμενες κλάσεις από τις οποίες εκτείνεται.

Δημιουργία του αιτήματος

Πριν προχωρήσουμε σε αυτό το σεμινάριο PHP Laravel και κάνουμε μερικές αλλαγές στο στέλεχος που δημιουργήθηκε από το UploadController, νομίζω ότι θα είναι πιο λογικό να δημιουργήσουμε πρώτα την κλάση αιτημάτων. Αυτό συμβαίνει επειδή η μέθοδος ελεγκτή που χειρίζεται το αίτημα πρέπει να πληκτρολογήσει hint το αντικείμενο αίτησης στην υπογραφή του, επιτρέποντάς του να επικυρώσει αυτόματα τα εισερχόμενα δεδομένα φόρμας (όπως ορίζεται στη μέθοδο rules(). Περισσότερα για αυτό αργότερα…) Προς το παρόν, ας χρησιμοποιήσουμε την εντολή artisan ξανά για να δημιουργήσουμε το στέλεχος αιτήματός μας:

php artisan make:request UploadFileRequest

Αυτή η εντολή θα δημιουργήσει ένα αρχείο που ονομάζεται UploadFileRequest μέσα στο app/Http/Requests/UploadFileRequest. Ανοίξτε το στέλεχος και ρίξτε μια ματιά… Θα το βρείτε πολύ απλό, περιέχει μόνο δύο μεθόδους, τη authorize() και τους κανόνες.

Δημιουργία της Λογικής Επικύρωσης

Ας τροποποιήσουμε το στέλεχος αιτήματος για να ικανοποιήσουμε τις ανάγκες της εφαρμογής μας. Τροποποιήστε το αρχείο έτσι ώστε να μοιάζει με αυτό:

<?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'
       ];
   }
}

Δεν υπάρχουν πολλές αλλαγές, αλλά παρατηρήστε ότι η μέθοδος authorize() επιστρέφει τώρα true αντί για false. Αυτή η μέθοδος αποφασίζει εάν θα επιτρέψει ή όχι την είσοδο στην αίτηση στην εφαρμογή. Εάν οριστεί σε false, διακόπτει την είσοδο του αιτήματος στο σύστημα (που κανονικά θα ήταν μια μέθοδος στον ελεγκτή). Αυτό θα ήταν ένα πολύ βολικό μέρος για να κάνετε τυχόν ελέγχους εξουσιοδότησης στον χρήστη ή οποιαδήποτε άλλη λογική που μπορεί να αποφασίσει εάν το αίτημα μπορεί να προχωρήσει στον ελεγκτή. Προς το παρόν, επιστρέφουμε απλώς true εδώ για να επιτρέψουμε σε οτιδήποτε και σε όλα να χρησιμοποιήσουν το αίτημα.

Η άλλη μέθοδος, κανόνες() είναι όπου μπαίνει όλη η μαγεία σε σχέση με την επικύρωση. Η ιδέα είναι απλή: επιστρέψτε έναν πίνακα που περιέχει ένα σύνολο κανόνων με τη μορφή:

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

Υπάρχουν πολλοί διαφορετικοί περιορισμοί επικύρωσης που υποστηρίζονται από τη Laravel αμέσως. Για μια πλήρη λίστα με αυτά, ανατρέξτε στην ηλεκτρονική τεκμηρίωση εδώ. Για την εφαρμογή μεταφόρτωσης, θα υπάρχουν δύο πεδία που μεταβιβάζονται μέσω αιτήματος POST από μια φόρμα στο μπροστινό μέρος. Η παράμετρος fileName πρέπει να περιλαμβάνεται μέσα στο σώμα της φόρμας (δηλαδή απαιτείται) και χρησιμοποιείται ως το όνομα αρχείου κάτω από το οποίο θα αποθηκεύσουμε το αρχείο στον χώρο αποθήκευσης (αυτό γίνεται στον ελεγκτή – θα φτάσουμε σε αυτό λίγο αργότερα). Καθορίζουμε επίσης ότι το όνομα του αρχείου πρέπει να είναι συμβολοσειρά προσθέτοντας έναν χαρακτήρα σωλήνα (|) και τη λέξη 'string'. Οι περιορισμοί οριοθετούνται πάντα από σωλήνες, επιτρέποντάς σας να καθορίσετε τυχόν πρόσθετα κριτήρια για το δεδομένο πεδίο σε μία μόνο γραμμή! Τι δύναμη!

Η δεύτερη παράμετρος, userFile , είναι το πραγματικό αρχείο που ανεβάζει ο χρήστης από μια φόρμα σε μια ιστοσελίδα. Απαιτείται επίσης UserFile και πρέπει να είναι αρχείο. Σημείωση: Αν περιμέναμε το μεταφορτωμένο αρχείο να είναι εικόνα, τότε θα χρησιμοποιούσαμε τον περιορισμό εικόνας, ο οποίος θα περιόριζε τους τύπους αρχείων που γίνονται αποδεκτοί ως ένας από τους δημοφιλείς τύπους εικόνας (jpeg, png, bmp, gif ή svg). Δεδομένου ότι θέλουμε να επιτρέψουμε στον χρήστη να ανεβάσει οποιονδήποτε τύπο αρχείου, θα τηρήσουμε απλώς τον περιορισμό επικύρωσης αρχείου.

Αυτό είναι το μόνο που υπάρχει στο αντικείμενο αίτησης. Η κύρια δουλειά του είναι απλώς να διατηρεί το αποδεκτό σύνολο κριτηρίων (περιορισμούς) που πρέπει να ικανοποιούν οι παράμετροι του σώματος της φόρμας προκειμένου να προχωρήσουμε βαθύτερα στην εφαρμογή. Ένα άλλο πράγμα που πρέπει να σημειωθεί είναι ότι αυτά τα δύο πεδία (userFile και filename) πρέπει επίσης να καθοριστούν μέσα στον κώδικα HTML με τη μορφή πεδίων εισαγωγής (με το όνομα πεδίου να αντιστοιχεί στο όνομα μέσα στο αντικείμενο αίτησης).

Ίσως ρωτάτε: βεβαίως αυτό καθορίζει τα χαρακτηριστικά του τι πρέπει να περιέχει ένα αίτημα φόρμας, αλλά πού γίνεται ο πραγματικός έλεγχος αυτών των περιορισμών; Θα μπούμε σε αυτό στη συνέχεια.

Τροποποίηση του ελεγκτή

Ανοίξτε την εφαρμογή/Http/Controllers/UploadController και κάντε τις ακόλουθες αλλαγές σε αυτήν:

<?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
   }
}

Επομένως, είναι μια αρκετά απλή προσέγγιση για την αποθήκευση των μεταφορτωμένων αρχείων στο δίσκο. Ακολουθεί μια ανάλυση της μεθόδου upload() παραπάνω:

  • Υπόδειξη τύπου για την κλάση αιτήματος στη μέθοδο ελεγκτή που εκτελεί τη λειτουργία "κρέας και πατάτες", ώστε να μπορούμε να επικυρώσουμε αυτόματα τα εισερχόμενα δεδομένα
  • Αφαιρέστε το αρχείο από το (τώρα επικυρωμένο) αντικείμενο αιτήματος μέσα στη μέθοδο του ελεγκτή (σε αυτήν την περίπτωση το ονομάσαμε upload() αλλά θα μπορούσε επίσης να είχε ονομαστεί σε ένα πιο τυποποιημένο όνομα όπως το store()).
  • Αφαιρέστε το όνομα αρχείου από το αίτημα
  • Δημιουργήστε το τελικό όνομα αρχείου που θα χρησιμοποιηθεί για την αποθήκευση του αρχείου κάτω από. Η μέθοδος getClientOriginalExtension() απλώς αρπάζει την αρχική επέκταση του μεταφορτωμένου αρχείου.
  • Αποθηκεύστε το αρχείο στο τοπικό σύστημα αρχείων χρησιμοποιώντας τη μέθοδο storeAs(), περνώντας στην ονομασμένη διαδρομή μέσα στον κατάλογο /storage ως το 1ο όρισμα και το όνομα αρχείου για να το αποθηκεύσετε ως δεύτερο.
  • Επιστρέψτε μια απάντηση JSON που υποδεικνύει ότι το αίτημα ήταν επιτυχές

Το πρότυπο λεπίδας

Το τελευταίο σημαντικό κομμάτι σε αυτό το παζλ είναι το πρότυπο blade, το οποίο θα περιέχει όλα τα HTML, CSS και javascript για την απλή εφαρμογή μας. Εδώ είναι ο κώδικας - Θα το εξηγήσουμε αργότερα.

<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>

Εδώ είναι τι μας /μεταφόρτωση η σελίδα μοιάζει με:

Το πρότυπο λεπίδας

Αυτό είναι ένα πολύ χαρακτηριστικό παράδειγμα ενός αρχείου blade που περιέχει μια φόρμα HTML και javascript/jQuery για την προσθήκη ασύγχρονης λειτουργικότητας (έτσι ώστε η σελίδα να μην ανανεώνεται). Υπάρχει ένα βασικό ετικέτα χωρίς χαρακτηριστικό μεθόδου (το οποίο θα εξηγήσω σε ένα δευτερόλεπτο) και με χαρακτηριστικό περίεργη ενέργεια με την τιμή {{route('file.upload')}}. Στη λεπίδα, αυτό είναι αυτό που είναι γνωστό ως α Οδηγίας. Μια οδηγία είναι απλώς ένα φανταχτερό όνομα για τη συνάρτηση – είναι συναρτήσεις συγκεκριμένες για πρότυπα blade που εκτελούν διαφορετικές λειτουργίες που είναι κοινές για την κατασκευή ιστοσελίδων και εφαρμογών Ιστού. Για καλύτερη κατανόηση όλων των καλών σκατά που μπορεί να κάνει το blade, ρίξτε μια ματιά στα έγγραφα εδώ. Στην παραπάνω περίπτωση, χρησιμοποιούμε την οδηγία διαδρομής για να δημιουργήσουμε μια διεύθυνση URL για την υποβολή της φόρμας μας.

Θυμηθείτε ότι ορίσαμε τις διαδρομές μας νωρίτερα στην εφαρμογή μέσα στο αρχείο web.php, προσδιορίζοντας ένα εύκολο να θυμάστε το όνομα για καθεμία από αυτές. Η οδηγία {{route()}} αποδέχεται ένα όνομα μιας διαδρομής, την αναζητά μέσα στη λίστα διαδρομών που είναι αποθηκευμένη στην κρυφή μνήμη και δημιουργεί μια πλήρη διεύθυνση URL με βάση τον ορισμό αυτής της διαδρομής στο αρχείο web.php. Για αυτήν την πρώτη περίπτωση, διευκρινίζουμε ότι θέλουμε η φόρμα να στείλει τα δεδομένα που υποβλήθηκαν στη διεύθυνση URL /process της αίτησής μας, η οποία ορίζεται ως ΜΕΤΑ διαδρομή.

Το επόμενο περίεργο πράγμα που μπορεί να έχετε παρατηρήσει είναι η ετικέτα @csrf ακριβώς κάτω από την ετικέτα ανοίγματος της φόρμας. Στο blade, αυτή η ετικέτα δημιουργεί μια παράμετρο _token στη φόρμα, η οποία ελέγχεται μέσα στην εφαρμογή πριν επιτραπεί η επεξεργασία των δεδομένων της φόρμας. Αυτό διασφαλίζει ότι τα δεδομένα μέσα στη φόρμα είναι έγκυρης προέλευσης και αποτρέπονται οι επιθέσεις πλαστογράφησης αιτημάτων μεταξύ ιστότοπων. Για περισσότερες πληροφορίες σχετικά με αυτό, δείτε το docs.

Μετά από αυτό ορίζουμε τη φόρμα μας ως κανονική, ωστόσο, σημειώστε ότι τα ονόματα των παραμέτρων της φόρμας μας, userFile και fileName είναι τα ακριβώς το ίδιο όπως ορίζεται μέσα στο αντικείμενο αιτήματός μας. Εάν ξεχάσαμε να συμπεριλάβουμε μια είσοδο για μια δεδομένη παράμετρο που είχε οριστεί στο αντικείμενο αιτήματος (ή το γράψαμε σωστά), το αίτημα θα αποτύγχανε και θα επέστρεφε ένα σφάλμα, εμποδίζοντας ποτέ το αίτημα της αρχικής φόρμας να χτυπήσει τη μέθοδο ελεγκτή που βρίσκεται στο UploadController@ επεξεργάζομαι, διαδικασία .

Προχωρήστε και δοκιμάστε το και υποβάλετε μερικά αρχεία στην εφαρμογή χρησιμοποιώντας αυτήν τη φόρμα. Στη συνέχεια, μεταβείτε στο /λίστα σελίδα για να δείτε τα περιεχόμενα του φακέλου μεταφόρτωσης, με τα αρχεία που ανεβάσατε να παρατίθενται σε έναν πίνακα:

Το πρότυπο λεπίδας

Η Μεγαλύτερη Εικόνα

Ας κάνουμε ένα βήμα πίσω και ας δούμε τι κάναμε σε αυτό το σεμινάριο Laravel.

Αυτό το διάγραμμα απεικονίζει την εφαρμογή ως έχει αυτήν τη στιγμή (εξαιρούνται οι λεπτομέρειες υψηλού επιπέδου):

Εκπαιδευτικό διάγραμμα Laravel

Θα πρέπει να θυμάστε ότι το αντικείμενο αιτήματος που κατασκευάσαμε στην αρχή αυτού του σεμιναρίου Laravel θα πρέπει να έχει τις ίδιες παραμέτρους που ορίζονται στη μέθοδο κανόνων του όπως είναι στη φόρμα στο πρότυπο blade (αν δεν διαβάσετε ξανά την ενότητα "Δημιουργία της λογικής επικύρωσης") . Ο χρήστης εισάγει τη φόρμα σε μια ιστοσελίδα που αποδίδεται μέσω μηχανής προτύπου blade (αυτή η διαδικασία είναι φυσικά σε αυτόματο πιλότο, οπότε δεν χρειάζεται καν να το σκεφτούμε) και υποβάλλει τη φόρμα. Ο κώδικας jQuery του προτύπου στο κάτω μέρος σταματά την προεπιλεγμένη υποβολή (η οποία θα ανακατευθύνει αυτόματα σε μια ξεχωριστή σελίδα), δημιουργεί ένα αίτημα ajax, φορτώνει το αίτημα με τα δεδομένα της φόρμας και ανέβασε το αρχείο και στέλνει το σύνολο στο πρώτο επίπεδο του εφαρμογή: το αίτημα.

Το αντικείμενο αίτησης συμπληρώνεται συσχετίζοντας τις παραμέτρους μέσα στη μέθοδο rules() με τις παραμέτρους της φόρμας που υποβλήθηκαν και, στη συνέχεια, επικυρώνει τα δεδομένα σύμφωνα με κάθε καθορισμένο κανόνα. Εάν πληρούνται όλοι οι κανόνες, το αίτημα μεταβιβάζεται σε οποιαδήποτε μέθοδο ελεγκτή που αντιστοιχεί στις τιμές που ορίζονται στο αρχείο διαδρομής web.php. Σε αυτήν την περίπτωση, είναι η μέθοδος process() του UploadController που κάνει τη δουλειά. Μόλις πατήσουμε τον ελεγκτή, γνωρίζουμε ήδη ότι το αίτημα πέρασε την επικύρωση, επομένως δεν χρειάζεται να δοκιμάσουμε ξανά εάν το όνομα αρχείου που δίνεται είναι, στην πραγματικότητα, μια συμβολοσειρά ή η παράμετρος userFile περιέχει πραγματικά κάποιο τύπο αρχείου… Μπορούμε να συνεχίσουμε ως κανονικός.

Στη συνέχεια, η μέθοδος ελεγκτή αρπάζει τις επικυρωμένες παραμέτρους από το αντικείμενο αιτήματος, δημιουργεί ένα πλήρες όνομα αρχείου συνενώνοντας την παράμετρο fileName που έχει περάσει με την αρχική επέκταση του userFile, αποθηκεύει το αρχείο σε έναν κατάλογο στην εφαρμογή μας και, στη συνέχεια, επιστρέφει μια απλή κωδικοποίηση JSON απάντηση που επαληθεύει ότι το αίτημα ήταν επιτυχές. Η απάντηση λαμβάνεται από τη λογική jQuery, η οποία κάνει μερικές ακόμη εργασίες που σχετίζονται με το περιβάλλον εργασίας χρήστη, όπως εμφάνιση του μηνύματος επιτυχίας (ή σφάλματος) για 5 δευτερόλεπτα και στη συνέχεια απόκρυψη του καθώς και διαγραφή των προηγούμενων καταχωρήσεων φόρμας… αυτό είναι έτσι ώστε ο χρήστης να γνωρίζει βεβαιωθείτε ότι το αίτημα ήταν επιτυχές και μπορούν να ανεβάσουν άλλο αρχείο, εάν το επιθυμούν.

Επίσης, σημειώστε στο παραπάνω διάγραμμα ακριβώς το σημείο που χαράσσεται η γραμμή μεταξύ του πελάτη και του διακομιστή. Αυτή η ιδέα είναι απολύτως κρίσιμη για να την κατανοήσετε και θα σας βοηθήσει να επιλύσετε προβλήματα και ζητήματα που μπορεί να έχετε στο μέλλον όταν αντιμετωπίζετε, για παράδειγμα, πολλαπλά ασύγχρονα αιτήματα που μπορεί να προκύψουν ανά πάσα στιγμή. Ο διαχωρισμός είναι ακριβώς στο όριο του αντικειμένου αιτήματος. Το ίδιο το αντικείμενο αίτησης μπορεί να θεωρηθεί ως η «πύλη» προς την υπόλοιπη εφαρμογή… Κάνει την αρχική επικύρωση και καταχώρηση των τιμών της φόρμας που μεταβιβάζονται από το πρόγραμμα περιήγησης Ιστού. Εάν κριθούν έγκυρα, τότε συνεχίζεται στον ελεγκτή. Όλα πριν από αυτό βρίσκονται στο μπροστινό μέρος (ο «πελάτης» κυριολεκτικά σημαίνει «στον υπολογιστή του χρήστη»). Η απάντηση επιστρέφεται από την εφαρμογή στην πλευρά του πελάτη, όπου ο κώδικας jQuery ακούει υπομονετικά την άφιξή του και κάνει μερικές απλές εργασίες διεπαφής χρήστη μόλις τον λάβει.

Καλύψαμε σχεδόν 90+ σημαντικά ερωτήματα Ερωτήσεις συνέντευξης που σχετίζονται με τη Laravel και την PHP για φρέσκους αλλά και έμπειρους υποψηφίους για να βρουν τη σωστή δουλειά.