آموزش Model و پایگاه داده در لاراول را در این قسمت با ما همراه باشید.
همانطور که در قسمت دوم آموزش لاراول اشاره کردیم فایلهای پیکربندی لاراول در پوشه config قرار گرفته اند. فایل .env
موجود در پوشه اصلی لاراول برای سهولت و مسائل امنیتی تنظیمات فریمورک مانند ارتباطات پایگاه داده، ایمیل و Cache را از شما دریافت میکند.
مطلب آشنایی با مفهوم پایگاه داده
اگر فایل database.php را از پوشه config باز کنیم تنظیمات پیکربندی پایگاه داده برای شما نمایان میشود. مهم ترین خط از این تنظیمات انتخاب سیستم پایگاه داده است که به شکل زیر است:
'default' => env('DB_CONNECTION', 'mysql'),
سیستم پایگاه داده پیش فرض موجود در لاراول MySql است. برای تغییر این سیستم از MySql به SQLite دو کار میتوانیم انجام دهیم.
1) عبارت فوق موجود در فایل database.php را از mysql به sqlite ویرایش کنیم.
2) در فایل .env
مقابل DB_CONNECTION عبارت sqlite را بنویسیم.
نکته: در تمرینهای این بخش از MySql استفاده میکنیم، برای تست کردن دستورات آموزش داده شده در ادامه تنظیمات DB_DATABASE
و DB_USERNAME
و DB_PASSWORD
را به درستی وارد کنید.
چرا برای ذخیره اطلاعات ویژه از فایل .env
استفاده میکنیم؟ دلیل این مساله این است که فایلهای .env
بدلیل شروع شدن با نقطه بوسیله Git بر روی سرور انتقال داده نمیشوند، بنابر این اگر پروژهای دارید که میخواهید آن را با دیگران به اشتراک بگذارید بهتر است از این فایل استفاده کنید تا اطلاعات محرمانه سرور شما فاش نشود!
نکته: اگر فایلها و پوشههایی دارید که نمیخواهید بر روی Git منتقل شود میتوانید اطلاعات را در فایل .gitignore
اضافه کنید.
آشنایی با Eloquent ORM
همان طور که در قسمت اول از آموزش لاراول خواندید Eloquent نام ORM مورد استفاده در Laravel است. در مبحث آشنایی با فریمورک ها نیز اشاره جامعی به کاربرد ORMها داشتیم و گفتیم ORM یا Object-relational mapping مهم ترین بخش هر فریمورک است.
استفاده از ORM موجود در Laravel مزایای زیر را برای شما به همراه دارد:
- امنیت Eloquent ORM بالاست و تقریبا نگران هک شدن از طریق پایگاه داده نباشید
- بازدهی عالی در فعالیتهای پیچیده
- سادگی در پیاده سازی پیچیده ترین روابط و استفاده آسان
- داشتن قابلیت مهاجرت به سیستمهای پایگاه داده متنوع
در لاراول به راحتی میتوانید سیستم خود را با سیستمهای پایگاه داده زیر را پیاده سازی کنید:
- MySQL
- Postgres
- SQLite
- SQL Server
البته سیستمهای پایگاه داده دیگر را نیز با نصب کردن کتابخانههای جانبی میتوان پیاده کرد. مانند:
لاراول و migrations
در مسیر databse -> migrations
فایلهایی ایجاد میشود که با استفاده از آنها به راحتی میتوان جداول پایگاه داده را ایجاد، روابط بین جداول را تعیین و در آنها هر نوع تغییری ایجاد کرد.
صرف نظر از این که سیستم پایگاه داده شما چیست این فایلها به سادگی جداول دیتابیس را برای شما ایجاد کرده و نرم افزار شما را آماده بهره برداری میکنند.
بخشی از یک فایل migration را در ادامه میبینید:
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
مثلا مانند سورس کد فوق با تعیین increments('id')
یک شناسه با نام ID و به صورت افزایش پذیر ایجاد میکنیم.
در خط دوم با تعیین string('name')
یک آیتم متنی با نام name ایجاد میکنیم.
در خط سوم با تعیین string('email')->unique()
آیتم email از نوع متنی و با unique یکتابودن آن را تضمین کنید.
در خط چهارم timestamps()
باعث ایجاد دو آیتم created_at و updated_at در پایگاه داده میشود.
در واقع میتوان گفت فایلهای migration زبان واحدی دارند که با آن دیگر لازم نیست زبان محاوره انواع سیستمهای پایگاه داده را یاد بگیرید.
به عنوان مثال نوع داده نوشتهها در SQlite برابر String در MySql و Oracle برابر Varchar است. ولی در این فایلها برای تعیین نوع نوشتهها تنها کافی است از string استفاده کنیم و در پیاده سازی خود Laravel با شناسایی نوع پایگاه داده این اطلاعات را تفسیر میکند.
برای ایجاد این فایلها در خط فرمان و در پوشه اصلی پروژه از دستور زیر استفاده میکنیم:
php artisan make:migration create_posts --create=posts
نکته: create_posts
و posts
نامهایی هستند که به دلخواه انتخاب میکنید.
اگر به پوشه migration مراجعه کنید خواهید دید یک فایل با نام تاریخ روز و در انتها create_posts_table ایجاد شده است. سورس این فایل به شرح زیر است:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePosts extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('posts');
}
}
در این فایل دو تابع up()
و down()
داریم. تابع up()
برای ایجاد جداول و down()
برای حذف جداول مورد استفاده قرار میگیرد. به صورت پیشفرض برای این جدول دو مقدار Id و timestamps ایجاد شد که همانطور که گفتیم timestamps دو آیتم created_at و updated_at را ایجاد میکند.
در پایین قصد داریم تابع up را به شکل زیر ویرایش کرده و آیتمهای جدیدی به آن بیفزاییم:
public function up()
{
Schema::create('posts', function (Blueprint $table){
$table->increments('id');
$table->timestamps();
$table->string('name');
$table->char('email', '22')->unique();
$table->integer('age')->unsigned();
$table->float('weight')->unsigned();
$table->boolean('disabled')->default(true);
});
}
آیتمهای فوق به ترتیب عبارتند از:
- خط 4: شناسه افزایشی id
- خط 5: همانطور که گفته شد دو آیتم created_at و updated_at
- خط 6: رشتهای برای ذخیره name
- خط 7: رشتهای 22 کاراکتری برای ذخیره email یکتا
- خط 8: ذخیره اعداد بدون علامت (unsigned) با نام age
- خط 9: ذخیره مقادیر عددی اعشاری بدون علامت با نام weight
- خط 10: ذخیره حالت True یا False در آیتم disabled
لیست دیگر Data Typeها و انواع داده را در این لینک ببینید.
بعد از ایجاد فایل migration با دستور زیر پایگاه داده را ایجاد کنید:
php artisan migrate
در زیر تصویر جدول posts را در phpMyAdmin میبینید:
ابزار Tinker در لاراول
ابزار Tinker برای مدیریت دیتابیس متصل به لاراول به این فریمورک افزوده شده است. اگر تنظیمات دیتابیس را در لاراول به درستی انجام داده باشید میتوانید از Tinker برای درج، ویرایش و حذف اطلاعات استفاده کرد.
با دستور زیر ابزار Tinker را باز میکنیم:
php artisan tinker
خط فرمان این ابزار مانند خط فرمان موجود در MySql امکان هر نوع کاری را برای ایجاد، ویرایش و حذف دادهها به شما میدهد.
پس از باز کردن ابزار tinker با دستور زیر مقادیری را به جدول posts بفرستید:
DB::table('posts')->insert(['created_at' => new DateTime, 'updated_at' => new DateTime, 'name' => 'hitos', 'email' => 'email@email.com', 'age' => 22, 'weight' => 2.2, 'disabled' => true]);
پس از insert کردن مقادیر به جدول posts با دستور زیر اطلاعات موجود در این جدول را فراخوانی میکنیم:
DB::table('posts')->get();
نتیجه مانند زیر خواهد بود:
با دستور زیر یک آیتم از جدول با شرط دریافت خواهد شد:
DB::table('posts')->where('name', 'name of post')->first();
در کامند بالا سعی در دریافت اولین آیتم با name برابر "name of post" داریم.
با دستور زیر با شرط تمام آیتمها با نام "name of post" را پاک میکنیم:
DB::table('posts')->where('name', 'name of post')->delete();
فراخوانی اطلاعات جداول در controller
در بالا آموختیم که چگونه با ابزار tinker مقادیری را به دیتابیس اضافه، و نمایش دهیم. در اینجا قصد داریم روش نمایش اطلاعات از دیتابیس را آموزش دهیم:
$posts= \DB::table('posts')->get();
return view('show', compact('posts'));
در سطر اول کلیه اطلاعات موجود در جدول posts را با متد get دریافت کردیم و در سطر دوم با return آنها را به فایل پوسته نمایشی show ارسال کردیم.
در فایل show.blade.php هم با کد زیر title کل پستها را لیست میکنیم:
<ul>
@foreach($posts as $post)
<li>{{ $post->name }}</li>
@endforeach
</ul>
نکته: همانطور که در بالا دیدیم برای صدا زدن آیتمهای موجود در جدول posts از $posts= \DB::table('posts')->get();
استفاده کردیم. چرا قبل از DB از \
استفاده کردیم؟ بکاسلش را حذف کرده با خطای زیر مواجه میشوید:
همانطور که در Controller صفحه میبینید یک namespace با نام namespace App\Http\Controllers;
برای صفحه تعریف شده است و وقتی قصد دارید از DB استفاده کنید، برنامه تصور میکند قصد دارید از این namespace برای یافتن سورس DB استفاده کنید، در صورتی که در این فایل تعریفی برای DB وجود ندارد. برای حل این مشکل دو راه حل دارید یا اینکه از بکاسلش استفاده کنید یا این که مسیر زیر را به بالای صفحه خود اضافه کنید:
use Illuminate\Support\Facades\DB;
ایجاد مدلها در لاراول
تا این جا با View و Controller از مدل MVC آشنا شدیم، و نوبت آن رسیده است که به ایجاد Model بپدازیم.
تا اینجا مستقیم و بدون واسطه اطلاعات را به پایگاه داده اضافه کرده و فراخوانی کردیم. در این قسمت مهم قصد داریم یک مدل برای جدول posts خود بسیازیم. در این جا پس از ایجاد فایلهای migration در خط فرمان از دستور زیر استفاده میکنیم:
php artisan make:model Post
توجه کنید با وجود این که نام جدول ما posts بود ولی داکیومنت و مستندات لاراول به ما میگوید که نام مدل را به صورت منفرد با حرف اول بزرگ وارد کنید، تا در آینده و در بروز رسانیهای لاراول با مشکل مواجه نشوید.
حال در ابزار tinker با دستور جدید میتوانید اطلاعات را فراخوانی کنید:
App\Post::all();
نکته: وقتی در ابزار tinker از DB::table('posts')->get();
استفاده میکردید خروجی مانند زیر بود:
ولی اگر از دستور App\Post::all();
استفاده کنید، خروجی مانند زیر خواهد بود:
در خروجی فوق و سطر چهارم میبینید برای استخراج اطلاعات از eloquent استفاده شده است، بر عکس و در روش قبلی tinker اطلاعات را به تنهایی و بدون eloquent استخراج میکرد.
کار با مدلها در Laravel
فایل Controller خود را به شکل زیر ویرایش میکنیم:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Post;
class MainController extends Controller
{
public function index()
{
echo Post::find(1);
}
}
همانطور که در بالا داریم با اضافه کردن use App\Post;
به Controller خود در واقع مدل Post را فراخوانی میکنیم.
در اولین سطر از تابع index خود با دستور echo Post::find(1);
از جدول Post یک آیتم با ID برابر 1 پیدا کرده و چاپ میکنیم. نتیجه به صورت یک آرایه Json در خروجی چاپ میشود.
می توان تابع index را به صورت زیر نیز پیاده سازی کرد:
public function index()
{
$post= Post::find(1);
return view('show', compact('post'));
}
در فایل show.blade.php از دستور زیر استفاده میکنیم تا نام آرایه json استخراج شده نمایش داده شود:
{{ $post->name }}
آشنایی با قابلیت Route Model Binding در لاراول
یکی از راه کارهای آسان فراخوانی آیتم از مدلها در لاراول استفاده از Route Model Binding است. برای استفاده از این قابلیت شما میتوانید به سادگی و بدون پرداختن به پیچیدگیهای فراخوانی آیتمها از مدل اطلاعات خود را صدا بزنید.
با فرض داشتن یک جدول و مدل برای postها در Router یک مسیر جدید مانند زیر ایجاد میکنیم:
Route::get('/page/{post}', 'MainController@page');
توجه کنید که درون براکت نام مدل خود را قرار میدهیم.
حال یک تابع با نام page و به شکل زیر ایجاد میکنیم:
public function page(Post $post)
{
return view('show', compact('post'));
}
در لایه نمایش show.blade.php دستور زیر را وارد کنید:
{{ $post->name }}
آدرس http://localhost:8000/page/1
را در مرورگر وارد میکنیم، و به سادگی خواهید دید آیتم name از جدول posts با idای برابر یک نمایش داده میشود.
اگر سوالی داشتید خوشحال میشویم در بخش نظرات با شما در ارتباط باشیم.
سلام و ممنون از آموزش های عالیتون
در هنگام کار با tinker و موقعی ک میخوام اطلاعات جدول رو get کنم با این پیغام مواجه میشم:
میشه راهنمایی کنین
احتمالا پسورد دیتابیس رو اشتباه ست کردید.