Yeni Başlayanlar İçin Laravel Eğitimi

Laravel nedir?

laravel PHP için açık kaynaklı bir web MVC çerçevesidir. Laravel, özel bir bağımlılık yöneticisine sahip modüler paketleme sistemi, ilişkisel veritabanlarına erişim ve uygulama dağıtımı ve bakımına yönelik diğer yardımcı programlar gibi özelliklerle PHP web uygulamalarının kolay geliştirilmesini sağlayan güçlü bir çerçevedir.

Laravel Taylor Otwell tarafından yaratıldı. Haziran 2011'deki ilk sürümünden (sürüm 1) bu yana, web geliştirme endüstrisinin PHP çerçeve sektöründe giderek daha popüler hale geldi. Bu popülerliğin büyük bir kısmı, stokla birlikte gelen, geliştiricilerin öncelikli düşündüğü birçok özelliğe bağlanabilir.

Neden Laravel?

Yaklaşık 2000, çoğu PHP kodları prosedürseldi ve karmaşık bir spagetti kodu karmaşasına sahip "senaryolar" biçiminde bulunabilirdi. En basit sayfalarda bile yoktu endişelerin ayrılmasıve dolayısıyla bir uygulamanın hızla bir bakım kabusuna dönüşmesi oldukça kolaydı. Dünyanın daha iyi bir şeye ihtiyacı vardı… PHP sürüm 5'e girin ve çok ihtiyaç duyulan çözünürlüğü ve çeşitli web uygulaması sorunlarına daha iyi çözümler getirmeye çalışan çeşitli PHP çerçevelerini girin.

O zamandan bu yana, bugün var olan ve kullanılan popüler çerçevelerin önünü açacak birçok çerçevenin yayınlandığını gördük. Bugün ilk üç (bizim görüşümüze göre) Zend Framework, Symfony ve tabii ki Laravel olacaktır. Bu çerçevelerin her biri benzer ilkeler üzerine kurulmuş ve (temelde) aynı ortak sorunları çözmeye yönelik olsa da, aralarındaki temel farklar uygulamalarında yatmaktadır. Sorunları nasıl çözecekleri konusunda her birinin kendine özgü tuhaflıkları var. Her birinin ürettiği kodlara baktığınızda onları birbirinden ayıran oldukça sağlam bir çizginin olduğunu göreceksiniz. Naçizane görüşümüze göre Laravel çerçevesi en iyisidir.

Hakkında daha fazla bilgi alın Laravel ve CodeIgniter arasındaki fark

Composer ile Laravel Nasıl İndirilir ve Kurulur

NOT Yerel sisteminizde zaten PHP'nin bir kopyasının kurulu olduğu varsayılmaktadır. Değilse, nasıl kurulacağını okuyabilirsiniz okuyun

Composer hem paket hem de bağımlılık yöneticisidir. Yüklemek için bir terminal açın ve yeni bir dizine cd ekleyin. Bu komutu çalıştırın:

curl -Ss getcomposer.org/installer | php

Bu komutun sonuçları şöyle görünecektir:

Laravel'i Composer ile indirin ve yükleyin

not Laravel kurulumuna ilişkin daha kapsamlı talimatlar için Laravel belgelerine bakın. okuyun.

Laravel'i kurmak için kullandığımız besteci.phar betiğini indirip derlediğini göreceksiniz. Yeni bir Laravel uygulaması kurmanın birçok yolu olmasına rağmen, bunu Laravel besteci betiği aracılığıyla yapacağız. Bu betiği yüklemek için şunu çalıştırın:

composer global require laravel/installer

Hangisi şuna benzeyecek:

Laravel'i Composer ile indirin ve yükleyin

Bu, tüm çerçeve dosyalarını ve ihtiyaç duyduğu tüm bağımlılıkları indirecek ve kuracaktır. Paketler, satıcı dizininin içine kaydedilecektir. İndirildikten ve kurulduktan sonra, aşağıdaki komutu vermek kadar kolaydır:

laravel new uploadApp

