(ادامه)آموزش جامع کدایگنایتر CodeIgniter
مدل – ویو – کنترلر
کدایگنایتر بر پایهی الگوی توسعه Model-View-Controller بنا شده. MVC یه روند توسعه نرمافزاری که منطق برنامه رو از ظاهر و نمایشش جدا میکنه. در عمل، بهشما اجازه میده که صفحات وبسایتتون شامل حداقل اسکریپتنویسی ممکن باشن چون نمایش اطلاعات مستقل از اسکریپتهای PHP خواهد بود.
- Model بیانگر ساختار دادههای شماست. معمولاً کلاسهای مدل شامل توابعی هستن که به شما کمک میکنه اطلاعات رو از دیتابیس استخراج یا داخلش درج و بروزرسانی کنید.
- View اطلاعاتی هست که به کاربر نشون داده میشه. یه ویو معمولاً یه صفحهی وب خواهد شد ولی در CodeIgniter، یه ویو میتونه حتی بخشی از یه صفحه (مثل هدر یا فوتر) هم باشه. همچنین میتونه یه صفحه RSS یا هر نوع «صفحه»ی دیگه باشه.
- Controller بعنوان یه واسطه بین مدل، ویو و هر منبع دیگه که برای پردازش درخواست HTTP و تولید صفحه وب خروجی لازمه عمل میکنه.
کدایگنایتر تقریباً میشه گفت وابستگی کمی به MVC داره چون مدلها اجباری نیستن. اگه نیاز به جداسازی ندارین یا احساس میکنین مدیریت مدلها نیازمند پیچیدگی بیشتر از اون چیزی میشه که نیاز دارین، میتونین اونها رو نادیده بگیرین و فقط با کمک کنترلرها و ویوها برنامه خودتون رو بسازین. کد ایگنایتر به شما اجازه میده که اسکریپتهای شخصی خودتون رو هم بهکار بگیرین یا حتی کتابخانههای هستهی سیستم رو توسعه بدین که شما رو قادر به کار درمسیری میکنه که بیشتر باهاش احساس راحتی میکنید.
اهداف طراحی و معماری
هدف تیم توسعهی کدایگنایتر، کسب بیشترین کارآیی، قابلیت و انعطافپذیری در کمترین و سبکترین پکیجِ ممکنه. برای رسیدن به این هدف، عملیات سنجش کارآیی و سرعت، بازبینی و بازنویسی کدها و سادهسازی رو در هر مرحله از فرایند توسعهی کدایگنایتر انجام میدن و هرچیزی که هدف موردنظر رو پیش نبره، کنار میگذارن.
از دیدگاه فنی و معماری، CodeIgniter با اهداف زیر تولید شده:
- ایجاد شئ پویا: در کدایگنایتر، عناصر برنامه بجای اینکه سراسری کار کنن، فقط در زمانی که درخواست بشن بارگذاری میشن و دستورالعملهاشون اجرا میشه. هیچ فرضی توسط سیستم درخصوص اینکه چه ابزارهایی لازمه، بجز حداقل ملزوماتی که برنامه کار کنه درنظر گرفته نمیشه. بنابراین سیستم بطور پیشفرض خیلی سبکه. رویدادهایی که توسط درخواست HTTP اتفاق میفتن و کنترلرها و ویوهایی که طراحی میکنید، تصمیم میگیرن که چهچیزی بارگذاری بشه.
- درجهی ترکیب ضعیف: درجهی ترکیب بهمعنای میزان تکیهی اجزای سیستم به همدیگه است. هرچقدر عناصر برنامه کمتر به همدیگه وابسته باشن، قابلیت استفادهی مجدد و انعطافپذیری سیستم بالاتر میره. هدف تیم توسعهی کدایگنایتر، یه سیستم غیروابسته است.
- منفردبودن عناصر: منفردبودن بهمعنای میزان متمرکزبودن عناصر روی یه هدف مشخص و محدوده. در CodeIgniter هر کلاس و توابعش بهمیزان زیادی مستقل و خودمختار هستن که اجازهی بیشترین کارآیی رو میده.
کدایگنایتر یه سیستم پویا با درجهی ترکیب ضعیف و دارای عناصر منفرده که برای رسیدن به سادگی، انعطاف و کارآیی بالا با مصرف کم حافظه و پردازنده تلاش زیادی میکنه.
پیشنیازهای سرور
نسخهی PHP پیشنهادی ما 5.6 یا بالاتره؛ ولی حداقل نسخهای که میتونه برای کدایگنایتر مورد استفاده قرار بگیره 5.3.7 هست (هرچند شدیداً توصیه میکنیم که از چنین نسخه قدیمی PHP استفاده نکنید چون مشکلات احتمالی امنیتی و کارآیی و همچنین عدم دسترسی به امکانات نسخههای جدید PHP در انتظار شما خواهد بود).
یه پایگاه دادهها برای اغلب برنامههای وب موردنیازه. درحالحاضر CodeIgniter میتونه با دیتابیسهای زیر کار کنه:
- MySQL نسخه 5.1 بهبعد ازطریق افزونههای mysql (منسوخشده) و mysqli و PDO
- Oracle ازطریق افزونههای oci8 و PDO
- PostgreSQL ازطریق افزونههای postgre و PDO
- MS SQL ازطریق افزونههای mssql و sqlsrv (نسخه 2005 و بالاتر) و PDO
- SQLite ازطریق افزونههای sqlite (نسخهی 2) و sqlite3 (نسخهی 3) و PDO
- CUBRID ازطریق افزونههای cubrid و PDO
- Interbase/Firebird ازطریق افزونههای ibase و PDO
- ODBC ازطریق افزونههای odbc و PDO (باید بدونید که درحقیقت ODBC یه لایهی جداسازی محسوب میشه)
-
خودآموز
این خودآموز برای آشنایی شما با فریمورک CodeIgniter و اصول الگوی طراحی MVC ایجاد شده و به شما نحوهی ایجاد یه برنامهی سادهی کدایگنایتر رو بصورت مرحله به مرحله نشون میده.توی این خودآموز شما یه وبسایت خبری ساده میسازین. اینکار رو با نوشتن کدهایی که میتونن صفحات ثابت رو بارگذاری کنن شروع میکنین. در مرحلهی بعدی یه بخش اخبار درست میکنید که آیتمهای خبری رو از دیتابیس میخونه. درنهایت یه فرم برای ایجاد اخبار جدید در پایگاه دادهها میسازین.
این خودآموز روی محورهای زیر تمرکز داره:
- مبانی پایهی MVC
- اصول مسیریابی
- اعتبارسنجی فرم
- انجام کوئریهای اولیه دیتابیس با استفاده از Query Builder
- این خودآموز به چند بخش تقسیم شده که هرکدوم قسمت کوچکی از کاربرد فریمورک CodeIgniter رو نشون میدن. این بخشها شامل موارد زیر خواهد بود:
- معرفی (همین بخش) که یه دید کلی از چیزی که قراره بسازیم ارائه میده
- صفحات ثابت، که به شما یاد میده مفاهیم پایه کنترلرها، ویوها و مسیریابی چیه.
- بخش اخبار، جایی که شما شروع به استفاده از مدلها میکنید و برخی عملیات سادهی پایگاه دادهها رو انجام میدین.
- ایجاد خبر جدید، که شما رو با عملیات پیشرفتهتر دیتابیس و اعتبارسنجی فرم آشنا میکنه.
- جمعبندی، که به شما یکسری منبع برای مطالعهی بیشتر و سایر منابع موردنیاز رو معرفی میکنه.
-
صفحات ثابت
توی این قسمت فرض کردیم که شما کدایگنایتر رو دانلود و فریمورک رو نصب کردین. اولین چیزی که باید انجام بدین، آمادهسازی یه کنترلر برای مدیریت این صفحات ثابته. یه کنترلر یه کلاسه که به شما کمک میکنه کارها رو انجام بدین. درواقع درحکم چسب توی برنامه شماست. برای مثال وقتی درخواستی برای این آدرس میاد:میتونیم تصور کنیم که یه کنترلر بهاسم news وجود داره. متدی که داخل این کنترلر فراخوانی شده latest هست و وظیفهی اون، استخراج 10 آیتم خبری و نمایش اونها در صفحه است. در اغلب موارد توی MVC آدرسهایی با الگوی زیر میبینید:
بهمرور که الگوهای URL پیچیدهتر میشن، این ساختار ممکنه تغییر کنه ولی فعلاً تمام چیزی که لازمه بدونیم همینه.
یه فایل در مسیر application/controllers/Pages.php با محتوای زیر بسازین:
12345678910<?phpclassPagesextendsCI_Controller{publicfunctionview($page='home'){}}شما یه کلاس بهاسم Pages ساختین که یه متد بهاسم view داره و این متد یه پارامتر میگیره بهاسم $page. این کلاس از CI_Controller مشتق شده که معناش اینه که کلاس Pages شما به متدها و فیلدهای تعریفشده داخل کلاس CI_Controller (فایل system/core/Controller.php) دسترسی داره.
کنترلر درحقیقت مرکز هر درخواست در توی وباپلیکیشن شما خواهد بود. در اصطلاح فنی توی مباحث کدایگنایتر، بهش Super Object میگن. مثل هر کلاس PHP دیگه، شما داخل بدنهی کنترلر خودتون بهش با $this اشاره میکنید. با کمک $this میتونین کتابخانهها، ویوها و… رو بارگذاری کنید و کلاً به فریمورک دستور بدین.
حالا که اولین متد خودتون رو ساختین، وقتشه یه قالب خیلی ساده برای صفحات بسازیم. ما دو View ایجاد میکنیم (قالب صفحات) که نقش هدر و فوتر صفحه رو دارن.
هدر رو در مسیر application/views/templates/header.php با محتوای زیر بسازین:
123456<html><head><title>CodeIgniter Tutorial</title></head><body><h1><?phpecho$title; ?></h1>این هدر شامل کد HTML پایهای هست که شما میخواین قبل از بارگذاری ویوی اصلی قرار بگیره و ما یه عنوان داخلش گذاشتیم. همچنین متغیر $title رو هم نمایش میده که بعداً توی کنترلر تعریفش میکنیم. حالا یه فوتر در مسیر application/views/templates/footer.php با محتوای زیر تعریف کنید:
123<em>© <?phpechodate('Y') ?></em></body></html>اضافهکردن منطق به کنترلر
قبلاً یه کنترلر با متد view() ساختین. این متد یه پارامتر دریافت میکنه که اسم صفحهای هست که باید بارگذاری بشه. توی این پروژه میخوایم صفحات ثابت رو در مسیر application/views/pages قرار بدیم. توی این مسیر، دو فایل به اسامی home.php و about.php بسازین. داخل این فایلها متن دلخواهتون رو بنویسید – هرچی دوست دارین – و اون رو ذخیره کنید.برای بارگذاری این صفحات باید چک کنید که صفحات درخواستشده وجود داره یا نه:
12345678910111213publicfunctionview($page='home'){if(!file_exists(APPPATH .'views/pages/'.$page.'.php')) {// Whoops, we don't have a page for that!show_404();}$data['title'] = ucfirst($page);// Capitalize the first letter$this->load->view('templates/header',$data);$this->load->view('pages/'.$page,$data);$this->load->view('templates/footer',$data);}الان وقتی صفحهای وجود داشتهباشه بارگذاری میشه و قبل و بعدش هدر و فوتر قرار میگیره و به کاربر نمایش داده میشه. اگه صفحه وجود نداشته باشه هم خطای "404 Page not found" ظاهر میشه.
اولین خط در این متد چک میکنه که صفحه واقعاً وجود داشته باشه. تابع داخلی PHP یعنی file_exists() برای بررسی این موضوع بکار رفته. تابع show_404() یه تابع داخلی کدایگنایتر هست که صفحه خطای پیشفرض رو نمایش میده.
توی فایل هدر، یه متغیر $title تعریف کردیم که برای سفارشیکردن عنوان صفحه ازش استفاده کردیم. مقدار این متغیر توی متد view باید تعریف بشه ولی بجای اینکه مستقیماً داخل متغیری به این اسم بگذاریم، باید به عنصر title از آرایهی $data نسبت بدیم.
آخرین چیزی که باید انجام بشه، بارگذاری ویوها بهترتیبی هست که باید نمایش داده بشن. دومین پارامتر در متد view() برای ارسال مقادیر به ویو بهکار میره. هر مقدار داخل آرایهی $data به یه متغیر همنام با اندیسش تبدیل میشه. بنابراین مقدار $data[‘title’] توی کنترلر به متغیر معادل $title توی ویو تبدیل میشه.
مسیریابی
کنترلر الان کار میکنه! توی مرورگرتون مسیر [your-site-url]/index.php/pages/view رو باز کنید تا صفحهی home رو ببینید. وقتی index.php/pages/view/about رو باز کنید محتوای صفحه about ظاهر میشه که بازم هدر و فوتر داخلشه.با استفاده از قوانین مسیریابی اختصاصی، قابلیت اختصاص هر آدرسی به هر کنترلر و متدی رو خواهید داشت و از مفهوم و قیدوبند اصلی آزاد بشین:
اجازه بدین اینکار رو انجام بدیم. فایل مسیریابی رو از مسیر application/config/routes.php باز کنید و این دو خط رو بهش اضافه کنید و تمام کدهای دیگه که هر عنصری به آرایه $route اضافه میکنه رو حذف کنید:
12$route['default_controller'] ='pages/view';$route['(:any)'] ='pages/view/$1';CodeIgniter قوانین مسیریابی خودش رو از بالا به پایین توی این فایل میخونه و درخواست واردشده رو به اولین قانونی که مطابقت پیدا کنه نسبت میده. هر قانون یه عبارت باقاعده (سمتچپ) داره که به یه کنترلر و متدش که با اسلش / جدا شدن (سمتراست) نسبت داده میشه. وقتی یه درخواست وارد میشه، کدایگنایتر دنبال اولین مطابقت میگرده و کنترلر و متد متناسب با اون رو فراخوانی میکنه و پارامترهای متناسب رو هم براش میفرسته.
اطلاعات بیشتر رو میتونید توی مستندات مسیریابی مطالعه کنین.
در اینجا قانون دوم در $routes با هر درخواستی با کمک الگوی سراسری (:any) مطابقت پیدا میکنه و پارامتر رو به متد view() از کلاس Pages میفرسته.
حالا مسیر index.php/about رو باز کنید. آیا شما رو مستقیماً به متد view() توی کنترلر Pages برد؟ خارقالعاده است!
-
بخش اخبار
توی بخش قبلی ما برخی از مفاهیم پایه فریمورک رو با نوشتن یه کلاس که شامل صفحات استاتیک بود یاد گرفتیم. همچنین آدرسها رو با اضافهکردن قوانین مسیریابی پاکسازی کردیم. حالا وقتشه که محتوای پویا رو معرفی کنیم و شروع به استفاده از یه پایگاه دادهها کنیم.آمادهسازی مدل
بجای اینکه عملیات مربوط به دیتابیس رو مستقیماً توی کنترلر بنویسیم، کوئریها رو باید توی یه مدل قرار بدیم تا بشه بعداً از اونها بهراحتی استفادهی مجدد کرد. مدلها جایی هستن که شما اطلاعات رو از دیتابیس یا سایر منابع استخراج میکنین یا داخلش ثبت و ویرایش میکنید. مدلها نمایندهی دادههای شما هستن.پوشه application/models رو باز کنید و یه فایل جدید بهاسم News_model.php بسازین و این کد رو بهش اضافه کنید:
12345678<?phpclassNews_modelextendsCI_Model{publicfunction__construct(){$this->load->database();}}این کد شبیه به کدی که قبلاً توی کنترلر ساخته بودیم بنظر میاد. یه مدل جدید با مشتقشدن از کلاس CI_Model میسازه و کتابخانه دیتابیس رو بارگذاری میکنه. اینکار باعث میشه کلاس کار با دیتابیس ازطریق شئ $this->db قابل دسترسی بشه.
قبل از اینکه از دیتابیس چیزی رو بخونیم، باید جدول موردنظرمون برای اخبار رو بسازیم. توی دیتابیس خودتون این کوئری رو اجرا کنید:
12345678CREATETABLEnews (idint(11)NOTNULLAUTO_INCREMENT,titlevarchar(128)NOTNULL,slugvarchar(128)NOTNULL,text textNOTNULL,PRIMARYKEY(id),KEYslug (slug));حالا که دیتابیس رو دارین و یه جدول هم ساخته شده و مدلش هم آماده است، میتونیم متدهای لازم برای کار با دیتابیس رو بنویسیم. برای اینکار لایه خلاصهسازی پایگاه دادهها یا Database Abstraction Layer همراه کد ایگنایتر یعنی QueryBuilder بکار میره. اینکار باعث میشه کوئریها رو یکبار بنویسیم و از اونها توی تمام پایگاههای داده پشتیبانیشده که در ابتدای این تاپیک معرفی کردیم استفاده کنین. این کد رو به مدلتون اضافه کنید:
12345678910publicfunctionget_news($slug= FALSE){if($slug=== FALSE) {$query=$this->db->get('news');return$query->result_array();}$query=$this->db->get_where('news',array('slug'=>$slug));return$query->row_array();}با این کد میتونیم دو کوئری مختلف رو اجرا کنیم: میتونیم تمام رکوردها رو بخونیم یا فقط رکورد خاصی رو برحسب فیلد slug استخراج کنیم. اگه دقت کنید متوجه میشین که متغیر $slug ازنظر امنیتی فیلتر نشده. خود Query Builder کد ایگنایتر این کار رو برای شما انجام میده.
نمایش اخبار
حالا که کوئریها نوشته شدن، مدل باید با ویوهایی که میخوان اخبار رو نمایش بدن ترکیب بشه. اینکار رو میتونیم توی کنترلر Pages که قبلاً ساختیم انجام بدیم ولی برای اینکه کارها واضحتر پیش بره، یه کنترلر جدید بهاسم News میسازیم. یه فایل کنترلر جدید در مسیر application/controllers/News.php ایجاد کنید:
1234567891011121314151617181920212223<?phpclassNewsextendsCI_Controller{publicfunction__construct(){parent::__construct();$this->load->model('news_model');$this->load->helper('url_helper');}publicfunctionindex(){$data['news'] =$this->news_model->get_news();}publicfunctionview($slug= NULL){$data['news_item'] =$this->news_model->get_news($slug);}}با یه نگاه به کد متوجه میشین که شباهتهای بین فایلهایی که ایجاد کردیم وجود داره. اول از همه به سازنده دقتکنید. ابتدا سازنده کلاس والد (CI_Controller) رو صدا زدیم و بعد مدل news_model رو بارگذاری کردیم تا بتونیم از اون توی تمام متدهای این کنترلر ازطریق اسمش استفاده کنیم. همچنین توابع کمکی URL رو هم بارگذاری کردیم چون بعداً میخوایم ازش توی ویو استفاده کنیم.
در مرحله بعدی دو متد تعریف شده که تمام اخبار یا یه خبر خاص رو استخراج میکنن. توی متد دوم پارامتری بهاسم $slug تعریف شده که مدل از این متغیر برای استخراج خبری که باید برگردونه استفاده کرده.
تا اینجا دادهها از دیتابیس باکمک مدل استخراج شدن ولی هیچ چیزی نمایش داده نشده. قدم بعدی ارسال این دادهها به ویوهاست. متد index رو به اینشکل تکمیل کنید:
123456789publicfunctionindex(){$data['news'] =$this->news_model->get_news();$data['title'] ='News archive';$this->load->view('templates/header',$data);$this->load->view('news/index',$data);$this->load->view('templates/footer');}این کد تمام اطلاعات رو از دیتابیس دریافت میکنه و اونها رو به یه متغیر نسبت میده. همچنین عنوان صفحه رو به متغیر $data[‘title] اختصاص میده و تمام این اطلاعات برای ویوها ارسال میشه. باید یه ویوی جدید برای نمایش اخبار ایجاد کنیم. فایل application/views/news/index.php رو با محتوای زیر بسازین:
12345678<h2><?phpecho$title; ?></h2><?phpforeach($newsas$news_item): ?><h3><?phpecho$news_item['title']; ?></h3><divclass="main"><?phpecho$news_item['text']; ?></div><p><a href="<?php echo site_url('news/' . $news_item['slug']); ?>">View article</a></p><?phpendforeach; ?>همونطور که مشخصه، یه حلقه برای اخبار ایجاد شده و به کاربر نشون داده میشه. در اینجا ما از ترکیب PHP و HTML برای قالبمون استفاده کردیم. اگه ترجیح میدین از یه زبان قالب استفاده کنید، میتونین به کلاس مفسر قالب CodeIgniter یا یه مفسر غیررسمی (مثل Smarty یا Twig و…) مراجعه کنید.
قسمت نمایش کلی اخبار الآن کامله ولی صفحهای که هر خبر رو نمایش میده هنوز وجود نداره. مدلی که قبلاً طراحی کردیم بهشکلی بوده که میتونه بهراحتی برای این منظور هم مورد استفاده قرار بگیره. تنها نیاز شما اینه که یکم کد به کنترلر اضافهکنید و یه ویوی جدید بسازین. به کنترلر News برگردین و متد view رو بصورت زیر تکمیل کنید:
1234567891011121314publicfunctionview($slug= NULL){$data['news_item'] =$this->news_model->get_news($slug);if(empty($data['news_item'])) {show_404();}$data['title'] =$data['news_item']['title'];$this->load->view('templates/header',$data);$this->load->view('news/view',$data);$this->load->view('templates/footer');}بجای فراخوانی get_news بدون پارامتر، متغیر $slug ارسال شده که باعث میشه فقط یه رکورد مربوط به همون خبر رو برمیگردونه. تنها کاری که باقی مونده، ساخت ویوی مربوطه در مسیر application/views/news/view.php با این محتواست:
12<h2><?phpecho$news_item['title']; ?></h2><p><?phpecho$news_item['text']; ?></p>مسیریابی
بخاطر وجود قانون مسیریابی عمومی و کلی که قبلاً ساختیم، باید یه مسیر جدید برای مشاهده کنترلری که جدیداً ایجاد کردیم بسازیم وگرنه همهی درخواستها به متد view از کنترلر Pages منتقل میشه. فایل مسیریابی application/config/routes.php رو بهشکل زیر ویرایش کنید. اینکار باعث میشه مطمئن بشیم که درخواستهایی که با کلمه news شروع شدن به متد متناسب با خودشون در کنترلر News هدایت میشن. خط اول آدرسی حاوی عبارت Slug رو به متد view و خط دوم آدرس news رو به متد پیشفرض یعنی index هدایت میکنه. دقتکنید که هرچقدر قوانین مسیریابی که مینویسیم عمومیتر میشن، باید اونها رو پایینتر بنویسیم چون درصورت مطابقت، دیگه قوانین بعد از اونها درنظر گرفته نمیشه:1234$route['news/(:any)'] ='news/view/$1';$route['news'] ='news';$route['(:any)'] ='pages/view/$1';$route['default_controller'] ='pages/view';چند خبر بصورت دستی توی دیتابیس ثبت کنید و مرورگرتون رو به مسیر index.php/news هدایت کنید تا نتیجه رو ببینید.
-
جمعبندی
توی این خودآموز تمام چیزهایی که از یه سیستم مدیریت محتوای کامل انتظار دارین رو پوشش ندادیم ولی شما رو با مباحث مهمی مثل مسیریابی، نوشتن کنترلرها و مدلها و… آشنا کردیم. امیدوارم که با این خودآموز، یه دید کلی دربارهی برخیاز الگوهای طراحی اولیهی کدایگنایتر پیدا کرده باشین.
حالا که شما این خودآموز رو تکمیل کردین، پیشنهاد میکنیم بقیهی مستندات رو مطالعه کنین. CodeIgniter اغلب بخاطر مستندات کاملش مورد تمجید و تعریف قرار میگیره. از این موضوع بعنوان یه مزیت استفاده کنین و عناوین مربوط به «آشنایی» و «موضوعات عمومی» رو بهدقت مطالعه کنید. شما باید مرجع کلاسها و کتابخانههای کمکی رو در زمان نیاز مطالعه کنین.
هر برنامهنویس سطح متوسط PHP باید بتونه بهراحتی در عرض چند روز با کدایگنایتر کار کنه. اگه هنوز هم سؤالی دربارهی فریمورک یا کدهای خودتون داخلش دارین، میتونین:
-
آدرسهای URL در کدایگنایتر
بطور پیشفرض URL ها در CodeIgniter طوری طراحی میشن که هم برای موتورهای جستجو و هم برای کاربران مناسب باشن. بجای استفاده از روش QueryString که توی سیستمهای پویا رایجه، کداینگایتر از روش قسمتبندیشده استفاده میکنه:1example.com/news/articles/my-articleنقل قول:دقتکنید که میشه درصورت تمایل، روش معمولی QueryString رو هم فعال کرد که در ادامه توضیح میدیم.
قسمتهای URL
بخشهای مختلف URL از الگوی MVC پیروی میکنن که معمولاً در قالب این ساختاره:1example.com/class/function/ID- اولین قسمت معادل کلاس کنترلری هست که باید فراخوانی بشه
- دومین قسمت بیانگر تابعی هست که توی کنترلر باید صدا زده بشه
- قسمت سوم و قسمتهای اختیاری بعدی بیانگر شناسه و هر متغیری هستن که باید برای متد موردنظر از کنترلر ارسال بشه
کتابخانه URI و همچنین کلاس کمکی URL شامل توابعی هستن که کار با دادههای URI رو راحتتر میکنه. بهعلاوه URLهای شما میتونن با کمک قابلیت مسیریابی URI از حالت پیشفرض خارج بشن تا انعطافپذیری لازم رو بدست بیارین.حذف فایل index.php از آدرس
بطور پیشفرض فایل index.php توی URL ها وجود داره:1example.com/index.php/news/article/my-article
اگه ماژول mod_rewrite توی وبسرور Apache شما فعال باشه، میتونین بهراحتی این فایل رو با کمک یه فایل htaccess. از آدرس حذف کنید. کافیه یه فایل به این اسم توی مسیر ریشه سایتتون بسازین و این کد رو داخلش بنویسین:1234RewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule ^(.*)$ index.php/$1 [L,NC,QSA]
در اینجا هر درخواستی که مستقیماً به یه فایل یا پوشهی فیزیکی (مثلاً فایلهای CSS و JS و…) اشاره نکنه، به index.php ارجاع داده میشه.نقل قول:دقت کنید که این قوانین ممکنه برحسب تنظیمات سرور شما کار نکنه. اگه چنین شرایطی پیش اومد، با پشتیبانی هاستتون تماس بگیرین.
اضافهکردن یه پسوند به URL ها
توی تنظیمات config/config.php میتونین یه پسوند برای آدرسهای تولیدشده توسط کدایگنایتر مشخص کنید. برای مثال اگه یه URL اینطوری باشه:1example.com/products/views/shows
میتونین اگه بخواین یه پسوند مثل .html اضافه کنید که باعث بشه صفحهی شما بهشکل خاصی دیده بشه:1example.com/products/views/shoes.html
فعالکردن حالت QueryString
توی برخی مواقع ممکنه ترجیح بدین از همون روش معمولی برای آدرسها استفاده کنید:1index.php?c=products&m=view&id=345
CodeIgniter از این قابلیت هم درصورت تمایل شما، پشتیبانی میکنه و میتونین برای فعالکردنش ازطریق فایل config/config.php اقدام کنید:123$config['enable_query_strings'] = FALSE;$config['controller_trigger'] ='c';$config['function_trigger'] ='m';
اگه پارامتر enable_query_string رو با مقدار TRUE تنظیم کنید، این قابلیت فعال میشه و کنترلرها و متدهای داخلشون باکمک شناسههای trigger که براشون معرفی کردین قابل دسترسی میشن:1index.php?c=controller&m=methodنقل قول:نکته: اگه از QueryString استفاده میکنین، باید خودتون URLها رو بصورت دستی بسازین و نمیتونین از کلاسهای کمکی URL (و سایر توابع کتابخانهای که URL تولید میکنن، مثل برخی از کلاسهای کمکی فرمها) استفاده کنید چون این ابزارها بهنحوی طراحی شدن که با روش قسمتبندیشده برای URL کار کنن.
کنترلرها
Controller ها قلب برنامه شما هستن چون اونها هستن که تشخیص میدن چطور باید به درخواستهای HTTP جواب داده بشه.یه Controller چیه؟
یه کنترلر در تعریف ساده، یه فایل کلاس هست که بهنحوی نامگذاری شده که میشه ازطریق وب مورد دسترسی قرار بگیره. برای مثال آدرس زیر رو درنظر بگیرین:1example.com/index.php/blog/
توی این مثال، کدایگنایتر سعی میکنه یه کنترلر بهاسم Blog.php رو پیدا و اون رو بارگذاری کنه.نقل قول:هروقت اسم یه کنترلر با اولین قسمت یه URI مطابقت داشته باشه، بارگذاری میشه.
بگذارین امتحان کنیم: Hello World!
اجازه بدین یه کنترلر ساده بسازیم که بشه در عمل ببینیمش. با ویرایشگر متنی دلخواه خودتون یه فایل به اسم application/controllers/Blog.php بسازین و این کد رو داخلش بنویسین:123456789<?phpclassBlogextendsCI_Controller{publicfunctionindex(){echo'Hello World!';}}نقل قول:مهم: دقت کنید که حتماً باید Blog.php با حرف بزرگ B شروع بشه.
حالا این آدرس رو باز کنید:1example.com/index.php/blog
اگه کارها رو درست انجام داده باشین، باید پیغام Hello World! رو ببینید.نقل قول:مهم: اسامی کلاسها باید با حروف بزرگ شروع بشن.
این کد درسته:1234<?phpclassBlogextendsCI_Controller{}
ولی این کد اشتباهه:1234<?phpclassblogextendsCI_Controller{}
ضمناً همیشه کنترلرهای خودتون رو از کلاس CI_Controller مشتق کنید تا متدهای مفیدی که داخلش تعریف شده (مثل رندرکردن ویوها و بارگذاری عناصر برنامه مثل مدلها و…) ازش ارث برده بشه.متدها
توی مثال بالا، اسم متد index بود. متد index همیشه بطور پیشفرض اگه قسمت دوم URI خالی باشه بارگذاری میشه. یه راه دیگه برای نمایش پیغام «سلام دنیا!» اینه:1example.com/index.php/blog/index
قسمت دوم در URI مشخص میکنه کدوم متد از کنترلر فراخوانی بشه. بگذارین این مورد رو هم امتحان کنیم. یه متد جدید به کنترلرتون اضافه کنین:1234567891011121314<?phpclassBlogextendsCI_Controller{publicfunctionindex(){echo'Hello World!';}publicfunctioncomments(){echo'Look at this!';}}
حالا این آدرس رو باز کنید تا نتیجهی اجرای متد comments رو ببینین:1example.com/index.php/blog/comments/
ارسال قسمتهای URI به متدها
اگه URI شما شامل بیش از دو قسمت باشه، قسمتهای سوم به بعد بعنوان پارامتر به متد شما ارسال میشن. برای مثال فرض کنین یه URI به اینصورت داریم:1example.com/index.php/products/shoes/sandals/123
متد شما قسمتهای 3 و 4 (یعنی sandals و 123) رو بعنوان پارامتر دریافت میکنه:12345678910<?phpclassProductsextendsCI_Controller{publicfunctionshoes($type,$id){echo'<p>'.$type.'</p>';echo'<p>'.$id.'</p>';}}نقل قول:مهم: اگه از قابلیت مسیریابی URI استفاده میکنین، قسمتهایی که برای متدتون ارسال میشه، مواردی هست که توی قوانین مسیریابی مشخص کردین.
تعریف Controller پیشفرض
CodeIgniter رو میشه طوری تنظیم کرد که اگه URI ارسال نشده باشه، یه کنترلر پیشفرض رو بارگذاری کنه (مثل وقتی که URL ریشه سایتتون رو فراخوانی میکنین). برای مشخصکردن یه کنترلر پیشفرض، فایل تنظیمات config/routes.php رو باز کنید و این متغیر رو پیدا و تنظیم کنین:1$route['default_controller'] ='blog';
که در اینجا blog اسم کنترلری هست که میخواین استفاده بشه. اگه الان آدرس اصلی سایت یعنی صفحه index.php رو بدون هیچ قسمت اضافه در URI فراخوانی کنین، پیغام Hello World! بصورت پیشفرض نمایش داده میشه.برای اطلاعات بیشتر به بخش «مسیرهای رزروشده» در مستندات مسیریابی URI مراجعه کنید.
تغییر الگوی فراخوانی متدها
همونطور که گفتیم، قسمت دوم URI معمولاً برای مشخصکردن اینکه کدوم متد در کنترلر فراخوانی بشه بکار میره. کدایگنایتر به شما اجازه میده که این رفتار رو با کمک متد _remap تغییر بدین:1234publicfunction_remap(){// Some code here}نقل قول:مهم: اگه کنترلر شما شامل متد _remap باشه، همیشه فراخوانی میشه و اصلاً مهم نیست که توی URI شما چهچیزی وجود داشته باشه. درواقع این متد رفتار عادی که باعث میشه URI تصمیم بگیره که چه متدی فراخوانی بشه رو تغییر میده و به شما اجازه میده قوانین مسیریابی دلخواه خودتون رو برای متدها بنویسید بدون اینکه لازم باشه فایل مسیریابی اصلی رو اصلاح کنید. این قابلیت برای استفادهی مجدد از کنترلرتون توی پروژههای بعدی خیلی مفیده.
متدی که توسط URI درخواست شده (معمولاً قسمت دوم URI)، بعنوان پارامتر برای متد _remap ارسال میشه:12345678publicfunction_remap($method){if($method==='some_method') {$this->$method();}else{$this->default_method();}}
سایر قسمتهای اضافه بعد از اسم متد، برای متد _remap بصورت یه آرایه بعنوان پارامتر دوم ارسال میشن که اختیاریه. این آرایه میتونه با ترکیب متد داخلی PHP یعنی call_user_func_array بکار بره تا رفتار پیشفرض CodeIgniter رو شبیهسازی کنه. برای مثال:123456789publicfunction_remap($method,$params=array()){$method='process_'.$method;if(method_exists($this,$method)){returncall_user_func_array(array($this,$method),$params);}show_404();}
پردازش خروجی
کدایگنایتر یه کلاس خروجی داره که وظیفهی ارسال محتوای نهایی تولیدشده رو برای مرورگر کاربر، بعهده داره. درمورد این کلاس میتونین اطلاعات بیشتری رو توی مستندات ویوها و کلاس Output پیدا کنین. در برخی مواقع ممکنه بخواین بعد از تولید محتوای نهایی که به هر شکلی بدست اومده، یکسری کارها رو قبل از ارسال به مرورگر کاربر انجام بدین. CodeIgniter به شما اجازه میده یه متد بهاسم _output توی کنترلرهای خودتون داشته باشین که خروجی نهایی رو دریافت میکنه و میتونه کارهای لازم رو روی اون انجام بده.نقل قول:مهم: اگه کنترلر شما شامل متدی بهاسم _output باشه، همیشه بجای نمایش مستقیم خروجی، این متد توسط کلاس Output فراخوانی میشه و خروجی که قرار بوده برای کلاینت ارسال بشه، به این متد تحویل داده میشه. پارامتر اول این متد شامل محتوای نهاییه.
به این مثال دقت کنین:1234publicfunction_output($output){echo$output;}نقل قول:نکته: دقت کنید که متد _output شما دادهها رو در وضعیت نهایی خودش دریافت میکنه. بنابراین قبلاز اینکه خروجی به متد _output تحویل داده بشه، دادههای مربوط به سنجش سرعت و کارآیی و مصرف حافظه هم نمایش داده میشن و همچنین فایلهای Cache هم درصورتی که قابلیت کشکردن رو فعال کرده باشین، نوشته میشن و هدرها هم اگه از قابلیت مربوطه استفاده کرده باشین، برای مرورگر ارسال میشه. برای اینکه محتوای خروجی کنترلر شما بهدرستی کش بشه میتونین توی متد _output اینطوری بنویسید:
123if($this->output->cache_expiration > 0) {$this->output->_write_cache($output);}
اگه از این قابلیت استفاده کنید، زمان اجرای صفحه و آمار مربوط به مصرف حافظه ممکنه دقیق نباشن چون هر پردازش بعدی که داخل این متد روی خروجی انجام بدین رو درنظر نمیگیرن. بعنوان یه راه دیگه برای کنترل خروجی قبلاز هرگونه پردازش نهایی، متدهای موجود در کتابخانهی خروجی رو نگاه کنین.
متدهای خصوصی
در برخی مواقع ممکنه بخواین یکسری متدهای کنترلر از دسترسی عمومی خارج بشه. برای رسیدن به چنین منظوری، کافیه خیلی ساده، اون متدها رو بصورت private یا protected تعریف کنین تا بعنوان یه درخواست URL مورد پردازش قرار نگیرن. برای مثال میتونین یه متد به این شکل داشته باشین:1234privatefunction_utility(){// Some code}
هر تلاشی برای دسترسی به این متد منجر به خطای 404 میشه:1example.com/index.php/blog/_utility/نقل قول:نکته: قراردادن یه Underscore (کارکتر _) قبل از اسم متد هم جلوی فراخوانی اون رو میگیره. این یه قابلیت مربوط به نسخههای قدیمی کدایگنایتر هست که بخاطر حفظ سازگاری اسکریپتهای قدیمی با نسخههای جدید فریمورک، همچنان باقی مونده.
سازماندهی کنترلرها در پوشههای فرعی
اگه دارین یه برنامه بزرگ میسازین، ممکنه بخواین یه ساختار سلسلهمراتبی برای کنترلرهای خودتون توی پوشههای تودرتو ایجاد کنین. CodeIgniter به شما اجازهی چنین کاری رو میده.خیلی ساده کافیه پوشههای فرعی رو داخل مسیر application/controllers ایجاد کنید و کلاسهای کنترلر خودتون رو داخلشون ذخیره کنین. وقتی از این قابلیت استفاده کنین، اولین قسمت توی URI باید پوشه رو مشخص کنه. برای مثال اگه کنترلر شما در این مسیر باشه:
1application/controllers/products/Shoes.phpبرای فراخوانی این کنترلر باید URI شما شبیه این باشه:
1example.com/index.php/products/shoes/show/123
هرکدوم از پوشههای فرعی میتونن یه کنترلر پیشفرض داشته باشن که اگه URL فقط شامل اسم پوشه بود، اون کنترلر فراخوانی بشه و اسم این کنترلر باید با اسمی که توی تنظیمات config/routes.php تحتعنوان default_controller مشخص کردین یکسان باشه.ضمناً با کمک قابلیت مسیریابی URI میتونین درصورت تمایل، آدرسها رو بهنحوی اصلاح کنین که اسامی پوشههای فرعی دیده نشه.
سازندههای کلاس
اگه بخواین از یه سازنده توی هرکدوم از کنترلرهای خودتون استفاده کنین، باید این کد رو داخل سازندهی خودتون بگذارین:1parent::__construct();
علت این موضوع اینه که سازندهی شما داره سازندهی کلاس والد یعنی CI_Controller رو رونویسی میکنه و اگه بخواین کنترلر کدایگنایتر بهشکل درست کار کنه باید سازندهی والد رو فراخوانی کنین. برای مثال:12345678910<?phpclassBlogextendsCI_Controller{publicfunction__construct(){parent::__construct();// Your own constructor code}}
سازندهها در مواقعی که میخواین یکسری مقادیر پیشفرض تنظیمکنین یا یکسری کارها رو وقتی که کلاس شما فراخوانی میشه و یه شئ ازش ساخته میشه، مفید هستن. سازندهها نمیتونن چیزی رو بعنوان نتیجه برگردونن ولی میتونن یکسری کارها رو بصورت پیشفرض انجام بدن.اسامی رزروشده برای متدها
از اونجا که کلاسهای کنترلر شما از کلاس Controller پیشفرض کدایگنایتر مشتق میشن، باید دقت کنید که اسم متدهای خودتون رو مشابه متدهایی که توی اون کلاس تعریفشده درنظر نگیرین چون دراینصورت متدهای شما متدهای کلاس والد رو رونویسی میکنن. فهرست اسامی رزروشده برای برای دیدن یه فهرست کامل بررسی کنید.نقل قول:مهم: شما هیچوقت نباید اسم یه متد رو همنام با کلاسش بگذارین. اگه اینکار رو انجام بدین و متد __construct توی اون کلاس وجود نداشته باشه، اونوقت متد index بعنوان سازندهی کلاس فراخوانی میشه! این قابلیت بخاطر سازگاری PHP با نسخهی قدیمی یعنی PHP4 توسط خود زبان PHP درنظر گرفته شده.
تمام شد!
توضیحاتی که گفتیم، بصورت خیلی خلاصه شامل تمام چیزهایی بود که باید درمورد کنترلرها میدونستین.
اسامی رزروشده
برای کمک به شما، کدایگنایتر یکسری توابع، متدها، کلاسها و متغیرهایی رو در عملیات داخلی خودش تعریف کرده. بخاطر همین، بعضی از اسامی رو نمیشه توسط برنامهنویس بکاربرد چون قبلاً مورداستفاده قرار گرفته. در اینجا فهرستی از اسامی رزروشده رو که نمیتونین استفاده کنین مشاهده میکنید.
اسامی کنترلرها
از اونجا که کلاسهای کنترلر از کلاس کنترلر اصلی برنامه مشتق میشن، باید مراقب باشین که اسم متدها رو مشابه متدهای کلاس اصلی بکار برین؛ درغیر اینصورت متدهای محلی شما، متدهایی که از کلاس والد بهارث رسیدن رو رونویسی میکنن. در اینجا فهرستی از اسامی رزروشده رو مشاهده میکنید که نباید اسم کنترلرتون رو یکی از اینها انتخاب کنید:
نقل قول:
CI_Controller
Default
index
توابع
نقل قول:
is_php()
is_really_writable()
load_class()
is_loeaded()
get_config()
config_item()
show_error()
show_404()
log_message()
set_status_header()
get_mimes()
html_escape()
remove_invisible_characters()
is_https()
function_usable()
get_instance()
_error_handler()
_exception_handler()
_stringify_attributes()
متغیرها
نقل قول:
$config
$db
$lang
ثابتها
نقل قول:
ENVIRONMENT
FCPATH
SELF
BASEPATH
APPPATH
VIEWPATH
CI_VERSION
MB_ENABLED
ICONV_ENABLED
UTF8_ENABLED
FILE_READ_MODE
FILE_WRITE_MODE
DIR_READ_MODE
DIR_WRITE_MODE
FOPEN_READ
FOPEN_READ_WRITE
FOPEN_WRITE_CREATE_DESTRUCTIVE
FOPEN_READ_WRITE_CREATE_DESTRUCTIVE
FOPEN_WRITE_CREATE
FOPEN_READ_WRITE_CREATE
FOPEN_WRITE_CREATE_STRICT
FOPEN_READ_WRITE_CREATE_STRICT
SHOW_DEBUG_BACKTRACE
EXIT_SUCCESS
EXIT_ERROR
EXIT_CONFIG
EXIT_UNKNOWN_FILE
EXIT_UNKNOWN_CLASS
EXIT_UNKNOWN_METHOD
EXIT_USER_INPUT
EXIT_DATABASE
EXIT__AUTO_MIN
EXIT__AUTO_MAX

