<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های نگار جوادزاده</title>
        <link>https://virgool.io/feed/@negarjavadzadeh</link>
        <description>backend developer( PHP + Laravel)</description>
        <language>fa</language>
        <pubDate>2026-04-14 18:36:44</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/208255/avatar/3bMeup.png?height=120&amp;width=120</url>
            <title>نگار جوادزاده</title>
            <link>https://virgool.io/@negarjavadzadeh</link>
        </image>

                    <item>
                <title>ارسال notification با استفاده از Firebase Cloud Messaging و مدیریت با لاراول</title>
                <link>https://virgool.io/@negarjavadzadeh/%D8%A7%D8%B1%D8%B3%D8%A7%D9%84-notification-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-firebase-cloud-messaging-%D9%88-%D9%85%D8%AF%DB%8C%D8%B1%DB%8C%D8%AA-%D8%A8%D8%A7-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-ffbluzs4ilo3</link>
                <description>سرویس Firebase Cloud Messaging چیست؟سرویس Firebase Cloud Messaging Platform (با نام قبلی GCM) یک سرویس اعلان رایگان تلفن همراه توسط Google است که توسعه دهندگان برنامه (شخص ثالث) را قادر می سازد اعلان ها را از سرورهای GCM (پیام رسان Google) برای کاربران خود ارسال کنند. ابزاری برای نوشتن یا ساختن درخواست های پیام. Notifications گزینه ای مبتنی بر GUI برای ایجاد درخواست های اعلان ارائه می دهد. برای اتوماسیون کامل و پشتیبانی از انواع پیام ها ، باید درخواست پیام را در یک محیط سرور معتبر ایجاد کنید که از Firebase Admin SDK یا پروتکل های سرور FCM پشتیبانی می کند. این محیط می تواند Cloud Functions برای Firebase ، Google App Engine یا سرور برنامه خود شما باشد.پیام Firebase به شما امکان می دهد  notifications را برای همه کاربران خود در هر نقطه از جهان ارسال کنید. در ادامه به آموزش استفاده از این پیام رسان با خواهیم پرداخت.Firebase Cloud Messagingدلایل استفاده از پیام رسان Firebase چیست؟اول ، Google Firebase Messaging Platform چند پلتفرمی است که به طور طبیعی در Firebase که دارای ویژگی های مجموعه طراحی شده برای Android ، iOS و وب تلفن همراه است ، جای می گیرد.دوم ، ارزش اصلی Firebase یکپارچه سازی ویژگی های متقابل است که توانایی ارسال سایر پیام های Firebase به راحتی از طریق FCM است. به عنوان مثال ، می توانید از Firebase Notifications برای ارسال مجدد Chrome push notifications به کاربران خود استفاده کنید.معماری FCMایجاد پروژه در Firebase اولین قدم ایجاد یک پروژه در محیط Google است.توجه: برای گذر از این آموزش ، باید با یک حساب Google وارد سیستم شده باشید که می تواند از کنسول Firebase استفاده کند.شما با کنسول Firebase یک پروژه ایجاد می کنید. کنسول Firebase را باز کنید. روی &quot;ایجاد پروژه جدید&quot; کلیک کنید. (اگر ویژگی های Google غیر از FCM را به پروژه اضافه کرده اید ، می توانید یک پروژه موجود Google را برای پیکربندی FCM وارد کنید.)ایجاد پروژه جدید در firebaseپنجره &quot;ایجاد یک پروژه&quot; باز می شود.اطلاعات زیر را وارد کنید و &quot;ایجاد پروژه&quot; را کلیک کنید.نام پروژهوارد Test شوید. این نام پروژه برنامه شما در کنسول Firebase است.کشور / منطقهانتخاب نام پروژهمرحله دوم ایجاد پروژهانتخاب موقعیت مکانیایجاد پروژه موفقیت آمیزصفحه شروع کنسول Firebase باز می شود.روی &quot;افزودن Firebase به برنامه Android خود&quot; کلیک کنید. (در این مقاله من پروژه اندروید ایجاد میکنم ولی شما میتوانید پلتفرم های دیگر را نیز استفاده کنید.)انتخاب پلتفرم اندرویدصفحه &quot;جزئیات برنامه&quot; باز می شود.نام بسته برنامه تلفن همراه را اینجا وارد کنید. (نام بسته مشخص شده هنگام ایجاد پروژه در Android Studio). این نام ، com.example.test در این آموزش است.اگر فقط از ویژگی FCM استفاده می کنید ، می توانید نام مستعار برنامه و گواهی امضای اشکال زدایی SHA-1 را حذف کنید. در غیر این صورت ، دستورالعمل های روی صفحه را دنبال کنید.پس از مشخص کردن جزئیات برنامه ، روی &quot;افزودن برنامه&quot; کلیک کنید.جزئیات برنامهبا دنبال کردن دستورالعمل های روی صفحه ، پیکربندی را ادامه دهید.صفحه &quot;کپی فایل پیکربندی&quot; به محض باز شدن صفحه ، فایل google-services.json را در دستگاه شما بارگیری می کند. فایل google-services.json را در Android Studio راه اندازی خواهید کرد.دستورالعمل اصلاح فایل build.gradle را نادیده بگیرید زیرا اصلاحاتی که روی صفحه انجام می شود باعث ایجاد خطای ساخت می شود. در مرحله های بعد فایل build.gradle را اصلاح کنید.برای بررسی کلید سرور ، ابتدا &quot;تنظیمات&quot; را از فهرست پروژه انتخاب کنید تا صفحه &quot;تنظیمات&quot; باز شود.تنظیماتبرگه &quot;Cloud Messaging&quot; را در صفحه &quot;تنظیمات&quot; باز کنید.تنظیمات عمومی پروژهدریافت کلید سرور شناسه ارسال کنندهکلید ذخیره شده در سرور برنامه ، کلید سرور است. این کلید سرور دسترسی مجاز به سرویس های Google را برای سرور برنامه فراهم می کند به عنوان یک روش توصیه شده ، هرگز نباید کلید API را در هر کجای کد مشتری خود قرار دهید.رشته ای که به عنوان کلید سرور نمایش داده می شود را در جایی نگه دارید. در مرحله بعدی در زمان استفاده از API برای ارسال notification  در پروژه لاراول از آن استفاده خواهیم کرد.برای پیکر بندی این سرویس روی اپلیکشن اندروید خود میتوانید از این منبع استفاده کنید.تفاوت شناسه فرستنده GCM و شناسه فرستنده FCM؟شناسه فرستنده (Google Cloud Messaging (GCM: یک مقدار عددی منحصر به فرد است که هنگام پیکربندی پروژه خود در Google Developers Console / Google Cloud Console ایجاد می شود. شماره پروژه شناسه فرستنده GCM است. در فرآیند ثبت نام برای شناسایی سرور برنامه ای که مجاز به ارسال پیام / اعلان به برنامه کاربر است استفاده می شود.شناسه فرستنده (Firebase Cloud Messaging (FCM: معادل شناسه فرستنده Google Cloud Messaging . در زیر تب Firebase&gt; Project&gt; Settings&gt; Cloud Messaging قابل دسترسی است.سرویس GCM یا FCM؟در حقیقت، FCM نسخه جدید GCM با نام تجاری Firebase است. FCM زیرساخت اصلی GCM را با SDK جدید به ارمغان می آورد تا توسعه پیام ابری را آسان تر کند.بررسی REST API های مهم Firebase Cloud Messagingما در پروژه لاراول برای ارسال notification از API ها استفاده خواهیم کرد به این منظور API های مهم این سرویس را بررسی میکنیم. ارسال notification تکیارسال notification گروهیبررسی اعتبار و صحت FCM registration id (این شناسه در هنگام نصب اپلیکشن برای هر دستگاه ایجاد میشود که سرویس پیام رسان از این شناسه برای ارسال اعلان به آن دستگاه استفاده میکند.)در این آموزش برای آزمایش API ها از Postman استفاده میکنیم.در همه این API ها  و برای احراز هویت از کلید سرور که در قسمت قبل بعد از ایجاد پروژه Firebase به دست آوردیم، استفاده میکنیم.1) ارسال notification تکیبرای ارسال notification به یک دستگاه، API ای با این مشخصات و از آدرس https://fcm.googleapis.com/fcm/send برای URL این API استفاده میشود.Headers توجه کنید که با توجه به شکل بالا متد API باید POST باشد. به جای کلید YOUR_API_KEY از کلید سرور خود استفاده کنید. برای body این API به این شکل عمل میکنیم:bodyمتن درخواست باید شامل &quot;notification&quot; و &quot;to&quot; باشد. هیچ محدودیتی در افزودن ویژگی ها به داده json  وجود ندارد و میتوانید هر طور که می خواهید کنترل کنید. در قسمت to باید FCM registration id مخصوص دستگاه مورد نظر که میخواهید اعلان را دریافت کند، را وارد میکنید. ارسال اشیا تو در تو نیز ممکن است مانند json زیر:{
    &amp;quotnotification&amp;quot:{
        &amp;quottitle&amp;quot:&amp;quotNew Text Message&amp;quot,
        &amp;quotimage&amp;quot:&amp;quothttps://firebase.google.com/images/social.png&amp;quot,
        &amp;quotmessage&amp;quot:&amp;quotHello how are you?&amp;quot,
        &amp;quotmeta&amp;quot:{
            &amp;quottype&amp;quot:&amp;quotsmall&amp;quot,
            &amp;quotinfo&amp;quot:&amp;quotSearch&amp;quot
        }
    },
    &amp;quotto&amp;quot:&amp;quotVALID_REGISTRATION_ID&amp;quot
}نتیجه از که در صورت موفقیت آمیز بودن ارسال اعلان مشاهده خواهید کرد به شکل زیر خواهد بود.نتیجه ارسال اعلان موفقیت آمیز2)ارسال notification گروهیبرای ارسال اعلان گروهی میتوانید از URL مربوط به ارسال تکی با متد POST استفاده کنید و  body را به شکل زیر بنویسید:bodyدقت کنید که داده های ارسالی را در json مربوط به notification نوشته و FCM registration id های مربوط به دستگاه ها را در آرایه registration_ids قرار دهید.همانند قسمت قبل در بخش notification داده های دیگری نیز میتوانید اضافه کنید.{
    &amp;quotregistration_ids&amp;quot: [
        &amp;quotVALID_REGISTRATION_ID1&amp;quot,
        &amp;quotVALID_REGISTRATION_ID2&amp;quot,
        &amp;quotVALID_REGISTRATION_ID3&amp;quot
    ],
    &amp;quotnotification&amp;quot:{
        &amp;quottitle&amp;quot:&amp;quottitle of notification&amp;quot,
        &amp;quotbody&amp;quot:&amp;quotbody of message&amp;quot,
        &amp;quotimage&amp;quot:&amp;quothttps://firebase.google.com/images/social.png&amp;quot
    }
}بعد از ارسال این API چنین جوابی را دریافت خواهید کرد:پاسخ ارسال گروهی اعلاندر این پاسخ 2 مورد بسیار مهم وجود دارد. اول تعداد اعلان های موفق و ناموفق. همان طور که در شکل مشاهده میکنید، 1اعلان موفق و 2 اعلان ناموفق از 3 اعلان ارسالی داشتیم. دوم نتیجه ارسال اعلان. با توجه به شکل بالا، &quot;VALID_REGISTRATION_ID1&quot; دارای اعتبار بوده و بقیه این شناسه ها فاقد اعتبار هستند.3)بررسی اعتبار و صحت FCM registration idبرای بررسی اعتبار FCM registration id  کاربر میتوانید از آدرس &lt;https://iid.googleapis.com/iid/info/&lt;VALID_REGISTRATION_ID برای URL با متد GET به شکل زیر استفاده کنید. توجه داشته باشید که FCM registration id مربوط به کاربر را در URL بالا به جای عبارت &lt;VALID_REGISTRATION_ID&gt; قرار دهید. Headersدر صورت صحت FCM registration id مورد نظر، پاسخ زیر را دریافت خواهید کرد که نمایش دهنده مشخصات اپلیکشن شماست. پاسخ FCM registration id دارای اعتبارمدیریت ارسال Notification با یک سیستم پیاده سازی شده با لاراولدر این قسمت میخواهیم یک سیستم مدیریت برای ارسال اعلان با لاراول پیاده سازی کنیم. در ابتدا یک پروژه لاراول با نام دلخواه ایجاد میکنیم. دستور زیر را در ترمینال خود اجرا کنید تا یک برنامه جدید Laravel ایجاد کنید (ایجاد این پروژه با استفاده از Laravel installer انجام میشود شما میتوانید با composer هم این پروژه را ایجاد کنید):laravel new notification-managementcd notification-managementایجاد پایگاه دادهما برای این پروژه از پایگاه داده My SQL استفاده خواهیم کرد. فایل env. پروژه خود را باز کنید و نام پایگاه داده را انتخاب کنید. برای مثال من نام پایگاه داده را notification انتخاب میکنم.123456DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=notification
DB_USERNAME=root
DB_PASSWORD=سپس در phpMyAdmin خود یک پایگاه داده خالی با نام notification ایجاد کنید تا جدول های مربوط به پروژه به وسیله migration ها در آن ایجاد شوند.در پستی که قبلا منتشر کرده ام، به طور کامل در مورد migration ها صحبت کرده ام. اگر هنوز آن را مطالعه نکرده اید، می توانید برای فهم بیشتر در مورد Migration ها به آن مراجعه کنید. (مبحث Migration ها در Laravel)برای احراز هویت پروژه، در لاراول 8 نیازی به کد های اضافه نیست و یک سیستم احراز هویت به صورت پیش فرض در زمان ایجاد پروژه روی سیستم موجود است. و migration مربوط به ایجاد جدول کاربران از قبل ایجاد شده (شما میتوانید ستون های این جدول را تغییر دهید.) و فقط برای ایجاد ui های مربوط به صفحه ورود و ثبت نام را میتوانید با اجرای دستور زیر در خط فرمان، ایجاد کنید. (ایجاد و تغییر این صفحات به دلخواه شما خواهد بود و در این مقاله به توضیحات این موارد نمی پردازیم).composer require laravel/ui php artisan ui bootstrap - -authما برای ذخیره کردن اطلاعات دستگاه های کاربران نیز باید جدولی اختصاصی ایجاد کنیم. ارتباط بین جدول های کاربران و دستگاه ها، یک به چند خواهد بود چون ما این مورد را که ممکن است یک کاربر با چند دستگاه از اپلیکشن ما استفاده کند را نیز درنظر میگیریم.برای ایجاد migration برای تولید جدول devices، دستور زیر را در خط فرمان خود وارد کنید.php artisan make:migration create_devices_tableبا اجرای این دستور فایل migration مربوط به جدول devices در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:// database/migrations/&lt;timestamp&gt;_create_devices_table.php
[...]
public function up(){
    Schema::create(&#039;Devices&#039;, function (Blueprint $table) {
        $table-&gt;increments(&#039;id&#039;);
        $table-&gt;unsignedBigInteger(&#039;user_id&#039;)-&gt;index();
        $table-&gt;string(&#039;os&#039;)-&gt;nullable();
        $table-&gt;string(&#039;manufacturer&#039;)-&gt;nullable();
        $table-&gt;string(&#039;model&#039;)-&gt;nullable();
        $table-&gt;string(&#039;version&#039;)-&gt;nullable();
        $table-&gt;string(&#039;versionRelease&#039;)-&gt;nullable();
        $table-&gt;string(&#039;fcm_reg_id&#039;, 191)-&gt;unique(); //شناسه ورود کاربر به اپلیکشن شما
        $table-&gt;string(&#039;app_version&#039;)-&gt;nullable();
        $table-&gt;timestamps();
        $table-&gt;foreign(&#039;user_id&#039;)-&gt;references(&#039;id&#039;)-&gt;on(&#039;users&#039;);
        });
    }
[...]در این فایل ستون های مورد نیاز آورده شده است شما بسته به نیاز خود میتوانید آن را تغییر دهید.سپس جدول های مربوط به اعلان ها را میسازیم. برای ایجاد migration برای تولید جدول messages، دستور زیر را در خط فرمان خود وارد کنید.php artisan make:migration create_messages_tableبا اجرای این دستور فایل migration مربوط به جدول messages در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:// database/migrations/&lt;timestamp&gt;_create_messages_table.php
[...]
public function up(){
    Schema::create(&#039;messages&#039;, function (Blueprint $table) {
        $table-&gt;increments(&#039;id&#039;);
        $table-&gt;string(&#039;title&#039;);
        $table-&gt;text(&#039;body&#039;);
        $table-&gt;unsignedBigInteger(&#039;sender_id&#039;);
        $table-&gt;foreign(&#039;sender_id&#039;)-&gt;references(&#039;id&#039;)-&gt;on(&#039;users&#039;);
        $table-&gt;timestamps();
    });
}
[...]سپس برای ایجاد ارتباط چند به چند بین جدول کاربران و پیام ها باید یک جدول دیگر ایجاد کنیم. ارتباط این 2 جدول چند به چند است به این دلیل که هر پیام را می توان به چند کاربر ارسال کرد و هر کاربر میتواند چند پیام دریافت کرده باشد. برای ایجاد این جدول هم میتوانید در همین فایل Schema مربوط به ایجاد جدول را بنویسید و هم میتوانید یک migration جدید ایجاد کنید.php artisan make:migration create_message_user_tableبا اجرای این دستور فایل migration مربوط به جدول message_user در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:// database/migrations/&lt;timestamp&gt;_create_message_user_table.php
[...]
public function up(){
    Schema::create(&#039;message_user&#039;, function (Blueprint $table) {
        $table-&gt;unsignedBigInteger(&#039;message_id&#039;)-&gt;index();
        $table-&gt;foreign(&#039;message_id&#039;)-&gt;references(&#039;id&#039;)-&gt;on(&#039;messages&#039;);
        $table-&gt;unsignedBigInteger(&#039;user_id&#039;)-&gt;index();
        $table-&gt;foreign(&#039;user_id&#039;)-&gt;references(&#039;id&#039;)-&gt;on(&#039;users&#039;);
     });
}
[...]مدل ها (Model)در این قسمت کلاسی برای دستگاه ها میسازیم و متد های زیر را به آن اضافه میکنیم. برای ساختن مدل برای دستگاه ، دستور زیر را اجرا کنید:php artisan make:model Deviceفایل Device.php را از پوشه App/Models باز کنید و همانند کد های زیر آن را تغییر دهید:&lt;?php
namespace App/Models;
use Illuminate\Database\Eloquent\Model;

class Device extends Model{
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = &#039;devices&#039;;

    /**
     * The database primary key value.
     *
     * @var string
     */
    protected $primaryKey = &#039;id&#039;;

    /**
     * Attributes that should be mass-assignable.
     *
     * @var array
     */
    protected $fillable = [&#039;user_id&#039; , &#039;os&#039;, &#039;manufacturer&#039;, &#039;model&#039;, &#039;version&#039;, &#039;versionRelease&#039;, &#039;fcm_reg_id&#039;, &#039;app_version&#039;];

    public function user(){
        return $this-&gt;belongsTo(&#039;App\Models\User&#039;, &#039;user_id&#039;);
    }

    public function messages(){
        return $this-&gt;belongsToMany(&#039;App\Models\Message&#039;, &#039;devicesinfo_message&#039;, 
                      &#039;deviceinfo_id&#039;,  &#039;message_id&#039;);
    }
}سپس کلاسی برای پیام ایجاد میکنیم و متد های زیر را به آن اضافه میکنیم. برای ساختن مدل برای پیام ، دستور زیر را اجرا کنید:php artisan make:model Messageفایل Message.php را از پوشه App/Models باز کنید و همانند کد های زیر آن را تغییر دهید:&lt;?php
namespace App/Models;
use Illuminate\Database\Eloquent\Model;

class Message extends Model{
    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = &#039;messages&#039;;

    /**
     * The database primary key value.
     *
     * @var string
     */
    protected $primaryKey = &#039;id&#039;;

    /**
     * Attributes that should be mass-assignable.
     *
     * @var array
     */
    protected $fillable = [&#039;title&#039;, &#039;body&#039;, &#039;sender_id&#039;];

    public function users(){
        return $this-&gt;belongsToMany(&#039;App\Models\User&#039;, &#039;message_user&#039;);
    }

    public function sender(){
        return $this-&gt;belongsTo(&#039;App\Models\User&#039;, &#039;sender_id&#039;, &#039;id&#039;);
    }
}ارتباط بین 3 جدول فوق به این صورت است که:کاربرها و دستگاه ها : یک به چند. هر کاربر چند دستگاه میتواند داشته باشد و هر دستگاه فقط مربوط به یک کاربر است.کاربر ها و پیام ها: چند به چند. هر کاربر میتواند چند پیام دریافت کند و هر پیام می تواند به چند کاربر ارسال شود. و در هر مدل ارتباط بین جدول ها را نیز پیاده سازی میکنیم. این متد ها را نیز به مدل User اضافه کنید:public function messages(){
    return $this-&gt;belongsToMany(&#039;App\Models\Message&#039;, &#039;message_user&#039;);
}

public function devices(){
    return $this-&gt;hasMany(&#039;App\Models\Device&#039;);
}ما همچنین با قرار دادن تعدادی از ستون ها در آرایه قابل پر کردن(fillable) برخی از ستون های پایگاه داده خود را به عنوان fillable تعریف کردیم. این به لاراول در مورد مدل ها می گوید: اگر من متد ایجاد(create) یا به روزرسانی(update) را فراخوانی کرده و آرایه ای به عنوان آرگمان فرستادم، فقط ستون هایی که قابلیت fillable را دارند را قبول کن.به این ترتیب ، از سناریویی جلوگیری خواهیم کرد که اگر کاربر بتواند از هر کدام از مرزهای امنیتی ما دور بماند و رکورد مورد نظر خود را برای درج یا به روزرسانی آنها بفرستد، اجازه این کار را نداشته باشد.کنترلر ها(controllers)در این قسمت ما با استفاده از API هایی که در قسمت قبل با آن ها آشنا شدیم، از طریق firebase cloud message به دستگاه هایی که در پایگاه داده ذخیره کردیم اعلان ارسال خواهیم کرد.یک کنترلر به نام MessageController ایجاد کنید تا در آن متد های مربوط به مدیریت اعلان را پیاده سازی کنیم. به این منظور دستور زیر را در خط فرمان اجرا کنید:php artisan make:Controller  MessageControllerسپس فایل MessageController.php ایجاد شده در مسیر App/Http/Controllers را این گونه تغییر دهید:&lt;?php
namespace App\Http\Controllers;

use App\Device;
use App\Http\Controllers\Controller;
use App\Message;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class MessageController extends Controller{

    /*این متد برای نمایش لیست پیام های ارسال شده اخیر تنظیم شده است که شامل بخش جست و جو بر اساس عنوان و متن پیام نیز هست. */

    public function index(Request $request){
        $perPage = 25;
        $query = Message::orderby(&amp;quotid&amp;quot, &amp;quotdesc&amp;quot);

        //filters
        $keyword = $request-&gt;get(&#039;search&#039;);
        if (!empty($keyword)) {
            $query-&gt;where(function ($query) use ($keyword) {
                $query-&gt;where(&#039;title&#039;, &#039;LIKE&#039;, &amp;quot%$keyword%&amp;quot)
                    -&gt;orWhere(&#039;body&#039;, &#039;LIKE&#039;, &amp;quot%$keyword%&amp;quot);
            });
        }
        $messages = $query-&gt;paginate($perPage);
        return view(&#039;messages.index&#039;, compact(&#039;messages&#039;));
    }

/*این متد به منظور نمایش فرم ارسال پیام میباشد. برای نمایش تعداد کاربرانی که پیام را دریافت خواهد کرد، ما تعداد را نیز به صفحه نمایش فرم ارسال میکنیم. */
    public function create(){
        $allUsersCount = User::count();
        return view(&#039;messages.create&#039;, compact(&#039;allUsersCount&#039;));
    }

/*این متد به منظور ارسال پیام میباشد*/
    public function store(Request $request){  
        /*اول قوانینی که ورودی این متد باید از آن پیروی کند را پیاده سازی میکنیم*/
        $request-&gt;validate([
            &#039;title&#039; =&gt; &#039;required&#039;,
            &#039;body&#039; =&gt; &#039;required&#039;,
            &#039;users_id&#039; =&gt; &#039;array|required&#039;
        ],[
            &#039;title.required&#039; =&gt; &#039;وارد کردن عنوان برای پیام الزامیست.&#039;,
            &#039;body.required&#039; =&gt; &#039;وارد کردن متن پیام الزامیست.&#039;,
            &#039;users_id.required&#039; =&gt; &#039;هیچ کاربری برای ارسال انتخاب نکردید!&#039;,
        ]);

        $users = $request-&gt;users_id;
        $tokens = [];

        /* ابتدا پیام ارسالی را در جدول ذخیره میکنیم.*/
        $message = Message::create([
            &#039;title&#039; =&gt; $request-&gt;title,
            &#039;body&#039; =&gt; $request-&gt;body,
            &#039;sender_id&#039; =&gt; Auth::id()
        ]);

         /*برای ارسال به تمام دستگاه های داخل پایگاه داده باید ستون مربوط به شناسه ورود کاربر به اپلیکشن را دریافت کرده و به عنوان گیرنده وارد کنیم. */
        $query = Device::select(&#039;id&#039;, &#039;fcm_reg_id&#039;, &#039;user_id&#039;);
                        $tokens = $query-&gt;pluck(&#039;fcm_reg_id&#039;)-&gt;all(); //آرایه شناسه دریافت کنندگان
                        $user_ids = $query-&gt;pluck(&#039;user_id&#039;)-&gt;all();//آرایه شناسه کاربران دستگاه های دریافت 
                                                                                                                                              کننده
                        $message-&gt;users()-&gt;sync(array_filter($user_ids));//در این خط جدول شناسه ها را 
                                                                                                                        همگام سازی میکنیم.
                  
        $data = [   //APIداده هایی فرستاده شده در بدنه 
                &amp;quotregistration_ids&amp;quot =&gt; $tokens,
                &amp;quotnotification&amp;quot =&gt; [
                    &amp;quottitle&amp;quot =&gt; $request-&gt;title,
                    &amp;quotbody&amp;quot =&gt; $request-&gt;body,
                    &amp;quotsound&amp;quot =&gt; &amp;quotdefault&amp;quot
                ]
            ];
            $dataString = json_encode($data);
            $headers = [ //سربرگ API
                &#039;Authorization: key=&#039; . env(&#039;SERVER-KEY&#039;), //توضیح در ادامه
                &#039;Content-Type: application/json&#039;,
            ];
            
             //API ارسال
            $ch = curl_init();

            curl_setopt($ch, CURLOPT_URL, &#039;https://fcm.googleapis.com/fcm/send&#039;);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);

            $response = curl_exec&#40;$ch&#41;;           //API پاسخ
            curl_close ( $ch );

            $failure = json_decode($response)-&gt;failure;     //تعداد ارسال های ناموفق
        }
        $msg = &amp;quotپیام با موفقیت ارسال شد. تعداد ارسال ناموفق: &amp;quot. $failure;
        return redirect(&#039;/messages&#039;)-&gt;with(&#039;success&#039;, $msg);
    }

    /*در این متد لیست افرادی که پیام را دریافت کردند را نمایش میدهیم.*/
    public function show(Request $request, $id){
        $message = Message::find($id);
        $query = $message-&gt;users();

        //filters
        $keyword = $request-&gt;get(&#039;search&#039;);
        if (!empty($keyword)) {
            $query-&gt;where(function ($query) use ($keyword) {
                $query-&gt;where(&#039;name&#039;, &#039;LIKE&#039;, &amp;quot%$keyword%&amp;quot)
                    -&gt;orWhere(&#039;phone&#039;, &#039;LIKE&#039;, &amp;quot%$keyword%&amp;quot);
            });
        }
        $users = $query-&gt;paginate(25);
        return view(&#039;messages.show&#039;, compact(&#039;users&#039;));
    }
}شما میتوانید متد های فوق را بر حسب نیاز خود تغییر دهید.برای احراز هویت برای API بخش Firebase همان طور که در قسمت قبل گفته شد، کلید سرور را به عنوان کلید احراز هویت باید در سربرگ بفرستیم ولی برای حفظ امنیت آن کد و به دلیل استفاده مکرر در بخش های دیگر، این کلید را در فایل env. با عنوان SERVER-KEY قرار میدهیم و به این شکل از آن استفاده میکنیم:. env(&#x27;SERVER-KEY&#x27;)مسیر ها (Routes)برنامه ما تقریباً آماده است حال مسیرهایی را برای دسترسی به تمام صفحاتی که تاکنون ایجاد کرده ایم تعریف می کنیم. فایل routes/web.php را باز کنید و موارد زیر را اضافه کنید:Route::resource(&#039;messages&#039; ,&#039;MessageController&#039;);ویو ها (views)شما میتوانید به صورت دلخواه view های مدیریت پیام خود را بسازید. فقط به این نکته توجه کنید که کل فایل های blade مربوط به پیام را در پوشه ای به نام messages قرار دهید. چون در کنترلر این گونه آدرس دهی شده است. اگه پوشه بندی دیگری را نظر گرفتید آن را در کنترلر ها هم تنظیم کنید.اجرای پروژهحال میتوانید با دستورphp artisan serveپروژه خود را اجرا کرده و در آدرس http://localhost:8000مشاهده کنید.نکته مهمدر مورد این که چه طور fcm_reg_id مربوط به دستگاه های کاربران اپلیکشن خود را چگونه ذخیره کنید، پیشنهاد میکنم با توجه به API هایی که اپلیکشن خود را به سرور و پنل مدیریت خود مرتبط میکنید، پیاده سازی کنید. برای مثال میتوانید API ای پیاده سازی کنید تا در زمان ورود و احراز هویت در اپلیکشن، اطلاعات مربوط به دستگاهی که اپلیکشن بر روی آن نصب شده را به سرور منتقل کرده و ذخیره کنید.امیدوارم مطالب ارائه شده برای شما مفید واقع شده باشد.  مراجع: https://docs.kii.com | https://www.izooto.com | https://medium.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Sat, 19 Dec 2020 20:16:08 +0330</pubDate>
            </item>
                    <item>
                <title>سیستم Message-oriented middleware یا MOM</title>
                <link>https://virgool.io/@negarjavadzadeh/%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-message-oriented-middleware-%DB%8C%D8%A7-mom-qckpuwzmevue</link>
                <description>Message-oriented middlewareسیستم MOM چیست؟میان افزار پیام محور(Message-oriented middleware)، نرم افزار یا زیرساخت سخت افزاری پشتیبانی از ارسال و دریافت پیام بین سیستم های توزیع شده است. MOM اجازه می دهد ماژول های برنامه در سیستم عامل های ناهمگن توزیع شود و از پیچیدگی برنامه های توسعه دهنده که شامل چندین سیستم عامل و پروتکل های شبکه هستند ، می کاهد. middleware ، یک لایه ارتباطی توزیع شده ایجاد می کند که توسعه دهنده برنامه را از جزئیات سیستم عامل های مختلف و رابط های شبکه عایق بندی می کند. API هایی که در سیستم عامل ها و شبکه های مختلف گسترش می یابند معمولاً توسط MOM ارائه می شوند.این لایه middleware به مولفه های نرم افزاری (applications ، Enterprise JavaBeans ، servlets و سایر مولفه ها) اجازه می دهد تا به طور مستقل توسعه یافته و در سیستم عامل های شبکه مختلف اجرا شوند و با یکدیگر تعامل داشته باشند. برنامه های توزیع شده در گره های مختلف شبکه از رابط برنامه برای برقراری ارتباط استفاده می کنند. علاوه بر این ، با ارائه یک رابط اداری ، می توان این سیستم جدید و مجازی از برنامه های بهم پیوسته را قابل اعتماد و ایمن کرد.الگوی MOM عناصر نرم افزاری را فراهم می کند که در تمام مولفه های ارتباطی معماری client/server قرار دارند و معمولاً از تماس های ناهمزمان بین برنامه های client وserver پشتیبانی می کنند. MOM از درگیری توسعه دهندگان برنامه با پیچیدگی ماهیتmaster-slave سازنده client/server می کاهد.انواع میان افزارها(middleware)تماس از راه دور (Remote Procedure Call) یا میان افزار مبتنی برRPCکارگزار درخواست شی(Object Request Broker) یا میان افزار مبتنی برORBمیان افزار پیام محور(Message Oriented Middleware) یا میان افزار مبتنی برMOMهمه این مدل ها این امکان را برای یک مولفه نرم افزار فراهم می کنند تا بر رفتار مولفه دیگری از طریق شبکه تأثیر بگذارد. تفاوت این middleware ها در این است که middleware های مبتنی به RPC و ORB، سیستم هایی از اجزای کاملاً بهم پیوسته ایجاد می کنند، در حالی که سیستم های مبتنی برMOM امکان اتصال آزادتر قطعات را فراهم می کنند. در یک سیستم مبتنی بر RPC یاORB ، وقتی procedure دیگری را فراخوانی می کند ، قبل از اینکه بتواند کار دیگری انجام دهد ، باید منتظر بماند تا جواب procedure فراخوانی شده برگردد. در این مدل های پیام رسانی همزمان ، میان افزار تا حدی به عنوان یک super-linker عمل می کند ، procedure فراخوانی شده را در یک شبکه قرار می دهد و از خدمات شبکه برای انتقال پارامترهای عملکرد یا روش procedure بهparameters استفاده می کند و سپس نتایج را باز می گرداند.مزایای الگوی MOMدلایل اصلی استفاده از پروتکل ارتباطی مبتنی بر پیام، توانایی آن در ذخیره (بافر) ، مسیریابی یا تبدیل پیام ها هنگام انتقال پیام ها از فرستنده ها به گیرنده ها است.یکی دیگر از مزیت های ارائه دهنده پیام رسانی با واسطه پیام رسانی بین مشتریان این است که با اضافه کردن یک رابط اداری ، می توانید عملکرد را کنترل و تنظیم کنید. بنابراین برنامه های مشتری به طور موثری از هر مشکلی به جز ارسال ، دریافت و پردازش پیام خلاص می شوند. برای حل مسائلی مانند قابلیت همکاری ، قابلیت اطمینان ، امنیت ، مقیاس پذیری و عملکرد ، به کدی نیاز داریم که سیستم MOM را اجرا و سرپرستی می کند.Asynchronicity (ناهمزمان)با استفاده از الگویMOM ، مشتری با فراخوانی API، پیامی به مقصدی که توسط ارائه دهنده مدیریت می شود ، ارسال می کند. تماس برای ارائه مسیر و ارسال پیام ، از خدمات ارائه دهنده استفاده می کند. پس از ارسال پیام ، مشتری می تواند با اطمینان از ارائه دهنده پیام ، پیام را تا زمانی كه مشتری گیرنده آن را بازیابی نكرده ، به انجام كارهای دیگر ادامه دهد. مدل مبتنی بر پیام ، همراه با وساطت ارائه دهنده ، ایجاد سیستمی از مولفه های اتصال آزاد را امکان پذیر می کند.الگوی MOM متشکل از یک دسته از نرم افزارهای ارتباطی بین برنامه ای است که در مقایسه با معماری درخواست پاسخ (request-response)، به طور معمول به پیام ناهمزمان(asynchronous) متکی است. در سیستم های asynchronous ، هنگامی که برنامه مقصد مشغول یا متصل نیست ، صف های پیام ذخیره سازی موقت را ایجاد می کنند. علاوه بر این ، اکثر سیستم های MY ناهمزمان، فضای ذخیره سازی مداومی را برای پشتیبان گیری از صف پیام فراهم می کنند. این بدان معناست که فرستنده و گیرنده نیازی به اتصال همزمان به شبکه ندارند (تحویل ناهمزمان) و مشکلات اتصال متناوب برطرف می شود. این همچنین به این معنی است که اگر برنامه گیرنده به هر دلیلی از کار بیفتد ، فرستندگان می توانند تحت تأثیر قرار نگیرند ، زیرا پیام هایی که ارسال می کنند به سادگی در صف پیام جمع می شوند تا بعداً هنگام شروع مجدد گیرنده ، پردازش بعدی انجام شود.Routing (مسیریابی)بسیاری از پیاده سازی هایmiddleware مبتنی بر پیام، به سیستم صف پیام بستگی دارد. برخی از پیاده سازی ها اجازه می دهد منطق مسیریابی توسط خود لایه پیام ارائه شود ، در حالی که برخی دیگر به برنامه های مشتری بستگی دارند تا اطلاعات مسیریابی را ارائه دهند یا ترکیبی از هر دو نمونه را فراهم کنند. برخی از پیاده سازی ها از الگوی پخش یا پخش چندرسانه ای استفاده می کنند.Transformation (تبدیل)در یک سیستم middleware مبتنی بر پیام ، پیام دریافت شده در مقصد، همان پیام اصلی که ارسال شده است، نیست. یک سیستم MOM با هوش داخلی می تواند پیام ها و مسیر را مطابق با نیازهای فرستنده یا گیرنده تغییر دهد. همراه با امکانات مسیریابی و پخش / پخش چندرسانه ای ، یک برنامه می تواند پیامی را در قالب اصلی خود ارسال کند و ممکن است دو یا چند برنامه دیگر هر کدام یک نسخه از پیام را در قالب اصلی خود دریافت کنند. بسیاری از سیستم های مدرن MOM ابزارهای پیچیده ای برای تبدیل پیام (یا نگاشت) فراهم می کنند که به برنامه نویسان اجازه می دهد قوانین تغییر شکل قابل استفاده برای یک عملیات drag-and-drop در GUI ساده را تعیین کنند.معایب الگوی MOMعیب اصلی بسیاری از سیستم هایmiddleware مبتنی بر پیام این است که آنها به یک مولفه اضافی در معماری ، عامل انتقال پیام (message broker) نیاز دارند. مانند هر سیستم ، افزودن یک جز دیگر می تواند منجر به کاهش عملکرد و قابلیت اطمینان شود و همچنین می تواند نگهداری سیستم را به طور کلی دشوار و گران کند.علاوه بر این ، بسیاری از ارتباطات بین برنامه ای جنبه ذاتی همزمان (synchronous) دارند ، به طور خاص فرستنده مایل است قبل از ادامه برای پاسخ به پیام منتظر بماند. از آنجا که ارتباطات مبتنی بر پیام ذاتاً به صورت ناهمزمان عمل می کنند ، ممکن است در چنین شرایطی مناسب نباشد. همانطور که گفته شد ، اکثر سیستم هایMOM از امکاناتی برای گروه بندی درخواست و پاسخ به عنوان یک معامله شبه همزمان برخوردار هستند.با وجود یک سیستم پیام رسانی همزمان ، تا زمانی که عملکرد فراخوانی شده کار خود را تمام کند، عملکرد فراخوانی پاسخ نمی دهد یا به عبارتی return نمی کند . در یک سیستم ناهمزمان به هم پیوسته ، مشتری تماس می تواند کار را بر روی گیرنده ادامه دهد تا زمانی که منابع مورد نیاز برای انجام این کار تخلیه شده و جز called فراخوان شده از کار بیفتد. البته با نظارت بر عملکرد و تنظیم جریان پیام می توان این شرایط را به حداقل رساند یا از آن اجتناب کرد ، اما این کاری است که برای سیستم پیام رسانی همزمان نیازی نیست. نکته مهم درک مزایا و مسئولیت های هر نوع سیستم است. هر سیستم برای انواع مختلف کارها مناسب است. برای دستیابی به رفتار مطلوب ، گاهی اوقات به ترکیبی از دو نوع سیستم نیاز است.صف پیامصف های پیام امکان تبادل اطلاعات بین برنامه های توزیع شده را فراهم می کند. یک صف پیام می تواند در حافظه یا دیسک قرار داشته باشد. پیام ها تا زمانی که توسط یک مشتری خدمات پردازش می شوند در صف باقی می مانند. از طریق صف پیام ، برنامه می تواند به طور مستقل پیاده سازی شود.پیاده سازی هاپروتکل صف انتظار پیام پیشرفته(AMQP) یک پروتکل لایه نرم افزار کاربردی استاندارد را برای middleware مبتنی به پیام را فراهم می کند.سرویس توزیع داده های گروه مدیریت شی(DDS) بسیاری از استانداردهای جدید را به مشخصات اساسی DDS اضافه کرده است.پروتکل XMPP یک پروتکل ارتباطی برای middleware مبتنی به پیام بر اساس XML (زبان نشانه گذاری قابل گسترش) است.پروتکل پیام رسانی متن محور(STOMP) که قبلاً با نام TTMP شناخته می شد ، یک پروتکل مبتنی بر متن ساده است ، فرمت سیم قابل همکاری را فراهم می کند که به مشتریان STOMP اجازه می دهد تا با هر پیام دهنده ای که پروتکل را پشتیبانی می کند صحبت کنند.مراجع : wikipedia.org</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Thu, 24 Sep 2020 00:06:54 +0330</pubDate>
            </item>
                    <item>
                <title>معماری های نرم افزار MVVM , MVP</title>
                <link>https://virgool.io/@negarjavadzadeh/%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-mvvm-mvp-whzrtsrxcbpd</link>
                <description>web app/software architecturalدر پست قبلی در مورد معماری نرم افزار صحبت کردیم. و انواع مختلفی از آن را به طور مختصر شرح دادم. در این پست به 2 نوع دیگر از معماری های برنامه میپردازیم که اکثرا در حوزه وب به کار می روند.برای مطالعه پست الگوی معماری نرم افزار و الگوی معماری فریم ورک Laravel می توانید از این لینک استفاده کنید.معماری MVVMمدل - نما - مدل نما (Model – view – Viewmodel) یک الگوی معماری نرم افزاری است که تفکیک توسعه رابط کاربری گرافیکی (view)، اعم از زبان علامت گذاری یا کد GUI را تسهیل می کند. و به توسعه منطق تجاری یا پشتیبان منطق بک اند (model) به طوری که view به هیچ بستر model خاصی وابسته نباشد، می پردازد. مدل نمای (Viewmodel)  معماری MVVM ، مبدل مقادیر است . به این معنی که وظیفه View model ، تبدیل اشیا(data objects) از مدل است به گونه ای که object ها به راحتی مدیریت و ارائه شوند. به این خاطر، View model  بیشتر از View، حالت model بودن دارد و بیشتر (نه همه ی) منطق نمایش view را کنترل می کند.  View model ممکن است یک الگوی میانجی را پیاده سازی کند ، دسترسی به منطق بک اند، در مجموعه موارد استفاده پشتیبانی شده توسط view را سازماندهی کند. معماری MVVM نوعی الگوی طراحی مدل ارائه Martin Fowler است. این معماری توسط معماران مایکروسافت Ken Cooper و Ted Peters به طور خاص برای ساده سازی برنامه نویسی مبتنی بر رابط های کاربر ابداع شده است. این الگو در (Windows Presentation Foundation (WPF (سیستم گرافیکی دات نت مایکروسافت) و Silverlight (مشتق برنامه اینترنت WPF) گنجانیده شد. John Gossman ، یکی از معماران WPF و Silverlight مایکروسافت ، MVVM را در وبلاگ خود در سال 2005 منتشر کرد. از Model – view – viewmodel به عنوان اتصال دهنده Model – View نیز یاد می شود ، خصوصاً در پیاده سازی هایی که شامل پلتفرم NET. نیستند. ZK (یک چارچوب برنامه وب نوشته شده به زبان جاوا) و KnockoutJS (یک کتابخانه جاوا اسکریپت) از MVVM استفاده می کنند.اجزای الگوی MVVMMVVM pattern1) مدل (Model)مدل یا به یک مدل دامنه ، که نمایانگر محتوای حالت واقعی است (یک رویکرد شی گرا) ، یا به لایه دسترسی به داده ، که نمایانگر محتوا است (یک رویکرد داده محور) اشاره دارد.2) نما (View) همانند الگوهای مدل-نما-کنترل کننده (MVC) و مدل-نما-ارائه دهنده (MVP) ، نمای ساختار ، طرح و شکل ظاهری است که کاربر در صفحه میبیند. view نمایشی از مدل را نشان می دهد و تعامل کاربر را با view (کلیک ها ، صفحه کلید ، حرکات و غیره) دریافت می کند. و مدیریت این موارد را از طریق اتصال داده (ویژگی ها ، تماس های رویداد و غیره) به مدل نمایش می دهد. که برای پیوند دادن view و view model تعریف شده است. در مورد الگوی MVC در پست قبل صحبت کردم. و الگوی MVP در ادامه توضیح داده خواهد شد.3) مدل نما (View model)مدل نما (View model) انتزاعی از نمای خصوصیات عمومی و دستورات است. به جای کنترل کننده الگوی MVC یا ارائه دهنده الگوی MVVM ، MVP دارای یک اتصال دهنده است که ارتباط بین view و خصوصیات محدود شده آن را در View model به صورت خودکار انجام می دهد. View model به عنوان حالت داده های موجود در مدل توصیف شده است.تفاوت اصلی بین View model و ارائه دهنده در الگوی MVP این است که ارائه دهنده به یک View مراجعه می کند ، در حالی که View model اینگونه نیست. در عوض ، یک view مستقیماً برای ارسال و دریافت به روزرسانی ها به خصوصیات موجود در View model متصل می شود. برای عملکرد کارآمد ، این امر به یک فن آوری اتصال نیاز دارد.4) اتصال دهنده (Binder)داده های اعلامی و الزام آور دستور در الگوی MVVM ضمنی است. در پشته راه حل مایکروسافت ، Binder یک زبان نشانه گذاری به نام XAML است. binder ، توسعه دهنده را از نوشتن منطق boilerplate برای همگام سازی view model و نview ، آزاد می کند. هنگامی که خارج از پشته مایکروسافت اجرا می شود ، وجود یک فناوری اتصال داده های اعلامی همان چیزی است که این الگو را ممکن می کند و بدون binder ، معمولاً از MVP یا MVC استفاده می شود و باید boilerplate بیشتری بنویسید (یا آنرا با ابزار دیگری تولید کنید).مزایای الگوی  MVVMالگوی MVVM برای استفاده از توابع اتصال داده در WPF (بنیاد ارائه Windows) طراحی شده است تا با حذف تقریباً همه کد (GUI (code-behind از لایه view ، جداسازی توسعه لایه view از بقیه الگو را تسهیل کند. به جای اینکه به توسعه دهندگان UX برای نوشتن کد GUI نیاز داشته باشند ، آنها می توانند از زبان نشانه گذاری (به عنوان مثال XAML) استفاده کنند و اتصال داده ها را به view model ایجاد کنند ، که توسط توسعه دهندگان برنامه نوشته شده و نگهداری می شود. تفکیک نقش به طراحان تعاملی اجازه می دهد تا بیش از برنامه ریزی منطق کسب و کار ، بر نیازهای UX تمرکز کنند. بنابراین لایه های یک برنامه می تواند در چندین جریان کاری برای بهره وری بالاتر توسعه یابد. حتی وقتی یک توسعه دهنده واحد روی کل کد پروژه کار می کند، تفکیک مناسب view از model بازده بیشتری دارد ، زیرا رابط کاربری معمولاً بر اساس بازخورد کاربر ، به طور مکرر و در اواخر چرخه تغییر می کند.الگوی MVVM تلاش می کند تا هر دو مزیت جداسازی توسعه عملکرد ارائه شده توسط MVC را بدست آورد ، در حالی که از مزایای اتصال داده ها و فریم ورک با اتصال داده ها به نزدیکترین مدل کاربرد خالص استفاده کند. برای صحت سنجی داده های ورودی ، از binder ، view model و ویژگی های بررسی داده لایه های تجاری استفاده می شود. نتیجه این است که مدل و فریم ورک تا حد امکان عملیات را هدایت می کند ، منطق برنامه را که مستقیماً view را دستکاری می کند از بین می برد یا به حداقل می رساند (به عنوان مثال      code-behind).معایب الگوی MVVMانتقادی از این الگو از جانب John Gossman  ، خالق MVVM ارائه شده است كه سربار اجرای MVVM برای عملیات ساده رابط كاربری &quot;بیش از حد&quot; است. وی می گوید برای کاربردهای بزرگتر ، تعمیم View Model دشوارتر می شود. علاوه بر این ، او نشان می دهد که اتصال داده در برنامه های بسیار بزرگ می تواند باعث مصرف قابل توجه حافظه شود.پیاده سازی ها.NET frameworksPrism LibraryCaliburn / Caliburn.MicroDevExpress MVVMDotVVM open source projectMVVMLight ToolkitReactiveUIMugen MVVM ToolkitUno Framework - Open SourceRasclMvvmCrossFreshMvvmJavaScript frameworksAngularReactjsAureliaDurandalEmber.jsExt JSKnockout.jsOmi.jsOracle JETSvelteVue.jsAndroid appsمراجع : wikipedia.orgمعماری MVPمدل-نما-ارائه دهنده (Model–view–presenter) مشتق شده از الگوی معماری مدل-نما-کنترل کننده (MVC) است و بیشتر برای ساخت رابط کاربر استفاده می شود. در MVP ، ارائه دهنده، عملکرد &quot;مرد میانه&quot; را بر عهده می گیرد. و تمام منطق ارائه به سمت presenter رانده می شود.MVP patternالگوی نرم افزاری MVP از اوایل دهه 1990 در Taligent ، سرمایه گذاری مشترک اپل ، IBM و Hewlett-Packard ایجاد شد. MVP مدل اصلی برنامه نویسی برای توسعه برنامه های Taligent در محیط CommonPoint مبتنی بر C ++  است. بعداً این الگو توسط Taligent به جاوا منتقل شد و در مقاله ای توسط Taligent CTO Mike Potel انتشار یافت.پس از متوقف شدن فعالیت Taligent در سال 1998 ، Andy Bower و Blair McGlashan  برای پایه ی چارچوب رابط کاربری Smalltalk از الگوی MVP اقتباس کردند. در سال 2006 ، مایکروسافت شروع به ادغام MVP در اسناد و مثالهای خود برای برنامه نویسی رابط کاربر در فریم ورک NET. کرد.تکامل و انواع مختلف الگوی MVP ، از جمله رابطه MVP با سایر الگوهای طراحی مانند MVC ، به طور مفصل در مقاله ای توسط Martin Fowler  و دیگری توسط Derek Greer مورد بحث قرار گرفته است.اجزای الگوی MVPالگوی MVP یک الگوی معماری رابط کاربری است که برای تسهیل آزمایش و بهبود در منطق ارائه طراحی شده است:مدل (Model) : مدل رابطی است که داده هایی را نشان می دهد که در رابط کاربری نمایش داده می شوند یا کاربر روی آن داده ها عملی انجام میدهد. لایه داده که مسئولیت رسیدگی به منطق تجارت و ارتباط با شبکه و لایه های پایگاه داده را دارد.نما (View) :  یک رابط غیرفعال است که داده ها (model) را نمایش می دهد و دستورات کاربر (events) را به سمت ارائه دهنده (presenter) هدایت می کند تا بر اساس آن داده ها، عمل کند.ارائه دهنده (Presenter) : ارائه دهنده بر اساس Model و View عمل می کند. داده ها را از مخازن (Model) بازیابی می کند و آنها را برای نمایش، منظم می کند.به طور معمول ، پیاده سازی View شی ارائه دهنده واقعی را ارائه می دهد و مرجعی را به خود ارائه می دهد. کد C # زیر یک سازنده View ساده را نشان می دهد ، جایی که ارائه دهنده دامنه اصلی رابط Domain Presenter را پیاده سازی می کند:public class DomainView : IDomainView
{
    private IDomainPresenter _domainPresenter = null;

    /// &lt;summary&gt;Constructor.&lt;/summary&gt;
    public DomainView()
    {
        _domainPresenter = new ConcreteDomainPresenter(this);
    }
}درجه منطق مجاز View در پیاده سازی های مختلف متفاوت است. از یک سو ، View کاملاً منفعل است و همه عملیات تعامل را به presenter هدایت می کند. در این فرمول ، هنگامی که یک کاربر یک رویداد از View را راه اندازی می کند ، کاری جز فراخوانی روشی از presenter، که هیچ پارامتر و مقدار بازگشتی ندارد. سپس presenter، داده ها را از طریق روش هایی که توسط رابط View تعریف شده است ، بازیابی می کند. سرانجام ، presenter با استفاده از Model کار می کند و View را با نتیجه به روز می کند. سایر نسخه های MVP اجازه می دهد تا برخی از عمل هاd کلاس قادر به تعامل ، event یا دستور خاص ، باشد. این اغلب برای معماری های تحت وب مناسب تر است. View ، که در مرورگر مشتری اجرا می شود ، بهترین مکان برای مدیریت تعامل یا دستور خاص است.از نظر لایه بندی ، کلاس presenter ممکن است متعلق به لایه برنامه در یک سیستم معماری چند لایه باشد ، اما همچنین می تواند به عنوان یک لایه ارائه دهنده، بین لایه برنامه و لایه رابط کاربر باشد.پیاده سازی ها1) .NETمحیط NET. مانند هر محیط توسعه دیگری از الگوی MVP پشتیبانی می کند. از همان Model و کلاس presenter  می توان برای پشتیبانی از چندین رابط ، مانند یک برنامه وب ASP.NET ، یک برنامه Windows Forms یا یک برنامه Silverlight ، استفاده کرد. presenter اطلاعات را از طریق رابط قابل دسترسی از طریق واسطه (view) از / به view دریافت می کند.علاوه بر اجرای دستی الگو ی MVP ، ممکن است از یک چارچوب model-view-presenter برای پشتیبانی از الگوی MVP به صورت خودکارتر استفاده شود.2) Javaدر یک برنامه جاوا (AWT / Swing / SWT) ، با اجازه دادن به کلاس رابط کاربر که یک رابط view را پیاده سازی کند ، می توان از الگوی MVP استفاده کرد.فریم ورک های جاوا شامل موارد زیر است:JavaFXEcho2Google Web ToolkitJFaceSwingVaadinZK3)PHPاز آنجا که در محیط اجرای انعطاف پذیر PHP ، امکانات گسترده ای برای منطق برنامه وجود دارد. اجرای لایه Model  بر روی برنامه،  برنامه آخر باقی مانده است.چارچوب های PHP شامل موارد زیر است:CodeIgniterLaravelNette Framework4)Kotlinکاتلین و چارچوب های مبتنی بر آن مانند Kodein Framework ، بر سازگاری چند پلتفرم تمرکز دارند. هدف این است که به دلیل چارچوبی که برای سازگاری با هر سیستم عامل ایجاد شده است ، فقط یک بار بر منطق تجارت تمرکز کرده و آن را پیاده سازی کنیم.مراجع : wikipedia.orgبا توجه به توضیحات داده شده شاید برای شما سوال باشد که فرق بین معماری های MVVM و MVP و MVC در چیست؟الگو های MVP و MVVM هر دو از مشتقات MVC هستند. تفاوت کلیدی بین MVC و مشتقات آن وابستگی هر لایه به لایه های دیگر و همچنین چگونگی محکم اتصال آنها به یکدیگر است.در MVC ، نما(View) در بالای معماری ما قرار می گیرد و کنترلر در کنار آن است. مدل ها زیر کنترل کننده قرار می گیرند ، بنابراین View ما از کنترل کننده ها و کنترل کننده ها از مدل ها اطلاعات دارند. در اینجا ، view ما مستقیماً به مدل ها دسترسی دارند. اگرچه قرار دادن مدل کامل در معرض دید ، بسته به پیچیدگی برنامه ما ممکن است دارای هزینه های امنیتی و عملکردی باشد. MVVM سعی دارد از این مسائل جلوگیری کند.در MVP ، نقش کنترل کننده با یک ارائه دهنده (Presenter) جایگزین می شود. ارائه دهندگان در همان سطح view قرار می گیرند ، و رویدادها را از طریق View و مدل مدیریت میکنند و اقدامات بین آنها را میانجی می کنند. بر خلاف MVVM ، مکانیزمی برای اتصال Views به ViewModels وجود ندارد ، بنابراین در عوض ما به هر View متکی هستیم که یک رابط کاربری را فراهم می کند تا ارائه دهنده بتواند با View تعامل داشته باشد.الگوی MVVM به ما اجازه می دهد زیر مجموعه های View خاص یک مدل را ایجاد کنیم ، که می تواند حاوی اطلاعات حالت و منطق، با اجتناب از نیاز به قرار دادن کل مدل در معرض نمایش، باشد. بر خلاف ارائه دهنده MVP ، برای ارجاع به یک View نیازی به ViewModel نیست. View می تواند به خصوصیات ViewModel متصل شود ، که به نوبه خود داده های موجود در مدل ها را در معرض نمایش قرار می دهد. همانطور که اشاره کردیم ، انتزاع View به این معنی است که منطق کمتری در کد پشت آن وجود دارد.با این حال یکی از نقاط ضعف این است که به سطح تفسیر بین ViewModel و View نیاز است و این می تواند هزینه های عملکردی داشته باشد. پیچیدگی این تفسیر می تواند متفاوت باشد: می تواند به سادگی کپی کردن داده ها یا به اندازه ی دستکاری آن در شکلی که دوست داریم View آن را ببیند، پیچیده باشد. MVC این مشکل را ندارد ، زیرا کل مدل به راحتی در دسترس است و می توان از چنین دستکاریهایی جلوگیری کرد.تفاوت هاي MVC ,MVVM, MVPمراجع:www.angularminds.com | www.oreilly.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Tue, 22 Sep 2020 20:45:02 +0330</pubDate>
            </item>
                    <item>
                <title>الگوی معماری نرم افزار و الگوی معماری فریم ورک Laravel</title>
                <link>https://virgool.io/@negarjavadzadeh/%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D9%88-%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%81%D8%B1%DB%8C%D9%85-%D9%88%D8%B1%DA%A9-laravel-ugvi29qck6x7</link>
                <description>الگو ی معماری نرم افزارتا به حال به این فکر کرده اید که سیستم های بزرگ در مقیاس سازمانی چگونه طراحی می شوند؟قبل از شروع تولید عمده نرم افزار ، ما باید معماری مناسبی را انتخاب کنیم که ویژگی های مطلوب را برای ما فراهم کند. از این رو ، ما باید معماری های مختلف را درک کنیم ، قبل از اینکه آنها را در طراحی خود اعمال کنیم.الگوی معماری چیست؟ یک راه حل کلی و قابل استفاده مجدد برای یک مشکل معمول در معماری نرم افزار در یک بافت خاص است. الگوهای معماری مشابه الگوی طراحی نرم افزار هستند اما دامنه وسیع تری دارند.تفاوت بین الگوی معماری نرم افزار و الگوی طراحی نرم افزار چیست؟معماری نرم‌افزار مسئول اسکلت‌بندی و زیرساخت کلی یک نرم‌افزار می‌باشد اما این در حالی است که طراحی نرم‌افزار (Software Design) مسئول طراحی در سطح کُد است بدین صورت که مشخص می‌شود وظایف هر یک از ماژول‌ها، اِسکوپ کلاس‌ها و اهداف هر یک از تابع ها چیست و ارتباط آن‌ها با یکدیگر چگونه باید باشد.الگوی طراحی مجموعه‌‌ای از راه‌کارها و الگوها در برنامه‌نویسی هستند که توسط توسعه دهنده های باتجربه در زمینه شیٔ‌گرایی پیاده‌سازی شده‌اند و توسعه‌دهندگان می‌توانند با به‌کارگیری آن‌ها دست به طراحی اپلیکیشن‌هایی انعطاف‌پذیر، تغییرپذیر با قابلیت نگه‌داری بالا بزنند.برای مطالعه بیشتر میتوانید به این لینک مراجعه کنید.انواع الگو های معماری نرم افزار رایج1)الگوی لایه ای (Layered pattern)از این الگو می توان برای ساختار برنامه هایی استفاده کرد که می توانند به گروههایی از وظایف فرعی تجزیه شوند ، که هر کدام از آنها در سطح خاصی از انتزاع هستند. هر لایه خدمات را به لایه بالاتر بعدی ارائه می دهد.4 لایه سیستم اطلاعات عمومی که به طور معمول یافت می شود به شرح زیر است:لایه ارائه (همچنین به عنوان لایه UI شناخته می شود)لایه کاربرد (همچنین به عنوان لایه سرویس نیز شناخته می شود)لایه منطق کسب و کار (همچنین به عنوان لایه دامنه نیز شناخته می شود)لایه دسترسی به داده ها (همچنین به عنوان لایه ماندگاری شناخته می شود)Layered patternموارد استفاده:برنامه های کاربردی دسک تاپ عمومی.برنامه های وب تجارت الکترونیکی.2)الگوی مشتری-سرور(Client-server pattern)این الگو از دو قسمت تشکیل شده است. یک سرور و چندین مشتری. مولفه سرور به چندین مولفه سرویس گیرنده خدمات ارائه می دهد. مشتری ها از سرور خدمات می خواهند و سرور خدمات مربوطه را به آن مشتری ارائه می دهد. علاوه بر این ، سرور همچنان به درخواست های مشتری گوش می دهد.Client-server patternموارد استفاده:برنامه های آنلاین مانند ایمیل ، اشتراک اسناد و خدمات بانکی.3)الگوی ارباب-برده(Master-slave pattern)این الگو از دو قسمت تشکیل شده است. master  و slaves. مولفه master کار را بین اجزای slave یکسان توزیع می کند و نتیجه نهایی نتایج حاصل از slave ها را محاسبه می کند.Master-slave patternموارد استفاده:در تکثیر پایگاه داده ، پایگاه داده master به عنوان منبع معتبر در نظر گرفته می شود و پایگاه داده های slave با آن هماهنگ می شوند.وسایل جانبی متصل به یک باس در سیستم رایانه ای (درایوهای master و slave).4)الگوی فیلتر لوله(Pipe-filter pattern)از این الگو می توان برای ساختار سیستم هایی استفاده کرد که جریان داده ای را تولید و پردازش می کنند. هر مرحله پردازش در یک جز فیلتر محصور شده است. داده هایی که باید پردازش شوند از طریق لوله ها منتقل می شوند. از این لوله ها می توان برای بافر یا اهداف هماهنگ سازی استفاده کرد.Pipe-filter patternموارد استفاده:کامپایلرها فیلترهای متوالی تجزیه و تحلیل واژگان ، تجزیه ، تحلیل معنایی و تولید کد را انجام می دهند.گردش کار در بیوانفورماتیک.5)الگوی کارگزار(Broker pattern)این الگو برای ساختار سیستم های توزیع شده با اجزای جدا شده استفاده می شود. این مولفه ها می توانند با فراخوانی سرویس از راه دور با یکدیگر ارتباط برقرار کنند. یک مولفه کارگزار مسئول هماهنگی ارتباط بین مولفه ها است.سرورها قابلیت های خود (خدمات و ویژگی ها) را برای یک کارگزار منتشر می کنند. مشتری ها از کارگزار درخواست خدمات می کنند و سپس کارگزار، مشتری را به سرویس مناسب از رجیستری خود هدایت می کند.Broker patternموارد استفاده:نرم افزار کارگزار پیام مانند Apache ActiveMQ ، Apache Kafka ، RabbitMQ و JBoss Messaging.6)الگوی همتا به همتا(Peer-to-peer pattern)در این الگو ، اجزای منفرد به عنوان همکار (peer) شناخته می شوند. همکاران ممکن است هم به عنوان یک مشتری عمل کنند ، هم از سایر همکاران خود درخواست خدمات کنند و هم به عنوان یک سرور ، خدمات خود را به سایر همکاران ارائه دهند. یک همکار (peer) ممکن است به عنوان مشتری یا سرور یا هر دو عمل کند و با گذشت زمان می تواند نقش خود را به صورت پویا تغییر دهد.Peer-to-peer patternموارد استفاده:شبکه های اشتراک فایل مانند Gnutella و G2.پروتکل های چندرسانه ای مانند P2PTV و PDTP.محصولات مبتنی بر ارزهای رمزپایه مانند بیت کوین و بلاکچین7) الگوی رویداد-گذرگاه(Event-bus pattern)این الگو در درجه اول با رویدادها سروکار دارد و دارای 4 مولفه اصلی است. منبع رویداد. شنوندگان رویداد. کانال. گذرگاه رویداد. منابع پیام ها را به کانال های خاص در گذرگاه رویداد منتشر می کنند. شنوندگان در کانال های خاصی مشترک می شوند. و از پیام های منتشر شده در کانالی که قبلاً در آن مشترک شده اند مطلع می شوند.Event-bus patternموارد استفاده:توسعه اندرویدخدمات اطلاع رسانی8)الگوی مدل-نمایش-کنترل کننده (Model-View-Controller pattern)این الگو یک برنامه تعاملی را به 3قسمت تقسیم میکند:مدل(Model) : شامل عملکرد و داده های اصلی است.نمایش(View) : اطلاعات را به کاربر نمایش می دهد (ممکن است بیش از یک نمایش تعریف شود).کنترل کننده(Controller) : ورودی کاربر را کنترل می کند.این کار برای تفکیک نمایش داخلی اطلاعات از روشهای ارائه اطلاعات به کاربر و پذیرش آن از طرف کاربر انجام می شود. این قطعات را از هم جدا کرده و امکان استفاده مجدد از کد را به شما می دهد.Model-View-Controller patternموارد استفاده:معماری برای برنامه های کاربردی شبکه جهانی وب به زبانهای اصلی برنامه نویسی.چارچوب های وب مانند Django و Rails و Laravel.9)الگوی تخته سیاه (Blackboard pattern)این الگو برای مشکلاتی مفید است که هیچ راهبرد قطعی برای آنها شناخته نشده است. الگوی تخته سیاه از 3 جز اصلی تشکیل شده است.تخته سیاه :  یک حافظه جهانی ساختار یافته حاوی اشیا از فضای راه حل.منبع دانش : ماژول های تخصصی با نمایندگی خودشان.جز کنترل  : ماژول ها را انتخاب ، پیکربندی و اجرا می کند.همه اجزا به تخته سیاه دسترسی دارند. مولفه ها ممکن است اشیا داده ای جدیدی تولید کنند که به تخته سیاه اضافه می شوند. مولفه ها به دنبال انواع خاصی از داده ها روی تخته سیاه هستند ، و ممکن است این موارد را با تطبیق الگو با منبع دانش موجود پیدا کنند.Blackboard patternموارد استفاده:تشخیص گفتارشناسایی و ردیابی خودروشناسایی ساختار پروتئینسونار تفسیر سیگنال ها10) الگوی مفسر (Interpreter pattern)این الگو برای طراحی مولفه ای که برنامه های نوشته شده به زبان اختصاصی را تفسیر می کند ، استفاده می شود. این مقاله به طور عمده چگونگی ارزیابی خطوط برنامه ها را که به عنوان جملات یا اصطلاحات نوشته شده در یک زبان خاص شناخته می شوند ، مشخص می کند. ایده اصلی داشتن کلاس برای هر نماد زبان است.Interpreter patternموارد استفاده:زبانهای جستجوی پایگاه داده مانند SQL.زبانهایی که برای توصیف پروتکل های ارتباطی استفاده می شوند.الگو های زیاد دیگر با ویژگی ها و کاربرد های دیگر نیز وجود دارند که میتوانید با استفاده از این لینک با  آن ها نیز آشنا شده و استفاده کنید.در این قسمت به توضیحات الگوی معماری نرم افزار و انواع رایج آن پرداختیم. در ادامه به توضیح الگوی معماری فریم ورک Laravel میپردازیم.الگوی معماری فریم ورک LaravelMVC patternلاراول یک چارچوب وب مبتنی بر PHP است که عمدتا بر اساس معماری MVC ساخته شده است. لاراول برای سهولت شروع کار پروژه های PHP برای توسعه دهندگان ایجاد شده است. با لاراول ، شما کمتر به تنظیمات ، معماری و وابستگی های یک پروژه فکر می کنید و مستقیماً وارد پروژه می شوید.هنگامی که شما یک پروژه جدید Laravel ایجاد می کنید ،این پروژه دارای ساختار زیر است:ساختار پروژه لاراولنحوه اجرای MVC در برنامه های لاراولالگوی Model view controller) MVC) امکان تعامل با پایگاه داده را فراهم می کند و بدون شک نیازی به پایگاه داده نیست. و ممکن است یک فایل JSON یا منبع دیگری باشد.  Model view controller شامل منطق است. به عنوان مثال راهی که می تواند داده های فرم را تأیید کند و با تعامل با مدل ، یک منبع را در پایگاه داده ذخیره کند. رابط کاربر برنامه ها (UI) به عنوان نمایی فراخوانی می شود که شامل HTML یا نشانه گذاری ارائه نیز می باشد. علاوه بر این ، همچنین می تواند دارای یک حلقه و منطق شرطی باشد. از موتورهای الگو برای درج منطق در نماها استفاده می شود و لاراول دارای موتورهای الگوی Blade برای افزودن منطق به درون نماها است.مسیرها (Routes):2 پرونده مسیر وجود دارد که در لاراول موجود است یکی از آنها web.php و دیگری api.php است. همه مسیرهای وب در پرونده های web.php مانند mywebsite.com/about یا mywebsite.com/contact ثبت شده اند. و مسیرهای مربوط به API در api.php ثبت شده اند.کنترل کننده ها و مدل ها(Controllers and Models):همه مدل ها در فهرست برنامه ها ذخیره می شوند و برای احراز هویت ، یک مدل کاربر پیش فرض با لاراول ارائه می شود. app\Http\controllers همه کنترل کننده ها را دارد و همچنین کنترلرهای پیش فرض دیگری نیز برای احراز هویت وجود دارد.نمایش (Views):نمایش ها را می توان در resources/views یافت. لاراول نمای پیش فرض مانند welcome.blade.php را فراهم کرده است. نماهای Laravel دارای پسوندی به نام پسوند blade.php. هستند بنابراین در زمان ایجاد نمایش ، باید پسوند blade را اضافه کنید.سایر دایرکتوری ها:لاراول دایرکتوری public را برای قرار دادن CSS ، js و سایر دارایی های ثابت شما فراهم کرده است. از طرف دیگر دایرکتوری Configuration شامل تمام فایل های پیکربندی است که به برنامه ما مربوط می شوند مانند session ، پایگاه داده و سایر تنظیمات.نحوه برسی درخواست در لاراولبه طور خلاصه ، لاراول وظیفه، وارد کردن تنها یک برنامه از طریق پرونده index.php را دارد و سپس با تنظیم مسیرهای تعریف شده ، درخواست را به کنترل کننده مربوطه هدایت می کند. کنترلر در صورت لزوم با مدل ارتباط برقرار کرده و مدل را در آن قرار می دهد ، سپس ابتدا باید View را بارگیری کند و سپس نتایج را برای کاربر ارسال کند. از طرف دیگر ، اگر یک رابط برنامه نویسی برنامه (API) باشد ، خروجی معمولاً از طریق فرم JSON است و با استفاده از بسته های مربوطه ، XML نیز پشتیبانی می شود.مراجع:  wikipedia.org | sokanacademy.com | towardsdatascience.com | blog.pusher.com | medium.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Thu, 10 Sep 2020 00:52:28 +0430</pubDate>
            </item>
                    <item>
                <title>فایل htaccess. چیست؟ و چه کاربردی دارد؟</title>
                <link>https://virgool.io/@negarjavadzadeh/%D9%81%D8%A7%DB%8C%D9%84-htaccess-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D9%87-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF%DB%8C-%D8%AF%D8%A7%D8%B1%D8%AF-sy6y1hs1lgpp</link>
                <description>Hyper Text Accessفایل htaccess. چیست؟لغت htaccess مخفف &quot;Hyper Text Access&quot; است که به فارسی می‌توان آن را به &quot;دسترسی توسط ابرمتن&quot; ترجمه کرد. در حالت عادی اگر بخواهید تغییراتی در وب سرور ایجاد کنید باید به فایل‌های تنظیمات وب سرور اصلی دسترسی داشته باشید، اما این فایل راه انجام بعضی کارها و تغییرات در وب سرور شما را بدون نیاز به فایل‌های اصلی ایجاد می‌کند. فایل htaccess توسط وب سرورهای Apache و Litespeed استفاده می‌شود.فایل های htaccess. در سطح یک دایرکتوری کار می کنند ، این فایل ها اجازه می دهند تا تنظیمات پیکربندی سراسری دستورالعمل های htaccess. بالاتر را، در درخت فهرست نادیده بگیرند.فایل htaccess. کجاست؟از لحاظ تئوری ، هر پوشه (دایرکتوری) در سرور شما می تواند یک فایل htaccess. داشته باشد. به طور کلی ، یک فایل htaccess. در پوشه ریشه وب شما وجود دارد (این پوشه ای است که تمام محتوای وب سایت شما را نگهداری می کند و معمولاً برچسب چیزی مانند public_html یا www دارد). در اغلب  سیستم های مدیریت محتوا مثل وردپرس و دروپال این فایل بصورت خودکار ایجاد می شود.در بیشتر file systems ، نام فایل هایی که با نقطه (.) شروع می شوند ، پرونده های مخفی هستند. این بدان معناست که به طور پیش فرض معمولاً قابل مشاهده نیستند. ولی با استفاده از ویژگی &quot;show hidden files&quot; در مدیریت فایل های خود می توانید این فایل را مشاهده کنید.اگر فایل htaccess. را نداشتید، برای ایجاد این فایل از روش زیر استفاده کنید:یک فایل جدید را در یک ویرایشگر متن ساده ایجاد کنید.آن را با فرمت ASCII (نه UTF-8 یا هر چیز دیگری) به عنوان htaccess. ذخیره کنید.(مطمئن شوید که htaccess.txt یا مواردی از این دست نباشد. پرونده باید فقط دارای نام htaccess. بدون پسوند پرونده اضافی باشد.)آن را از طریق FTP یا مدیر فایل مبتنی بر مرورگر خود در فهرست مناسب بارگذاری کنید.کاربرد های htaccessفایل htaccess یک فایل متن کوچک اما پر قدرت است که بسیاری از جنبه‌های نحوه نمایش صفحات وب را کنترل می‌کند. مانند انتقال کاربر به آدرس دیگر(redirect)، فعال کردن فشرده سازی فایل‌ها توسط سرور(gzip)، بازنویسی آدرس ها(rewrite urls)، فعال سازی کش مرورگر(leverage browser cache) ، امکان محافظت از رمز عبور برای وب سایت ها (password protection)، نمایش صفحات خطای سفارشی (Error Handling) مانند صفحه 404، افزایش سئو از طریق یک خط مشی سازگار با اسلش دنباله دار (SEO) و بسیاری دیگر را تنها با اضافه کردن چند خط کد به این فایل کوچک می‌توان انجام داد.در بیشتر نرم افزارهای تولید محتوا، با تغییر htaccess.txt به htaccess. می‌توان گزینه بهینه سازی آدرس‌ها برای گوگل را فعالسازی نمود، این قابلیت برای مدیران تارنماها از اهمیت فوق العاده ای برخوردار است.در این مقاله به تعدادی از این کاربرد های فایل htaccess  اشاره میکنیم:1) مدیریت خطا هااستفاده از فایل های htaccess. برای تعیین اسناد خطا بسیار ساده است ، یکی از ساده ترین کارهایی که می توانید با این فایل ها انجام دهید.کد خطا چیست؟هنگامی که درخواستی از وب سرور ارائه می شود ، سعی می شود به آن درخواست پاسخ دهد ، معمولاً با ارائه سندی (در مورد صفحات HTML) ، یا با دسترسی به یک برنامه و بازگرداندن خروجی (در مورد سیستم های مدیریت محتوا و برنامه های وب دیگر). اگر مشکلی در این زمینه رخ دهد ، خطایی ایجاد می شود. انواع مختلف خطاها دارای کد خطاهای مختلف هستند. احتمالاً با خطای 404 آشنا هستید که اگر سندی در سرور پیدا نشود این خطا برمی گردد. بسیاری از کدهای خطای دیگر وجود دارد که سرور می تواند با آنها پاسخ دهد.Errorsاگر هیچ نوع مدیریت خطایی را مشخص نکنید ، سرور به سادگی پیام را به مرورگر باز می گرداند و مرورگر یک پیام خطای عمومی را به کاربر نشان می دهد. این معمولاً ایده آل نیست. پس بهتر است اسنادی را برای این خطا ها طراحی کنید. برای هر کد خطایی که می خواهید مدیریت کنید یک سند HTML ایجاد کنید. می توانید این موارد را هرچه دوست دارید نامگذاری کنید ، اما بهتر است که نام آنها را چیزی بنویسید که به شما کمک کند به خاطر داشته باشید برای چه چیزی استفاده می کنید ، مانند: not-found یا به سادگی 404. سپس ، در فایل htaccess. ، مشخص کنید که کدام سند را با کدام نوع خطا استفاده می کنید.ErrorDocument 400 /errors/bad-request.htmlErrorDocument 401 /errors/auth-reqd.htmlErrorDocument 403 /errors/forbid.htmlErrorDocument 404 /errors/not-found.htmlErrorDocument 500 /errors/server-err.html2) محافظت از رمز عبورهدف اصلی از فایل های htaccess. محدود کردن دسترسی به برخی از فهرست ها بر اساس هر کاربر بود. بنابراین ابتدا آن را بررسی خواهیم کرد.فایل htpasswd.نام های کاربری و رمزهای عبور برای سیستم htaccess. در یک فایل htpasswd. ذخیره می شوند.اینها هر یک به صورت زیر ذخیره می شوند:username:encryptedpasswordمهم است که بدانید رمز عبور ذخیره شده در فایل رمزعبور، واقعی نیست که برای ورود به سیستم استفاده می شود. بلکه یک هش رمزنگاری رمز عبور است. این بدان معنی است که رمز عبور از طریق الگوریتم رمزگذاری اجرا شده است و نتیجه ذخیره می شود. هنگامی که یک کاربر وارد سیستم می شود ، رمز عبور متن ساده وارد می شود و از طریق همان الگوریتم اجرا می شود. اگر ورودی یکسان باشد ، گذرواژه ها مطابقت دارند و به کاربر اجازه دسترسی داده می شود. ذخیره رمزهای عبور از این طریق باعث امنیت بیشتر آنها می شود. اگر کسی بخواهد به پرونده htpasswd. شما دسترسی پیدا کند ، فقط رمزهای عبور هش شده را می بیند ، نه نسخه های اصلی. و هیچ راهی برای بازسازی نسخه های اصلی از هش وجود ندارد.  این یک رمزگذاری یک طرفه است. فایل htpasswd. را کجا نگه دارید؟برای هر فایل htaccess. نیازی نیست که یک فایل جداگانه htpasswd. داشته باشید. در واقع ، در بیشتر موارد ، باید یک حساب برای کل حساب web hosting یا server directory اصلی خود داشته باشید. پرونده htpasswd. نباید در یک فهرست عمومی قابل دسترسی باشد ( نه public_html یا www یا زیر شاخه فرعی). باید بالاتر از آن باشد ، در پوشه ای که فقط از طریق خود سرور قابل دسترسی است. نحوه استفاده از htpasswd. با htaccess.هر دایرکتوری می تواند فایل htaccess. مخصوص به خود را داشته باشد ، با مجموعه کاربران خاص خود که مجاز به دسترسی به آن هستند. به صورت پیش فرض تمام کاربران (از جمله کسانی که وارد سیستم نشده اند) به همه دایرکتوری ها اجازه دسترسی دارند. برای محدود کردن دسترسی باید موارد زیر را به فایل  htaccess. اضافه کنید:AuthUserFile /usr/local/etc/.htpasswd
AuthName &amp;quotName of Secure Area&amp;quot
AuthType Basic
&lt;Limit GET POST&gt;
require valid-user
&lt;/Limit&gt;خط اول، مسیر و نام فایل را به لیست نام های کاربری و رمزهای عبور شما مشخص می کند. خط دوم، نامی را برای منطقه امن مشخص می کند. این می تواند هر آنچه دوست دارید باشد. خط سوم احراز هویت &quot;اساسی&quot; را مشخص می کند ، همان چیزی است که شما معمولاً به آن نیاز دارید.برچسب &lt;Limit&gt; محدودیت هایی را مشخص می کند (در این حالت ، امکان دریافت یا ارسال به هر پرونده موجود در فهرست). درون برچسب های  &lt;Limit&gt; لیستی از افراد مجاز به دسترسی به پرونده ها وجود دارد.در مثال بالا ، هر کاربر معتبری می تواند به پرونده ها دسترسی پیدا کند. اگر می خواهید دسترسی به یک کاربر خاص یا تعداد کمی از کاربران را محدود کنید ، می توانید آنها را نام ببرید.AuthUserFile /usr/local/etc/.htpasswd
AuthName &amp;quotName of Secure Area&amp;quot
AuthType Basic
&lt;Limit GET POST&gt;
require user johnsmith
require user janedoe
&lt;/Limit&gt;همچنین می توانید کاربران را در گروه ها قرار داده و اجازه دسترسی مبتنی بر گروه را بدهید. این کار با اضافه کردن فایل دیگری که گروه ها را مشخص می کند انجام می شود. استفاده از htaccess. و htpasswd. برای محدود کردن دسترسی به برخی از پرونده های موجود در سرور تنها در صورت داشتن تعداد زیادی فایل استاتیک منطقی است. این ویژگی زمانی توسعه یافت که وب سایت ها معمولاً مجموعه ای از اسناد HTML و منابع مرتبط بودند. اگر از سیستم مدیریت محتوا (CMS) مانند وردپرس یا دروپال استفاده می کنید ، می توانید از ویژگی های مدیریت کاربر داخلی برای محدود کردن یا اعطای دسترسی به محتوا استفاده کنید.3)فعال کردن  Server Side Includesمشمولان سمت سرور (Server Side Includes) یک زبان برنامه نویسی سبک وزن است که در درجه اول برای جاسازی اسناد HTML در سایر اسناد HTML استفاده می شود. این باعث می شود که بتوان از عناصر معمول مانند سرصفحه ها ، زیر صفحه ها ، ستون های فرعی و منوها دوباره استفاده مجدد کرد. شما می توانید آن را به عنوان یک پیش درآمد سیستم های مدیریت محتوا در نظر بگیرید.&lt;!-- include virtual=&amp;quotheader.shtml&amp;quot --&gt;زبان SSI همچنین دارای دستورالعمل های شرطی (if, else, etc) و متغیرها می باشد که آن را به یک زبان اسکریپت نویسی کامل ، اگر  چه تا حدی سخت ، تبدیل می کند. (به طور معمول ، هر پروژه ای که پیچیده تر از تعداد انگشت شماری include باشد ، باعث می شود که یک توسعه دهنده زبان محکم تری مانند PHP یا Perl را انتخاب کند.)فعال کردن SSIبرخی از سرورهای میزبان وب Server Side Includes را به طور پیش فرض فعال می کنند. اگر فعال نبود ، می توانید آن را با فایل htaccess. خود فعال کنید ، مانند این موارد:AddType text/html .shtml
AddHandler server-parsed .shtml
Options Indexes FollowSymLinks Includesاین کد ها، SSI را برای همه فایل هایی که پسوند shtml. دارند فعال می کند.فعال کردن SSI برای فایل های html.اگر می خواهید SSI را روی فایل های html. فعال کنید ، می توانید یک دستورالعمل به htaccess. اضافه کنید:AddHandler server-parsed .htmlفایده انجام این کار این است که شما می توانید از SSI استفاده کنید بدون اینکه به دنیا بگویید که از آن استفاده می کنید. همچنین ، اگر پیاده سازی ها را در آینده تغییر دهید ، می توانید پسوند فایل های html خود را حفظ کنید. نکته منفی این مسئله این است که هر پرونده html با SSI تجزیه می شود. اگر فایلهای html زیادی دارید که به تجزیه SSI نیاز ندارند ، این امر می تواند سربار غیرضروری زیادی را برای شما ایجاد کند، زمان بارگذاری صفحه شما را کند و از منابع CPU استفاده کند.فعال کردن SSI برای صفحات Indexاگر نمی خواهید همه فایل های html را تجزیه کنید ، اما می خواهید از SSI در صفحه اصلی خود استفاده کنید ، باید این مورد را در فایل htaccess. خود مشخص کنید. دلیل این امر این است که وقتی وب سرور به دنبال صفحه اصلی دایرکتوری است ، به دنبال index.html است ، مگر اینکه شما خلاف آن را بگویید.اگر فایل های html را تجزیه نمی کنید ، برای کار با SSI باید صفحه اصلی خود را index.shtml نامگذاری کنید و سرور شما نمی داند به طور پیش فرض به دنبال آن (به عنوان صفحه اصلی ) باشد. برای فعال کردن آن ، به سادگی خط زیر را به فایل htaccess. اضافه کنید:DirectoryIndex index.shtml index.htmlاین به وب سرور هشدار می دهد که پرونده index.shtml  فایل اصلی برای پوشه است. پارامتر دوم ، index.html یک نسخه پشتیبان است ، در صورتی که index.shtml پیدا نمی شود. 4) لیست سیاه IP و لیست سفید IPشما می توانید از htaccess. برای مسدود کردن آدرس IP خاص کاربران (لیست سیاه) استفاده کنید. این در صورتی مفید است که شما کاربران را از آدرس های IP خاص شناسایی کرده اید که باعث مشکل شده اند. همچنین می توانید عکس این کار را انجام دهید و همه را بجز بازدیدکنندگان از یک آدرس IP خاص (لیست سفید) مسدود کنید. این درصورتی مفید است که لازم است دسترسی شما فقط به کاربران تأیید شده محدود شود.لیست سیاه برای IP ها order allow,deny
deny from 111.22.3.4
deny from 789.56.4.
allow from allخط اول بیان می کند که باید دستورالعمل های allow قبل از دستورالعمل های deny ارزیابی شوند. این بدان معنی است که اجازه از همه حالت پیش فرض خواهد بود و سپس فقط کسانی که با دستورالعمل های deny مطابقت دارند رد می شوند. اگر به order deny, allow معکوس شود ، آخرین چیزی که ارزیابی می شود allow است ، که به همه اجازه می دهد تا به deny غلبه کند.به خط سوم توجه کنید که 789.56.4 را deny کرده است. این یک آدرس IP کامل نیست. با این کار تمام آدرس های IP موجود در آن بلوک (هر یک از آنها با 789.56.4 شروع می شود) را رد می کند.شما می توانید هر تعداد آدرس IP را که می خواهید ،با دستورالعمل deny، رد کنید.لیست سفید برای IP هالیست سفید، عکس لیست سیاه است. (محدود کردن همه به جز مواردی که شما مشخص کرده اید.)همانطور که حدس می زنید ، دستورالعمل سفارش باید معکوس شود ، به این ترتیب ابتدا همه رد می شوند ، اما سپس آدرس های خاص مجاز هستند.order deny,allow
deny from all
allow from 111.22.3.4
allow from 789.56.4.5) تعیین یک فایل پیش فرض برای یک دایرکتوریوقتی از یک وب سرور برای یک URL درخواست می شود که نام یک فایل را مشخص نمی کند ، فرض موجود در اکثر وب سرورها این است که URL به یک دایرکتوری اشاره دارد.بنابراین ، در صورت درخواست http://example.com ، وب سرور Apache  (و سایر وب سرورها) در دایرکتوری ریشه دامنه(معمولاً / public_html یا موارد مشابه)، فایل پیش فرض را جست و جو میکند.  فایل پیش فرض (به طور پیش فرض) index.html نامیده می شود. این به ابتدای اینترنت برمی گردد زمانی که یک وب سایت فقط مجموعه ای از اسناد بود و صفحه &quot;خانه&quot; معمولاً نمایه ای از این اسناد بود.اما ممکن است شما نخواهید که index.html صفحه پیش فرض باشد. به عنوان مثال ، ممکن است به نوع پرونده دیگری مانند index.shtml ، index.xml یا index.php نیاز داشته باشید. یا ممکن است صفحه اصلی خود را &quot;index&quot; نام گذاری نکنید و بخواهید آن را چیزی متفاوت مانند home.html یا main.html بنامید.تنظیم صفحه پیش فرض دایرکتوریفایل htaccess. به شما این امکان را می دهد که صفحه پیش فرض یک دایرکتوری را به راحتی تنظیم کنید:DirectoryIndex  [filename here]اگر می خواهید پیش فرض شما home.html باشد ، میتوانید کد زیر را در فایل htaccess. جا گذاری کنید:DirectoryIndex  home.htmlتنظیم چندین صفحه پیش فرضهمچنین می توانید بیش از یک DirectoryIndex را مشخص کنید:DirectoryIndex index.php index.shtml index.htmlروش کار بدین صورت است که سرور وب ابتدا به دنبال اولین مورد می گردد. اگر نتواند آن را پیدا کند ، به دنبال مورد دوم می گردد و غیره.چرا چندین صفحه پیش فرض تعریف کنیم؟ مطمئناً می دانیم از کدام پرونده می خواهیم به عنوان صفحه پیش فرض خود استفاده کنیم!بخاطر بسپارید که htaccess. بر دایرکتوری خودش و همه زیر دایرکتوری های ان تأثیر می گذارد، تا زمانی که توسط یک فایل htaccess. دایرکتوری بالاتر لغو شود. این بدان معنی است که یک فایل htaccess. در پوشه ریشه شما می تواند دستورالعمل های بسیاری از زیر شاخه ها را ارائه دهد و هر یک ممکن است نام صفحه پیش فرض خود را داشته باشد. امکان قرار دادن این قوانین در یک فایل htaccess. در ریشه به این معنی است که شما مجبور نیستید تمام دستورالعمل های دیگر پرونده را در هر سطح دایرکتوری کپی کنید.6) هدایت URL و بازنویسی URLیکی از رایج ترین موارد استفاده از فایل های htaccess. ، هدایت URL است.وقتی URL یک سند یا منبع تغییر کرده است باید از هدایت URL استفاده شود. این امر به ویژه اگر وب سایت خود را دوباره سازماندهی کرده یا نام دامنه را تغییر داده باشید بسیار مفید است.هدایت موقت یا دائمیاز نظر مرورگر ، دو نوع هدایت وجود دارد ، 301 و 302 (این اعداد به کد خطای تولید شده توسط وب سرور اشاره دارد.) 301 به معنای &quot;انتقال دائمی&quot; است ، در حالی که 302 به معنای &quot;انتقال موقت&quot; است. در اکثر موارد ، شما می خواهید از 301 استفاده کنید. این ویژگی باعث حفظ هرگونه حق امتیاز SEO در URL اصلی می شود و آن را به صفحه جدید منتقل می کند. همچنین باعث می شود بیشتر مرورگرها بوک مارک های خود را به روز کنند. اکثر مرورگرها نقشه قدیمی به جدید را نیز ذخیره می کنند ، بنابراین وقتی پیوند یا کاربر سعی در دستیابی به نسخه اصلی دارد ، آنها به سادگی درخواست URL جدید می کنند. اگر URL به طور دائم تغییر کرده باشد ، اینها همه نتایج مطلوبی هستند.دلیل بسیار کمی برای استفاده از تغییر مسیر 302 وجود دارد ، زیرا معمولاً دلیل بسیار کمی برای تغییر موقت URL وجود دارد. تغییر URL همیشه نامطلوب است ، اما گاهی اوقات لازم است. تغییر موقتی آن ، با برنامه ریزی برای تغییر بعداً ، یک ایده بد است و تقریباً همیشه قابل اجتناب است.تمام مثالهای این بخش از تغییر مسیر 301 استفاده می کنند.تغییر مسیر در مقابل بازنویسی (Redirect vs. Rewrite)برای تغییر &quot;URL&quot; با دستورالعمل های htaccess. دو روش مختلف وجود دارد . دستور Redirect  موتور mod_rewriteدستور Redirect در واقع یک پیام تغییر مسیر به مرورگر می فرستد ، به او می گوید که چه URL دیگری را جستجو کند.به طور معمول ، ابزار mod_rewrite یک &quot;URL&quot; (آدرس ارائه شده در یک درخواست) را به چیزی تبدیل می کند که سیستم فایل یا CMS آن را بفهمد ، و سپس درخواست را به گونه ای اداره می کند که انگار URL ترجمه شده URL درخواست شده است. وقتی از این طریق استفاده می شود ، مرورگر وب متوجه نمی شود که اتفاقی افتاده است . فقط محتوای درخواستی را دریافت می کند.از ابزار mod_rewrite می توان برای تغییر مسیر 301 نیز استفاده کرد که همانند دستور Redirect عمل می کنند ، اما با گزینه های بیشتر برای قوانین mod_rewrite می تواند دستورالعمل های پیچیده تطبیق و بازنویسی الگو را داشته باشد ، که Redirect نمی تواند از آنها استفاده کند.تغییر مسیر صفحه اصلیکد زیر برای هدایت یک صفحه به URL دیگر ، است:Redirect 301 /relative-url.html http://example.com/full-url.htmlاین دستور تک خطی دارای چهار قسمت است که هر قسمت با یک فضای جداگانه جدا شده اند:دستور Redirectنوع تغییر مسیر (301 - انتقال به صورت دائمی)آدرس( URL) نسبی صفحه اصلیآدرس کامل صفحه جدید.آدرس( URL) نسبی مربوط به دایرکتوری حاوی فایل htaccess. است که معمولاً ریشه وب یا ریشه دامنه است. بنابراین اگر http://example.com/blog.php به http://blog.example.com منتقل شده باشد ، کد به شرح زیر است:Redirect 301 /blog.php  http://blog.example.comهدایت بخش بزرگی از وب سایت شمااگر ساختار دایرکتوری خود را تغییر مکان داده اید ، اما نام صفحه خود را یکسان نگه داشته اید ، ممکن است بخواهید تمام درخواست های یک دایرکتوری خاص را به دایرکتوری جدید هدایت کنید.Redirect 301 /old-directory http://example.com/new-directoryهدایت مجدد یک سایت کاملاگر کل سایت شما به یک URL جدید منتقل شده باشد:Redirect 301 / http://newurl.comهدایت www به غیر wwwبه طور فزاینده ای ، وب سایت ها از زیر دامنه www دور می شوند. واقعاً هرگز ضروری نبوده است ، اما این مسئله از روزهایی که بیشتر افرادی که یک وب سایت را اداره می کردند از یک سرور برای ذخیره بسیاری از اسناد خود استفاده می کردند ، استفاده می شد و از فهرست www یا &quot;شبکه جهانی وب&quot; برای محتوایی که می خواستند با دیگران به اشتراک بگذارند،  استفاده می شد.این روزها ، برخی از مردم استفاده می کنند ، و برخی دیگر استفاده نمی کنند. متأسفانه ، برخی از کاربران هنوز بصورت خودکار www را در مقابل هر URL از روی عادت  تایپ می کنند. اگر از www استفاده نمی کنید ، می خواهید مطمئن شوید که این درخواست ها در مکان مناسب قرار دارند، شما باید از ماژول mod_rewrite استفاده کنید ، که احتمالاً قبلاً در میزبان وب شما نصب شده است.Options +FollowSymlinks
RewriteEngine on
RewriteCond % ^www.example.com [NC]
RewriteRule ^(.*)$ http://example.org/$1 [R=301,NC]مراقب باشید!بسیاری از راهنماهای htaccess. و mod_rewrite برخی از کد های زیر را برای تحقق این امر ارائه می دهند:Options +FollowSymlinks
RewriteEngine on
RewriteCond % !^example.com [NC]
RewriteRule ^(.*)$ http://example.org/$1 [R=301,NC]مشکل این کد این است که، همه زیر دامنه ها را به دامنه اصلی هدایت می کند. بنابراین نه فقط www.example.com ، بلکه همچنین blog.example.com و admin.example.com و هر چیز دیگری. این احتمالاً رفتاری نیست که شما می خواهید.هدایت به wwwاما اگر از زیر دامنه www استفاده می کنید چه می کنید؟احتمالاً باید  هدایت را تنظیم کنید تا مطمئن شوید افراد به مکان مورد نظر خود می روند. به خصوص اکنون که احتمال می رود افراد کمتری به صورت خودکار آن www را به ابتدای URL ها اضافه کنند.شما فقط کد بالا را معکوس کنید.RewriteEngine On
RewriteCond % ^example.com [NC]
RewriteRule ^(.*) http://www.website.com/$1 [R=301,NC]آیا باید خطاهای 404 را به صفحه اصلی هدایت کنم؟چندین راهنما در مورد هدایت  htaccess شامل دستورالعمل هایی برای نحوه هدایت خطاهای 404 به صفحه اصلی است.هدایت مجدد خطاهای 404 به صفحه اصلی سایت یک ایده وحشتناک است. این بازدیدکنندگان را گیج می کند ، آنها نمی توانند بفهمند که چرا به جای یک صفحه خطای مناسب 404 ، صفحه اول یک سایت را مشاهده می کنند.همه وب سایت ها باید یک صفحه 404 سفارشی داشته باشند که به طور واضح به کاربر توضیح دهد که نمی توان محتوا را پیدا کرد و در حالت ایده آل ، برخی از ویژگی های جستجو را برای کمک به کاربر در یافتن خواسته های خود ارائه می دهد.چرا از htaccess به جای گزینه های جایگزین استفاده کنیم؟می توانید تغییر مسیر را در پرونده های PHP یا با هر نوع دیگری از برنامه نویسی سمت سرور تنظیم کنید. همچنین می توانید آنها را در سیستم مدیریت محتوا تنظیم کنید.اما استفاده از htaccess معمولاً سریعترین نوع تغییر مسیر است. با استفاده از هدایت مجدد مبتنی بر PHP یا سایر زبان های اسکریپت نویسی سمت سرور ، باید کل درخواست تکمیل شود و اسکریپت در واقع قبل از ارسال پیام تغییر مسیر به مرورگر ، تفسیر شود.با هدایت htaccess ، سرور مستقیماً به پیام تغییر مسیر پاسخ می دهد و  این خیلی سریعتر است.البته باید توجه داشته باشید، برخی از سیستم های مدیریت محتوا در واقع با به روزرسانی برنامه ی htaccess تغییر مسیرها را مدیریت می کنند. به عنوان مثال وردپرس دارای افزونه های ریدایرکت است که از این طریق کار می کنند. این به شما عملکرد استفاده مستقیم از htaccess را می دهد و در عین حال راحتی مدیریت را از طریق برنامه به شما می دهد.پنهان کردن فایل htaccess. (ملاحظات امنیتی)هیچ دلیلی وجود ندارد که کسی بتواند فایل htaccess شما را از وب مشاهده کند. علاوه بر این ، دلایل زیادی وجود دارد که شما قطعاً نمی خواهید کسی فایل htaccess شما را ببینند.بزرگترین مسئله این است که اگر از یک فایل htpasswd. استفاده می کنید ، محل آن در فایل htaccess. مشخص شده است. دانستن اینکه کجا می توان آن را پیدا کرد ، یافتن آن را آسان تر می کند.علاوه بر این ، به عنوان یک قاعده کلی ، شما نمی خواهید جزئیات مربوط به اجرای خود را به مردم ارائه دهید.قوانین rewrite، تنظیمات دایرکتوری ، امنیت و همه مواردی که برای آن از htaccess. استفاده می کنید. پنهان کردن همه این پشت صحنه در وب سرور یک روش امنیتی خوب است. هر چقدر یک هکر بتواند در مورد سیستم شما بیشتر بیاموزد ، به خطر انداختن آن آسان تر است. پنهان کردن فایل htaccess. از دید عموم بسیار آسان است. فقط کد زیر را اضافه کنید:&lt;Files .htaccess&gt;
order allow,deny
deny from all
&lt;/Files&gt;در این مقاله سعی کردم به بیشتر کاربرد ها و مواردی که از فایل htaccess استفاده می شود اشاره کنم. برای مطالعه بیشتر می توانید به مراجع زیر مراجعه کنید.مراجع: wikipedia.org | blog.iranserver.com | whoishostingthis.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Fri, 04 Sep 2020 23:45:35 +0430</pubDate>
            </item>
                    <item>
                <title>چه طور در لاراول چند احراز هویت داشته باشیم!</title>
                <link>https://virgool.io/laravel-community/%DA%86%D9%87-%D8%B7%D9%88%D8%B1-%D8%AF%D8%B1-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84-%DA%86%D9%86%D8%AF-%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AA-%D8%AF%D8%A7%D8%B4%D8%AA%D9%87-%D8%A8%D8%A7%D8%B4%DB%8C%D9%85-jumn73s1qakb</link>
                <description>Laravel Multi Authاگر مدتی از لاراول استفاده کرده باشید ، حتما در مورد احراز هویت لاراول  چیزهای زیادی را شنیده اید. در اين پست می خواهیم در مورد احراز هویت چند گانه لاراول صحبت کنیم. احراز هویت چندگانه باعث می شود کلاس های مختلف کاربران، دسترسی به قسمتهای مختلف یا مشابه یک برنامه مشابه را داشته باشند.دلایل زیادی وجود دارد که شما ممکن است بخواهید از چندین احراز هویت در برنامه Laravel خود استفاده کنید. به عنوان مثال ، شما یک برنامه بزرگ دارید که کل یک شرکت را اداره می کند. مشتریان همچنین از طریق همین برنامه با محصول و خدمات شرکت ارتباط برقرار می کنند. همچنین این نرم افزار دارای یک وبلاگ است و یک بخش در شرکت وجود دارد که مسئولیت رسیدگی به وبلاگ را بر عهده دارد. در این شرکت بازاریاب هایی مشغول به کار هستند و از همین نرم افزار استفاده میکنند.سطح دسترسی در این برنامه باید متفاوت باشد.از برنامه بالا مشاهده می کنیم که در حال حاضر 4 مجموعه کاربر وجود دارد. برای مشتریان ، ما می توانیم از آنها بخواهیم که برای دسترسی به سیستم از یک فرآیند تأیید خاص استفاده کنند. برای نویسندگان ، آنها می توانند یک پروسه احراز هویت کاملاً متفاوت و حتی محتوایی داشته باشند تا بتوانند یک روند مدیریت محتوا قوی تر داشته باشند. برای بازاریاب ها یک فرآیند احراز هویت جدا وجود دارد و برای بقیه شرکت ، شما می توانید نقش های مختلفی داشته باشید که عملکردهای مختلف را نشان می دهد.حال ، به چگونگی ایجاد احراز هویت چندگانه برای طبقه مختلف کاربران خود می پردازیم.شروعما یک برنامه Laravel ایجاد خواهیم کرد که دارای 4 کلاس کاربر است - مدیر ، نویسنده ، بازاریاب، مشتری. ما برای 4 کلاس کاربر guard درست می کنیم و قسمت های مختلف برنامه خود را بر اساس آن دسته از guard ها محدود می کنیم.ما باید یک برنامه جدید Laravel ایجاد کنیم. دستور زیر را در ترمینال خود اجرا کنید تا یک برنامه جدید Laravel ایجاد کنید (ایجاد این پروژه با استفاده از Laravel installer انجام میشود شما میتوانید با composer  هم این پروژه را ایجاد کنید):laravel new multi-auth - - authcd multi-authایجاد پایگاه دادهما برای این پروژه از پایگاه داده My SQL استفاده خواهیم کرد. فایل env. پروژه خود را باز کنید و نام پایگاه داده را انتخاب کنید. برای مثال من نام پایگاه داده را multi-auth انتخاب میکنم.DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=multi-auth
DB_USERNAME=root
DB_PASSWORD=سپس در phpMyAdmin خود یک پایگاه داده خالی با نام multi-auth ایجاد کنید تا جدول های مربوط به پروژه به وسیله migration  ها در آن ایجاد شوند. در پستی که قبلا منتشر کرده ام، به طور کامل در مورد migration ها صحبت کرده ام. اگر هنوز آن را مطالعه نکرده اید، می توانید برای فهم بیشتر در مورد Migration ها به آن مراجعه کنید. (مبحث Migration ها در Laravel)در این پروژه migration هایی برای جدول مدیران، نویسندگان و بازاریاب ها خواهیم نوشت. جدول آنها به اندازه جدول مشتری ها ساده خواهد بود ، اما شما می توانید آنها را بر اساس نیازهای خاص خود، آنها را گسترش دهید. توجه داشته باشید که جدول مشتری ها با استفاده از auth - -  در ابتدا ی ایجاد پروژه، ایجاد شده است.ایجاد جدول برای مدیران(Admins)برای ایجاد migration برای تولید جدول admins، دستور زیر را در خط فرمان خود وارد کنید.php artisan make:migration create_admins_tableبا اجرای این دستور فایل migration مربوط به جدول admins در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:// database/migrations/&lt;timestamp&gt;_create_admins_table.php
[...]
public function up(){
    Schema::create(&#039;admins&#039;, function (Blueprint $table) {
        $table-&gt;increments(&#039;id&#039;);
        $table-&gt;string(&#039;name&#039;);
        $table-&gt;string(&#039;email&#039;)-&gt;unique();
        $table-&gt;string(&#039;password&#039;);
        $table-&gt;boolean(&#039;is_super&#039;)-&gt;default(false);
        $table-&gt;rememberToken();
        $table-&gt;timestamps();
    });
}
[...]با کد های بالا ما یک migration برای ایجاد جدول admins نوشتیم که با استفاده از متد های Eloquent نوع ستون های جدول را تعیین کردیم.برای کاربران دیگر هم همانند &quot;Admins&quot; عمل میکنیم.ایجاد جدول برای نویسندگان(Writers)برای ایجاد migration برای تولید جدول writers، دستور زیر را در خط فرمان خود وارد کنید.php artisan make:migration create_writers_tableبا اجرای این دستور فایل migration مربوط به جدول writers در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:// database/migrations/&lt;timestamp&gt;_create_writers_table.php
[...]
public function up(){
    Schema::create(&#039;writers&#039;, function (Blueprint $table) {
        $table-&gt;increments(&#039;id&#039;);
        $table-&gt;string(&#039;name&#039;);
        $table-&gt;string(&#039;email&#039;)-&gt;unique();
        $table-&gt;string(&#039;password&#039;);
        $table-&gt;boolean(&#039;is_editor&#039;)-&gt;default(false);
        $table-&gt;rememberToken();
        $table-&gt;timestamps();
    });
}
[...]ایجاد جدول برای بازاریاب ها(Marketers)برای ایجاد migration برای تولید جدول marketers، دستور زیر را در خط فرمان خود وارد کنید.php artisan make:migration create_marketers_tableبا اجرای این دستور فایل migration مربوط به جدول marketers در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:// database/migrations/&lt;timestamp&gt;_create_marketers_table.php
[...]
public function up(){
    Schema::create(&#039;marketers&#039;, function (Blueprint $table) {
        $table-&gt;increments(&#039;id&#039;);
        $table-&gt;string(&#039;name&#039;);
        $table-&gt;string(&#039;email&#039;)-&gt;unique();
        $table-&gt;string(&#039;password&#039;);
        $table-&gt;boolean(&#039;is_super)-&gt;default(false);
        $table-&gt;rememberToken();
        $table-&gt;timestamps();
    });
}
[...]حال migration های نوشته شده را با استفاده از دستور زیر اجرا کنید:php artisan migrateحال جدول هایی که اطلاعات آن را در migration ها نوشتیم در پایگاه داده multi-auth ایجاد شد. شما میتوانید این جدول ها را در phpMyAdmin خود ببینید.تنظیمات مدل ها(Models)ما کلاسهای مختلفی از کاربران برای برنامه خود داریم و آنها از جداول پایگاه داده مختلف استفاده می کنند. برای استفاده از این جداول مختلف برای احرازهویت ، باید مدل هایی را برای آنها تعریف کنیم. این مدل ها مانند مدل User خواهند بود و خاصیت های کلاس Authenticable را به ارث میبرند.مدل Adminبرای ساختن مدل برای مدیر ، دستور زیر را اجرا کنید:php artisan make:model Adminفایل Admin.php را از پوشه App باز کنید و همانند کد های زیر آن را تغییر دهید:// app/Admin.php
&lt;?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable{
    use Notifiable;
    protected $guard = &#039;admin&#039;;
    protected $fillable = [ &#039;name&#039;, &#039;email&#039;, &#039;password&#039;, ];
    protected $hidden = [ &#039;password&#039;, &#039;remember_token&#039;, ];
}هنگامی که شما قصد استفاده از مدلی را برای احراز هویت دارید و قصد دارید از guard پیش فرض user استفاده نکنید ، مهم است که guard مورد استفاده خود را تعیین کنید. در این مورد ما از  admin guard استفاده می کنیم.در ادامه در مورد guard ها بیشتر توضیح داده خواهد شد .ما همچنین با قرار دادن آنها در آرایه قابل پر کردن(fiilable)  برخی از ستون های پایگاه داده خود را به عنوان fillable تعریف کردیم. این به لاراول در مورد مدل زیر می گوید: اگر من متد ایجاد(create) یا به روزرسانی(update) را فراخوانی کرده و آرایه ای به عنوان آرگمان فرستادم، فقط ستون هایی که قابلیت fillable را دارند را قبول کن.به این ترتیب ، از سناریویی جلوگیری خواهیم کرد که اگر کاربر بتواند از هر کدام از مرزهای امنیتی ما دور بماند و رکورد مورد نظر خود را برای درج یا به روزرسانی آنها بفرستد، اجازه این کار را نداشته باشد.برای آرایه hidden ، ما به لاراول می گوییم وقتی مدل را به API یا نمای خود برگردانید ، این ستون ها را بازنگرداند.برای کاربران دیگر همانند Admin عمل میکنیم.مدل Writerبرای ساختن مدل برای نویسنده ، دستور زیر را اجرا کنید:php artisan make:model Writerفایل Writer.php را از پوشه App باز کنید و همانند کد های زیر آن را تغییر دهید:// app/Writer.php
&lt;?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Writer extends Authenticatable{
    use Notifiable;
    protected $guard = &#039;writer&#039;;
    protected $fillable = [ &#039;name&#039;, &#039;email&#039;, &#039;password&#039;, ];
    protected $hidden = [ &#039;password&#039;, &#039;remember_token&#039;, ];
}مدل Marketerبرای ساختن مدل برای بازاریاب ، دستور زیر را اجرا کنید:php artisan make:model Marketerفایل Marketer.php را از پوشه App باز کنید و همانند کد های زیر آن را تغییر دهید:// app/Marketer.php
&lt;?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Marketer extends Authenticatable{
    use Notifiable;
    protected $guard = &#039;marketer&#039;;
    protected $fillable = [ &#039;name&#039;, &#039;email&#039;, &#039;password&#039;, ];
    protected $hidden = [ &#039;password&#039;, &#039;remember_token&#039;, ];
}تعریف Guardها نحوه احراز هویت کاربران برای هر درخواست را در لاراول، guard ها تعریف می كنند. لاراول برای احراز هویت برخی از guard ها را به طور پیش فرض دارد، اما ما می توانیم خودمان را نیز guard جدید ایجاد کنیم. این به ما این امکان را می دهد تا از سیستم احراز هویت پیش فرض Laravel با مدل های Admin و Writer و Marketer نیز استفاده کنیم.فایل config/auth.php را باز کرده و guard های جدید خود را همانند کد های زیر به ان وارد کنید.// config/auth.php
&lt;?php
[...]
&#039;guards&#039; =&gt; [
    [...]
    &#039;admin&#039; =&gt; [
        &#039;driver&#039; =&gt; &#039;session&#039;,
        &#039;provider&#039; =&gt; &#039;admins&#039;,
    ],
    &#039;writer&#039; =&gt; [
        &#039;driver&#039; =&gt; &#039;session&#039;,
        &#039;provider&#039; =&gt; &#039;writers&#039;,
    ],
    &#039;marketer&#039; =&gt; [ 
        &#039;driver&#039; =&gt; &#039;session&#039;,
        &#039;provider&#039; =&gt; &#039;marketers&#039;,     ],
],
[...]ما سه guard جدید مدیر و نویسنده و بازاریاب را اضافه کردیم و provider آنها را تنظیم کردیم. این provider به لاراول می گویند وقتی سعی می کنیم از guard ها استفاده کنیم ، برای احراز هویت یا اعتبار سنجی از چه چیزی استفاده کند.اکنون موارد زیر را به لیست provider ها اضافه کنید:// config/auth.php
[...]
&#039;providers&#039; =&gt; [
    [...]
    &#039;admins&#039; =&gt; [
        &#039;driver&#039; =&gt; &#039;eloquent&#039;,
        &#039;model&#039; =&gt; App\Admin::class,
    ],
    &#039;writers&#039; =&gt; [
        &#039;driver&#039; =&gt; &#039;eloquent&#039;,
        &#039;model&#039; =&gt; App\Writer::class,
    ],
    &#039;marketers&#039; =&gt; [
         &#039;driver&#039; =&gt; &#039;eloquent&#039;,  
         &#039;model&#039; =&gt; App\Marketer::class,     ],
],
[...]اکنون ، ما provider های تعریف شده را به همراه guard های فوق تنظیم کرده ایم. ما driver را eloquent قرار داده ایم زیرا از Eloquent ORM به عنوان مدیر پایگاه داده ما استفاده می کنیم.تنظیمات کنترلر ها(controllers)برای استفاده از guard های خود برای احراز هویت، می توانیم کنترلرهای احراز هویت موجود را اصلاح کنیم یا موارد جدیدی ایجاد کنیم. شما می توانید بر اساس نیازهای خاص خود انتخاب کنید که استفاده کنید. در این آموزش این کنترلرها را اصلاح خواهیم کرد.اصلاح LoginControllerفایل LoginController در app/Http/Controllers/Auth را باز کرده و این گونه تغییر دهید:// app/Http/Controllers/Auth/LoginController.php
&lt;?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
[...]
use Illuminate\Http\Request;
use Auth;
[...]
class LoginController extends Controller{
    [...]
    public function __construct(){
        $this-&gt;middleware(&#039;guest&#039;)-&gt;except(&#039;logout&#039;);
        $this-&gt;middleware(&#039;guest:admin&#039;)-&gt;except(&#039;logout&#039;);
        $this-&gt;middleware(&#039;guest:writer&#039;)-&gt;except(&#039;logout&#039;);
        $this-&gt;middleware(&#039;guest:marketer&#039;)-&gt;except(&#039;logout&#039;);   
    }
    [...]
}ما middleware را برای محدود کردن دسترسی به این کنترلر یا متد های آن تنظیم کردیم. مهم است که ما انواع مختلف guest را در کنترلر تعریف کنیم. به این ترتیب ، اگر یک نوع کاربر به سیستم وارد شوید و سعی کنید از یک کاربر دیگر برای ورود به سیستم استفاده کنید ، شما را به یک صفحه احراز هویت از پیش تعریف شده هدایت می کند. برای مثال اگر من به عنوان نویسنده وارد سیستم شوم، دیگر قادر نخواهم بود همزمان به عنوان مدیر نیز وارد سیستم بشوم.در پستی که قبلا منتشر کرده ام، به طور کامل در مورد middleware ها صحبت کرده ام. اگر هنوز آن را مطالعه نکرده اید، می توانید برای فهم بیشتر در مورد Middleware ها به آن مراجعه کنید.  (مبحث Middleware ها در Laravel)حال برای مدیر پنل ورود ایجاد کنید: // app/Http/Controllers/Auth/LoginController.php
[...]
public function showAdminLoginForm(){
    return view(&#039;auth.login&#039;, [&#039;url&#039; =&gt; &#039;admin&#039;]);
}
public function adminLogin(Request $request){
    $this-&gt;validate($request, [
        &#039;email&#039; =&gt; &#039;required|email&#039;,
        &#039;password&#039; =&gt; &#039;required|min:6&#039;
    ]);
    if (Auth::guard(&#039;admin&#039;)-&gt;attempt([&#039;email&#039; =&gt; $request-&gt;email, &#039;password&#039; =&gt; $request-&gt;password], $request-&gt;get(&#039;remember&#039;))) {
        return redirect()-&gt;intended(&#039;/admin&#039;);
    }
    return back()-&gt;withInput($request-&gt;only(&#039;email&#039;, &#039;remember&#039;));
    }
[...]ما متدی را برای بازگشت صفحه ورود به سیستم برای Admin تنظیم کرده ایم. برای همه ی انواع کاربر از همان صفحه استفاده خواهیم کرد و فقط آدرس اینترنتی ارسال شده (URL) را تغییر می دهیم. این کار باعث می شود از نوشتن کد های تکراری جلوگیری کنیم.ما همچنین متد adminLogin را تعریف می کنیم که ابتدا بررسی می کند که فیلد های مربوطه اعتبار داشته باشند. برای این قسمت شما میتوانید اعتبارنامه شخصی ایجاد کرده و پیام های متناسب با آن ها را خودتان مشخص کنید(برای مثال در این جا حداقل طول رمز عبور 6 می باشد شما میتوانید این عدد را تغییر دهید). سپس سعی می کنیم کاربر را با guard مدیر (َAdmin) وارد سیستم کنیم. مهم این است که هنگام تلاش برای ورود به سیستم ، این guard را تنظیم کنیم تا Auth اعتبارنامه مطابق جدول مناسب را بررسی کند. همچنین تأیید اعتبار ما را تنظیم می کند ، بنابراین می توانیم صفحات را بر اساس نوع کاربری که وارد آن شده است محدود کنیم.ما یک کاربر معتبر را به یک URL خاص هدایت می کنیم و یک کاربر غیرمجاز را به صفحه ورود ارسال می کنیم.همین کار را برای ورود نویسنده و بازاریاب تکرار میکنیم.// app/Http/Controllers/Auth/LoginController.php
[...]
public function showWriterLoginForm(){
    return view(&#039;auth.login&#039;, [&#039;url&#039; =&gt; &#039;writer&#039;]);
}
public function writerLogin(Request $request){
    $this-&gt;validate($request, [
         &#039;email&#039; =&gt; &#039;required|email&#039;,
         &#039;password&#039; =&gt; &#039;required|min:6&#039;
    ]);
    if (Auth::guard(&#039;writer&#039;)-&gt;attempt([&#039;email&#039; =&gt; $request-&gt;email,  &#039;password&#039; =&gt; $request-&gt;password],  $request-&gt;get(&#039;remember&#039;))) {
         return redirect()-&gt;intended(&#039;/writer&#039;);
     }
     return back()-&gt;withInput($request-&gt;only(&#039;email&#039;, &#039;remember&#039;));
    }
[...]
public function showMarketerLoginForm(){     
    return view(&#039;auth.login&#039;, [&#039;url&#039; =&gt; &#039;marketer&#039;]); 
} 
public function marketerLogin(Request $request){    
     $this-&gt;validate($request, [ 
                              &#039;email&#039; =&gt; &#039;required|email&#039;, 
                              &#039;password&#039; =&gt; &#039;required|min:6&#039;
     ]); 
    if (Auth::guard(&#039;marketer&#039;)-&gt;attempt([&#039;email&#039; =&gt; $request-&gt;email,  &#039;password&#039; =&gt; $request-&gt;password],  $request-&gt;get(&#039;remember&#039;))) {                                                           
         return redirect()-&gt;intended(&#039;/marketer&#039;);                                                             
     }          
     return back()-&gt;withInput($request-&gt;only(&#039;email&#039;, &#039;remember&#039;));
}
 [...]اصلاح RegisterControllerفایل RegisterController در app/Http/Controllers/Auth را باز کرده و این گونه تغییر دهید:// app/Http/Controllers/Auth/RegisterController.php
&lt;?php
[...]
namespace App\Http\Controllers\Auth;
use App\User;
use App\Admin;
use App\Writer;
use App\Marketer;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
[...]
class RegisterController extends Controller{
[...]
    public function __construct(){
        $this-&gt;middleware(&#039;guest&#039;);
        $this-&gt;middleware(&#039;guest:admin&#039;);
        $this-&gt;middleware(&#039;guest:writer&#039;);
        $this-&gt;middleware(&#039;guest:marketer&#039;);
    }
    [...]
}در سازنده این کلاس، middleware های مربوط را تنظیم نمودیم ، دقیقاً مانند آنچه که با LoginController انجام دادیم.اکنون متد هایی برای بازگشت صفحات ثبت نام برای کاربران مختلف را تنظیم می کنیم:// app/Http/Controllers/Auth/RegisterController.php
[...]
public function showAdminRegisterForm(){
    return view(&#039;auth.register&#039;, [&#039;url&#039; =&gt; &#039;admin&#039;]);
}
public function showWriterRegisterForm(){
    return view(&#039;auth.register&#039;, [&#039;url&#039; =&gt; &#039;writer&#039;]);
}
public function showWriterRegisterForm(){
    return view(&#039;auth.register&#039;, [&#039;url&#039; =&gt; &#039;marketer&#039;]);
}
[...]این مشابه کاری است که ما برای نمایش صفحات مختلف ورود به سیستم انجام داده ایم.اکنون می توانیم متد های خود را برای ایجاد یک مدیر تعریف کنیم:// app/Http/Controllers/Auth/RegisterController.php
[...]
protected function createAdmin(Request $request){
    $this-&gt;validator($request-&gt;all())-&gt;validate();
    $admin = Admin::create([
                                  &#039;name&#039; =&gt; $request[&#039;name&#039;],
                                  &#039;email&#039; =&gt; $request[&#039;email&#039;],
                                  &#039;password&#039; =&gt; Hash::make($request[&#039;password&#039;]),
    ]);
    return redirect()-&gt;intended(&#039;login/admin&#039;);
}
[...]سپس متد های ایجاد نویسنده و بازاریاب را مشابه متد بالا ایجاد میکنیم:// app/Http/Controllers/Auth/RegisterController.php
[...]
protected function createWriter(Request $request){
    $this-&gt;validator($request-&gt;all())-&gt;validate();
    $writer = Writer::create([
                                &#039;name&#039; =&gt; $request[&#039;name&#039;],
                                &#039;email&#039; =&gt; $request[&#039;email&#039;],
                                &#039;password&#039; =&gt; Hash::make($request[&#039;password&#039;]),
    ]);
    return redirect()-&gt;intended(&#039;login/writer&#039;);
}
[...]
protected function createMarketer(Request $request){
    $this-&gt;validator($request-&gt;all())-&gt;validate(); 
    $marketer = Marketer::create([ 
                                &#039;name&#039; =&gt; $request[&#039;name&#039;], 
                                &#039;email&#039; =&gt; $request[&#039;email&#039;], 
                                &#039;password&#039; =&gt; Hash::make($request[&#039;password&#039;]), 
    ]); 
    return redirect()-&gt;intended(&#039;login/marketer&#039;); 
} 
[...]تنظیمات صفحات احراز هویتدر ابتدای توضیحات، در قسمت ایجاد پروژه از دستور laravel new multi-auth - - authبرای ایجاد پروژه استفاده کردیم. در این دستور قسمت auth- -  صفحات مربوط به احراز هویت و همچنین کنترلر های مربوط را ساخت و ما در قسمت های قبل برای احراز هویت چندگانه، کنترلر های مربوط را اصلاح کردیم. حال صفحات مربوط به احراز هویت موجود در resources/views/auth را اصلاح میکنیم.برای ورود 4 گروه کاربر از یک صفحه مشترک با URL های متفاوت استفاده میکنیم. برای این کار فایل login.blade.php را این گونه اصلاح کنید:// resources/views/auth/login.blade.php
[...]
&lt;div class=&amp;quotcard-header&amp;quot&gt; {{ isset($url) ? ucwords($url) : &amp;quot&amp;quot}} {{ __(&#039;Login&#039;) }}&lt;/div&gt;
&lt;div class=&amp;quotcard-body&amp;quot&gt;
@isset($url)
    &lt;form method=&amp;quotPOST&amp;quot action=&#039;{{ url(&amp;quotlogin/$url&amp;quot) }}&#039; aria-label=&amp;quot{{ __(&#039;Login&#039;) }}&amp;quot&gt;
@else
    &lt;form method=&amp;quotPOST&amp;quot action=&amp;quot{{ route(&#039;login&#039;) }}&amp;quot aria-label=&amp;quot{{ __(&#039;Login&#039;) }}&amp;quot&gt;
@endisset
@csrf
[...]
&lt;/div&gt;
[...]در حال بررسی این نکته هستیم که وقتی یک پارامتر url را به صفحه منتقل کردیم، عمل فرم را برای استفاده از پارامتر url اصلاح کنیم. همچنین عنوان فرم را طوری تغییر دادیم که نوع کاربر را بر اساس پارامتر ورود، به سیستم خود نشان می دهد.برای ثبت نام 4 گروه کاربر از یک صفحه مشترک با URL های متفاوت استفاده میکنیم. برای این کار فایل register.blade.php را این گونه اصلاح کنید:// resources/views/auth/register.blade.php
[...]
&lt;div class=&amp;quotcard-header&amp;quot&gt; {{ isset($url) ? ucwords($url) : &amp;quot&amp;quot}} {{ __(&#039;Register&#039;) }}&lt;/div&gt;
&lt;div class=&amp;quotcard-body&amp;quot&gt;
@isset($url)
    &lt;form method=&amp;quotPOST&amp;quot action=&#039;{{ url(&amp;quotregister/$url&amp;quot) }}&#039; aria-label=&amp;quot{{ __(&#039;Register&#039;) }}&amp;quot&gt;
@else
    &lt;form method=&amp;quotPOST&amp;quot action=&amp;quot{{ route(&#039;register&#039;) }}&amp;quot aria-label=&amp;quot{{ __(&#039;Register&#039;) }}&amp;quot&gt;
@endisset
@csrf
[...]
&lt;/div&gt;
[...]در این قسمت نیز همانند صفحه ورود عمل کردیم.البته این نکته را نیز در نظر بگیرید که در عمل درست نیست که مدیر سیستم خود در سیستم ثبت نام کند. برای امنیت بیشتر ثبت نام مدیر توسط مدیر دیگر یا از ابتدا توسط seed های سیستم انجام می گیرد. برای ثبت نام مدیر توسط مدیر دیگر کافیست یک کنترلر برای مدیر سیستم (AdminController) ساخته و متد های مربوط به ایجاد مدیر جدید و نمایش فرم ثبت نام آن را به AdminController منتقل کنید و middleware ها را برای مدیر تنظیم کنید((&#x27;middleware(&#x27;auth:admin). و مسیر دهی ها را که در ادامه به آن ها اشاره میشود را به پنل مدیر سیستم منتقل کنید.ساخت پنل مخصوص 4 دسته از کاربران برای بعد از احراز هویت ما تنظیمات صفحه ورود و ثبت نام را تکمیل کردیم ، حال صفحاتی را ایجاد کنیم که مدیران و نویسندگان و بازاریاب ها بعد از احراز هویت آنها را ببینند. خط فرمان را باز کنید و دستورات زیر را برای ایجاد فایل های جدید اجرا کنید. بعد ، قطعه کد مربوطه را در پرونده ها وارد خواهیم کرد.$ touch resources/views/layouts/auth.blade.php$ touch resources/views/admin.blade.php$ touch resources/views/writer.blade.php$ touch resources/views/marketer.blade.php     $ touch resources/views/home.blade.phpاین کد را در فایل auth.blade.php قرار دهید:// resources/views/layouts/auth.blade.php
&lt;!DOCTYPE html&gt;
&lt;html lang=&amp;quot{{ str_replace(&#039;_&#039;, &#039;-&#039;, app()-&gt;getLocale()) }}&amp;quot&gt;
    &lt;head&gt;
        &lt;meta charset=&amp;quotutf-8&amp;quot&gt;
        &lt;meta http-equiv=&amp;quotX-UA-Compatible&amp;quot content=&amp;quotIE=edge&amp;quot&gt;
        &lt;meta name=&amp;quotviewport&amp;quot content=&amp;quotwidth=device-width, initial-scale=1&amp;quot&gt;
        &lt;!-- CSRF Token --&gt;
        &lt;meta name=&amp;quotcsrf-token&amp;quot content=&amp;quot{{ csrf_token() }}&amp;quot&gt;
        &lt;title&gt;{{ config(&#039;app.name&#039;, &#039;Laravel&#039;) }}&lt;/title&gt;
        &lt;!-- Scripts --&gt;
        &lt;script src=&amp;quot{{ asset(&#039;js/app.js&#039;) }}&amp;quot defer&gt;
        &lt;!-- Fonts --&gt;
        &lt;link rel=&amp;quotdns-prefetch&amp;quot href=&amp;quothttps://fonts.gstatic.com&amp;quot&gt;
       &lt;link href=&amp;quothttps://fonts.googleapis.com/css?family=Raleway:300,400,600&amp;quot rel=&amp;quotstylesheet&amp;quot type=&amp;quottext/css&amp;quot&gt;
       &lt;!-- Styles --&gt;
       &lt;link href=&amp;quot{{ asset(&#039;css/app.css&#039;) }}&amp;quot rel=&amp;quotstylesheet&amp;quot&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div id=&amp;quotapp&amp;quot&gt;
            &lt;nav class=&amp;quotnavbar navbar-expand-md navbar-light navbar-laravel&amp;quot&gt;
            &lt;div class=&amp;quotcontainer&amp;quot&gt;
                &lt;a class=&amp;quotnavbar-brand&amp;quot href=&amp;quot{{ url(&#039;/&#039;) }}&amp;quot&gt;
                   {{ config(&#039;app.name&#039;, &#039;Laravel&#039;) }}
                &lt;/a&gt;
               &lt;button class=&amp;quotnavbar-toggler&amp;quot type=&amp;quotbutton&amp;quot data-toggle=&amp;quotcollapse&amp;quot data-target=&amp;quot#navbarSupportedContent&amp;quot aria-controls=&amp;quotnavbarSupportedContent&amp;quot aria- 
expanded=&amp;quotfalse&amp;quot aria-label=&amp;quot{{ __(&#039;Toggle navigation&#039;) }}&amp;quot&gt;
                 &lt;span class=&amp;quotnavbar-toggler-icon&amp;quot&gt;&lt;/span&gt;
            &lt;/button&gt;
            &lt;div class=&amp;quotcollapse navbar-collapse&amp;quot id=&amp;quotnavbarSupportedContent&amp;quot&gt;
                &lt;!-- Left Side Of Navbar --&gt;
                &lt;ul class=&amp;quotnavbar-nav mr-auto&amp;quot&gt;&lt;/ul&gt;
                &lt;!-- Right Side Of Navbar --&gt;
                &lt;ul class=&amp;quotnavbar-nav ml-auto&amp;quot&gt;
                &lt;!-- Authentication Links --&gt;
                &lt;li class=&amp;quotnav-item dropdown&amp;quot&gt;
               &lt;a id=&amp;quotnavbarDropdown&amp;quot class=&amp;quotnav-link dropdown-toggle&amp;quot href=&amp;quot#&amp;quot role=&amp;quotbutton&amp;quot 
data-toggle=&amp;quotdropdown&amp;quot aria-haspopup=&amp;quottrue&amp;quot aria-expanded=&amp;quotfalse&amp;quot v-pre&gt;
                     Hi There &lt;span class=&amp;quotcaret&amp;quot&gt;&lt;/span&gt;
                &lt;/a&gt;
                &lt;div class=&amp;quotdropdown-menu dropdown-menu-right&amp;quot aria-labelledby=&amp;quotnavbarDropdown&amp;quot&gt;
                    &lt;a class=&amp;quotdropdown-item&amp;quot href=&amp;quot{{ route(&#039;logout&#039;) }}&amp;quot
=&amp;quotevent.preventDefault();
                     document.getElementById(&#039;logout-form&#039;).submit();&amp;quot&gt;
                       {{ __(&#039;Logout&#039;) }}
                    &lt;/a&gt;
                   &lt;form id=&amp;quotlogout-form&amp;quot action=&amp;quot{{ route(&#039;logout&#039;) }}&amp;quot method=&amp;quotPOST&amp;quot 
                            style=&amp;quotdisplay: none;&amp;quot&gt;
                        @csrf
                   &lt;/form&gt;
               &lt;/div&gt;
              &lt;/li&gt;
             &lt;/ul&gt;
         &lt;/div&gt;
     &lt;/div&gt;
&lt;/nav&gt;
&lt;main class=&amp;quotpy-4&amp;quot&gt;
     @yield(&#039;content&#039;)
&lt;/main&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;حال پنل مدیران را طراحی کنید: admin.blade.php// resources/views/admin.blade.php
@extends(&#039;layouts.auth&#039;)
@section(&#039;content&#039;)
    &lt;div class=&amp;quotcontainer&amp;quot&gt;
        &lt;div class=&amp;quotrow justify-content-center&amp;quot&gt;
            &lt;div class=&amp;quotcol-md-8&amp;quot&gt;
                &lt;div class=&amp;quotcard&amp;quot&gt;
                    &lt;div class=&amp;quotcard-header&amp;quot&gt;Admin Dashboard&lt;/div&gt;
                   &lt;div class=&amp;quotcard-body&amp;quot&gt;Hi boss!&lt;/div&gt;
                 &lt;/div&gt;
             &lt;/div&gt;
         &lt;/div&gt;
    &lt;/div&gt;
@endsectionحال پنل نویسندگان را طراحی کنید:writer.blade.php// resources/views/writer.blade.php
@extends(&#039;layouts.auth&#039;)
@section(&#039;content&#039;)
    &lt;div class=&amp;quotcontainer&amp;quot&gt;
        &lt;div class=&amp;quotrow justify-content-center&amp;quot&gt;
            &lt;div class=&amp;quotcol-md-8&amp;quot&gt;
                &lt;div class=&amp;quotcard&amp;quot&gt;
                    &lt;div class=&amp;quotcard-header&amp;quot&gt;Writer Dashboard&lt;/div&gt;
                   &lt;div class=&amp;quotcard-body&amp;quot&gt;Hi there, awesome writer!&lt;/div&gt;
                 &lt;/div&gt;
             &lt;/div&gt;
         &lt;/div&gt;
    &lt;/div&gt;
@endsectionحال پنل بازاریاب ها را طراحی کنید:marketer.blade.php// resources/views/marketer.blade.php
@extends(&#039;layouts.auth&#039;)
@section(&#039;content&#039;)
    &lt;div class=&amp;quotcontainer&amp;quot&gt;
        &lt;div class=&amp;quotrow justify-content-center&amp;quot&gt;
            &lt;div class=&amp;quotcol-md-8&amp;quot&gt;
                &lt;div class=&amp;quotcard&amp;quot&gt;
                    &lt;div class=&amp;quotcard-header&amp;quot&gt;Marketer Dashboard&lt;/div&gt;
                   &lt;div class=&amp;quotcard-body&amp;quot&gt;Hi there, awesome marketer!&lt;/div&gt;
                 &lt;/div&gt;
             &lt;/div&gt;
         &lt;/div&gt;
    &lt;/div&gt;
@endsectionحال پنل مشتری ها را طراحی کنید:home.blade.php (البته این فایل موجود است کافیست آن را اصلاح کنید.)// resources/views/home.blade.php
@extends(&#039;layouts.auth&#039;)
@section(&#039;content&#039;)
    &lt;div class=&amp;quotcontainer&amp;quot&gt;
        &lt;div class=&amp;quotrow justify-content-center&amp;quot&gt;
            &lt;div class=&amp;quotcol-md-8&amp;quot&gt;
                &lt;div class=&amp;quotcard&amp;quot&gt;
                    &lt;div class=&amp;quotcard-header&amp;quot&gt;Dashboard&lt;/div&gt;
                   &lt;div class=&amp;quotcard-body&amp;quot&gt;Hi there, regular user!&lt;/div&gt;
                 &lt;/div&gt;
             &lt;/div&gt;
         &lt;/div&gt;
    &lt;/div&gt;
@endsectionتنظیمات مسیر هابرنامه ما تقریباً آماده است حال مسیرهایی را برای دسترسی به تمام صفحاتی که تاکنون ایجاد کرده ایم تعریف می کنیم. فایل  routes/web.php را باز کنید و موارد زیر را جایگزین کنید:// routes/web.php
&lt;?php
Route::view(&#039;/&#039;, &#039;welcome&#039;);
Auth::routes();
Route::get(&#039;/login/admin&#039;, &#039;Auth\LoginController@showAdminLoginForm&#039;);
Route::get(&#039;/login/writer&#039;, &#039;Auth\LoginController@showWriterLoginForm&#039;);
Route::get(&#039;/login/marketer&#039;, &#039;Auth\LoginController@showMarketerLoginForm&#039;);
Route::get(&#039;/register/admin&#039;, &#039;Auth\RegisterController@showAdminRegisterForm&#039;);
Route::get(&#039;/register/writer&#039;, &#039;Auth\RegisterController@showWriterRegisterForm&#039;);
Route::get(&#039;/register/marketer&#039;, &#039;Auth\RegisterController@showMarketerRegisterForm&#039;);
Route::post(&#039;/login/admin&#039;, &#039;Auth\LoginController@adminLogin&#039;);
Route::post(&#039;/login/writer&#039;, &#039;Auth\LoginController@writerLogin&#039;);
Route::post(&#039;/login/marketer&#039;, &#039;Auth\LoginController@marketerLogin&#039;);
Route::post(&#039;/register/admin&#039;, &#039;Auth\RegisterController@createAdmin&#039;);
Route::post(&#039;/register/writer&#039;, &#039;Auth\RegisterController@createWriter&#039;);
Route::post(&#039;/register/marketer&#039;, &#039;Auth\RegisterController@createMarketer&#039;);
Route::view(&#039;/home&#039;, &#039;home&#039;)-&gt;middleware(&#039;auth&#039;);
Route::view(&#039;/admin&#039;, &#039;admin&#039;);
Route::view(&#039;/writer&#039;, &#039;writer&#039;);
Route::view(&#039;/marketer&#039;, &#039;marketer);در صورت احراز هویت ، نحوه هدایت کاربران باید اصلاح شود!این مسئله مهم است که نحوه تغییر مسیر کاربران در هنگام احراز هویت را اصلاح کنید. Laravel به طور پیش فرض همه کاربران معتبر را به home/ هدایت می کند. اگر تغییر مسیر را تغییر ندهیم ، با خطا مواجه خواهیم شد. برای حل این خطا فایل app/Http/Controllers/Middleware/RedirectIfAuthenticated.php را اصلاح کنید.// app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
&lt;?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated{
    public function handle($request, Closure $next, $guard = null){
        if ($guard == &amp;quotadmin&amp;quot &amp;&amp; Auth::guard($guard)-&gt;check()) {
            return redirect(&#039;/admin&#039;);
        }
        if ($guard == &amp;quotwriter&amp;quot &amp;&amp; Auth::guard($guard)-&gt;check()) {
            return redirect(&#039;/writer&#039;);
        }
        if ($guard == &amp;quotmarketer&amp;quot &amp;&amp; Auth::guard($guard)-&gt;check()) { 
            return redirect(&#039;/marketer&#039;);  
        }
        if (Auth::guard($guard)-&gt;check()) {
            return redirect(&#039;/home&#039;);
        }
        return $next($request);
    }
}میان افزار RedirectIfAuthenticated محافظ auth را به عنوان پارامتر دریافت می کند. این middleware هنگامی شروع می شود که می خواهیم از هر صفحه ای که برای کاربران معتبر قابل بازدید است، بازدید کنیم. سپس می توانیم نوع احراز هویت کاربر را تعیین کنیم و آنها را به ترتیب تغییر دهیم.کنترل کننده استثناء احراز هویت را اصلاح کنید!یک مورد آزار دهنده وجود دارد که هنگام هدایت کاربر اتفاق می افتد. شما انتظار دارید اگر مشتری سعی کند به writer/ دسترسی پیدا کند، اما تأیید نشده باشد ، به login/writer/  هدایت شود ، ولی این اتفاق نمی افتد. آنها به login/  سیستم هدایت می شوند که این چیزی نیست که ما می خواهیم. برای اطمینان از اینکه وقتی مشتری سعی می کند از writer/ بازدید کند ، او به login/writer/ هدایت شود یا همین روال برای پنل های دیگر کاربران ، باید کنترل کننده استثنا را اصلاح کنیم. فایل app/Exceptions را باز کنید و موارد زیر را اضافه کنید:// app/Exceptions/Handler.php
&lt;?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
[...]
use Illuminate\Auth\AuthenticationException;
use Auth;
[...]
class Handler extends ExceptionHandler{
    [...]
    protected function unauthenticated($request, AuthenticationException $exception){
        if ($request-&gt;expectsJson()) {
            return response()-&gt;json([&#039;error&#039; =&gt; &#039;Unauthenticated.&#039;], 401);
        }
       if ($request-&gt;is(&#039;admin&#039;) || $request-&gt;is(&#039;admin/*&#039;)) {
           return redirect()-&gt;guest(&#039;/login/admin&#039;);
       }
       if ($request-&gt;is(&#039;writer&#039;) || $request-&gt;is(&#039;writer/*&#039;)) {
           return redirect()-&gt;guest(&#039;/login/writer&#039;);
       }
      if ($request-&gt;is(&#039;marketer&#039;) || $request-&gt;is(&#039;marketer/*&#039;)) {  
          return redirect()-&gt;guest(&#039;/login/marketer&#039;); 
       }
       return redirect()-&gt;guest(route(&#039;login&#039;));
    }
}برای استفاده از این استثنا باید به یک نکته توجه کنید! برای تمامی مسیر های مربوط به پنل هر یک از کاربران از ویژگی prefix استفاده کنید و اول مسیر guard مربوط به آن دسته از کاربر را وارد کنید. به این دلیل که در این استثنا بر اساس مسیر، guard را اعمال میکنیم. اجرای پروژهحال میتوانید با دستورphp artisan serveپروژه خود را اجرا کرده و در آدرس http://localhost:8000مشاهده کنید. مراجع : pusher.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Fri, 07 Aug 2020 00:29:16 +0430</pubDate>
            </item>
                    <item>
                <title>مبحث Middleware در Laravel</title>
                <link>https://virgool.io/@negarjavadzadeh/%D9%85%D8%A8%D8%AD%D8%AB-middleware-%D8%AF%D8%B1-laravel-rvpza7qpcwgm</link>
                <description> Middleware in Laravelچرا Middleware؟تصور کنید یک سیستم برای ثبت دارایی های افراد پیاده سازی کرده اید. به طوری که فقط مدیران سیستم اجازه ثبت دارایی برای کاربران را دارند (خود کاربران نباید اجازه ثبت هیچ دارایی برای خود داشته باشند). برای این کار شما ابتدا فرمی را در پنل مدیر ایجاد می کنید و با استفاده از آن فرم برای کاربر دارایی ثبت میکنید. این فرم با استفاده از متد post و url ای که در پوشه route تعریف کرده اید عمل میکند. به طوری که url مربوط به آن فرم، متد مربوط به آن url را از controller اجرا میکند. که این متد مربوط به ذخیره دارایی در پایگاه داده مربوط به کاربر مورد نظر است. حال اگر کاربر url مربوط به صفحه ثبت دارایی را بداند، بدون این که مدیر سیستم باشد، میتواند برای خود یا دیگر کاربران، دارایی ثبت کند! که این مشکل بزرگی برای امنیت سیستم پیاده سازی شده است! این یکی از مشکلاتی است که در زمان استفاده از درخواست های HTTP به وجود می آید. برای حل این مشکل، لاراول مکانیزم Middleware را ارائه کرده است. تعریف Middleware(میان افزار)یک مکانیزم مناسب برای فیلتر کردن درخواستهای HTTP که وارد برنامه شما می شوند، است. به عنوان مثال ، Laravel شامل middleware ای است که تأیید اعتبار کاربر برنامه شما را تأیید می کند. در صورت عدم احراز هویت کاربر ، middleware، کاربر را به صفحه ورود به سیستم هدایت می کند. اما ، در صورت احراز هویت کاربر ، middleware به شما اجازه می دهد تا بیشتر به برنامه وارد شوید.میان افزارهای اضافی را می توان برای انجام انواع کارها علاوه بر تأیید اعتبار کاربر ، نوشت. چندین middleware در چارچوب Laravel وجود دارد ، از جمله middleware برای احراز هویت و محافظت از CSRF. همه این middlewareها در مسیر  /app/Http/Middleware قرار دارند.ساخت Middleware جدیداگر با لاراول آشنا باشید قطعا با دستورات php artisan آشنایی دارید!برای ساخت یک middleware جدید از دستورphp artisan make : middlewareاستفاده میکنیم. middleware ایجاد شده در مسیر  /app/Http/Middleware قرار دارد.php artisan help make:middlewareبا توجه به راهنمایی تصویر بالا میتوان از این دستور استفاده کرد. برای مثال برای ساخت یک middleware برای کنترل نقش مدیر از دستور زیر استفاده میکنیم.php artisan make : middleware IsAdminاین دستور یک کلاس IsAdmin جدید را در پوشه app/Http/Middleware شما قرار می دهد. در این middleware ، تنها در صورتی که نقش کاربر، مدیر باشد ، اجازه دسترسی به درخواست های بعدی را خواهیم داد. در غیر این صورت ، کاربران را به url پنل کاربر(user/) هدایت می کنیم. &lt;?php
namespace App\Http\Middleware;
use Closure;
class IsAdmin{
    /**
    * Handle an incoming request.
    *
    * @param \Illuminate\Http\Request $request
    * @param \Closure $next
    * @return mixed
    */
    public function handle($request, Closure $next){
        if (!$request-&gt;isAdmin) {
            return redirect(&#039;user&#039;);
        }
        return $next($request);
    }
}همان طور که در کد بالا مشاهده میکنید، اگر کاربر، admin نباشد، به مسیر user/ هدایت می شود. در غیر این صورت درخواست بیشتر به برنامه ارسال میشود. بعد از تایید شدن middleware درخواست بعدی callback می شود.بهتر است قبل از وارد شدن به برنامه ، از middleware به عنوان مجموعه ای از درخواست های HTTP استفاده کنید. هر لایه می تواند درخواست را بررسی کند و حتی آن را به طور کامل رد کند.همه middleware ها از طریق service container حل می شوند ، بنابراین شما می توانید وابستگی های مورد نیاز خود را در یک سازنده middleware تایپ کنید.قبل و بعد از Middlewareاین که آیا یک middleware پیش از درخواست یا بعد از درخواست اجرا شود ، به خود middleware بستگی دارد. به عنوان مثال ، middleware زیر قبل از درخواست توسط برنامه ، وظایفی را انجام می دهد:&lt;?php
namespace App\Http\Middleware;
use Closure;
class BeforeMiddleware{
    public function handle($request, Closure $next){
        // Perform action
        return $next($request);
    }
}در حالی که ، این middleware بعد از اینکه درخواست توسط برنامه درخواست شد ، وظیفه خود را انجام می دهد:&lt;?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware{
    public function handle($request, Closure $next){
        $response = $next($request);
        // Perform action
        return $response;
    }
}ثبت Middlewareمیان افزار سراسریاگر می خواهید یک middleware در طی هر درخواست HTTP به برنامه شما اجرا شود ، کلاس middleware را در ویژگی middleware$ کلاس app/Http/Kernel.php وارد کنید.اختصاص Middleware به مسیرهااگر میخواهید middleware را به مسیرهای خاص اختصاص دهید ، ابتدا باید  middleware را یک کلید در فایل app/Http/Kernel.php خود اختصاص دهید. به طور پیش فرض ، ویژگی routeMiddleware$  این کلاس شامل ورودی هایی برای middleware همراه با Laravel است. برای اضافه کردن موارد دلخواه خود ، آن را در این لیست قرار دهید و کلید انتخابی خود را به آن اختصاص دهید:// Within App\Http\Kernel Class...

protected $routeMiddleware = [
     &#039;auth&#039; =&gt; \App\Http\Middleware\Authenticate::class,
     &#039;auth.basic&#039; =&gt; \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
     &#039;bindings&#039; =&gt; \Illuminate\Routing\Middleware\SubstituteBindings::class,
     &#039;cache.headers&#039; =&gt; \Illuminate\Http\Middleware\SetCacheHeaders::class,
     &#039;can&#039; =&gt; \Illuminate\Auth\Middleware\Authorize::class,
     &#039;guest&#039; =&gt; \App\Http\Middleware\RedirectIfAuthenticated::class,
     &#039;signed&#039; =&gt; \Illuminate\Routing\Middleware\ValidateSignature::class,
     &#039;throttle&#039; =&gt; \Illuminate\Routing\Middleware\ThrottleRequests::class,
     &#039;verified&#039; =&gt; \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];پس از تعریف middleware در   HTTP kernel ، شما می توانید از متد middleware برای اختصاص middleware به یک مسیر استفاده کنید:Route::get(&#039;user/profile&#039;, function () {
    //
})-&gt;middleware(&#039;auth&#039;);همچنین میتوانید چندین middleware را به مسیر اختصاص دهید:Route::get(&#039;/&#039;, function () {
    //
})-&gt;middleware(&#039;first&#039;, &#039;second&#039;);در هنگام اختصاص middleware ، شما همچنین می توانید نام کامل کلاس واجد شرایط را وارد کنید:use App\Http\Middleware\IsAdmin;
Route::get(&#039;admin/profile&#039;, function () {
    //
})-&gt;middleware(IsAdmin::class);هنگام اختصاص middleware به گروهی از مسیرها ، گاهی ممکن است لازم باشد كه از كاربرد middleware برای یك مسیر اختصاصی در گروه جلوگیری كنید. شما می توانید این روش را با استفاده از روش withoutMiddleware انجام دهید:use App\Http\Middleware\IsAdmin;
Route::middleware([IsAdmin::class])-&gt;group(function () {
    Route::get(&#039;/admin&#039;, function () {
        //
    });
    Route::get(&#039;/&#039;, function () {
    //
    })-&gt;withoutMiddleware([IsAdmin::class]);
});متد withoutMiddlewareفقط می تواند middleware مسیر را حذف کند و برای middleware سراسری کاربرد ندارد.گروه های Middlewareبعضی اوقات ممکن است بخواهید چندین middleware را با یک کلید واحد گروه بندی کنید تا آنها را آسان تر در مسیرها اختصاص دهید. شما میتوانید این کار را با استفاده از خاصیت  middlewareGroups$ در  kernel HTTP خود انجام دهید.لاراول دارای گروه های میان افزار WEB و API است که حاوی middleware رایج است که ممکن است بخواهید در مسیرهای  web UI و API  خود اعمال کنید:/**
* The application&#039;s route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
    &#039;web&#039; =&gt; [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    &#039;api&#039; =&gt; [
        &#039;throttle:60,1&#039;,
        &#039;auth:api&#039;,
    ],
];گروه های Middleware ممکن است به مسیرها و اقدامات کنترل کننده(controller) با استفاده از همان نحوی که middleware های فردی اختصاص داده شده باشد ، اختصاص یابد. مجدداً ، اختصاص دادن گروه های middleware بسیار راحت تر از اختصاص تعداد زیادی middleware به یک مسیر است:Route::get(&#039;/&#039;, function () {
    //
})-&gt;middleware(&#039;web&#039;);

Route::group([&#039;middleware&#039; =&gt; [&#039;web&#039;]], function () {
    //
});

Route::middleware([&#039;web&#039;, &#039;subscribed&#039;])-&gt;group(function () {
    //
});گروه middleware وب به طور خودکار توسط RouteServiceProvider به پرونده routes/web.php شما اعمال می شود.مرتب سازی Middlewareبه ندرت ، ممکن است شما برای اجرای middleware یک ترتیب خاص نیاز داشته باشید اما هنگام تعیین تکلیف در مسیر ، نظم آنها را کنترل نکنید. در این حالت ، شما می توانید اولویت میان افزار خود را با استفاده از ویژگی middlewarePriority$ در فایل app/Http/Kernel.php برنامه خود مشخص کنید:/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
    \Illuminate\Routing\Middleware\ThrottleRequests::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];پارامترهای Middlewareمیان افزار همچنین می تواند پارامترهای دیگری را دریافت کند. به عنوان مثال ، اگر برنامه شما قبل از انجام یک عمل خاص باید تأیید کند که کاربر تأیید شده دارای &quot;نقش&quot; خاصی است ، می توانید یک واسطه CheckRole ایجاد کنید که یک نام نقش را به عنوان یک آرگومان اضافی دریافت می کند.پارامترهای اضافی middleware بعد از آرگمان next$ به میان افزار منتقل می شود:&lt;?php
namespace App\Http\Middleware;
use Closure;
class CheckRole{
    /**
    * Handle the incoming request.
    *
    * @param \Illuminate\Http\Request $request
    * @param \Closure $next
    * @param string $role
    * @return mixed
    */
    public function handle($request, Closure $next, $role){
        if (! $request-&gt;user()-&gt;hasRole($role)) {
            // Redirect...
        }
        return $next($request);
    }
}پارامترهای Middleware ممکن است هنگام تعیین مسیر با جدا کردن نام Middleware و پارامترها با یک &#x27;:&#x27; مشخص شوند. چندین پارامتر باید با کاما مشخص شود:Route::put(&#039;post/{id}&#039;, function ($id) {
    //
})-&gt;middleware(&#039;role:editor&#039;);میان افزار (Middleware) خاتمه پذیربعضی اوقات ممکن است middleware بعد از ارسال پاسخ HTTP به مرورگر ، برخی کارها را انجام دهد. اگر یک روش خاتمه را در میان افزار خود تعریف کنید و سرور وب شما از FastCGI استفاده می کند ، پس از ارسال پاسخ به مرورگر ، روش terminate به طور خودکار فراخوانی می شود:&lt;?php
namespace Illuminate\Session\Middleware;
use Closure;
class StartSession{
    public function handle($request, Closure $next){
        return $next($request);
    }
    public function terminate($request, $response){
        // Store the session data...
    }
}متد خاتمه باید هم درخواست و هم پاسخ را دریافت کند. پس از تعریف middleware خاتمه پذیر ، باید آن را به لیست route یا middleware سراسری در فایل app/Http/Kernel.php اضافه کنید.هنگام فراخوانی متد terminate در middleware ، لاراول نمونه جدیدی از middleware را از             service container رفع می کند. اگر دوست دارید از همان نمونه میان افزار استفاده کنید که متد های handle و terminate فراخوانی شد ، middleware را با استفاده از متد Singleton در container ثبت کنید. معمولاً این کار باید به متد register در AppServiceProvider.php انجام می شود:use App\Http\Middleware\TerminableMiddleware;
/**
* Register any application services.
*
* @return void
*/
public function register(){
    $this-&gt;app-&gt;singleton(TerminableMiddleware::class);
}مراجع: laravel.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Wed, 05 Aug 2020 23:57:08 +0430</pubDate>
            </item>
                    <item>
                <title>مبحث Migration ها در Laravel</title>
                <link>https://virgool.io/@negarjavadzadeh/migration-in-laravel-ab66ednjcj48</link>
                <description>migrations in laravelچرا Migration ؟تصور کنید می خواهید یک پروژه لاراول را با دوستانتان توسعه دهید، برای این کار علاوه بر استفاده اشتراکی از کد های پروژه، میبایست طرحواره پایگاه داده ی پروژه را نیز با یکدیگر به اشتراک بگذارید! حال فرض کنید یکی از هم تیمی های شما قصد در ایجاد یک ستون در یک جدول در پایگاه داده دارد، برای اینکه در ادامه روند پروژه شما مشکلی پیش نیاید و تمام اعضای گروه آخرین نسخه به روز طرحواره پایگاه داده را داشته باشند، تمام اعضای گروه باید آن ستون را با همان نام و در همان جدول به صورت دستی ایجاد کنند. این همه کار فقط برای ایجاد یک ستون!!!این مشکل را لاراول با استفاده از migration  ها حل کرده است. در ادامه بیشتر با migration ها آشنا می شویم:ساخت یک Migration :اگر با لاراول آشنا باشید قطعا با دستورات php artisan  آشنایی دارید!برای ساخت یک migration از دستورphp artisan make : migration استفاده میکنیم. migration  ایجاد شده در مسیر database/migrations قرار دارد.php artisan help make:migrationبا توجه به راهنمایی تصویر بالا میتوان از این دستور استفاده کرد. برای مثال برای ساخت یک جدول به نام users ،از دستورphp artisan make:migration create_users_table  - -create=usersاستفاده میکنیم. در دستور بالا به چند نکته باید توجه کرد:1)قبل از قسمت options ما timestamp را create_users_table نام گذاری کردیم. این نام گذاری اختیاریست ولی بهتر است نام مناسب (قراردادی) در نظر بگیرید.2)اگر از قبل جدول users را دارید و فقط میخواهید اطلاعاتی را به آن migrateکنید بهتر است به جای create - - از table - - استفاده کنید.3)همان طور که گفته شد این فایل به طور پیش فرض در مسیر database/migrations ایجاد خواهد شد ولی اگر بخواهید مسیر آن را تغییر دهید میتوانید از path - - استفاده کنید. توجه داشته باشد که مسیر تعیین شده بایستی نسبت به مسیر پایه اپلیکیشن تعیین شود.ساختار Migrationیک کلاس migration دارای 2 متد up و down می باشد. که متد up برای افزودن جدول ها یا ستون ها و یا index های جدید در پایگاه داده استفاده می شود. و متد down معکوس متد up بوده و عملیات انجام گرفته توسط این متد را به عقب برمیگرداند. در هر 2 متد میتوان از سازنده طرحواره(schema builder) استفاده کرد.برای مثال در قطعه کد زیر نحوه ایجاد جدول users را با تعدادی ستون مشاهده میکنید. (البته توجه داشته باشید که این قطعه کد را داخل فایل migration ایجاد شده با دستورphp artisan make:migration create_users_table  - -create=usersقرار میدهیم.)&lt;?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration{
    /**
     * Run the migrations.
    *
    * @return void
    */
    public function up(){
        Schema::create(&#039;users&#039;, function (Blueprint $table) {
            $table-&gt;id();
            $table-&gt;string(&#039;name&#039;);
            $table-&gt;string(&#039;last_name&#039;)-&gt;nullable();
            $table-&gt;string(&#039;email&#039;)-&gt;unique();
            $table-&gt;string(&#039;password&#039;);
            $table-&gt;timestamps();
         });
    }
    /**
    * Reverse the migrations.
    *
    * @return void
    */
    public function down(){
        Schema::dropIfExists(&#039;users&#039;);
    }
}توجه کنید که به تعداد جدول های ایجاد شده (Schema::create) در متد up بایستی در متد down آن را به عقب برگردانید (Schema::dropIfExists). اجرای تمام Migration هابرای اجرای migration های موجود در database/migrations میبایست دستورphp artisan migrateرا در خط فرمان اجرا کنیم. که ترتیب اجرای این migration ها بر اساس timestamp های آن ها خواهد بود(تاریخ و ساعتی که موقع ایجاد، لاراول برای آن ها در نظر میگیرد).اجرای migration تحت هر شرایطی در مرحله ی production:برخی از عملیات migration مخرب است ، به این معنی که ممکن است باعث از بین رفتن اطلاعات شما شود. برای اینکه از اجرای این دستورات در برابر پایگاه داده در محیط production محافظت کنید ، قبل از اجرای دستورات از شما خواسته می شود تا تأیید کنید. برای مجبور کردن دستورات بدون درخواست تایید، از force - - استفاده کنید.                                                                                        php artisan migrate  - - forceبازگرداندن Migration ها به عقببرای برگرداندن آخرین عملیات migration ، می توانید از دستور برگشت استفاده کنید. این دستور آخرین دسته migration ها را برمیگرداند ، که ممکن است شامل چند فایل migartion باشد:php artisan migrate:rollbackبرای بازگرداندن تمام migration های اپلیکشن خود، میتوانید از دستور تنظیم مجدد  استفاده کنید.php artisan migrate:resetبرای بازگرداندن و اجرای مجدد تمام migration در یک دستور از دستور refresh استفاده میکنیم.php artisan migrate:refreshبرای حذف و اجرای مجدد تمام migration ها در یک دستور میتوان از دستور fresh استفاده کرد.php artisan migrate:freshبرای بازگرداندن تعداد محدودی از migration ها میتوانید از step - - استفاده کنید. برای مثال برای بازگرداندن 2 ،migration آخر از دستورphp artisan migrate:rollback - -step=2استفاده میکنیم. این گزینه برای تمام دستورات برگشت صادق است.توجه کنید که با اجرای این دستورها اطلاعات ثبت شده در جدول های بازگردانده شده حذف میشود. بنابراین برای ساخت دوباره اطلاعات داخل جدول از seed- - استفاده کنید.جدول هاساخت جدول جدید با schemaبرای ایجاد جدول جدید در پایگاه داده، از روش ایجاد در نمای Schema استفاده کنید.() create دو آرگومان را می پذیرد: اولین آرگمان، نام جدول است ، و دومی یک Closure است که یک شیء Blueprint را دریافت می کند که برای تعریف جدول جدید استفاده می شود. هنگام ایجاد جدول ، می توانید از هر یک از روش های ستون سازنده schema برای تعریف ستون های جدول استفاده کنید.Schema::create(&#039;users&#039;, function(Blueprint $table){
        $table-&gt;id();
  });بررسی وجود جدول / ستونبا استفاده از متد های hasTable و hasColumn می توانید وجود جدول یا ستون را بررسی کنید.if (Schema::hasTable(&#039;users&#039;)){  // your code }if (Schema::hasColumn(&#039;users&#039;, &#039;email&#039;)){ // your code }اتصال به پایگاه داده و گزینه های جدول:اگر می خواهید یک عملیات schema را بر روی اتصال بانک اطلاعاتی انجام دهید که اتصال پیش فرض شما نیست ، از متد اتصال استفاده کنید:Schema::connection(&#039;foo&#039;)-&gt;create(&#039;users&#039;, function(Blueprint $table){       
        $table-&gt;id();
  });شما می توانید از دستورات زیر برای سازندهschemaبرای تعریف گزینه های جدول استفاده کنید:موتور ذخیره سازی جدول (MySQL) را مشخص کنید.$table-&gt;engine = &#039;InnoDB&#039;;یک مجموعه کاراکتر پیش فرض تنظیم شده برای جدول (MySQL) مشخص کنید.$table-&gt;charset = &#039;utf8mb4&#039;;یک ترکیب بندی پیش فرض برای جدول (MySQL) مشخص کنید.$table-&gt;collation = &#039;utf8mb4_unicode_ci&#039;;یک جدول موقتی ایجاد کنید (به جز SQL Server).$table-&gt;temporary();تغییر نام جدول برای تغییر نام جدول موجود ، از روش تغییر نام استفاده کنید:Schema::rename($from, $to);حذف جدولبرای حذف یک جدول موجود ، می توانید از روش های drop یا dropIfExists استفاده کنید:Schema::drop(&#039;users&#039;);Schema::dropIfExists(&#039;users&#039;);تغییر نام جداول با کلیدهای خارجیقبل از تغییر اسم جدول، بایستی بررسی شود که تمامیconstraint های کلید خارجی موجود در جدول دارای اسم مشخص و صریح در فایل هایmigration هستند. در غیر این صورت لاراول خود یک اسم بر اساس قرارداد تخصیص می دهد و این امر سبب می شود constraint کلید خارجی به اسم قدیمی جدول اشاره کند.ستون هاساخت ستون هامیتوانید از متد table در نمای Schema برای به روزرسانی جداول موجود استفاده کنید. مانند متد  create ، متد table دو آرگومان را می پذیرد: نام جدول و Closureکه نمونه Blueprint را دریافت می کند که می توانید برای اضافه کردن ستون به جدول استفاده کنید.Schema::table(&#039;users&#039;, function (Blueprint $table) {
      $table-&gt;string(&#039;email&#039;);
});انواع ستون موجودسازندهschema، انواع مختلفی از ستون ها را در اختیار شما قرار می دهد که می توانید هنگام ساخت جداول خود استفاده کنید. من در این جا به برخی از آن ها اشاره میکنم.معادل(&#x27;table-&gt;bigIncrements(&#x27;id$            $table-&gt;id();                             معادل (&#x27;table-&gt;unsignedBigInteger(&#x27;user_id$$table-&gt;foreignId(&#039;user_id&#039;);مقدار ستون id (کلید اصلی) را با یک معادل &quot;عدد صحیح بزرگ بدون علامت&quot; افزایش می دهد.$table-&gt;bigIncrements(&#039;id&#039;);ستون معادل BIGINT  در پایگاه داده$table-&gt;bigInteger(&#039;votes&#039;);ستون معادل BLOB در پایگاه داده$table-&gt;binary(&#039;data&#039;);ستون معادل BOOLEAN در پایگاه داده$table-&gt;boolean(&#039;confirmed&#039;);ستون معادل CHAR در پایگاه داده با (حداکثر) طول مشخص.$table-&gt;char(&#039;name&#039;, 100);ستون معادل DATE  در پایگاه داده$table-&gt;date(&#039;created_at&#039;);ستون معادل DECIMAL در پایگاه داده  با دقت (کل رقم) و مقیاس (رقم اعشار).$table-&gt;decimal(&#039;amount&#039;, 8, 2);ستون معادل DOUBLE در   پایگاه داده  با دقت (کل رقم) و مقیاس (رقم اعشار).$table-&gt;double(&#039;amount&#039;, 8, 2);ستون معادل ENUM در پایگاه داده$table-&gt;enum(&#039;level&#039;, [&#039;easy&#039;, &#039;hard&#039;]);ستون معادل FLOAT  در پایگاه داده با دقت (کل رقم) و مقیاس (رقم اعشار).$table-&gt;float(&#039;amount&#039;, 8, 2);ستون معادل افزایش خودکار در پایگاه داده (کلید  اصلی).$table-&gt;increments(&#039;id&#039;);ستون معادل INTEGER در پایگاه داده$table-&gt;integer(&#039;votes&#039;);ستون معادل IP address در پایگاه داده$table-&gt;ipAddress(&#039;visitor&#039;);ستون معادل JSON در پایگاه   داده$table-&gt;json(&#039;options&#039;);ستون معادل JSONB در پایگاه داده$table-&gt;jsonb(&#039;options&#039;);ستون معادل LONGTEXT در پایگاه داده$table-&gt;longText(&#039;description&#039;);ستون  remember_token را با نوع داده ای (VARCHAR (100   و امکان NULL بودن به پایگاه داده اضافه می کند.$table-&gt;rememberToken();ستون معادل VARCHAR در پایگاه داده با (حداکثر) طول مشخص$table-&gt;string(&#039;name&#039;, 100);ستون معادل TEXT در پایگاه داده$table-&gt;text(&#039;description&#039;);ستون های  created_at و updated_at را به جدول پایگاه داده اضافه می کند.$table-&gt;timestamps(0);لیست کامل این ستون ها را میتوانید از Laravel.com مطالعه فرمایید.اصلاح کنندگان ستونعلاوه بر انواع ستون های ذکر شده در بالا ، چندین تغییر دهنده ستون وجود دارد که می توانید هنگام افزودن ستون به جدول پایگاه داده از آنها استفاده کنید. برای مثال ، برای ساختن ستون &quot;nullable&quot; ، می توانید از متد nullable استفاده کنید.Schema::table(&#039;users&#039;, function(Blueprint $table){
        $table-&gt;string(&#039;email&#039;)-&gt;nullable();
  });در زیر لیستی از برخی  column modifier های موجود را مشاهده می کنید. در این لیست index modifier ها لحاظ نشده است.ستون های INTEGER را به صورت خودکار افزایش میدهد. (کلید اصلی)-&gt;autoIncrement()مجموعه کاراکتر را برای ستون مشخص میکند (MySQL).-&gt;charset(&#039;utf8mb4&#039;)مقدار &quot;پیش فرض&quot; برای ستون را مشخص   میکند.-&gt;default($value)به طور پیش فرض مقدار NULL  را به ستون می دهد.-&gt;nullable($value = true)ستون های INTEGER را به صورت بدون علامت تنظیم کنید (MySQL)-&gt;unsigned()لیست کامل این ستون ها را میتوانید از Laravel.com مطالعه فرمایید.ویرایش ستون های جدولپیش از اقدام به ویرایش یک ستون، بایستی doctrine/dbal را به فایل composer.json اضافه کنید. با بهره گیری از کتابخانه ی Doctrine DBAL می توان وضعیت جاری ستون را مشخص کرده و query های مورد نیاز SQL را جهت اعمال تغییرات تعریف شده به ستون مورد نظر بکار برد.composer require doctrine/dbalمتد change به شما امکان می دهد نوع و ویژگی های ستون های موجود را تغییر دهید. به عنوان مثال ، شما ممکن است بخواهید اندازه یک ستون string را افزایش دهید. برای مثال، اندازه ستون name را با این دستور از 25 به 50 افزایش میدهیم:Schema::table(&#039;users&#039;, function(Blueprint $table){
       $table-&gt;string(&#039;name&#039;, 50)-&gt;change();
});یا حتی میتوان به آن ستون ویژگی nullable را افزود.Schema::table(&#039;users&#039;, function (Blueprint $table) {
     $table-&gt;string(&#039;name&#039;, 50)-&gt;nullable()-&gt;change();
  });توجه داشته باشید که فقط ستون های زیر قابل تغییر هستند.bigInteger, binary, boolean, date, dateTime, dateTimeTz, decimal, integer, json, longText, mediumText, smallInteger, string, text, time, unsignedBigInteger, unsignedInteger, unsignedSmallInteger , uuid.برای تغییر نام ستون ، می توانید از متد renameColumn در سازنده schema استفاده کنید.Schema::table(&#039;users&#039;, function (Blueprint $table){
       $table-&gt;renameColumn(&#039;from&#039;, &#039;to&#039;);
 });هر جدولی که ستون از نوع enum در خود داشته باشد، اجازه ی تغییر هیچ یک از ستون ها را به شما نمی دهد (این امکان در حال حاضر پشتیبانی نمی شود).حذف ستون های جدولبرای حذف ستون ، از متد dropColumn در سازنده schema استفاده کنید. قبل از حذف ستون ها از پایگاه داده SQLite ، شما نیاز دارید که doctrine/dbal را به فایل composer.json اضافه کنید.و دستور به روزرسانی composer را در ترمینال خود اجرا کنید تا کتابخانه نصب شود.Schema::table(&#039;users&#039;, function (Blueprint $table){
      $table-&gt;dropColumn(&#039;votes&#039;);
  });شما می توانید با دادن آرایه ای از نام ستون ها به متد dropColumn به عنوان آرگمان، چندین ستون را از یک جدول حذف کنید.Schema::table(&#039;users&#039;, function (Blueprint $table){
       $table-&gt;dropColumn([&#039;votes&#039;, &#039;avatar&#039;, &#039;location&#039;]);
  });فهرست ها(indexes)ساخت فهرستسازنده طرحواره Laravel از چندین نوع فهرست مختلف پشتیبانی می کند. مثال زیر یک ستون email جدید ایجاد می کند و مشخص می کند که مقادیر آن باید منحصر به فرد باشند. برای ایجاد index ، می توانیم متد unique را بر روی تعریف ستون قرار دهیم:$table-&gt;string(&#039;email&#039;)-&gt;unique();ممکن است بعد از تعریف ستون ، بخواهید index ایجاد کنید. مثلا:$table-&gt;string(&#039;email&#039;);
$table-&gt;unique(&#039;email&#039;);شما حتی می توانید مجموعه ای از ستون ها را به یک متد indexمنتقل کنید تا یک compound (یا composite) ایجاد شود:$table-&gt;index([&#039;account_id&#039;, &#039;created_at&#039;]);لاراول به طور خودکار یک نام index بر اساس جدول ، نام ستون ها و نوع فهرست تولید می کند، اما شما میتوانید یک آرگومان دوم را برای مشخص کردن نام indexخود به متد ارسال کنید:$table-&gt;unique(&#039;email&#039;, &#039;unique_email&#039;);انواع فهرست موجودهر متد index برای مشخص کردن نام index ، یک آرگومان دوم اختیاری را می پذیرد. در صورت خالی گذاشتن آرگمان دوم ، نام از نام جدول و ستون (های) مورد استفاده برای index و همچنین نوع index گرفته می شود.یک کلید اصلی را اضافه می کند.$table-&gt;primary(&#039;id&#039;);کلیدهای composite را اضافه می کند.$table-&gt;primary([&#039;id&#039;, &#039;parent_id&#039;]);اندیس منحصر به فرد اضافه می کند.$table-&gt;unique(&#039;email&#039;);اندیس ساده اضافه می کند.$table-&gt;index(&#039;state&#039;);اندیس مخصوص اضافه می کند. (ب جز SQLite)$table-&gt;spatialIndex(&#039;location&#039;);لاراول از مجموعه کاراکتر utf8mb4 به صورت پیش فرض استفاده می کند ، که شامل پشتیبانی از ذخیره &quot;emojis&quot; در پایگاه داده نیز می باشد. اگر نسخه ای از MySQL قدیمی تر از نسخه 5.7.7 یا MariaDB قدیمی تر از نسخه 10.2.2 را اجرا می کنید ، ممکن است لازم باشد که طول رشته پیش فرض تولید شده توسط migration ها را به صورت دستی پیکربندی کنید تا MySQLبتواند برای آنها index ایجاد کند. شما می توانید با فراخوانی متد Schema::defaultStringLength از AppServiceProvider خود پیکربندی کنید.use Illuminate\Support\Facades\Schema;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(){
      Schema::defaultStringLength(191);
}یا می توانید گزینه innodb_large_prefix را برای پایگاه داده خود فعال کنید. برای راهنمایی در مورد نحوه فعال سازی صحیح این گزینه به مستندات پایگاه داده خود مراجعه کنید.تغییر نام فهرست(index)برای تغییر نام یک فهرست ، می توانید از متد renameIndex استفاده کنید. این روش نام index فعلی را به عنوان اولین آرگومان و نام جدید مورد نظر به عنوان آرگومان دوم خود می پذیرد.$table-&gt;renameIndex(&#039;from&#039;, &#039;to&#039;);حذف فهرست(index)برای حذف یک index ، باید نام index را مشخص کنید. به طور پیش فرض ، Laravel به طور خودکار یک نام index را بر اساس نام جدول ، نام ستون فهرست شده و نوع فهرست اختصاص می دهد(اسم جدول، اسم ستون فهرست شده و نوع آن فهرست را به صورت زنجیره ای به هم متصل می کند). در اینجا چند مثال آورده شده است.یک کلید اصلی را از جدول &quot;users&quot; حذف می کند.$table-&gt;dropPrimary(&#039;users_id_primary&#039;);یک فهرست منحصر به فرد را از جدول &quot;users&quot; حذف می کند.$table-&gt;dropUnique(&#039;users_email_unique&#039;);فهرست اصلی را از جدول &quot;geo&quot; حذف می کند.$table-&gt;dropIndex(&#039;geo_state_index&#039;);یک فهرست مخصوص را از جدول &quot;geo&quot; (به جز SQLite)   حذف می کند.$table-&gt;dropSpatialIndex(&#039;geo_location_spatialindex&#039;);اگر مجموعه ای از ستون ها را به متد ای منتقل کنید که index ها را حذف می کند ، در آن صورت برای اندیس ها بر اساس اسم جدول، ستون و نوع کلید اسم قراردادی ایجاد می شود.Schema::table(&#039;geo&#039;, function(Blueprint $table){
      $table-&gt;dropIndex([&#039;state&#039;]); // Drops index &#039;geo_state_index&#039;
  });محدودیت های کلید خارجی(Foreign Key)لاراول همچنین امکان افزودن محدودیت کلید خارجی در جدول را فراهم می آورد. کلید خارجی برای تعریف و حفظ ارتباط بین جداول در پایگاه داده بکار می رود.  برای مثال یک ستون user id در جدول posts ایجاد می کنیم که به ستون id در جدول users اشاره می کند.Schema::table(&#039;posts&#039;, function(Blueprint $table){
     $table-&gt;unsignedBigInteger(&#039;user_id&#039;);
     $table-&gt;foreign(&#039;user_id&#039;)-&gt;references(&#039;id&#039;)-&gt;on(&#039;users&#039;);
  });از آنجا که این syntax ترجیحا&quot; درازاست ، Laravel روشهای مختصرتری را ارائه می دهد که با استفاده از قرارداد یک تجربه بهتر برای توسعه دهنده رقم میزند. مثال بالا می تواند به صورت زیر نوشته شود:Schema::table(&#039;posts&#039;, function (Blueprint $table){
        $table-&gt;foreignId(&#039;user_id&#039;)-&gt;constrained();
  });در این جا به جای (&#x27;references(&#x27;id&#x27;)-&gt;on(&#x27;users از foreignId  و ()constrained استفاده میکند. که foreignId معادل unsignedBigInteger است. اگر نام ستون موجود در جدول را که اشاره خواهد کرد را براساس قرارداد (زنجیره ای از نام جدول اشاره شده و ستون مورد نظر) انتخاب کرده اید، میتوانید ()constrained را بدون آرگمان استفاده کنید ولی اگر نام ها را بر اساس قرار داد انتخاب نکرده اید، بایستی نام جدولی که به آن اشاره میکنید را به عنوان آرگمان به ()constrained ارسال کنید.همچنین می توانید عملکرد مورد نظر را برای ویژگی های &quot;on delete&quot; و &quot; on update&quot; محدودیت مشخص کنید.$table-&gt;foreignId(&#039;user_id&#039;) -&gt; constrained() -&gt; onDelete(&#039;cascade&#039;);ویژگی&#x27;cascade&#x27;به این معنی است که با حذف (یا به روزرسانی) ردیف parent، ستون child نیز تغییر کند و به هم وابسته باشند.برای حذف کردن یک کلید خارجی ، می توانید از متد dropForeign استفاده کرده و محدودیت کلید خارجی را حذف کنید تا به عنوان یک آرگومان حذف شود. محدودیت های کلید خارجی از همان علامت گذاری به عنوان index استفاده می کنند ، بر اساس نام جدول و ستون های موجود در محدودیت ، و پس از آن پسوند  &quot;foreign_&quot;:$table-&gt;dropForeign(&#039;posts_user_id_foreign&#039;);یا می توانید یک مقدار از نوع آرایه ارسال کنید که برای حذف کلید خارجی به صورت خودکار از اسم قراردادی محدودیت کلید خارجی استفاده می کند.$table-&gt;dropForeign([&#039;user_id&#039;]);با استفاده از متدهای زیر می توانید محدودیت های کلیدی خارجی را در migration خود فعال یا غیرفعال کنید:Schema::enableForeignKeyConstraints();Schema::disableForeignKeyConstraints();پایگاه داده SQLite به طور پیش فرض محدودیت های کلید خارجی را غیرفعال می کند. هنگام استفاده از SQLite ، قبل از تلاش برای ایجاد آنها در migration ، اطمینان حاصل کنید که پشتیبانی کلید خارجی را در پیکربندی پایگاه داده خود فعال کنید. علاوه بر این ، SQLite تنها با ایجاد جدول از کلیدهای خارجی پشتیبانی می کند و نه هنگام تغییر جدول.مراجع: laravel.com</description>
                <category>نگار جوادزاده</category>
                <author>نگار جوادزاده</author>
                <pubDate>Mon, 15 Jun 2020 16:00:06 +0430</pubDate>
            </item>
            </channel>
</rss>