Aşağıdakine benzer bir çıktı göreceksiniz:

Laravel'i Composer ile indirin ve yükleyin

Composer, Laravel'in çalışması için ihtiyaç duyduğu tüm paketleri kuruyor. Birkaç dakika sürebilir, bu yüzden sabırlı olun. Tamamlandıktan sonra, nelerin kurulu olduğuna bir göz atmak için ls -al komutunu çalıştırın.

Yaygın bir Laravel uygulamasındaki dizinlerin kısa bir dökümü aşağıda verilmiştir:

  • uygulama/ : Bu, uygulama kodumuzun bulunduğu kaynak klasördür. Tüm denetleyiciler, ilkeler ve modeller bu klasörün içindedir
  • önyükleme/ : Uygulamanın başlangıç ​​komut dosyasını ve birkaç sınıf haritası dosyasını içerir
  • yapılandırma/: Uygulamanın yapılandırma dosyalarını tutar. Bunlar genellikle doğrudan değiştirilmez; bunun yerine uygulamanın kökündeki .env (ortam) dosyasında ayarlanan değerlere dayanır.
  • veri tabanı/ : Geçişler, tohumlar ve test fabrikaları dahil olmak üzere veritabanı dosyalarını barındırır
  • halk/ : Derlenmiş varlıkları ve tabii ki bir index.php dosyasını içeren, herkese açık klasör
  • kaynaklar/ : Javascript dosyaları, dil dosyaları, CSS/SASS dosyaları ve uygulamada kullanılan tüm şablonlar (blade şablonları olarak adlandırılır) gibi ön uç varlıkları içerir
  • rotalar/ : Uygulamadaki tüm rotalar burada yer almaktadır. Rotaların birkaç farklı “kapsamı” vardır ancak odaklanacağımız web.php dosyasıdır.
  • depolamak/ : Uygulama tarafından kullanılan tüm geçici önbellek dosyaları, oturum dosyaları, derlenmiş görünüm komut dosyaları ve günlük dosyaları
  • testler/ : Birim testleri ve fonksiyonel testler gibi uygulamaya yönelik test dosyalarını içerir.
  • SATICI/ : Besteci ile yüklenen tüm bağımlılık paketleri

Şimdi uygulamanın geri kalanını oluşturalım ve özel bir ustaca komutla çalıştıralım (Apache veya nginx gibi bir web sunucusu kurma ve yapılandırma zahmetinden kendimizi kurtarmak için). .env dosyası, /config dizinindeki dosyaların uygulamayı yapılandırmak için kullandığı tüm yapılandırma değerlerini içerir. İçinde, uygulamanın dahili bileşenleri tarafından kullanılan çeşitli parametreler için konfigürasyon değerinin olduğunu fark edeceksiniz.

Uygulama tasarımı: Gereksinimlerimizin hızlı bir özeti

Bu çevrimiçi Laravel eğitiminde yalnızca iki şeyi yapacak çok basit bir uygulama geliştireceğiz:

  1. bir web formundan dosya yüklemelerini yönetme
  2. Daha önce yüklenen dosyaları farklı bir sayfada görüntüleme.

Bu proje için uygulamamız salt yazılabilir olacaktır; bu, kullanıcının yalnızca dosya yazabileceği ve yüklediği dosyaların listesini görebileceği anlamına gelir. Bu uygulama son derece basittir ancak Laravel becerilerinizi ve bilginizi geliştirmeye başlamanız için iyi bir uygulama olarak hizmet etmelidir. Kısaltmak adına her türlü veritabanı modellemeyi, geçişleri ve kimlik doğrulamayı hariç tuttum ancak gerçek dünyadaki bir uygulamada bunların dikkate almak isteyeceğiniz ek şeyler olduğunu unutmayın.

