سلام دوستان لاراولی! می‌خوایم قسمت ششم از مجموعه پست‌های ۸۰ سوال مصاحبه لاراول رو بررسی کنیم. پیشنهاد می‌کنم قبلش مقدمه و قسمت نکته دوستانه رو بخونین.

 

سوالاتی که توی این قسمت بررسی می‌کنیم:

  1. لاراول از چه تابعی برای Hash استفاده می‌کنه؟
  2. HTTP Client چیه؟
  3. Accessor و Mutator چیه؟
  4. Directive توی Blade چیه و چطوری یکی بسازیم؟
  5. چطوری اسم جدول رو توی مدل عوض کنیم؟
  6. دستور -mcr هنگام ساختن مدل چکار می‌کنه؟
  7. ACL چیه؟
  8. متد insertGetId چکار می‌کنه؟
  9. چه راه‌هایی برای مرتب کردن روت‌های برنامه می‌شناسین؟
  10. هنگام بروز خطا، چطوری از نمایش متغیرهای فایل .env جلوگیری کنیم؟

 

51. لاراول از چه تابعی برای Hash استفاده می‌کنه؟

لاراول به طور پیشفرض از تابع bcrypt برای هش کردن استفاده می‌کنه. این کار رو متد make از کلاس Hash انجام میده:

$hashed = Hash::make('plain text');

تنظیمات مربوط به هش، توی فایل config/hash.php قرار گرفته که می‌تونیم از اونجا از تابع دلخواه خودمون استفاده کنیم.

 

52. HTTP Client چیه؟

HTTP Client لاراول ابزاری هست که برای ارسال درخواست‌های HTTP و تعامل با سرویس‌های تحت وب استفاده میشه. HTTP Client پشت پرده از پکیج گازِل (Guzzle) استفاده می‌کنه و برای این معرفی شده تا کار با اون رو ساده‌تر و سریع‌تر کنه. به قول معروف، یک Wrapper هست برای گازِل. با HTTP Client، بدون پیچیدگی‌هایی که گازل داره، می‌تونیم درخواست‌های HTTP به یک سرور دیگه بفرستیم.

 

53. Accessor و Mutator چیه؟

اگه می‌خوایم Attribute های مدل رو طبق یک فرمت دلخواه نشون بدیم یا ذخیره کنیم، از Accessor و Mutator استفاده می‌کنیم. Accessor برای زمانی استفاده میشه که می‌خوایم یک Attribute رو با فرمت دلخواه نشون بدیم و Mutator برای زمانی استفاده میشه که می‌خوایم برای یک Attribute مقدار دلخواه تنظیم کنیم.

 

Accessor
فرض کنیم همیشه می‌خوایم اسم کاربران رو طوری نمایش بدیم که حرف اول، بصورت Uppercase (با حروف بزرگ) باشه. اگه کاربرا یک Attribute به اسم name داشته باشن، اسم Accessor میشه getNameAttribute که باید اون رو بصورت یک متد توی مدل User تعریف کنیم:

<?php

namespace App\Models;

class User extends Model
{
    public function getNameAttribute($name)
    {
        return ucfirst($name);
    }
}

با این کار، توی هر جایی از برنامه که از $user->name استفاده می‌کنیم، لازم نیست از ucfirst استفاده کنیم. چون از قبل بطور خودکار اعمال شده.

 

Mutator
فرض کنیم می‌خوایم رمز عبور کاربرا رو هش کنیم. اگه کاربرا یک Attribute به اسم password داشته باشن، اسم Mutator برای اون میشه setPasswordAttribute که اون رو باید بصورت یک متد توی مدل کاربران تعریف کنیم:

<?php

namespace App\Models;

class User extends Model
{
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = Hash::make($value);
    }
}

با این کار هر جایی از برنامه که به رمز عبور کاربر مقدار می‌دیم، لازم نیست عملیات مربوط به هش رو تکرار کنیم. فقط کافیه به password یک مقدار خام بدیم تا Mutator مربوط به اون اجرا بشه:

$user = User::find(29);
$user->password = 'rabbit';

// or

User::create([
    'password' => 'rabbit'
])

// or

$user->update([
    'password' => 'rabbit'
])

 

54. Directive توی Blade چیه و چطوری یکی بسازیم؟

توی فایل Blade به رشته‌هایی که با @ شروع میشن میگن Directive. مثلاً:

@if(...)

@endif

@foreach (...)

@endforeach

@csrf
@method('...')

Directive ها مثل کدهای PHP عمل می‌کنن و توسط موتور Blade رندر میشن. هدف از معرفی اونها جلوگیری از نوشتن کدهای PHP و تمیز نگه داشتن فایل Blade هست. اگه با لاراول کار کرده باشیم، قطعاً Directive های کاربردی زیادی رو می‌شناسیم. اما اگه بخوایم یکی دلخواه بسازیم از متد directive کلاس Blade استفاده می‌کنیم. کدمون رو بصورت زیر توی متد boot توی AppServiceProvider می‌نویسیم:

public function boot()
{
    Blade::directive('hello', function ($name) {
        return "<?php echo $name ?>";
    });
}

بعد از نوشتن باید دستور آرتیزان view:clear رو اجرا کنیم. و نهایتاً از اون بصورت زیر توی فایل Blade استفاده می‌کنیم:

@hello($user->name)

 

55. چطوری اسم جدول رو توی مدل عوض کنیم؟

