Laravel'i daha ileri itmek - Laravel 5.7 için en iyi ipuçları ve iyi uygulamalar

Bu yazının Miguel Piedrafita’nın Blogcast uygulaması sayesinde sesli bir sürümü var.

Laravel, temiz, çalışan ve hata ayıklama yapabilen kod yazmak için birçok PHP geliştiricisi tarafından bilinmektedir. Aynı zamanda, bazen dokümanda listelenmeyen ya da öyle olan birçok özelliği desteklemektedir, ancak çeşitli nedenlerle kaldırılmıştır.

2 yıldan beri üretimde Laravel ile çalışıyorum ve hatalı kod yazmayı daha iyi koda yazmayı öğrendim ve ilk başladığımdan beri Laravel'in avantajını kullandım. Laravel ile kod yazarken size yardımcı olabilecek gizemli püf noktalarını göstereceğim.

Sorgulamanız gerektiğinde yerel kapsamları kullanın

Laravel, Query Builder'ı kullanarak veritabanı sürücünüz için sorgu yazmak için güzel bir yöntem sunar. Bunun gibi bir şey:

$ orders = Order :: where ('status', 'teslim edildi') -> where ('ücretli', doğru) -> get ();

Bu çok hoş. Bu beni SQL'den vazgeçti ve benim için daha ulaşılabilir olan kodlamaya odakladı. Ancak yerel kapsamlar kullanırsak bu kod parçası daha iyi yazılabilir.

Yerel kapsamlar, veri almaya çalışırken zincirleyebileceğimiz kendi Query Builder yöntemlerimizi oluşturmamızı sağlar. Örneğin, -> where () ifadeleri yerine -> delivery () ve -> paid () yöntemini daha temiz bir şekilde kullanabiliriz.

İlk olarak, Sipariş modelimizde bazı yöntemler eklemeliyiz:

sınıf Sipariş Modeli genişletiyor
{
   ...
   public işlev frameworkDelivered ($ query) {
      $ query-> where ('status', 'iletildi');
   }
   genel işlev kapsamıPaid ($ query) {
      $ query-> where döndürün ('ücretli', doğru);
   }
}

Yerel kapsamları bildirirken, kapsam [Something] tam adlandırma kullanmalısınız. Bu şekilde, Laravel bunun bir kapsam olduğunu bilir ve bunu Query Builder'ınızda kullanır. Laravel tarafından otomatik olarak enjekte edilen ilk argümanı eklediğinizden ve sorgu oluşturucu örneği olduğundan emin olun.

$ orders = Order :: delivery () -> paid () -> get ();

Daha dinamik alım için dinamik yerel kapsamları kullanabilirsiniz. Her kapsam size parametreler vermenizi sağlar.

sınıf Sipariş Modeli genişletiyor
{
   ...
   genel işlev kapsamıStatus ($ query, string $ status) {
      $ query-> where döndürün ('status', $ status);
   }
}
$ orders = Order :: status ('teslim edildi') -> paid () -> get ();

Bu makalenin ilerisindeki bölümlerinde, snake_case'i neden veritabanı alanları için kullanmanız gerektiğini öğreneceksiniz, ancak işte birinci neden: Laravel varsayılan olarak, önceki kapsamı değiştirmek için [Bir şey] özelliğini kullanıyor. Böylece öncekinin yerine şunları yapabilirsiniz:

Sipariş ( 'teslim') :: whereStatus ->) (ücretli -> get ();

Laravel, Something'in snake_case versiyonunu arayacaktır [Something]. DB'nizde durum varsa önceki örneği kullanacaksınız. Shipping_status varsa, kullanabilirsiniz:

Sipariş ( 'teslim') :: whereShippingStatus ->) (ücretli -> get ();

Seçim senin!

Gerektiğinde istek dosyaları isteyin

Laravel formlarınızı doğrulamak için size sağlam bir yol sunar. Bu bir POST isteği veya bir GET isteğidir, ihtiyaç duyarsanız doğrulamakta başarısız olur.

Bu şekilde kontrol cihazınızda doğrulayabilirsiniz:

public function store ($ istek isteyin)
{
    $ validatedData = $ request-> validate ([
        'title' => 'gerekli | benzersiz: gönderiler | max: 255',
        'body' => 'gerekli'
    ]);

    // Blog yazısı geçerli ...
}

Ancak, denetleyici yöntemlerinde çok fazla kod bulunduğunda, oldukça kötü olabilir. Kontrol cihazınızda mümkün olduğunca fazla kod azaltmak istiyorsunuz. En azından, gerçekten çok mantık yazmam gerekirse ilk düşündüğüm şey budur.

Laravel, istek sınıfları oluşturarak ve eski moda İstek sınıfı yerine bunları kullanarak istekleri doğrulamak için * sevimli * bir yol sunar. Sadece isteğinizi oluşturmalısınız:

php esnaf yapmak: istek StoreBlogPost

Uygulama / Http / İstekler / klasörünün içinde istek dosyanızı bulacaksınız:

sınıf StoreBlogPostRequest FormRequest'i genişletir
{
   kamu işlevi yetkilendirmek ()
   {
      $ $ this-> user () -> can ('create.posts');
   }
   ortak işlev kuralları ()
   {
       dönüş [
         'title' => 'gerekli | benzersiz: gönderiler | max: 255',
         'body' => 'gerekli'
       ];
   }
}

Şimdi, yönteminizde Illuminate \ Http \ Request yerine, yeni oluşturulan sınıfla değiştirmelisiniz:

App \ Http \ Requests \ StoreBlogPostRequest kullanın;
genel işlev deposu (StoreBlogPostRequest $ request)
{
    // Blog yazısı geçerli ...
}

Authorize () yöntemi bir boolean olmalıdır. Eğer yanlışsa, 403 atacaktır, bu yüzden onu app / Exceptions / Handler.php render s render () yönteminde yakaladığınızdan emin olun:

public function render ($ request, İstisna $ istisna)
{
   if ($ istisna instanceof \ Illuminate \ Auth \ Access \ AuthorizationException) {
      //
   }
   dönüş ebeveyn :: render ($ request, $ istisna);
}

Burada, request sınıfındaki eksik metod, messages () işlevidir; bu, doğrulama işleminin başarısız olması durumunda döndürülecek iletileri içeren bir dizidir:

sınıf StoreBlogPostRequest FormRequest'i genişletir
{
   kamu işlevi yetkilendirmek ()
   {
      $ $ this-> user () -> can ('create.posts');
   }
   ortak işlev kuralları ()
   {
       dönüş [
         'title' => 'gerekli | benzersiz: gönderiler | max: 255',
         'body' => 'gerekli'
       ];
   }
   genel işlev mesajları ()
   {
      dönüş [
        'title.required' => 'Başlık gerekli.',
        'title.unique' => 'Gönderi başlığı zaten var.',
        ...
      ];
   }
}

Onları kontrol cihazınızda yakalamak için blade dosyalarınızdaki hata değişkenini kullanabilirsiniz:

@ if ($ error-> any ())
   @foreach ($ error-> all () $ error olarak)
      {{$ error}}
   @endforeach
@endif

Belirli bir alanın doğrulama mesajını almak istemeniz durumunda, bunu istediğiniz gibi yapabilirsiniz (doğrulama için o alan geçerse yanlış bir boolean varlık döndürür):


@ if ($ errors-> has ('title'))
   
@endif

Sihirli kapsamlar

Bir şey inşa ederken, zaten gömülü olan sihirli kapsamları kullanabilirsiniz

  • Sonuçları alçalma, alçalma ile alın:
Kullanıcı :: () son -> get ();
  • Sonuçları alçaltarak herhangi bir alana göre alın:
Kullanıcı :: En son ( 'last_login_at') -> olsun ();
  • Sonuçları rastgele sırayla al:
Kullanıcı :: inRandomOrder () -> olsun ();
  • Sorgu yöntemini yalnızca gerçek bir şey olduğunda çalıştırın:
// Kullanıcının haber sayfasında olduğunu ve ilk önce en yenisine göre sıralamak istediğini varsayalım
// etkialanim.com.tr/news?sort=new
User :: when ($ request-> query ('sort'), işlev ($ query, $ sort) {
   if ($ sort == 'new') {
      $ query-> latest ();
   }
   
   $ query döndür;
}) -> () olsun;

When () yerine kullanabilirsiniz, aksi takdirde () ifadesinin tam tersidir.

Büyük sorgulamalar yapmaktan (veya yanlış yazılmışlardan) kaçınmak için İlişkileri kullanın.

Daha fazla bilgi edinmek için bir sorguda bir ton bağlantı kullandınız mı? Bu SQL komutlarını Query Builder ile bile yazmak oldukça zordur, ancak modeller zaten İlişkiler ile bunu yapmaktadır. Belki de belgelerin sağladığı yüksek miktarda bilgi nedeniyle ilk başta aşina olmayacaksınız, ancak bu, işlerin nasıl yürüdüğünü ve uygulamanızın nasıl daha düzgün çalışmasını sağladığınızı daha iyi anlamanıza yardımcı olacaktır.

İlişkilerin belgelerini buradan kontrol edin.

Zaman alan işler için İşleri kullanın

Laravel Jobs, görevleri arka planda çalıştırmak için güçlü bir zorunluluktur aracıdır.

  • Bir e-posta göndermek ister misiniz? Meslekler.
  • Mesaj yayınlamak ister misiniz? Meslekler.
  • Görüntüleri işlemek ister misiniz? Meslekler.

İşler, kullanıcılarınızın bu gibi zaman alıcı görevlerde yükleme süresinden vazgeçmenize yardımcı olur. Adlarını sıraya koyabilirler, öncelik sırasına koyabilirler ve tahmin et ne olur - Laravel mümkün olan her yerde kuyrukları uygular: arka planda bazı PHP'leri işlemek veya bildirimler göndermek veya olayları yayınlamak, sıralar vardır!

Queues’in belgelerini buradan kontrol edebilirsiniz.

Laravel Horizon'u kuyruklar için kullanmayı çok seviyorum çünkü kurulumu kolay, Süpervizör kullanılarak daemonize edilebiliyor ve yapılandırma dosyası aracılığıyla Horizon'a her sıra için kaç işlem istediğimi söyleyebilirim.

Veri tabanı standartlarına ve Erişimcilerine sadık kalın

Laravel size en başından beri değişkenlerinizin ve metodlarınızın $ camelCase camelCase () olması gerektiğini ve veritabanı alanlarınızın snake_case olması gerektiğini öğretir. Neden? Çünkü bu bize daha iyi erişimciler kurmamıza yardımcı oluyor.

Accessors, doğrudan modelimizden oluşturabileceğimiz özel alanlardır. Veritabanımız first_name, last_name ve age içeriyorsa, first_name ve last_name ile eşleşen ad adında özel bir alan ekleyebiliriz. Endişelenmeyin, bu DB'ye hiçbir şekilde yazılmayacak. Bu, bu belirli modelin sahip olduğu özel bir özellik. Kapsamlar gibi tüm erişimciler özel bir adlandırma sözdizimine sahiptir: getSomethingAttribute:

sınıf Kullanıcı Modeli genişletir
{
   ...
   public function getNameAttribute (): string
   {
       $ this-> first_name döndür. ' ' $ This-> last_name.;
   }
}

$ User-> name kullanıldığında, birleştirme işlevini döndürür.

Varsayılan olarak, eğer dd ($ user) ise name niteliği gösterilmez, ancak $ appends değişkenini kullanarak bunu genel olarak kullanılabilir hale getirebiliriz:

sınıf Kullanıcı Modeli genişletir
{
   $ appends korumalı = [
      'Name',
   ];
   ...
   public function getNameAttribute (): string
   {
       $ this-> first_name döndür. ' ' $ This-> last_name.;
   }
}

Şimdi, her dd yaptığımızda ($ user), değişkenin orada olduğunu göreceğiz (ama yine de, bu veri tabanında mevcut değil)

Bununla birlikte, dikkatli olun: zaten bir ad alanınız varsa, işler biraz farklıdır: $ appends içindeki ad artık gerekli değildir ve nitelik işlevi zaten depolanan değişken olan bir parametre için bekler (artık değişmeyecek $ bunu kullanın).

Aynı örnek için isimleri ucfirst () olarak kullanmak isteyebiliriz:

sınıf Kullanıcı Modeli genişletir
{
   $ appends korumalı = [
      //
   ];
   ...
   public function getFirstNameAttribute ($ firstName): string
   {
       dönüş ucfirst ($ firstName);
   }
   public function getLastNameAttribute ($ lastName): string
   {
      return ucfirst ($ lastName);
   }
}

Şimdi, $ user-> first_name kullandığımızda, büyük harfli bir ilke döndürecektir.

Bu özellik nedeniyle, veritabanı alanlarınız için snake_case kullanmak iyidir.

Modelle ilgili statik verileri yapılandırmalarda saklama

Yapmayı sevdiğim şey modelle ilgili statik verileri modelin içinde depolamak. Sana göstereyim.

Bunun yerine:

BettingOdds.php

sınıf BettingOdds Model genişletir
{
   ...
}

config / bettingOdds.php

dönüş [
   'spor' => [
      'futbol' => 'spor: 1',
      'tenis' => 'spor: 2',
      'basketbol' => 'spor: 3'
      ...
   ],
];

Ve onlara erişerek:

Yapılandırma (’bettingOdds.sports.soccer’);

Bunu yapmayı tercih ederim:

BettingOdds.php

sınıf BettingOdds Model genişletir
{
   statik $ spor korumalı = [
      'futbol' => 'spor: 1',
      'tenis' => 'spor: 2',
      'basketbol' => 'spor: 3'
      ...
   ];
}

Ve onlara kullanarak onlara erişin:

BettingOdds :: $ spor [ 'futbol'];

Neden? Çünkü başka işlemlerde kullanılması daha kolaydır:

sınıf BettingOdds Model genişletir
{
   statik $ spor korumalı = [
      'futbol' => 'spor: 1',
      'tenis' => 'spor: 2',
      'basketbol' => 'spor: 3'
      ...
   ];
   public function kapsamSpor ($ query, string $ sport)
   {
      if (! isset (self :: $ spor [$ spor])) {
         $ query döndür;
      }
      
      $ query-> where döndürün ('sport_id', self :: $ sports [$ sport]);
   }
}

Şimdi kapsamların tadını çıkarabiliriz:

BettingOdds :: spor (futbol ') -> (get);

Ham dizi işleme yerine koleksiyon kullan

O günlerde, dizilerle ham bir şekilde çalışmaya alışmıştık:

$ meyveler = ['elma', 'armut', 'muz', 'çilek'];
foreach ($ meyve olarak $ meyve) {
   echo 'var'. $ Meyve;
}

Şimdi, dizilerdeki verileri işlememize yardımcı olacak gelişmiş yöntemleri kullanabiliriz. Bir dizinin içindeki verileri filtreleyebilir, dönüştürebilir, yineleyebilir ve değiştirebiliriz:

$ meyveler = topla ($ meyveler);
$ meyve = $ meyve-> reddet (işlev ($ meyve) {
   $ meyve iade === 'elma';
}) -> toArray ();
['armut', 'muz', 'çilek']

Daha fazla ayrıntı için Koleksiyonlar ile ilgili kapsamlı belgelere bakın.

Query Builders ile çalışırken, -> get () yöntemi bir Koleksiyon örneği döndürür. Ancak Koleksiyonu bir Sorgu oluşturucu ile karıştırmamaya dikkat edin:

  • Sorgu Oluşturucuyu Insde, herhangi bir veri almadık. Sorgu ile ilgili birçok yöntem var: orderBy (), where (), etc.
  • -> get () öğesine basıldıktan sonra veriler alınır, bellek tüketilir, bir Koleksiyon örneği döndürür. Bazı Sorgu Oluşturucu yöntemleri kullanılamıyor veya bunlar var, ancak adları farklı. Daha fazla bilgi için Mevcut Yöntemleri kontrol edin.

Verileri Sorgu Oluşturucu düzeyinde filtreleyebilirseniz, yapın! Koleksiyon örneğine geldiğinde filtrelemeye güvenmeyin - bazı yerlerde çok fazla bellek kullanırsınız ve istemezsiniz. Sonuçlarınızı sınırlandırın ve dizinleri DB düzeyinde kullanın.

Paketleri kullanın ve tekerleği yeniden icat etmeyin

İşte kullandığım bazı paketler:

  • Laravel Blade Yönergeleri
  • Laravel CORS (rotalarınızı diğer kökenlerden koruyun)
  • Laravel Tag Helper (Blade'te HTML etiketlerinin daha iyi kullanımı)
  • Laravel Sluggable (sümüklü böcek üretme konusunda faydalıdır)
  • Laravel Yanıtlayıcı (JSON API'sini daha kolay oluşturun)
  • Görüntü Müdahalesi (görüntüleri tarzında işleyin)
  • Horizon (en az yapılandırmaya sahip denetleyici sıralar)
  • Sosyetik (sosyal medya ile giriş yapmak için minimum konfigürasyon)
  • Pasaport (güzergahlar için OAuth uygulaması)
  • Spatie’nin ActivityLog'u (modeller için etkinliği takip edin)
  • Spatie’nin Yedeği (yedekleme dosyaları ve veritabanları)
  • Spatie’nin Blade-X’i (kendi HTML etiketlerinizi tanımlayın; Laravel Tag Helper ile iyi çalışır)
  • Spatie’nin Medya Kitaplığı (modellere dosya eklemenin kolay yolu)
  • Spatie’nin Tepki Önbelleği (önbellek denetleyicisi yanıtları)
  • Spatie’nin Koleksiyon Makroları (koleksiyonlarda daha fazla makro)

İşte yazdığım bazı paketler:

  • Arkadaş (sosyal medyada olduğu gibi takip et ve engelle)
  • Zamanlama (zaman çizelgeleri oluşturun ve saatlere ve günlere karşı kontrol edin)
  • Değerlendirme (oran modelleri)
  • Koruyucu (izin sistemi, kolay yol)

Anlamak çok mu zor? Bana ulaş!

Eğer Laravel hakkında daha fazla sorunuz varsa, DevOps ile ilgili herhangi bir konuda yardıma ihtiyacınız varsa veya sadece bir Teşekkür!