كتاب "Laravel. دليل كامل. الطبعة الثانية

صورةمرحبا ، هابروجيتلي! ما الذي يميز Laravel عن أطر PHP الأخرى؟ السرعة والبساطة. يتيح لك التطوير السريع للتطبيق ونظام بيئي شامل ومجموعة أدوات Laravel إنشاء مواقع وتطبيقات بسرعة باستخدام رمز نظيف وقابل للقراءة.

يقدم Matt Staffer ، وهو معلم شهير ومطور رئيسي ، نظرة عامة على الإطار وأمثلة محددة للعمل معه. سيساعد الكتاب مطوري PHP ذوي الخبرة على إدخال موضوع جديد بسرعة لتنفيذ مشروع على Laravel. يغطي المنشور أيضًا مواضيع Laravel Dusk و Horizon ، ويجمع معلومات حول موارد المجتمع والحزم الأخرى التي ليست جزءًا من جوهر Laravel. في هذا الكتاب سوف تجد: • أدوات لجمع بيانات المستخدم ، والتحقق منها ، وتطبيعها ، وتصفيتها • Blade ، محرك قالب مخصص مخصص من Laravel • نموذج معبر ORM معبّر للعمل مع قواعد بيانات التطبيق • معلومات حول دور كائن طلب الإضاءة في دورة حياة التطبيق • PHPUnit ، Mockery and Dusk لاختبار كود PHP الخاص بك • أدوات لكتابة JSON و RESTful API • واجهات للوصول إلى نظام الملفات والجلسات وملفات تعريف الارتباطذاكرة التخزين المؤقت والبحث • تنفيذ قوائم الانتظار والوظائف والأحداث ونشر أحداث WebSocket

محرك قالب الشفرة


تعمل PHP كلغة قالب بشكل جيد نسبيًا. ولكن لها عيوبها ، لذلك لا يمكنك استخدام <؟ Php مضمنة في كل مكان. معظم الأطر الحديثة لها لغة قالب خاصة بها.

تقدم Laravel محرك قالب Blade الخاص بها استنادًا إلى محرك .NET Razor. لديها بنية موجزة ، ومفهومة إلى حد ما ، مصحوبة بنموذج وراثي قوي وبديهي وقابلية توسعة سهلة.

يمكنك التعرف بسرعة على شكل Blade في المثال 4.1.

المثال 4.1 أمثلة على الشفرة

<h1>{{ $group->title }}</h1>
{!! $group->heroImageHtml() !!}

@forelse ($users as $user)
       • {{ $user->first_name }} {{ $user->last_name }}<br>
@empty
       No users in this group.
@endforelse

كما ترى ، فإن شفرة Blade تستخدم الأقواس المتعرجة لـ Echo والاتفاقية التي تسبق فيها علامات المستخدم الخاصة بها ، المسماة "أوامر" ، بـ @. ستقوم بتطبيق توجيهات لجميع هياكل الإدارة الخاصة بك ، بالإضافة إلى الوراثة وأي وظائف مخصصة تريد إضافتها.

إن بنية Blade نظيفة وموجزة ، لذا فإن العمل معها أسهل وأكثر متعة من البدائل. ولكن في الوقت الذي تحتاج فيه إلى شيء معقد في قوالبك - الميراث المتداخل أو الظروف المعقدة أو العودية - يظهر المحرك أفضل جانب له. مثل أفضل مكونات Laravel ، فإنه يبسط ويتيح الوصول إلى متطلبات التطبيق الثقيلة.

بالإضافة إلى ذلك ، نظرًا لأن كل بنية Blade يتم تجميعها في كود PHP العادي ثم يتم تخزينها في ذاكرة التخزين المؤقت ، فهي سريعة وتسمح لك باستخدام PHP الأصلي في ملفات هذا المحرك إذا رغبت في ذلك. ومع ذلك ، فإنني أوصي بتجنب استخدام PHP عندما يكون ذلك ممكنًا على الإطلاق - عادة إذا كنت بحاجة إلى القيام بشيء غير ممكن مع Blade أو توجيه المستخدم ، فإن هذا لا ينطبق على النموذج.

عرض البيانات