Uygulamanın beklendiği gibi çalışmasını sağlamak için ihtiyaç duyacağımız bileşenlerin listesi:

  • A degistirebilirsin. dış dünyanın (internet) uygulamayı kullanmasına olanak sağlayacak ve ayrıca yüklenen dosyayı kaydetme mantığının nerede bulunduğunu işaret edecek uç noktayı belirtecek
  • A kontrolör yanıt akışına yönelik isteği işleyen
  • A şablon önceden yüklenen dosyaların listesini ve gerçek yükleme formunu görüntülemek için kullanılacaktır
  • A talep denetleyicinin web formundan iletilen verileri doğrulamak için kullanacağı

Rota Nedir?

Laravel'deki bir rota, temel olarak, uygulama tarafından sunulan bazı işlevselliklere yönelik bir "işaretçi" görevi gören, bir URI tarafından belirtilen bir uç noktadır. En yaygın olarak, bir rota yalnızca denetleyicideki bir yönteme işaret eder ve aynı zamanda hangi HTTP yöntemlerinin bu URI'ye ulaşabileceğini de belirler. Rota her zaman denetleyici yöntemi anlamına da gelmez; uygulamanın yürütülmesini tanımlanmış bir Kapatma veya anonim işleve de aktarabilir.

Rotayı neden kullanmalıyım?

Rotalar, projenin kök dizinindeki /routes klasörü altındaki dosyalarda saklanır. Varsayılan olarak, uygulamanın farklı "taraflarına" karşılık gelen birkaç farklı dosya vardır ("taraflar" altıgen mimari metodolojisinden gelir). Bunlar şunları içerir:

  • web.php Herkese açık “tarayıcı” tabanlı rotalar. Bunlar en yaygın olanlardır ve web tarayıcısının çarptığı şeylerdir. Web ara katman yazılımı grubu üzerinden çalışırlar ve ayrıca aşağıdakiler için olanaklar içerirler: csrf koruması (form tabanlı kötü amaçlı saldırılara ve saldırılara karşı savunmaya yardımcı olur) ve genellikle bir dereceye kadar "durum" içerir (bununla oturumlardan yararlandıklarını kastediyorum)
  • api.php Bir API grubuna karşılık gelen ve dolayısıyla API ara yazılımının varsayılan olarak etkin olduğu rotalar. Bu rotalar durum bilgisizdir ve oturumları veya çapraz istek hafızası yoktur (bir istek diğer herhangi bir istekle veri veya hafıza paylaşmaz; her biri kendi kendine kapsüllenir).
  • console.php Bu rotalar, uygulamanız için oluşturduğunuz özel zanaatkar komutlarına karşılık gelir
  • channels.php Etkinlik yayını için rotaları kaydeder

Şu anda ilgilenilmesi gereken anahtar dosya tarayıcıya özel olan web.php dosyasıdır. Varsayılan olarak tanımlanmış bir rota zaten vardır; bu, uygulamanızın web köküne (web kökü genel dizindedir) giderken sağ tıkladığınız yoldur. Yükleme uygulamamızın çalışması için üç farklı rotaya ihtiyacımız olacak:

  • /upload Bu, dosyaları yüklemek için web formumuzu görüntüleyen ana sayfanın URI'si olacaktır.
  • /process Bu, /upload URI'sinde bulunan formun, form tarafından gönderilen verileri (formun "eylem") gönderdiği yerdir.
  • /list Bu siteye yüklenen tüm dosyaları listeler

notlar Yükleme formunu ve dosya listesini görüntülemeye ilişkin tüm mantığı tek bir sayfada toplamak istersek /list uç noktasına ihtiyaç duyulmayabilir, ancak elimizdeki konuya biraz daha konu katmak için şimdilik bunları ayrı tuttuk. .

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

Bu Laravel çerçeve eğitiminde, istenen her rota için, mevcut HTTP'ye özgü istek yöntemlerinden birini (get(), post(), put(), delete(), kullanarak) web.php rota dosyasında açıkça listeleyeceğiz. patch() veya options() ). Bunların her birinin dökümü için, kontrol edin Re-Tweet dışarı. Bu yöntemlerin yaptığı şey, hangi HTTP fiillerinin belirli bir rotaya erişmesine izin verildiğini belirtmektir. Birden fazla HTTP fiilini kabul edebilmek için bir rotaya ihtiyacınız varsa (bu, hem ilk verileri hem de gönderilen form verilerini görüntülemek için tek bir sayfa kullanıyorsanız durum böyle olabilir), Route::any( ) yöntem.

