
توی دوره رایگان PHP، هر چیزی که برای حرفهای شدن نیاز داری رو یاد میگیری! از مفاهیم پایه تا پیشرفته، همراه با یه پروژه واقعی برای ساخت یه سایت مثل آپارات.
مشاهده بیشتر
توی این دوره با هم یه وبسایت خبری واقعی رو از صفر میسازیم! از طراحی دیتابیس و احراز هویت تا ساخت API و یه پنل مدیریت حرفهای، همه رو یاد میگیریم و آماده پروژههای واقعی میشی!
مشاهده بیشترمشخصات مقاله
آموزش Migrations در Laravel
پایگاه داده: Migrations
- مقدمه
- ایجاد Migration
- ساختار Migration
-
اجرای Migrations
- بازگردانی Migration ها به عقب
-
نحوه ی نوشتن migrations
- ایجاد جداول
- تغییر اسم / حذف جداول
- ایجاد ستون ها
- ویرایش ستون ها
- حذف ستون ها
- ایجاد اندیس
- حذف اندیس
- محدودیت های کلید خارجی (foreign key constraint)
مقدمه
Migrations به مثابه ی version control برای پایگاه داده ایفای نقش می کنند و این امکان را برای تیم برنامه نویسی فراهم می کند تا به راحتیschema ی پایگاه داده ی اپلیکیشن را بین اعضای تیم به اشتراک بگذارند. به عبارت دیگر migrations به اعضای تیم کمک می کند تا تغییرات پایگاه داده را تایید ثبت کنند و نیز همیشه یک نسخه ی بروز از پایگاه داده در اختیار داشته باشند.
migrations در راستای ساخت آسان (ساختار) schema برای پایگاه داده ی اپلیکیشن، همراه با schema builder (شِما ساز) چارچوب نرم افزاریLaravel بکار می رود.
schema facade فریم ورک Laravel از هر پایگاه داده ای پشتیبانی می کند و به شما امکان می دهد تا به راحتی جداول مورد نیاز را ایجاد و دستکاری کنید. در واقع این فریم ورک با تکیه بر قابلیت database-agnistic روشی مستقل از پایگاه داده برای ایجاد و اعمال تغییرات بر روی جدول فراهم می کند. (database-agnostic به قابلیت یک نرم افزار برای کار با هر سیستم مدیریت بانک اطلاعاتی اشاره دارد).
ایجاد Migration
به منظور ایجاد یک migration جدید کافی است دستور آرتیزانmake:migration را فراخوانی نمایید.
1 2 | php artisan make:migration create_users_table <button></button> |
migration ای که توسط این دستور ایجاد می شود به طور پیش فرض در پوشه یdatabase/migrations قرار می گیرد. اسم تمامی فایل هایmigration دارای یک timestamp می باشد که به شما اجازه می دهد تا ترتیب زمانی و اجرای migration ها را تشخیص دهید.
دو آپشن --table و --create را می توان جهت تعیین اسم جدول و اینکه آیا migration یک جدول جدید ایجاد می کند یا خیر مورد استفاده قرار داد (پارامتر --table برای تعیین جدولی که migration بر روی آن اعمال می شود و اگر قرار است migration یک جدول جدید ایجاد کند پارامتر --create را به انتهای دستور Artisan الحاق کنید). با تنظیم این آپشن ها صرفا migration stub file ایجاد شده را از پیش با جدول مشخص شده پر می کنیم (stub file: فایلی که به نظر کاربر مقیم بر روی دیسک هست اما در واقع به طور کامل یا جزئی بر روی سیستم ذخیره سازی دیگری قرار گرفته):
1 2 3 | php artisan make:migration add_votes_to_users_table --table=users php artisan make:migration create_users_table --create=users <button></button> |
اگر می خواهید یک مسیر سفارشی برای migration خود مشخص کنید، کافی است آپشن --path را به دستور make:migration اضافه نمایید. مسیر تعیین شده بایستی نسبت (relative) به مسیر پایه (base) اپلیکیشن تعیین شود.
ساختار Migration
یک کلاس migration دربردارنده ی دو متد می باشد: up و down. متد up جهت افزودن جداول، ستون ها یا اندیس های جدید به پایگاه داده بکار می رود، در حالی که متد down معکوس متد مزبور بوده و عملیات انجام گرفته توسط متد up را (به عقب) برمی گرداند.
داخل هر دوی این توابع می توان schema builder لاراول را برای ایجاد و ویرایش جداول به صورت صریح، مورد استفاده قرار داد. در زیر یک نمونه Migration ساده که جدولی به نام flights را ایجاد می کند، مشاهده می کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateFlightsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create( 'flights' , function (Blueprint $table ) { $table ->increments( 'id' ); $table ->string( 'name' ); $table ->string( 'airline' ); $table ->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop( 'flights' ); } } <button></button> |
اجرای migration ها
به منظور اجرای تمامی migration های اعمال نشده بر روی اپلیکیشن، کافی است دستور آرتیزان migrate را بکار ببرید. اگر از Homesteadاستفاده می کنید، بایستی این دستور را از داخل ماشین مجازی مذکور اجرا کنید:
1 2 | php artisan migrate <button></button> |
اگر در زمان اجرای migrations با خطای "class not found" مواجه شدید، کافی است دستورcomposer dump-autoload را اجرا کرده و فرمان migrate را مجدد فراخوانی نمایید.
اجرای migration تحت هر شرایطی در مرحله ی production
برخی از عملیات migration مخرب هستند، بدین معنی که ممکن است با اجرای آن ها اطلاعاتی را از دست بدهید. برای اینکه چنین دستورات و عملیاتی بر روی پایگاه داده ی اپلیکیشن در محیط production اجرا نشود، پیش از اجرای عملیات از شما تائیدیه برای اجازه ی اجرای آن ها درخواست می شود. حال برای اینکه migration بی چون و چرا و درخواست تائیدیه اجرا شود، از پارامتر --force استفاده می کنیم:
1 2 | php artisan migrate --force <button></button> |
بازگرداندن Migration ها به عقب
برای به عقب بازگرداندن (تغییرات) به قبل از آخرین عملیات migration انجام شده، کافی است دستور rollback را بکار ببرید. توجه داشته باشید که این دستور آخرین مجموعه عملیات migration اعمال شده بر روی برنامه (migration batch) را (که در کل چندین فایل migration را شامل می شود) به عقب برمی گرداند:
1 2 | php artisan migrate:rollback <button></button> |
دستور migrate:reset تمامی migration های اعمال شده بر روی اپلیکیشن شما را به عقب برمی گرداند:
1 2 | php artisan migrate:reset <button></button> |
اجرای rollback / migrate طی یک دستور واحد (بازگردانی و اجرای مجدد آن ها)
دستور migrate:refresh ابتدا تمامی migration های پایگاه داده را به عقب برگردانده و سپس دستور migrate را اجرا می کند. این دستور عملا کل پایگاه داده ی شما را از نو می سازد:
1 2 3 | php artisan migrate:refresh php artisan migrate:refresh --seed <button></button> |
نحوه ی نوشتن migrations
ایجاد جداول جدید
برای ایجاد جدول جدید در پایگاه داده، متد create را در Schema facade بکار ببرید. متد create دو آرگومان می پذیرد که اولی اسم جدول و دومی یک تابع Closure است. تابع Closure یک شی Blueprint به عنوان آرگومان پذیرفته که به وسیله ی آن جدول جدید را تعریف می کند:
1 2 3 4 | Schema::create( 'users' , function (Blueprint $table ) { $table ->increments( 'id' ); }); <button></button> |
برای تعریف ستون های جدول نیز می توانید هریک از column method های schema builder را در زمان ایجاد جدول بکار ببرید.
بررسی وجود ستون / جدول
با فراخوانی متد hasTable و hasColumn می توان به وجود یا عدم وجود جدول / ستون مورد نظر پی برد:
1 2 3 4 5 6 7 | if (Schema::hasTable( 'users' )) { // } if (Schema::hasColumn( 'users' , 'email' )) { // } <button></button> |
connection و storage engine
اگر می خواهید برای اجرای عملیات مربوط به schema از یک connection غیر پیش فرض استفاده کنید، توصیه می شود متد connectionرافراخوانی کنید:
1 2 3 4 | Schema::connection( 'foo' )->create( 'users' , function ( $table ) { $table ->increments( 'id' ); }); <button></button> |
به منظور انتخاب و تنظیم storage engine برای جدول مورد نظر، بایستی خاصیت (property) engine را در schema builder مقدار دهی کنید:
1 2 3 4 5 | Schema::create( 'users' , function ( $table ) { $table ->engine = 'InnoDB' ; $table ->increments( 'id' ); }); <button></button> |
تغییر نام / حذف جداول
به منظور تغییر نام جدول جاری می بایست متد rename را فراخوانی کنید:
1 2 | Schema::rename( $from , $to ); <button></button> |
جهت حذف جدول نیز می بایست متد drop یا dropIfExists را بکار ببرید:
1 2 3 | Schema::drop( 'users' ); Schema::dropIfExists( 'users' ); <button></button> |
تغییر نام جداول همراه با foreign key ها
قبل از تغییر اسم جدول، بایستی بررسی شود که تمامی constraint های کلید خارجی موجود در جدول دارای اسم مشخص و صریح در فایل هایmigration هستند. در غیر این صورت لاراول خود یک اسم بر اساس قرارداد تخصیص می دهد و این امر سبب می شود constraint کلید خارجی به اسم قدیمی جدول اشاره کند.
ایجاد ستون های جدید
به منظور بروز رسانی جدول جاری، متد table را در façade Schema بکار می بریم. همانند create، متد table دو آرگومان ورودی می پذیرد: 1. اسم جدول مورد نظر 2. تابع Closure با یک نمونه از Blueprint به عنوان ورودی که توسط آن ستون های جدید را به جدول اضافه می کنیم:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->string( 'email' ); }); <button></button> |
نوع ستون های قابل استفاده
schema builder لاراول از ستون های با نوع داده ای مختلف پشتیبانی می کند:
تعریف کنندگان ستون (Column Modifiers)
علاوه بر نوع ستون هایی که در جدول بالا مشاهده می کنید، column modifier های دیگری وجود دارد که می توانید در زمان افزودن ستون به جدول مورد استفاده قرار دهید. به عنوان مثال، برای افزودن امکان null پذیری به ستون مورد نظر می توان متد nullable را صدا زد:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->string( 'email' )->nullable(); }); <button></button> |
در زیر لیستی از تمامی column modifier های موجود را مشاهده می کنید. در این لیست index modifier ها لحاظ نشده است:
ویرایش ستون های جدول
پیش نیازها
پیش از اقدام به ویرایش یک ستون، بایستی dependency (وابستگی) doctrine/dbal را به فایل composer.json اضافه کنید. با بهره گیری از کتابخانه ی Doctrine DBAL می توان وضعیت جاری ستون را مشخص کرده و query های مورد نیاز SQL را جهت اعمال تغییرات تعریف شده به ستون مورد نظر بکار برد.
بروز رسانی ATTRIBUTE های ستون
متد change به شما اجازه می دهد نوع داده ای ستون جاری را به نوع دیگری تغییر دهید یا attribute های ستون را ویرایش نمایید. به عنوان مثال، شاید لازم باشد طول ستون رشته ای را افزایش دهید. در زیر طول ستون رشته ای name را از 25 به 50 تغییر می دهیم:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->string( 'name' , 50)->change(); }); <button></button> |
می توانید ستون را ویرایش کرده و به آن قابلیت پذیرش مقدار null را اعطا کنید:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->string( 'name' , 50)->nullable()->change(); }); <button></button> |
هر جدولی که ستون از نوع enum در خود داشته باشد، اجازه ی ویرایش هیچ یک از ستون ها را به شما نمی دهد (این امکان در حال حاضر پشتیبانی نمی شود).
تغییر اسم ستون ها
برای تغییر اسم ستون، می توانید متد renameColumn را در schema builder بکار ببرید. پیش از تغییر اسم ستون، لازم استdoctrine/dbal dependency را به فایل composer.json اضافه نمایید:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->renameColumn( 'from' , 'to' ); }); <button></button> |
تغییر اسم ستون در جدولی که دارای ستون از نوع enum هست، در حال حاضر پشتیبانی نمی شود.
حذف ستون ها از جدول
به منظور حذف یک ستون از جدول، متد dropColumn را در Schema builder فراخوانی نمایید:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->dropColumn( 'votes' ); }); <button></button> |
می توان چندین ستون را همزمان از یک جدول حذف کرد. برای این منظور آرایه ای از اسم ستون ها را به متد ذکر شده ارسال می کنیم:
1 2 3 4 | Schema::table( 'users' , function ( $table ) { $table ->dropColumn([ 'votes' , 'avatar' , 'location' ]); }); <button></button> |
پیش از حذف ستون از پایگاه داده ی SQLite، می بایست doctrine/dbal dependency را به فایل composer.json اضافه کرده و دستور composer update را در پنجره ی فرمان اجرا کنید تا کتابخانه ی مورد نظر نصب شود.
اگر از پایگاه داده ی SQLite استفاده می کنید، باید بدانید که حذف و ویرایش چندین ستون طی یک migration واحد امکان پذیر نیست.
ایجاد و افزودن اندیس
schema builder فریم ورک لاراول از انواع اندیس پشتیبانی می کند. ابتدا به مثالی توجه می کنیم که در آن مقادیر ستون بر اساس تعریف کوئری باید منحصربفرد باشد. برای ایجاد اندیس مورد نظر، کافی است متد unique را به انتهای تعریف ستون در کوئری الحاق کنیم:
1 2 | $table ->string( 'email' )->unique(); <button></button> |
یا می توانید اندیس را پس از تعریف ستون به صورت زیر ایجاد نمایید. مثال:
1 2 | $table ->unique( 'email' ); <button></button> |
حتی می توان آرایه ای از ستون ها را برای ایجاد اندیس ترکیبی به متد index ارسال نمود:
1 2 | $table ->index([ 'account_id' , 'created_at' ]); <button></button> |
Laravel خود یک اسم معقول برای اندیس ایجاد می کند، با این حال شما می توانید اسم دلخواه خود را به عنوان آرگومان دوم به متد ارسال نمایید:
1 2 | $table ->index( 'email' , 'my_index_name' ); <button></button> |
انواع اندیس مورد پشتیبانی
حذف اندیس
جهت حذف یک اندیس می بایست اسم اندیس را ارائه دهید. همان طور که در بالا گفته شد به صورت پیش فرض Laravel یک اسم مناسب به هریک از اندیس ها تخصیص می دهد. حال به منظور حذف اندیس مورد نظر بایستی اسم جدول، اسم ستون اندیس گذاری شده و نوع آن اندیس را به صورت زنجیره ای به هم متصل کنید. در جدول زیر نمونه هایی را مشاهده می کنید:
چنانچه آرایه ای از ستون ها را به متد حذف اندیس ارسال کنید، در آن صورت برای اندیس ها بر اساس اسم جدول، ستون و نوع کلید اسم قراردادی ایجاد می شود:
1 2 3 4 | Schema::table( 'geo' , function ( $table ) { $table ->dropIndex([ 'state' ]); // Drops index 'geo_state_index' }); <button></button> |
محدودیت های کلید خارجی (Foreign Key Constraints)
Laravel همچنین امکان افزودن محدودیت کلید خارجی در جدول را فراهم می آورد. کلید خارجی برای تعریف و حفظ ارتباط بین جداول در سطح پایگاه داده بکار می رود. یک ستون user id در جدول posts ایجاد می کنیم که به ستون id در جدول users اشاره می کند:
1 2 3 4 5 | Schema::table( 'posts' , function ( $table ) { $table ->integer( 'user_id' )->unsigned(); $table ->foreign( 'user_id' )->references( 'id' )->on( 'users' ); }); <button></button> |
می توانید عملیات دلخواه را برای property های on delete و on update محدودیت مورد نظر تعریف کنید:
1 2 3 4 | $table ->foreign( 'user_id' ) ->references( 'id' )->on( 'users' ) ->onDelete( 'cascade' ); <button></button> |
جهت حذف یک کلید خارجی از جدول، می توانید متد dropForeign را بکار ببرید. محدودیت های کلید خارجی نیز از همان قرارداد های نام گذاری اندیس ها پیروی می کنند. بنابراین جهت حذف کلید خارجی از جدول اسم جدول و ستون های مشمول محدودیت را ذکر کرده، سپس به انتهای اسم پسوند "_foreign را الصاق نمایید:
1 2 | $table ->dropForeign( 'posts_user_id_foreign' ); <button></button> |
یا می توانید یک مقدار از نوع آرایه ارسال کنید که برای حذف کلید خارجی به صورت خودکار از اسم قراردادی محدودیت کلید خارجی استفاده می کند:
1 2 | $table ->dropForeign([ 'user_id' ]); <button></button> |
می توانید محدودیت های کلید خارجی را داخل migration ها فعال یا غیرفعال نمایید. برای این منظور متدهای زیر را بکار ببرید:
1 2 3 | Schema::enableForeignKeyConstraints(); Schema::disableForeignKeyConstraints(); <button></button> |