كما ترى في المثال 4.1 ، يتم استخدام الأقواس {{و}} لتغليف كود PHP الذي ترغب في عرضه. يعمل الرمز {{$ $ variable}} مثل <؟ = $ Variable؟> في لغة PHP البسيطة.

ومع ذلك ، هناك فرق: يعمل Blade على حماية جميع التعيينات افتراضيًا باستخدام وظيفة htmlentities () PHP لحماية المستخدمين من لصق البرامج النصية الضارة. هذا يعني أن {{$ variable}} مكافئ وظيفيًا لـ <؟ = Htmlentities ($ variable)؟>. إذا كنت لا تريد الهروب من المخرجات ، استخدم {!!! وبدلا من ذلك.
{{ }} -

, Blade ({{}}) -. Laravel , Blade Handlebars?

Blade {{ @. , , :

// Blade; $bladeVariable
//
{{ $bladeVariable }}

// @ "{{ handlebarsVariable }}"
//
@{{ handlebarsVariable }}

verbatim( http://bit.ly/2OnrPRP ).

الهياكل الحاكمة


ستكون معظم هياكل التحكم في Blade مألوفة. يكرر الكثير مباشرة اسم وهيكل العلامة نفسها في PHP.

هناك عدد قليل من المساعدين للراحة ، ولكن بشكل عام تبدو هياكل التحكم أكثر نظافة من PHP.

الانشاءات الشرطية


النظر في الهيكل المنطقي للإدارة.

@if

التعبيرif ($ condition) في Blade يترجم إلى <؟ Php if ($ condition):؟>.آخر، آخرإذا و إنهاء إذا- بنفس أسلوب التركيب في PHP. نلقي نظرة على

مثال 4.2. مثال 4.2. @إذاآخر، آخرإذا و إنهاء إذا

@if (count($talks) === 1)
     There is one talk at this time period.
@elseif (count($talks) === 0)
     There are no talks at this time period.
@else
     There are {{ count($talks) }} talks at this time period.
@endif

كما هو الحال مع التعبيرات الشرطية الخاصة بـ PHP ، يمكنك مزجها ودمجها كما تريد. ليس لديهم منطق معين ؛ يوجد محلل مع بحث في النموذجif ($ condition) واستبداله بكود PHP المقابل.

@unless @endunless

unless ، من ناحية أخرى ، هي بناء جديد ليس له مكافئ مباشر في PHP. هذا عكسif. unless ($ condition) هو نفس <؟ php if (! $ condition). يمكنك مشاهدة ذلك في المثال 4.3.

مثال 4.3 unless وendunless

@unless ($user->hasPaid())
       You can complete your payment by switching to the payment tab.
@endunless

دورات


بعد ذلك ، ضع في اعتبارك الدورات.

@for, @foreach @while

إلى عن على، foreach و في حينالعمل في Blade بنفس الطريقة كما في PHP (الأمثلة 4.4-4.6).

مثال 4.4إلى عن على وforfor

@for ($i = 0; $i < $talk->slotsCount(); $i++)
      The number is {{ $i }}<br>
@endfor

مثال 4.5 foreach وendforeach

@foreach ($talks as $talk)
       • {{ $talk->title }} ({{ $talk->length }} minutes)<br>
@endforeach

مثال 4.6. في حين وفي الوقت نفسه

@while ($item = array_pop($items))
       {{ $item->orSomething() }}<br>
@endwhile

@forelse @endforelse

إلى عن علىهو آخر foreach، والتي يمكن تنفيذها حتى لو كان الكائن الذي تبحث عنه فارغًا. لقد رأينا هذا في العمل في بداية الفصل. يوضح المثال 4.7 خيارًا آخر.

مثال 4.7.إلى عن علىآخر

@forelse ($talks as $talk)
       • {{ $talk->title }} ({{ $talk->length }} minutes)<br>
@empty
       No talks this day.
@endforelse

متغير LOOP $ في التوجيهات تنبأ

وتوجيهات FORELSEforeach و إلى عن علىآخر (تم تقديمه في Laravel 5.3) يضيف متغير $ loop ، والذي لا يتوفر في PHP foreach loops. عندما تستخدم داخل حلقةforeach أو إلى عن علىelse stdClass .

• index — 0 ; 0 — « ».

• iteration — 1 ; 1 — « ».

• remaining — , .

• count — .

• first — , , .

• last — , , .

• depth — «» : 1 , 2 . .

• parent — $loop , foreach؛ خلاف ذلك باطلا.

إليك مثال عن كيفية عمل ذلك:

<ul>
@foreach ($pages as $page)
       <li>{{ $loop->iteration }}: {{ $page->title }}
             @if ($page->hasChildren())
             <ul>
             @foreach ($page->children() as $child)
             <li>{{ $loop->parent->iteration }}
                   .{{ $loop->iteration }}:
                   {{ $child->title }}</li>
             @endforeach
             </ul>
             @endif
       </li>
@endforeach
</ul>

وراثة القالب


يوفر Blade إطار عمل توريث القالب الذي يسمح للعروض بالتوسيع والتعديل وتضمين طرق عرض أخرى.

دعونا نرى كيف يتم بناء الميراث مع بليد.

تعريف أقسام الصفحة باستخدام @ section / @ show directives and يخضع أو يستسلم


لنبدأ بتخطيط Blade عالي المستوى ، كما في المثال 4.8. هذا هو تعريف غلاف الصفحة الشامل الذي سنضع فيه لاحقًا محتوى خاصًا بالصفحة.

مثال 4.8. هيكل الشفرة

<!-- resources/views/layouts/master.blade.php -->
<html>
       <head>
              <title>My Site | @yield('title', 'Home Page')</title>
       </head>
       <body>
              <div class="container">
                    @yield('content')
              </div>
              @section('footerScripts')
                     <script src="app.js"></script>
              @show
       </body>
</html>

يشبه هذا صفحة HTML عادية ، ولكن يمكنك رؤية العائد في مكانين (العنوان والمحتوى) ، وقمنا بتعريف القسم في الثالث (footerScripts). هنا لدينا ثلاثة توجيهات بليد: فقطيخضع أو يستسلم('المحتوى')، يخضع أو يستسلم("العنوان" ، "الصفحة الرئيسية") مع القيمة الافتراضية و @ section / @ تظهر مع المحتوى الفعلي فيه.

على الرغم من أنها تبدو مختلفة قليلاً ، إلا أنها تعمل بشكل أساسي. يحدد الثلاثة جميعًا أن هناك قسمًا باسم معين (المعلمة الأولى) يمكن توسيعه لاحقًا ، وماذا تفعل إذا لم يتم توسيع القسم. يفعلون ذلك إما باستخدام سطر إرجاع ("الصفحة الرئيسية") ، أو بدون عودة (لن يتم عرض أي شيء إذا لم يتم توسيع التوجيه) ، أو مع عودة الكتلة بالكامل (في هذه الحالة).

ماهو الفرق؟ فييخضع أو يستسلم("المحتوى") ليس هناك محتوى افتراضي. الى جانب ذلك ، فييخضع أو يستسلم("العنوان") سيتم عرضه فقط إذا لم يتم توسيع التوجيه. خلاف ذلك ، لن يكون للأقسام التابعة لها وصول آلي إلى القيمة الافتراضية. يحدد @ @ / @ القيمة في وقت واحد القيمة الافتراضية ويجعل محتوياتها في متناول أطفالها عبرparent.

إذا كان لديك مثل هذا التخطيط الرئيسي ، يمكنك توسيعه في ملف قالب جديد ، كما في المثال 4.9.

مثال 4.9. تمديد تخطيط شفرة

<!-- resources/views/dashboard.blade.php -->
@extends('layouts.master')

@section('title', 'Dashboard')

@section('content')
       Welcome to your application dashboard!
@endsection

@section('footerScripts')
      @parent
      <script src="dashboard.js"></script>
@endsection

تتيح لنا طريقة عرض الطفل هذه عرض بعض المفاهيم الجديدة لوراثة Blade.

@extends

في المثال 4.9 ، باستخدامextends ('layouts.master') ، نحدد أنه لا يجب عرض هذا العرض بمفرده ، ولكن بدلاً من ذلك يوسع عرضًا آخر. هذا يعني أن دورها هو إنشاء محتوى أقسام مختلفة ، ولكن ليس للعمل بمفردها. يشبه سلسلة من كتل المحتوى أكثر من صفحة HTML. يحدد السطر أيضًا أن العرض الذي يمدده يقع في resources / views / Layouts / master.blade.php.

يجب أن يقوم كل ملف بتوسيع ملف واحد فقط ، ويجب أن يكون الاستدعاءextends هو السطر الأول من الملف.

@section @endsection

باستخدامsection ("title" ، "Dashboard") ، نقدم المحتوى الخاص بنا للقسم الأول ، العنوان. نظرًا لأن المحتوى قصير جدًا ، بدلاً منsection وendsection ، نستخدم نموذجًا مختصرًا. يسمح لك هذا بتمرير المحتوى كمعلمةsection الثانية ، ثم الانتقال. إذا كنت مرتبكًا قليلاً معsection بدونendsection ، يمكنك استخدام بناء الجملة المعتاد.

منsection ("المحتوى") فصاعدًا ، نستخدم بناء الجملة المعتاد لتعريف محتويات قسم المحتوى. حتى ندرج تحية صغيرة. ومع ذلك ، لاحظ: عند استخدامsection في طريقة عرض تابعة ، فإنك تنتهي بـendsection (أو الاسم المستعار الخاص به)قف) في حين أن تبين، والتي تكون مخصصة لتحديد الأقسام في طرق العرض الرئيسية.

@parent

منsection ('footerScripts') فصاعدًا ، نستخدم بناء الجملة المعتاد لتعريف محتويات قسم footerScripts.

تذكر أننا قمنا بالفعل بتعريف هذا المحتوى (أو على الأقل "قيمته الافتراضية") بالفعل في التخطيط الرئيسي. إذاً هذه المرة لدينا خياران: إما الكتابة فوق المحتويات من طريقة العرض الرئيسية ، أو الإضافة إليها.
يمكنك أن ترى أن لدينا القدرة على تضمين محتوى من العرض الرئيسي باستخدام توجيهparent داخل هذا القسم. خلاف ذلك ، سيتم إعادة كتابة محتويات القسم بالكامل مع كل ما تم تحديده في أصل هذا القسم.

إدراج مكونات العرض


الآن بعد أن اكتشفنا أساسيات الميراث ، يمكن استخدام عدد قليل من الحيل.

@include

ماذا لو كنا في رأي واحد ونريد استخدام آخر؟ ربما يكون هناك زر تسجيل ، من المستحسن إعادة إضافته في جميع أنحاء الموقع. وربما أريد تحديد نص الزر في كل مرة نستخدمه. ألق نظرة على المثال 4.10.

مثال 4.10. تضمين مكونات العرض معتتضمن

<!-- resources/views/home.blade.php -->
<div class="content" data-page-name="{{ $pageName }}">
      <p>Here's why you should sign up for our app: <strong>It's Great.</strong></p>

      @include('sign-up-button', ['text' => 'See just how great it is'])
</div>

<!-- resources/views/sign-up-button.blade.php -->
<a class="button button--callout" data-page-name="{{ $pageName }}">
      <i class="exclamation-icon"></i> {{ $text }}
</a>

تتضمنيقوم بسحب أحد المكونات ونقل البيانات إليه (اختياري). يرجى ملاحظة أنه لا يمكنك فقط تمرير البيانات بشكل صريح للتضمين من خلال المعلمة الثانيةتتضمن، ولكن يمكنك أيضًا الرجوع إلى أي متغيرات في الملف المضمّن تكون متاحة للعرض المضمن (في هذا المثال ، $ pageName). يمكنك أن تفعل ما تريد ، لكنني أوصي بالوضوح لتمرير كل متغير تنوي تطبيقه دائمًا.

يمكنك أيضًا استخدام التوجيهاتتتضمنإذا تتضمنمتى و تتضمنأولاً ، كما هو موضح في المثال 4.11.

المثال 4.11. تضمين وجهات نظر شرطية

{{--  ,    --}}
@includeIf('sidebars.admin', ['some' => 'data'])

{{--  ,     true --}}
@includeWhen($user->isAdmin(), 'sidebars.admin', ['some' => 'data'])

{{--        --}}
@includeFirst(['customs.header', 'header'], ['some' => 'data'])

@each

يمكنك تخيل الظروف التي تحتاج فيها إلى التكرار عبر مصفوفة ومجموعة و تتضمنجزء لكل عنصر. هناك توجيه لهذا.كل.

لنفترض أن لدينا لوحة وحدات جانبية ونريد تضمين عدة وحدات باسمها. ألق نظرة على المثال 4.12.

مثال 4.12. باستخدام مكونات العرض في حلقة معكل

<!-- resources/views/sidebar.blade.php -->
<div class="sidebar">
      @each('partials.module', $modules, 'module', 'partials.empty-module')
</div>

<!-- resources/views/partials/module.blade.php -->
<div class="sidebar-module">
      <h1>{{ $module->title }}</h1>
</div>

<!-- resources/views/partials/empty-module.blade.php -->
<div class="sidebar-module">
      No modules :(
</div>

النظر في بناء الجملة كل. المعلمة الأولى هي اسم مكون العرض. والثاني هو مصفوفة أو مجموعة للتكرار. ثالثًا ، اسم المتغير الذي سيتم بموجبه تمرير كل عنصر (في هذه الحالة ، كل عنصر في صفيف وحدات $) إلى العرض. والمعلمة الرابعة الاختيارية هي طريقة عرض توضح ما إذا كانت المصفوفة أو المجموعة فارغة (أو إذا كنت ترغب في ذلك ، يمكنك تمرير سلسلة هنا سيتم استخدامها كنموذجك).

باستخدام المداخن


ربما يكون من الصعب إدارة القالب العام باستخدام Blade الأساسي - عندما تحتاج كل طريقة عرض في التسلسل الهرمي لـ Blade إلى إضافة شيء إلى قسم معين - مثل إضافة إدخال إلى مصفوفة.

الحالة الأكثر شيوعًا هي عندما تحتوي بعض الصفحات (وأحيانًا بمعنى أوسع على أقسام معينة من الموقع) على ملفات CSS وجافا سكريبت فريدة محددة تحتاج إلى تحميلها. تخيل أن لديك ملف CSS "عام" للموقع بأكمله ، وملف CSS لقسم المهمة وملف CSS لصفحة "الحصول على وظيفة".

مكدسات شفرة مصنوعة لذلك. في القالب الأصلي ، قم بتعريف مكدس العنصر النائب. ثم ، في كل قالب فرعي ، يمكنك "دفع" السجلات هناك باستخدامإدفع/ @ endpush ، الذي يضيفها إلى نهاية المكدس في الصورة النهائية. يمكنك أيضًا استخدام @ prepend / @ endprepend لإضافتها إلى البداية. يوضح المثال 4.13 هذا.

مثال 4.13. باستخدام مداخن الشفرة

<!-- resources/views/layouts/app.blade.php -->
<html>
<head><!--  --></head>
<body>
       <!--    -->
       <script src="/css/global.css"></script>
       <!-- ,       -->
       @stack('scripts')
</body>
</html>

<!-- resources/views/jobs.blade.php -->
@extends('layouts.app')

@push('scripts')
        <!--  -    -->
        <script src="/css/jobs.css"></script>
@endpush

<!-- resources/views/jobs/apply.blade.php -->
@extends('jobs')

@prepend('scripts')
       <!--  -    -->
       <script src="/css/jobs--apply.css"></script>

@endprepend

هذا يؤدي إلى النتيجة التالية:

<html>
<head><!--  --></head>
<body>
       <!--    -->
       <script src="/css/global.css"></script>
       <!-- ,       -->
       <script src="/css/jobs--apply.css"></script>
       <script src="/css/jobs.css"></script>
</body>
</html>

استخدام المكونات والفتحات


يقدم Laravel نموذجًا آخر لتضمين المحتوى بين طرق العرض ، والذي تم تقديمه في 5.4: المكونات والفتحات. تكون الأولى أكثر فاعلية في السياقات عندما تستخدم طرق عرض المكون وتمرر أجزاء كبيرة من المحتوى إليها كمتغيرات. انظر إلى المثال 4.14 للحصول على توضيح لنموذج أو تلميح أداة قد ينبه المستخدم إلى خطأ أو إجراء آخر.

مثال 4.14. تعد النافذة المشروطة مثالاً سيئًا لعرض مكون

<!-- resources/views/partials/modal.blade.php -->
<div class="modal">
      <div>{{ $content }}</div>
      <div class="close button etc">...</div>
</div>

<!--    -->
@include('partials.modal', [
       'body' => '<p>The password you have provided is not valid. Here are the rules
       for valid passwords: [...]</p><p><a href="#">...</a></p>'
])

هذا كثير جدًا لمثل هذا المتغير وهو مثالي للمكون.

المكونات ذات الفتحات هي مكونات طرق العرض المصممة لتشمل أجزاء كبيرة ("فتحات") لاسترداد المحتوى من قالب مضمن. يوضح المثال 4.15 كيفية إجراء هندسة عكسية للكود من المثال 4.14 باستخدام المكونات والفتحات.

مثال 4.15. نافذة مشروط كمكون أكثر ملاءمة مع فتحات

<!-- resources/views/partials/modal.blade.php -->
<div class="modal">
      <div>{{ $slot }}</div>
      <div class="close button etc">...</div>
</div>

<!--    -->
@component('partials.modal')
        <p>The password you have provided is not valid.
        Here are the rules for valid passwords: [...]</p>

        <p><a href="#">...</a></p>
@endcomponent

كما ترى في المثال 4.15 ، التوجيه مكونيسمح لك باستخراج كود HTML الخاص بنا من سلسلة مضغوطة من متغير والعودة إلى مساحة القالب. يستقبل متغير slot $ في قالب مكوننا أي محتوى تم نقله إليهمكون.

فتحات مركبة


الطريقة التي استخدمناها في المثال 4.15 تسمى الفتحة "الافتراضية" ؛ كل ما تمر بهمكونوendcomponent ، تم تمريرهما إلى متغير slot $. ولكن يمكنك أيضًا الحصول على أكثر من مجرد فتحة افتراضية. تخيل نافذة مشروطة بعنوان ، كما في المثال 4.16.

مثال 4.16. مكون تمثيل شكلي مع متغيرين

<!-- resources/views/partials/modal.blade.php -->
<div class="modal">
      <div class="modal-header">{{ $title }}</div>
      <div>{{ $slot }}</div>
      <div class="close button etc">...</div>
</div>

يمكنك استخدام التوجيه فتحة في تحدياتهم مكونلنقل المحتوى إلى فتحات غير الافتراضية ، كما هو موضح في المثال 4.17.

مثال 4.17. انقل أكثر من فتحة واحدة إلى أحد المكونات

@component('partials.modal')
        @slot('title')
               Password validation failure
        @endslot

        <p>The password you have provided is not valid.
        Here are the rules for valid passwords: [...]</p>

        <p><a href="#">...</a></p>
@endcomponent

وإذا كانت هناك متغيرات أخرى في وجهة نظرك لا معنى لها باعتبارها فتحة ، فلا يزال بإمكانك تمرير مجموعة من المحتويات كمعلمة ثانية ل مكون نفس الشيء مع تتضمن. ألق نظرة على المثال 4.18.

مثال 4.18. تمرير البيانات إلى مكون بدون فتحات

@component('partials.modal', ['class' => 'danger'])
         ...
@endcomponent

تسمية المكون كإرشاد


هناك خدعة لتبسيط مكونات المكالمة: الأسماء المستعارة. ما عليك سوى استدعاء Blade :: Component () في واجهة Blade - الأكثر شيوعًا هو طريقة التمهيد AppServiceProvider - ثم تمريرها إلى موقع المكون ثم اسم التوجيه المطلوب ، كما هو موضح في المثال 4.19.

المثال 4.19. الاسم المستعار لأحد المكونات على أنه توجيه

// AppServiceProvider@boot
Blade::component('partials.modal', 'modal');

<!--   -->
@modal
         Modal content here
@endmodal


»يمكن العثور على مزيد من المعلومات حول الكتاب على موقع الناشر على الإنترنت
» المحتويات
» مقتطفات

لـ Khabrozhiteley خصم 25 ٪ على القسيمة - Laravel

عند دفع النسخة الورقية من الكتاب ، يتم إرسال كتاب إلكتروني عبر البريد الإلكتروني.

All Articles