Hem Route::get() hem de Route::post() yöntemlerinin (ve Route cephesindeki diğer HTTP fiilleriyle ilgili yöntemlerin) ikinci argümanı, izin verilen HTTP isteğiyle (GET, POST, PATCH, vb.) rotanın uç noktasına ulaştığında yürütülen belirli bir Denetleyicinin ve bu denetleyicinin içinde barındırılan yöntemin adıdır. Üç rota için de UploadController'ı kullanıyoruz ve bunları aşağıdaki şekilde belirttik:

Rota Nedir?

Her rotada çağırdığımız son yöntem, bağımsız değişken olarak tek bir dizeyi kabul eden ve belirli bir rotayı hatırlanması kolay bir adla az çok "etiketlemek" için kullanılan name() işlevidir (bizim durumumuzda, yükleme, işleme ve listeleme). URL tamamen aynı şekilde adlandırıldığında her rotaya kendi adını vermenin çok iyi bir özellik gibi görünmediğinin farkındayım, ancak /users/profile/dashboard/config gibi belirli bir rotanız olduğunda gerçekten kullanışlı oluyor. profil yöneticisi veya kullanıcı yapılandırması olarak hatırlanması daha kolay olacaktır.

Cepheler üzerine bir not:

  • Cepheler, uygulamanın servis konteynerinde mevcut olan sınıflara “statik” bir arayüz sağlar.”
  • Manuel olarak eklenmesi veya yapılandırılması gereken uzun sınıf adlarını hatırlamadan Laravel'in özelliklerini kullanmanıza olanak tanıyan kısa ve akılda kalıcı bir sözdizimi sağlarlar.

Bu Laravel çerçeve eğitiminde yukarıdaki rota tanımlarında, yeni bir Illuminate/Routing/Router nesnesini manuel olarak başlatmak ve bu nesnede karşılık gelen yöntemleri çağırmak yerine Route cephesini kullanıyoruz. Bu sadece yazmayı kurtaran bir kısayol. Cepheler Laravel çerçevesinde yoğun bir şekilde kullanılır; onlara daha fazla aşina olabilirsiniz ve olmalısınız. Cephelere ilişkin dokümanları şu adreste bulabilirsiniz: okuyun.

Denetleyici Nedir?

Bir kontrolcü, Laravel'in dayandığı "MVC" (Model-View-Controller) mimarisindeki "C"dir. Bir kontrolcünün işi bu basit tanıma indirgenebilir: İstemciden isteği alır ve istemciye bir yanıt döndürür. Bu, temel tanımdır ve aynı zamanda herhangi bir denetleyicinin minimum gereksinimleridir. Bu iki şey arasında yaptığı şey genellikle denetleyicinin "aksiyonu" (veya "rotanın uygulanması") olarak kabul edilir. İstemciye uygulamaya ikinci giriş noktası olarak davranır (birincisi istektir), müşteri istek yükünü (buna bir sonraki bölümde değineceğiz) gönderir ve bir tür yanıt bekler (bir tür yanıt olarak). başarı sayfası, yönlendirme, hata sayfası veya başka herhangi bir HTTP yanıtı).

Bir denetleyici (temel olarak), o rotaya ulaşıldığında "eylem" olarak ayarlanan anonim bir işlevle rota tanımıyla aynı şeyi yapar. Aradaki fark, bir rota gerçek URL tanımına göre satır içinde tanımlanırken bir denetleyicinin endişelerin ayrılmasını iyi bir şekilde sağlamasıdır; bu, temel olarak rotaya atanan URI'yi rotanın uygulamasıyla veya bu rota olduğunda yürütülen kodla eşleştirdiğimiz anlamına gelir. vurmak.

Örneğin, aşağıdaki iki kod parçası aynı işi yapacaktır:

Örnek 1: Tek bir yöntem çağrısında rotanın tanımı ve uygulanması (web.php yönlendirme dosyasında)

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

Örnek #2: Rotanın tanımı,routes/web.php içindedir, ancak uygulaması /app/Http/Controllers/HelloWorldController sınıfının içinde bulunur

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

Her ne kadar Laravel örneği #2 çok daha fazla iş gibi görünse de (ki öyle değil; sadece biraz daha fazla kod hepsi bu), verilen "merhaba dünya" rotası için eylem mantığımızı bunun yerine bir denetleyicinin içine yerleştirerek elde ettiğimiz faydalara bakın. rotanın bir geri arama işlevi olarak tanımlanmasıyla:

  1. Mantığımız temiz bir şekilde kendi sınıfına ayrılmıştır (kaygıların ayrılması)
  2. Denetleyicimiz, daha sonra ek özellikler eklememiz gerekirse genişletilmek üzere ayarlanmıştır... Diyelim ki bir "elveda dünya" özelliği eklemek istedik... Bu durumda denetleyiciyi daha genel bir "HelloController" olarak yeniden adlandırırdık ve sonra iki ayrı yöntem tanımlardık, Merhaba() ve Güle güle(). Ayrıca haritayı haritalayan iki ayrı rota tanımlamamız gerekir. /Merhaba ve / Güle güle URI'leri denetleyicideki uygun yönteme yönlendirin. Bu, her bir rotanın uygulamasının geri çağırma işlevleri olarak tanımlandığı bir rota dosyasının genişletilmesiyle karşılaştırıldığında arzu edilen bir durumdur.
  3. Laravel, belirli bir rotayı bulmak için gereken süreyi hızlandıracak şekilde uygulamadaki tüm rota tanımlarını önbelleğe alma yerleşik yeteneğine sahiptir (uygulama performansını artırır); Bununla birlikte, bundan yalnızca uygulama içindeki tanımlı rotalarınızın tümü denetleyiciye özgü eşlemeler kullanılarak yapılandırılmışsa yararlanabilirsiniz (yukarıdaki Örnek #2'ye bakın)

Bize yeni bir denetleyici oluşturacak bu komutu çalıştıralım.

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

Temel olarak, bu komutun yaptığı şey, /app/Http/Controllers/UploadController.php adresindeki ana denetleyici dizininde "UploadController" adlı bir denetleyici için bir saplama oluşturmaktır. Bu dosyayı açıp bir göz atmaktan çekinmeyin. Bu çok basittir çünkü denetleyicinin yalnızca doğru ad alanı yoluna ve genişletildiği gerekli sınıflara sahip, kısaltılmış bir sürümüdür.

Talebin Oluşturulması

Bu PHP Laravel eğitiminde ilerlemeden ve UploadController'ın oluşturulan taslağında birkaç değişiklik yapmadan önce, ilk önce istek sınıfını oluşturmanın daha mantıklı olacağını düşünüyorum. Bunun nedeni, isteği işleyen denetleyici yönteminin imzasında istek nesnesini tip ipucu olarak yazması ve böylece gelen form verilerini otomatik olarak doğrulaması (rules() yönteminde belirtildiği gibi. Daha sonra buna değineceğim…) Şimdilik, istek taslağımızı oluşturmak için artisan komutunu tekrar kullanalım:

php artisan make:request UploadFileRequest

Bu komut, app/Http/Requests/UploadFileRequest içinde UploadFileRequest adlı bir dosya oluşturacaktır. Taslağını açın ve bir göz atın… Bunu çok basit bulacaksınız, yalnızca iki yöntem içeriyor: Authorize() ve kurallar.

Doğrulama Mantığını Oluşturma

Uygulamamızın ihtiyaçlarını karşılamak için istek saplamasını değiştirelim. Dosyayı şu şekilde görünecek şekilde değiştirin:

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

Çok fazla değişiklik olmadı ancak Authorize() yönteminin artık false yerine true değerini döndürdüğüne dikkat edin. Bu yöntem, isteğin uygulamaya girmesine izin verilip verilmeyeceğine karar verir. Yanlış olarak ayarlanırsa isteğin sisteme girişi durdurulur (bu normalde denetleyicideki bir yöntem olacaktır). Bu, kullanıcı üzerinde herhangi bir yetkilendirme kontrolü veya isteğin denetleyiciye iletilip iletilmeyeceğine karar verebilecek başka bir mantık oluşturmak için çok kullanışlı bir yer olacaktır. Şimdilik, her şeyin isteği kullanmasına izin vermek için burada sadece true değerini döndürüyoruz.

Diğer yöntem olan Rules() ise doğrulama konusunda tüm sihrin devreye girdiği yerdir. Fikir basit: aşağıdaki biçimde bir dizi kural içeren bir dizi döndürün:

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

Laravel tarafından kutudan çıktığı haliyle desteklenen birçok farklı doğrulama kısıtlaması vardır. Bunların tam listesi için çevrimiçi belgelere bakın okuyun. Yükleme uygulamamız için, ön uçtaki bir formdan POST isteği yoluyla geçirilecek iki alan olacak. fileName parametresi form gövdesinin içine dahil edilmeli (yani gerekli) ve depolamada dosyayı saklayacağımız dosya adı olarak kullanılır (bu denetleyicide yapılır - birazdan buna geleceğiz). Ayrıca, bir boru karakteri (|) ve 'dize' sözcüğü ekleyerek dosya adının bir dize olması gerektiğini belirtiyoruz. Kısıtlamalar her zaman borularla sınırlandırılır ve bu da tek bir satırda belirtilen alan için herhangi bir ek ölçüt belirtmenize olanak tanır! Ne güç!

İkinci parametre olan userFile, kullanıcının bir web sayfasındaki formdan yüklediği gerçek dosyadır. UserFile da gereklidir ve , eğer mülteci statüleri sona erdirilmemişse Amerika'ya geldikten bir yıl sonra bir dosya olsun. Not: Yüklenen dosyanın bir resim olmasını bekliyor olsaydık, bunun yerine, popüler resim türlerinden biri olarak kabul edilen dosya türlerini (jpeg, png, bmp, gif veya svg) sınırlayan resim kısıtlamasını kullanırdık. Kullanıcının herhangi bir dosya türünü yüklemesine izin vermek istediğimizden, yalnızca dosya doğrulama kısıtlamasına sadık kalacağız.

İstek nesnesinin hepsi bu kadar. Ana görevi, uygulamada daha derinlere ilerlemek için formun gövde parametrelerinin karşılaması gereken kabul edilebilir kriterler (kısıtlamalar) kümesini tutmaktır. Dikkat edilmesi gereken bir diğer nokta da bu iki alanın (kullanıcıDosyası ve dosya adı) HTML kodu içinde giriş alanları biçiminde (alan adı istek nesnesinin içindeki isme karşılık gelecek şekilde) belirtilmesi gerektiğidir.

Şunu soruyor olabilirsiniz: Bunun bir form isteğinin içermesi gereken özellikleri tanımladığından emin olabilirsiniz, ancak bu kısıtlamaların gerçek kontrolü nerede yapılıyor? Bundan sonra bu konuya gireceğiz.

Denetleyiciyi Değiştirme

app/Http/Controllers/UploadController'ı açın ve aşağıdaki değişiklikleri yapın:

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

Dolayısıyla yüklenen dosyaları diske kaydetmek oldukça basit bir yaklaşımdır. Yukarıda upload() yönteminin bir dökümü verilmiştir:

  • 'Et ve patates' işlevini yerine getiren denetleyici yönteminde istek sınıfını yazın, böylece gelen verileri otomatik olarak doğrulayabiliriz
  • Dosyayı, denetleyici yöntemi içindeki (artık doğrulanmış) istek nesnesinden alın (bu durumda ona upload() adını verdik, ancak aynı zamanda mağaza() gibi daha standartlaştırılmış bir adla da adlandırılabilirdi).
  • Dosya adını istekten çıkarın
  • Dosyayı altına kaydetmek için kullanılacak son dosya adını oluşturun. getClientOriginalExtension() yöntemi yalnızca yüklenen dosyanın orijinal uzantısını alır.
  • Dosyayı, saveAs() yöntemini kullanarak yerel dosya sisteminde saklayın; /storage dizini içindeki adlandırılmış yolu 1. argüman olarak ve altına kaydedilecek dosya adını da ikinci argüman olarak iletin.
  • İsteğin başarılı olduğunu belirten bir JSON yanıtı döndür

Bıçak Şablonu

Bu bulmacanın son büyük parçası, basit uygulamamız için tüm HTML, CSS ve javascript'i tutacak olan blade şablonudur. İşte kod–Daha sonra açıklayacağız.

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

İşte bizim /yüklemek sayfa şuna benziyor:

Bıçak Şablonu

Bu, HTML formu ve asenkron işlevsellik eklemek için javascript/jQuery içeren bir blade dosyasının çok tipik bir örneğidir (böylece sayfa yenilenmez). Temel bir yöntem niteliği olmayan (bir saniye içinde açıklayacağım) ve {{route('file.upload')}} değerine sahip ilginç bir eylem niteliği olan etiket. Blade'de buna bir Direktif. Direktif, işlev için sadece süslü bir isimdir; bunlar, web sayfalarının ve web uygulamalarının oluşturulmasında ortak olan farklı işlemleri gerçekleştiren blade şablonlarına özgü işlevlerdir. Blade'in yapabileceği harika şeyleri daha iyi anlamak için dokümanlara göz atın okuyun. Yukarıdaki durumda, form gönderimimiz için bir URL oluşturmak amacıyla rota yönergesini kullanıyoruz.

Rotalarımızı uygulamada daha önce web.php dosyasında tanımladığımızı ve her biri için hatırlanması kolay bir ad belirttiğimizi unutmayın. {{route()}} yönergesi bir rotanın adını kabul eder, bunu dahili olarak önbelleğe alınmış rotalar listesinde arar ve web.php dosyasındaki o rotanın tanımına dayalı olarak tam bir URL oluşturur. Bu ilk durum için formun gönderilen verileri uygulamamızın /process URL'sine göndermesini istediğimizi belirtiyoruz. POST rota.

Fark etmiş olabileceğiniz bir sonraki tuhaf şey, açılış formu etiketinin hemen altındaki @csrf etiketidir. Blade'te bu etiket form üzerinde, form verilerinin işlenmesine izin verilmeden önce uygulama içinde kontrol edilen bir _token parametresi oluşturur. Bu, formdaki verilerin geçerli bir kökene sahip olmasını sağlar ve siteler arası istek sahteciliği saldırılarını önler. Bu konuda daha fazla bilgi için bkz. docs.

Bundan sonra formumuzu normal olarak tanımlıyoruz ancak form parametrelerimizin adlarının userFile ve fileName olduğunu unutmayın. Aynı tam istek nesnemizde tanımlandığı gibi. İstek nesnesinde tanımlanan belirli bir parametre için bir girdi eklemeyi unutursak (veya onu yanlış yazarsak), istek başarısız olur ve bir hata döndürülür, bu da orijinal form isteğinin UploadController@ konumunda bulunan denetleyici yöntemine isabet etmesini engeller. işlem .

Devam edin ve deneyin ve bu formu kullanarak uygulamaya birkaç dosya gönderin. Daha sonra şuraya gidin: /liste Yüklediğiniz dosyaların bir tabloda listelendiği yükleme klasörünün içeriğini görmek için sayfa:

Bıçak Şablonu

Bigger Picture

Bir adım geriye gidelim ve bu Laravel eğitiminde neler yaptığımıza bakalım.

Bu diyagram, uygulamanın şu anki halini göstermektedir (üst düzey ayrıntılar hariç):

Laravel öğretici diyagramı

Bu Laravel eğitiminin başında oluşturduğumuz istek nesnesinin, blade şablonundaki formda olduğu gibi kendi kurallar yönteminde tanımlanan parametrelerle aynı parametrelere sahip olması gerektiğini hatırlamalısınız (eğer değilse “Doğrulama Mantığını Oluşturma” bölümünü tekrar okuyun). . Kullanıcı, blade şablon motoru aracılığıyla oluşturulan bir web sayfasına formu girer (bu işlem elbette otomatik pilotta olduğundan bunu düşünmemize bile gerek kalmaz) ve formu gönderir. Şablonun alttaki jQuery kodu, varsayılan gönderimi durdurur (bu otomatik olarak ayrı bir sayfaya yönlendirilir), bir ajax isteği oluşturur, isteği form verileriyle yükler ve dosyayı yükler ve her şeyi bizim birinci katmanımıza gönderir. başvuru: istek.

İstek nesnesi, Rules() yöntemi içindeki parametreler gönderilen form parametreleriyle ilişkilendirilerek doldurulur ve ardından veriler, belirtilen her kurala göre doğrulanır. Tüm kurallar yerine getirilirse istek, web.php yönlendirme dosyasında tanımlanan değerlere karşılık gelen denetleyici yöntemine iletilir. Bu durumda işi yapan UploadController'ın proses() yöntemidir. Denetleyiciye ulaştığımızda, isteğin doğrulamayı geçtiğini zaten biliyoruz, bu nedenle verilen dosya adının aslında bir dize olup olmadığını veya userFile parametresinin gerçekten bir tür dosya içerip içermediğini yeniden test etmemize gerek yok… Devam edebiliriz. normal.

Denetleyici yöntemi daha sonra doğrulanmış parametreleri istek nesnesinden alır, fileName parametresinde iletilen userFile parametresini userFile öğesinin orijinal uzantısıyla birleştirerek tam bir dosya adı oluşturur, dosyayı uygulamamızdaki bir dizin içinde saklar ve ardından basit bir JSON kodlu basit dosya adı döndürür. isteğin başarılı olduğunu doğrulayan yanıt. Yanıt, başarı (veya hata) mesajını 5 saniye boyunca görüntülemek, ardından gizlemek ve önceki form girişlerini temizlemek gibi kullanıcı arayüzü ile ilgili birkaç görevi daha yapan jQuery mantığı tarafından alınır. Bu, kullanıcının bilmesi içindir. İsteğin başarılı olduğundan emin olun ve isterlerse başka bir dosya yükleyebilirler.

Ayrıca, yukarıdaki diyagramda istemci ile sunucu arasındaki çizginin tam olarak nerede çizildiğine dikkat edin. Bu kavram sizin için kesinlikle çok önemlidir ve gelecekte, örneğin herhangi bir anda oluşabilecek birden fazla eşzamansız isteği idare ederken karşılaşabileceğiniz sorunları ve meseleleri çözmenize yardımcı olacaktır. Ayrım, istek nesnesinin sınırındadır. İstek nesnesinin kendisi, uygulamanın geri kalanına "ağ geçidi" olarak düşünülebilir... Web tarayıcısından geçirilen form değerlerinin ilk doğrulamasını ve kaydını yapar. Geçerli kabul edilirlerse, denetleyiciye devam eder. Ondan önceki her şey ön uçtadır ("istemci" kelimesi tam olarak "kullanıcının bilgisayarında" anlamına gelir). Yanıt, uygulamadan istemci tarafına geri döndürülür ve burada jQuery kodumuz sabırla onun gelişini bekler ve onu aldıktan sonra birkaç basit kullanıcı arayüzü görevi yapar.

Sıkça sorulan neredeyse 90'dan fazla önemli konuyu ele aldık Laravel ve PHP ile ilgili röportaj soruları Yeni başlayanların yanı sıra deneyimli adayların da doğru işi bulmaları için.