مسیریابی URI

مجتبی پاکزاد کدایگنایتر 3.1.9 در حال تکمیل رایگان

معمولا یک ارتباط یک‌به‌یک بین یک استرینگ URI و متد/کلاس کنترلر متناظرش وجود دارد. معمولا سگمنت‌ها در یک URI، الگویی به شکل زیر دارند:

example.com/class/function/id/

گرچه، در برخی موارد ممکن است بخواهید این رابطه را بازتعریف (remap) کنید به طوری که یک متد/ کلاس متفاوت بتواند به جای متد/کلاس متناظر با URL فراخوانی شود.

اصطلاحات فنی

ریمَپ (remap) بازتعریف URLها در فایل Route است. در واقع انتساب یک قانون برای تغییر مسیر پیش‌فرض یک URL را ریمَپ می‌گویند. در قسمت وایلدکارد، این مورد با مثال توضیح داده شده است.

برای مثال، فرض کنید می‌خواهید URLهایی مطابق با الگوی زیر داشته باشید:

example.com/product/1/
example.com/product/2/
example.com/product/3/
example.com/product/4/

در حالت عادی، سگمنت دومِ URL، برای نام متد رزرو شده است، اما در مثال بالا، سگمنت دوم به آی‌دی محصولات اختصاص یافته است. برای غلبه بر این، کدایگنایتر امکان بازتعریف هندلرِ URI را ارائه می‌دهد.

تنظیم قوانین مسیریابی شخصی

قوانین مسیریابی در فایل application/config/routes.php تعریف می‌شوند. در این فایل، یک آرایه با نام $route وجود دارد که امکان تعیین کردن معیارهای مسیریابی را ارائه می‌دهد. مسیرها می‌توانند هم با استفاده از وایلدکاردها و هم با استفاده از عبارت‌های باقاعده مشخص شوند.

وایلدکاردها

یک مسیر با استفاده از وایلدکارت احتمالا چیزی شبیه به خط زیر است:

$route['product/:num'] = 'catalog/product_lookup';

در یک مسیر، کلید آرایه حاوی URI مشخصی است که باید با درخواست کاربر منطبق باشد، در حالی که مقدار آرایه، مقصدی که باید مسیریابی پیش‌فرض به آن تغییر کند را مشخص می‌کند. در مثال بالا، اگر کلمه product بدون کم و زیاد در اولین سِگمنتِ URL یافت شود، و پشت سر آن، یک عدد در سگمنت دوم یافت شود، قوانین مسیریابی تغییر می‌کند و متد product_lookup از کلاس catalog فراخوانی می‌شود.

می‌توانید از مقادیر منطبق بدون یک حرف کم یا زیاد استفاده کنید یا حتی از دو نوع وایلدکارد استفاده کنید.

(:num) با یک سگمنت تماما عددی منطبق است. (:any) با یک سگمنت حاوی هر کاراکتری (به جز فوراسلش '/'، که یک جداکننده است) منطبق است.

توجه

وایلدکاردها در حقیقت، نام‌های مستعاری برای عبارت‌های باقاعده هستند، که به ترتیب :any به [^/]+ و :num به [0-9]+ ترجمه می‌شوند.

توجه

مسیرها به ترتیبی که تعریف شده‌اند بررسی می‌شوند. بالاترین مسیر اولویت بیشتری نسبت به موارد بعدی دارد.

توجه

قوانین مسیربابی، فیلتر نیستند! به عوان مثال اگر foo/bar/(:num) جلوی فراخوانی متد bar از کنترلر Foo با یک مقدار غیرعددی را نمی‌گیرد اگر یک مسیر معتبر باشد.

مثال‌ها

در ادامه مثال‌هایی درباره مسیریابی وجود دارد:

$route['journals'] = 'blogs';

یک URL شامل کلمه journals در سگمنت اول اشاره به کلاس blogs دارد.

$route['blog/joe'] = 'blogs/users/34';

یک URL که سگمنت اول آن blog/joe است و لود این URL منجر به فراخوانی متد users از کلاس blogs می‌شود. آی‌دی دارای مقدار 34 است.

$route['product/(:any)'] = 'catalog/product_lookup';

URL بالا نیز در سگمنت اول، کلمه product وجود دارد و در سگمنت دوم هر چیزی می‌تواند قرار گیرد. URLهای منطبق بر این الگو، منجر به فراخوانی متد product_lookup از کلاس catalog می‌شوند.

$route['product/(:num)'] = 'catalog/product_lookup_by_id/$1';

در این URL، سگمنت اول product است و سگمنت دوم یک عدد است که در صورتی که پارامتر دوم منطبق با الگوی خواسته شده (عددی) باشد، به عنوان پارامتر به متد product_lookup_by_id از کلاس catalog پاس داده می‌شود.

مهم

در ابتدا و انتهای دستورات مسیریابی از اسلش (/) استفاده کنید.

عبارت‌های باقاعده

اگر بخواهید می‌توانید از عبارت‌های باقاعده، به جای وایلدکاردها در قوانین مسیریابی خود استفاده کنید. هر عبارت باقاعده معتبری مجاز است تا به عنوان بَک‌رفرنس استفاده شود.

اصطلاحات فنی