اگه یک مدل داشته باشیم به اسم BookStore، بطور پیشفرض جدولی که در نظر گرفته میشه برای این مدل book_stores خواهد بود. یعنی حالت snake case و حالت جمع. پس باید یک جدول با همین اسم توی دیتابیس داشته باشیم. اما اگه اسم جدول چیزی غیر از اون هست، اسم اون رو بصورت زیر توی مدل تعریف می‌کنیم:

<?php

namespace App\Models;

class Flight extends Model
{
    protected $table = 'my_book_stores';
}

 

56. دستور -mcr هنگام ساختن مدل چکار می‌کنه؟

اگه هنگام ساختن مدل با دستور آرتیزان، دستور -mcr رو اضافه کنیم:

php artisan make:model Book -mcr

علاوه بر مدلی که ساخته میشه، یک فایل مایگریشن و یک کنترلر بصورت Resource برای مدل ساخته میشه.

Model created successfully.
Created Migration: 2020_10_10_092957_create_books_table
Controller created successfully.

 

57. ACL چیه؟

فرض کنیم یه وبسایت خبری داریم با بخش‌های مختلفی مثل مقالات، دسته‌بندی‌ها و نظرات. و می‌خوایم کاربرانی رو تعیین کنیم برای مدیریت این بخش‌ها. با استفاده از تکنیک ACL می‌تونیم یک سری مجوز بسازیم و اونها رو به کاربرا نسبت بدیم. مثلاً می‌خوایم یک کاربر فقط مخصوص مدیریت کردن نظرات باشه. ابتدا یک مجوز می‌سازیم مثلاً به اسم read_comments، بعد اون رو به بی‌نهایت کاربر نسبت می‌دیم. اینطوری فقط کاربری که مجوز read_comments رو داشته باشه می‌تونه به بخش نظرات دسترسی داشته باشه.

یکی از خوبی‌های استفاده از این تکنیک اینه که می‌تونیم بی‌نهایت مجوز و نقش تعریف کنیم و اونها رو به کاربرا نسبت بدیم، بدون اینکه که جدول کاربران تغییر کنه یا جدا باشه. ACL مخفف Access-control list هست و برای پیاده‌سازی اون توی لاراول پکیج‌های زیادی وجود داره.

 

58. متد insertGetId چکار می‌کنه؟

اگه می‌خوایم بعد ثبت کردن یک رکورد توی دیتابیس، ID اون رو داشته باشیم، بجای استفاده از متد insert()، از متد insertGetId() استفاده می‌کنیم. این متد توی Query Builder در دسترس هست:

$id = DB::table('users')->insertGetId([
    'email' => 'john@example.com',
    'name' => 'John'
]);

 

59. چه راه‌هایی برای مرتب کردن روت‌های برنامه می‌شناسین؟

یکی از راه‌ها استفاده از متد group هست. با این متد می‌تونیم از تکرار جلوگیری کنیم. کد زیر رو در نظر بگیرین که بدون استفاده از متد group نوشته شده:

Route::get('/admin/users', 'Admin\Web\UserController')->middleware('auth');
Route::get('/admin/posts', 'Admin\Web\PostController')->middleware('auth');
Route::get('/admin/comments', 'Admin\Web\Comment')->middleware('auth');

حالا با استفاده از متد group می‌تونیم اونها رو بصورت زیر بنویسیم:

Route::group([
    'middleware' => 'auth',
    'namespace' => 'Admin\Web',
    'prefix' => '/admin'
], function() {
    Route::get('/users', 'UserController');
    Route::get('/posts', 'PostController');
    Route::get('/comments', 'CommentController');
});

برای آشنایی بیشتر با روتینگ لاراول، پست زیر رو ببینید:

یک راه دیگه برای مرتب‌سازی روت‌ها، جداسازی فایل‌های روت هست که پیشنهاد می‌کنم این پست اختصاصی رو بخونین:

 

60. هنگام بروز خطا، چطوری از نمایش متغیرهای فایل .env جلوگیری کنیم؟

وقتی توی برنامه یک Exception مهار نشده رخ بده و اگه مقدار APP_DEBUG توی فایل .env برابر با true باشه، صفحه دیباگ برنامه، همه متغیرهای فایل .env و مقادیرشون رو نشون میده. برای جلوگیری از نمایش متغیرهای حساس مثلاً APP_KEY و DB_PASSWORD ، می‌تونیم اونها رو بصورت زیر مخفی کنیم. این کد رو توی فایل config/app.php می‌نویسیم:

return [

    // ...

    'debug_hide' => [
        '_ENV' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],

        '_SERVER' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],

        '_POST' => [
            'password',
        ],
    ],
];

برای ورژن لاراول ۷ و بالاتر از کلید debug_hide استفاده می‌کنیم. در غیر این صورت از کلید debug_blacklist.   اگه می‌خوایم همه متغیرها رو مخفی کنیم، از کد زیر استفاده می‌کنیم:

'debug_hide' => [
    '_COOKIE' => array_keys($_COOKIE),
    '_SERVER' => array_keys($_SERVER),
    '_ENV' => array_keys($_ENV),        
],

اگه از صفحه‌های قدیمی نمایش خطا استفاده می‌کنین، با این کار، خروجی بصورت زیر خواهد بود:

تصویر نوشته
عکس از  از

 

خب دوستان این هم از قسمت ۶. روزتون خوش 😉🖐️

منابعی که برای این پست استفاده کردم: