Laravelni oldinga itarish - Laravel 5.7 uchun eng yaxshi maslahatlar va eng yaxshi amaliyotlar

Ushbu postda Migel Piedrafitaning Blogcast ilovasi tufayli audio versiyasi mavjud.

Laravel allaqachon ko'plab PHP ishlab chiquvchilari tomonidan toza, ishlaydigan va nosozliklarni tuzatuvchi kod yozish uchun tanilgan. Bundan tashqari, u ko'plab hujjatlarni qo'llab-quvvatlaydi, ba'zida hujjatlar ro'yxatiga kiritilmagan yoki ular yo'q edi, ammo ular turli sabablarga ko'ra olib tashlangan.

Men Laravel bilan ishlab chiqarishdan foydalanish sohasida 2 yil ishladim va yomon kodni yozishni yaxshi kodga qadar o'rgandim va men Laravel bilan birinchi marta kod yozishni boshlaganimdan beri foydalandim. Men sizga Laravel bilan kod yozishda sizga yordam beradigan sirli fokuslarni ko'rsatmoqchiman.

Biror narsani so'rash kerak bo'lganda mahalliy miqyoslardan foydalaning

Laravel Query Builder-dan foydalanib, ma'lumotlar bazasi drayveri uchun so'rovlarni yozishning yaxshi usuliga ega. Shunga o'xshash narsa:

$ buyurtmalar = Buyurtma :: qayerda ('status', 'etkazib berish') -> qaerda ('to'langan', haqiqiy) -> olish ();

Bu juda yaxshi. Bu meni SQL-dan voz kechishga va kodlash haqida o'ylashga majbur qildi. Ammo mahalliy bitishmalardan foydalansak, bu bit kodni yaxshiroq yozish mumkin.

Mahalliy miqyoslar bizga ma'lumotlarni qidirishda zanjirlashimiz mumkin bo'lgan Query Builder usullarini yaratishga imkon beradi. Masalan, -> qaerda () gaplar o'rniga biz toza usulda -> etkazilgan () va -> pullik () dan foydalanishimiz mumkin.

Birinchidan, Buyurtma modelimizga ba'zi usullarni qo'shishimiz kerak:

sinf buyurtma Model kengaytiradi
{
   ...
   public function rangeDelivered ($ query) {
      qaytish $ query-> qaerda ('status', 'etkazilgan');
   }
   publicPreactionPaid ($ query) {
      return query query-> qaerda ('to'langan', true);
   }
}

Mahalliy miqyoslarni e'lon qilayotganda, siz aniq bir nomlanish doirasidan foydalanishingiz kerak. Shu tarzda, Laravel bu hajm ekanligini bilib oladi va undan sizning so'rovlaringizni yaratishda foydalanadi. Laravel tomonidan avtomatik ravishda kiritiladigan birinchi so'rovni qo'shganingizga ishonch hosil qiling va so'rovlarni tuzuvchi misol.

$ buyurtmalar = Buyurtma :: etkazilgan () -> pullik () -> olish ();

Keyinchalik dinamik ravishda olish uchun siz mahalliy dinamiklardan foydalanishingiz mumkin. Har bir qamrov parametrlarni berishga imkon beradi.

sinf Buyurtma Model kengaytiradi
{
   ...
   publicStatus umumiy funktsiyasi ($ so'rov, $ string holati) {
      qaytish $ query-> qaerda ('status', $ status);
   }
}
$ buyurtmalar = Buyurtma :: holat ('etkazilgan') -> pullik () -> olish ();

Keyinchalik ushbu maqolada, nima uchun snake_case-ni ma'lumotlar bazasi maydonchalari uchun ishlatishingiz kerakligini bilib olasiz, ammo bu erda birinchi sabab: Laravel odatdagidek [biror narsa] oldingi doirani almashtirish uchun foydalanadi. Shunday qilib, avvalgisining o'rniga, quyidagilarni qilishingiz mumkin:

Buyurtma :: whereStatus ('etkazilgan') -> pullik () -> olish ();

Laravel narsa-ning [narsa] ning snake_case versiyasini qidiradi. Agar sizning MB da statusingiz bo'lsa, avvalgi misoldan foydalanasiz. Agar sizda transport_statuslari bo'lsa, siz quyidagilarni ishlatishingiz mumkin.

Buyurtma :: whereShippingStatus ('etkazilgan') -> pullik () -> olish ();

Bu sizning tanlovingiz!

Zarur bo'lganda, so'rovlar fayllaridan foydalaning

Laravel sizning shakllaringizni tekshirishning mohirona usulini taqdim etadi. Bu POST yoki GET so'rovidir, agar kerak bo'lsa, uni tasdiqlay olmaydi.

Siz bu usulni o'zingizning kontrolörünüzde tasdiqlashingiz mumkin:

jamoat funktsiyalari do'koni ($ so'rovni so'rash)
{
    $ validatedData = $ request-> validate ([
        'title' => 'zarur | noyob: xabarlar | max: 255',
        'body' => 'zarur',
    ]);

    // Blog posti haqiqiy ...
}

Ammo sizning nazorat qilish usulingizda juda ko'p kod mavjud bo'lsa, bu juda yomon bo'lishi mumkin. Tekshirish moslamasida imkon qadar ko'proq kodni kamaytirishni xohlaysiz. Hech bo'lmaganda, mantiqan to'g'ri yozish kerak bo'lsa, menimcha, bu birinchi narsa.

Laravel sizga so'rovlarni tasdiqlash uchun "yoqimli" usulni taqdim etadi, so'rovlar sinflarini yaratib, ularni eski so'rovlar klassi o'rniga ishlatadi. Faqat so'rovingizni yaratishingiz kerak:

php usta qilish: StoreBlogPost-ga murojaat qiling

Ilova / Http / Requests / papka ichida siz so'rov faylini topasiz:

sinf StoreBlogPostRequest FormRequest-ni kengaytiradi
{
   public function authorize ()
   {
      return $ this-> user () -> can ('create.posts');
   }
   jamoat funktsiyalari qoidalari ()
   {
       qaytish [
         'title' => 'zarur | noyob: xabarlar | max: 255',
         'body' => 'zarur',
       ];
   }
}

Endi, metodingizdagi Illuminate \ Http \ Request o'rniga, siz yangi yaratilgan sinf bilan almashtirishingiz kerak:

App \ Http \ Requestlar \ StoreBlogPostRequest-dan foydalanish;
jamoat funktsiyalari do'koni (StoreBlogPostRequest $ so'rovi)
{
    // Blog posti haqiqiy ...
}

Authorize () usuli mantiqiy bo'lishi kerak. Agar u noto'g'ri bo'lsa, u 403 ni tashlaydi, shuning uchun uni ilova / istisnolar / Handler.php ning render () usulida ushlaganingizga ishonch hosil qiling:

ommaviy funktsiyani ko'rsatish ($ so'rov, $ istisno)
{
   if ($ istisno holati \ Illuminate \ Avuth \ Access \ AuthorizationException) {
      //
   }
   return parent :: render ($ so'rov, $ istisno);
}

Bu erda etishmayotgan usul, so'rovlar sinfida xabarlar () funktsiyasi, ya'ni tekshiruv muvaffaqiyatsiz bo'lgan taqdirda qaytariladigan xabarlarni o'z ichiga olgan qator:

sinf StoreBlogPostRequest FormRequest-ni kengaytiradi
{
   public function authorize ()
   {
      return $ this-> user () -> can ('create.posts');
   }
   jamoat funktsiyalari qoidalari ()
   {
       qaytish [
         'title' => 'zarur | noyob: xabarlar | max: 255',
         'body' => 'zarur',
       ];
   }
   ommaviy funktsiya xabarlari ()
   {
      qaytish [
        'title.required' => 'Sarlavha kerak.',
        'title.unique' => 'Xabarning sarlavhasi allaqachon mavjud.',
        ...
      ];
   }
}

Kontrolleringizda ularni ushlab turish uchun siz pichoq fayllaridagi xatolar o'zgaruvchisidan foydalanishingiz mumkin:

@if ($ xatolar-> har qanday ())
   @foreach ($ error-> all () $ error)
      {{$ error}}
   @endforeach
@endif

Agar siz biron bir maydonning haqiqiyligini tekshirish xabarini olishni xohlasangiz, uni xuddi shunday qilishingiz mumkin (agar ushbu maydon uchun tekshirish o'tkazilgan bo'lsa, u noto'g'ri-mantiqiy ob'ektni qaytaradi):


@if ($ error-> ichida ('title'))
   
@endif

Sehrli doiralar

Ishlarni qurishda siz allaqachon o'rnatilgan sehrli doiralardan foydalanishingiz mumkin

  • Yaratilgan_at, kamaygan bo'yicha natijalarni oling:
User :: latest () -> get ();
  • Olingan natijalarni istalgan maydonchadan pastga tushiring:
User :: latest ('last_login_at') -> get ();
  • Natijalarni tasodifiy tartibda oling:
Foydalanuvchi :: inRandomOrder () -> get ();
  • Agar biror narsa haqiqat bo'lsa, so'rov usulini ishga tushiring:
// Aytaylik, foydalanuvchi yangiliklar sahifasida va uni avval yangisi bo'yicha saralashni xohlaydi
// mydomain.com/news?sort=new
Foydalanuvchi :: qachon ($ request-> query ('sort'), funktsiya ($ query, $ sort) {
   if ($ sort == 'new') {
      qaytish $ query-> latest ();
   }
   
   $ so'rovini qaytarish;
}) -> get ();

Siz qachondan () o'rniga foydalanishingiz mumkin, bundan qachon () ning aksi.

Katta so'rovlarning oldini olish uchun (yoki noto'g'ri yozilgan) munosabatlardan foydalaning.

Ko'proq ma'lumot olish uchun so'rovda bir necha tonna birikmalardan foydalanganmisiz? Ushbu SQL buyruqlarini, hatto Query Builder-da yozish juda qiyin, ammo modellar buni allaqachon Relationship-da bajaradilar. Ehtimol, dastlab hujjatlar bilan ta'minlangan ma'lumotlarning ko'pligi tufayli siz bilan tanish bo'lmasligingiz mumkin, ammo bu narsalar qanday ishlashini va ilovangizni qanday qilib yumshoqroq qilishni yaxshiroq tushunishga yordam beradi.

Aloqalar hujjatlarini bu erda tekshiring.

Vaqt talab qiladigan ishlarni bajarish uchun ishlardan foydalaning

Laravel Jobs - bu vazifalarni fonda bajarish uchun kuchli zaruriy vosita.

  • Elektron pochta xabarini yubormoqchimisiz? Ishlar.
  • Xabar uzatmoqchimisiz? Ishlar.
  • Rasmlarni qayta ishlashni xohlaysizmi? Ishlar.

Bo'sh ish o'rinlari sizning foydalanuvchilaringizga yuklash vaqtidan voz kechishga yordam beradi. Ularni nomlangan navbatga qo'yish mumkin, ular ustuvorlashtirilishi mumkin va nima ekanligini taxmin qilish kerak - Laravel deyarli hamma joyda navbatni amalga oshirdi: yoki PHPni fonda qayta ishlash yoki xabarlarni yuborish yoki tadbirlarni translyatsiya qilish, navbatlar mavjud!

Siz bu erda Queues hujjatlarini tekshirishingiz mumkin.

Men Laravel Horizonni navbat uchun ishlatishni yaxshi ko'raman, chunki uni sozlash juda oson, uni Supervisor yordamida o'chirib qo'yish mumkin va konfiguratsiya fayli orqali men Horizonga har bir navbat uchun qancha protsedura kerakligini aytishga qodirman.

Ma'lumotlar bazasi standartlari va aksessuarlarga rioya qiling

Laravel boshidanoq sizga o'zgaruvchilar va usullaringiz $ camelCase camelCase () bo'lishi kerakligini va ma'lumotlar bazangiz maydonchalari snake_case bo'lishi kerakligini o'rgatadi. Nima uchun? Chunki bu bizga yaxshiroq kirish vositalarini yaratishda yordam beradi.

Aksessuar - bu bizning modelimizdan to'g'ridan-to'g'ri qurishimiz mumkin bo'lgan maxsus maydonlar. Agar bizning ma'lumotlar bazamizda first_name, last_name va age mavjud bo'lsa, biz birinchi ism va familiyani birlashtiradigan maxsus nomlangan maydonni qo'shishimiz mumkin. Xavotir olmang, bu hech qanday tarzda MBda yozilmaydi. Bu faqat ushbu o'ziga xos modelning o'ziga xos xususiyati. Barcha kirish maydonchalari kabi maxsus nomlash sintaksisi mavjud: getSomethingAttribute:

sinf Modelni kengaytiradi
{
   ...
   umumiy funktsiya getNameAttribute (): string
   {
       return this this-> first_name. ' '. $ this-> last_name;'
   }
}

$ User-> nomidan foydalanganda u bog'lanishni qaytaradi.

Odatiy bo'lib, agar biz dd ($ user) bo'lsa, atribut atributi ko'rsatilmaydi, ammo $ appends o'zgaruvchisidan foydalanib, buni umuman oladigan qilishimiz mumkin:

sinf Modelni kengaytiradi
{
   himoyalangan $ appends = [
      'ism',
   ];
   ...
   umumiy funktsiya getNameAttribute (): string
   {
       return this this-> first_name. ' '. $ this-> last_name;'
   }
}

Endi, har safar dd ($ user) o'zgaruvchisi borligini ko'ramiz (lekin bu ma'lumotlar bazasida mavjud emas).

Ehtiyot bo'ling, agar sizda nom maydoni bo'lsa, unda narsalar bir oz farq qiladi: $ appends ichidagi nom endi kerak emas va atribut funktsiyasi allaqachon saqlangan o'zgaruvchini ko'rsatadigan bitta parametrni kutadi (biz endi boshqa bo'lmaydi) dollardan foydalaning).

Xuddi shu misol uchun biz ismlarni ucfirst () so'rashimiz mumkin:

sinf Modelni kengaytiradi
{
   himoyalangan $ appends = [
      //
   ];
   ...
   umumiy funktsiya getFirstNameAttribute ($ firstName): string
   {
       qaytish ucfirst ($ firstName);
   }
   umumiy funktsiya getLastNameAttribute ($ lastName): string
   {
      qaytish ucfirst ($ lastName);
   }
}

Endi, biz $ user-> first_name-dan foydalanganda, u bosh harfli birinchi qatorni qaytaradi.

Ushbu xususiyat tufayli snake_case-ni ma'lumotlar bazangiz maydonchalari uchun ishlatish yaxshi.

Modelga tegishli statik ma'lumotlarni configlarda saqlamang

Menga yoqadigan narsa bu modelga tegishli statik ma'lumotlarni saqlashdir. Sizga ko'rsatay.

Buning o‘rniga:

BettingOdds.php

sinf BettingOdds Modelni kengaytiradi
{
   ...
}

config / bettingOdds.php

qaytish [
   'sport' => [
      'futbol' => 'sport: 1',
      'tennis' => 'sport: 2',
      'basketbol' => 'sport: 3',
      ...
   ],
];

Va ularga kirish:

config ('bettingOdds.sports.soccer');

Men buni qilishni afzal ko'raman:

BettingOdds.php

sinf BettingOdds Modelni kengaytiradi
{
   himoyalangan statik $ sport = [
      'futbol' => 'sport: 1',
      'tennis' => 'sport: 2',
      'basketbol' => 'sport: 3',
      ...
   ];
}

Va ularga quyidagilar orqali kiring:

BettingOdds :: $ sport ['futbol'];

Nima uchun? Keyingi ishlarda foydalanish osonroq bo'lganligi sababli:

sinf BettingOdds Modelni kengaytiradi
{
   himoyalangan statik $ sport = [
      'futbol' => 'sport: 1',
      'tennis' => 'sport: 2',
      'basketbol' => 'sport: 3',
      ...
   ];
   public funktsiyasiSport ($ so'rov, $ sport qatori)
   {
      if (! isset (self :: $ sport [$ sport]))) {
         $ so'rovini qaytarish;
      }
      
      qaytish $ query-> qaerda ('sport_id', self :: $ sport [$ sport]);
   }
}

Endi biz keng qamrovlardan bahramand bo'lishimiz mumkin:

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

Massivli ishlov berish o'rniga to'plamlardan foydalaning

O'sha kunlarda biz massivlar bilan ishlamas edik:

$ mevalar = ['olma', 'nok', 'banan', 'qulupnay'];
oldingi (mevalar $ meva sifatida) {
   echo "menda" $ meva;
}

Endi biz massivlarda ma'lumotlarni qayta ishlashga yordam beradigan ilg'or usullardan foydalanishimiz mumkin. Massiv ichidagi ma'lumotlarni filtrlashimiz, o'zgartirishimiz, o'zgartirishimiz va o'zgartirishimiz mumkin:

$ mevalar = yig'ish ($ mevalar);
$ mevalar = $ mevalar-> rad qilish (funktsiya ($ mevalar) {
   qaytish $ meva === 'olma';
}) -> to Arrray ();
['nok', 'banan', 'qulupnay']

Qo'shimcha ma'lumot olish uchun To'plamlarda keng qamrovli hujjatlarni ko'rib chiqing.

Query Builders bilan ishlashda -> get () usuli To'plam namunasini qaytaradi. To'plamni Query builder bilan aralashtirib yubormaslik uchun ehtiyot bo'ling:

  • Query Builder-ni kiriting, biz hech qanday ma'lumot olmadik. Bizda so'rov bilan bog'liq ko'plab usullar mavjud: orderBy (), qaerda () va hk.
  • Biz urganimizdan so'ng -> get (), ma'lumotlar olinadi, xotira tugadi va To'plam namunasini qaytaradi. Ba'zi Query Builder usullari mavjud emas yoki ular mavjud, ammo ularning nomi boshqacha. Ko'proq ma'lumot uchun mavjud usullarni tekshiring.

Agar siz Query Builder darajasida ma'lumotlarni filtrlay olsangiz, buni bajaring! To'plam namunasiga kelganda filtrlashga ishonmang - ba'zi joylarda siz juda ko'p xotiradan foydalanasiz va istamaysiz. Natijalaringizni cheklang va MB ma'lumotlar darajasida indekslardan foydalaning.

Paketlardan foydalaning va g'ildirakni ixtiro qilmang

Men foydalanadigan ba'zi paketlar:

  • Laravel Blade Direktivalari
  • Laravel CORS (yo'nalishlaringizni boshqa manbalardan himoya qiling)
  • Laravel Tag Helper (HTML teglaridan Blade-da yaxshiroq foydalanish)
  • Laravel Sluggable (ishlab chiqarish haqida gap ketganda foydali)
  • Laravel Responder (JSON API yaratish osonroq)
  • Rasmlar aralashuvi (rasmlarni uslubda ishlatish)
  • Horizon (minimal konfiguratsiyaga ega bo'lgan navbatchi nazoratchilar)
  • Socialite (ijtimoiy tarmoqlarga kirish uchun minimal konfiguratsiya)
  • Pasport (yo'nalishlar uchun OAuth-ni joriy qilish)
  • Spatie'sLogLog (modellar uchun treklar)
  • Spatie-ning zahira nusxasi (zaxira fayllari va ma'lumotlar bazalari)
  • Spatie Blade-X (o'z HTML-teglaringizni aniqlang; Laravel Tag Helper bilan yaxshi ishlaydi)
  • Spatie-ning media kutubxonasi (fayllarni modellarga biriktirishning oson usuli)
  • Spatie-ning javob keshi (kesh boshqaruvchisi javoblari)
  • Spatie to'plamidagi makroslar (to'plamdagi boshqa makroslar)

Mana men yozgan ba'zi paketlar:

  • Tanlangan (ijtimoiy tarmoqlardagi kabi, kuzatib borish va blokirovka qilish)
  • Jadval (jadval tuzing va soat va kunni tekshiring)
  • Reyting (narx modellari)
  • Vasiy (ruxsat tizimi, oson yo'l)

Tushunish juda qiyinmi? Menga yet!

Agar sizda Laravel haqida boshqa savollar bo'lsa, DevOps bilan bog'liq har qanday ma'lumotga muhtoj bo'lsangiz yoki rahmat aytishni xohlasangiz, meni Twitter @rennokki orqali topishingiz mumkin!