بَک‌رفرنس (Backreference) به استفاده با ارجاع از عبارت باقاعده قبلی مَچ شده، می‌گویند. برای مثال عبارت <([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1> یک تگ باز و بسته اچ‌تی‌ام‌ال را نشان می‌دهد، این عبارت ابتدا تگ اول را مشخص کرده و \1 در تگ دوم به معنی تکرار همین عبارت است. برای تکرارهای بیشتر همین عبارت \1 و برای تکرار عبارت‌های متفاوت از \2 و \3 و به همین ترتیب استفاده کنید.

توجه

اگر از بَک‌رفرنس استفاده می‌کنید، باید از سینتکس $ به جای \\ استفاده کنید.

یک مسیر حاوی عبارت باقاعده، چیزی شبیه به مقداردهی زیر است:

$route['products/([a-z]+)/(\d+)'] = '$1/id_$2';

در مثال بالا، یک URI شبیه به products/shirts/123 منجر به فراخوانی متد id_123 از کلاس کنترلر shirts می‌شود.

با عبارت‌های باقاعده، حتی می‌توانید چند سگمنت را همزمان بدست آورید. برای مثال، اگر کاربری به سطح محافظت شده با پسورد اپلیکیشن شما دسترسی داشته باشد و بخواهید کاربر بعد از لاگین، به صفحه‌ای ریدایرکت شود که قبل از صفحه لاگین در آن بوده، احتمالا مثال زیر مفید واقع می‌شود:

$route['login/(.+)'] = 'auth/login/$1';

توجه

در مثال بالا، اگر پلیس‌هولدر $1 دارای یک / نیز بود، باز هم به چند پارامتر تجزیه و این پارامترها به Auth::login() ارسال می‌شدند.

اگر با عبارت‌های باقاعده آشنایی ندارید و می‌خواهید درباره آن‌ها بیشتر بدانید، تگ عبارت‌های باقاعده نقطه شروع خوبی است.

توجه

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

کال‌بَک‌ها

همچنین برای پردازش بَک‌رفرنس‌ها می‌توانید از کال‌بَک‌ها در محل معمول نوشتن قوانین مسیریابی استفاده کنید.

$route['products/([a-zA-Z]+)/edit/(\d+)'] = function ($product_type, $id)
{
return 'catalog/product_edit/' . strtolower($product_type) . '/' . $id;
};

استفاده از فعل‌های HTTP در مسیرها

امکان استفاده از فعل‌های HTTP (متد ریکوئست) برای تعریف قوانین مسیریابی وجود دارد. این مورد خصوصا در ساخت اپلیکیشن‌های REFTful مفید است. می‌توانید از فعل‌های استاندارد HTTP (شامل GET و PUT و POST و DELETE و PATCH) یا یک فعل سفارشی (مانند PURGE) استفاده کنید. فعل‌های استفاده شده در قوانین HTTP، حساس به کوچک و بزرگ بودن حروف هستند. همه چیزی که باید انجام دهید، افزودن فعل به عنوان کلید آرایه به مسیر است. مثال:

$route['products']['put'] = 'product/insert';

در مثال بالا، یک ریکوئست PUT به URL حاوی products منجر به فراخوانی متدِ کنترلر Product::insert() (درواقع متد insert() از کنترلر Product) شده است.

$route['products/(:num)']['DELETE'] = 'product/delete/$1';

یک رئکوست DELETE به URL حاوی products به عنوان پارامتر اود و یک عدد به عنوان پارامتر دوم، به متد Product::delete() مَپ شده است (یعنی منجر به فراخوانی این متد می‌شود) که مقدار عددی به عنوان پارامتر اول به این متد ارسال می‌شود.

البته، استفاده از فعل‌های HTTP اختیاری است.

مسیرهای رزرو شده

سه مسیر رزرو شده وجود دارد:

$route['default_controller'] = 'welcome';

این مسیر به اکشنی اشاره دارد که اگر URI دارای هیچ داده‌ای نبود، باید لود شود. این مورد زمانی اتفاق می‌افتد که بازدیدکنندگان URL روت اپلیکیشن را لود می‌کنند. مقدار تخصیص داده شده به این آرایه می‌تواند به صورت controller/method باشد و اگر متد مشخص نشود، متد پیش‌فرض کنترلر که است، فراخوانی خواهد شد. در مثال بالا، Welcome::index() فراخوانی می‌شود.

توجه

از یک دایرکتوری نمی‌توانید به عنوان بخشی از این تنظیمات استفاده کنید!

توصیه می‌کنیم که یک مسیر پیش‌فرض داشته باشید وگرنه به صورت پیش‌فرض خطای 404 نمایش داده خواهد شد.

$route['404_override'] = '';

این مسیر نشان می‌دهد که اگر کنترلر درخواستی پیدا نشود، کدام کلاس کنترلر باید لود شود. این مسیر، صفحه خطای 404 پیش‌فرض را بازنویسی می‌کند. قوانین مشابه default_controller نیز در اینجا اعمال می‌شود.

این مسیریابی هیچگونه تاثیری بر عملکرد فانکشن show_404() ندارد. این فانکشن به صورت پیش‌فرض فایل application/views/errors/error_404.php را لود می‌کند.

$route['translate_uri_dashes'] = FALSE;

همانطور که از مقدار بولین مشخص است، این انتساب در واقع یک مسیر نیست، بلکه گزینه اختیاری است که شما را قادر می‌سازد تا به صورت اتوماتیک تمام دَش‌های (-) استفاده شده در سگمنت‌های URL که مربوط به کنترلر و متد هستند را با آندراسکور (_) جایگزین کنید، بنابراین بی‌نیاز از تعریف مسیرهای جدید برای این کار خواهید بود. از این لحاظ که استفاده از دَش در نامگذاری متدها و کلاس‌ها مجاز نیست و در صورت استفاده نیز منجر به توقف برنامه (fatal error) می‌شود، لازم است که از این گزینه استفاده شود.

منبع
URI Routing