تا این مرحله از دورهٔ آشنایی با معماری MVC با موفقیت توانستهایم تا لایههای View و Model را پیادهسازی نماییم؛ حال در این آموزش قصد داریم تا به توسعهٔ لایهٔ Controller بپردازیم که این وظیفه را دارا است تا مابین دو لایهٔ دیگر ارتباط برقرار سازد. برای این منظور، پوشهای تحت عنوان Controllers
ساخته و فایلی تحت عنوان DefaultController.php
با محتویات زیر داخل آن ایجاد میکنیم:
<?php
namespace Base\Controllers;
use Core\BaseController;
class DefaultController extends BaseController
{
public function homepage()
{}
public function about($param = null)
{}
public function notfound()
{}
public function users()
{}
}
طبق روال معمول، ابتدا به ساکن اقدام به درج نِیماِسپس این فایل میکنیم و با توجه به اینکه قرار است در این فایل از کلاسهای User
،Database
و BaseController
استفاده نماییم، آنها را use
میکنیم.
نامی مشابه نام فایل تحت عنوان DefaultController
برای این کلاس در نظر گرفته و این در حالی است که این کنترلر کلیهٔ خصوصیات خود را از کلاس BaseController
به ارث خواهد برد؛ به عبارتی، از این پس میتوانیم از ویژگیهای کلاس BaseController
که حاوی کدهای زیر است در کنترلر خود استفاده نماییم:
<?php
namespace Core;
use Core\Interfaces\ControllerInterface;
class BaseController implements ControllerInterface
{
public function renderView($moduleType, $controllerName, $view, $data = [])
{
require_once "../app/$moduleType/Views/$controllerName/$view.php";
}
}
همانطور که قبلاً در حین نوشتن این کلاس توضیح دادیم، فانکشن ()renderView
این وظیفه را دارا است تا بر اساس پارامترهایی که میگیرد، ویوی مرتبط را ایمپورت نماید. داخل کلاس DefaultController
چهار متد یا اَکشن مختلف داریم که عبارتند از:
- متد ()homepage
به منظور نمایش هومپیج سایت
- متد ()about
به منظور نمایش صفحهٔ دربارهٔ ما
- متد ()notfound
به منظور نمایش صفحهٔ 404
- متد ()users
به منظور نمایش لیست کاربران
ساخت اَکشن مرتبط با صفحهٔ هومپیج
متد یا اَکشن ()homepage
را به صورت زیر تکمیل کرده سپس به توضیح آن خواهیم پرداخت:
public function homepage()
{
parent::renderView('Base', 'default', 'homepage');
}
شیئگرایی در زبان پیاچپی بدین صورت است که اگر از داخل کلاس فرزند بخواهیم به متدی از کلاس والد دست یابیم، میباید از کیورد parent
استفاده نماییم بدین صورت که این کیورد را نوشته سپس علائم ::
را درج میکنیم و نام متد مربوطه از کلاس والد را مینویسیم. بر همین اساس، داخل بدنهٔ متد ()homepage
به متد ()renderView
دست یافتهایم که این وظیفه را دارا است تا به ویویی مرتبط با آرگومانی که دریافت میکند ارجاع دهد. چنانچه به پارامترهای ورودی متد ()renderView
نگاهی بیندازیم، خواهیم دید که این متد برای اجرا نیاز به پارامترهای زیر دارد:
public function renderView($moduleType, $controllerName, $view, $data = [])
{
require_once "../app/$moduleType/Views/$controllerName/$view.php";
}
پارامتر moduleType$
به نام ماژول اشاره دارد که در این مثال مقدار استرینگ Base
را در نظر گرفتهایم. پارامتر controllerName$
به نام کنترلر اشاره دارد که در این مثال مقدار استرینگ default
را در نظر گرفتهایم که این مقدار با همان فولدری که داخل لایهٔ Views
ساخته و گفتیم که همنام با کنترلر است مرتبط میباشد. پارامتر سوم به نام فایل ویو اشاره دارد که در این مثال استرینگ about
را در نظر گرفتهایم که در نهایت با استرینگ php.
کانتکت شده و همنام با ویوی about.php
میگردد. در نهایت هم پارامتر data$
را داریم که در اَکشن ()homepage
آن را پاس ندادهایم چرا که به آن نیازی نخواهیم داشت.
ساخت اَکشن مرتبط با صفحهٔ دربارهٔ ما
اَکشن ()about
را به صورت زیر تکمیل کرده سپس به توضیح آن خواهیم پرداخت:
public function about($param = null)
{
parent::renderView('Base', 'default', 'about', [
'param' => $param,
]);
}
همانطور که میبینیم، اَکشن ()about
بر خلاف ()homepage
یک پارامتر ورودی تحت عنوان param$
با مقدار اولیهٔ []
میگیرد سپس آن را در قالب آرگومان چهارم به متد ()renderView
پاس داده و در فایل about.php
به صورت زیر مورد استفاده قرار میدهیم:
<!DOCTYPE html>
<html>
<head>
<title>About</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="../../../../css/styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<h1>About</h1>
<p>This is the about page of the site. <?= $data['param'] ?></p>
</div>
</body>
<script src="../../../../js/app.js"></script>
</html>
میبینیم که در خط چهاردهم با استفاده از تگهای <? =?>
اقدام به چاپ آرایهٔ ['data['param$
کردهایم.
ساخت اَکشن مرتبط با صفحهٔ 404
اَکشن مرتبط با صفحهٔ 404 هم کاملاً مشابهٔ اَکشن صفحهٔ هومپیج است به طوری که داریم:
public function notfound()
{
parent::renderView('Base', 'default', 'notfound');
}
در ارتباط با طراحی صفحههای 404 توصیه میکنیم به مقالهٔ نکات یوایکسی برای طراحی صفحههای خطای 404 مراجعه نمایید.
ساخت اَکشن مرتبط با صفحهٔ لیست کاربران
در ارتباط با اَکشنهای کنترلر DefaultController
، موردی که نسبت به سایرین از پیچیدگی بیشتری برخوردار میباشد ()users
است چرا که در این اَکشن قصد داریم تا ارتباط مابین ویو و مدل را برقرار سازیم:
public function users()
{
$database = (new Database())->connect();
$users = new User($database);
$result = $users->fetch();
$result = $result->fetchAll(\PDO::FETCH_ASSOC);
parent::renderView('Base', 'default', 'users', [
'param' => $result,
]);
}
در تفسیر کدهای داخل این متد میتوان گفت که ابتدا آبجکتی از روی کلاس Database
ساخته و متد ()connect
آن را فراخوانی کردهایم و آن را به متغیری تحت عنوان database$
منتسب نمودهایم سپس آبجکتی از روی مدل User
ساخته و متغیر database$
را به عنوان پارامتر ورودی این کلاس پاس دادهایم و در نهایت این مدل را به متغیری تحت عنوان users$
منتسب کردهایم. در ادامه متغیری تحت عنوان result$
ساختهایم که مقدارش برابر با فراخوانی متد ()fetch
روی آبجکت users$
است و در نهایت هم مجدد مقدار این متغیر را برابر با فراخوانی متدی تعبیهشده در کلاس PDO
تحت عنوان ()fetchAll
روی همان متغیر قرار دادهایم.
با توجه به اینکه متد ()fetch
در مدل User
متغیر statement$
را ریترن میکند، لذا به متغیر تعبیهشدهٔ ()fetchAll
در کلاس PDO
دسترسی خواهیم داشت که به عنوان پارامتر ورودی این متد از PDO::FETCH_ASSOC\
استفاده نمودهایم که این دستور را به کلاس مذکور میدهد تا نتایج فراخوانی دادهها از جدول users
را در قالب یک به اصطلاح Associative Array ریترن کند که در آن کلیدهای آرایه همان ستونهای جدول users
است.
در پایان، همچون اَکشنهای دیگر این کنترلر، متغیر result$
را به عنوان مقدار کلید param
از آرگومان چهارم متد ()renderView
به فایل users.php
پاس دادهایم که با مراجعه به این فایل خواهیم داشت:
<!DOCTYPE html>
<html>
<head>
<title>Users` List</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="../../../../css/styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<h1>Users` List</h1>
<?php
if ($data['param']) {
echo "<ol>";
foreach ($data['param'] as $user) {
echo "<li>{$user['first_name']} {$user['last_name']}</li>";
}
echo "</ol>";
}
?>
</div>
</body>
<script src="../../../../js/app.js"></script>
</html>
میبینیم که به سادگی روی این آرایه foreach
زده و تکتک مقادیر آن را چاپ کردهایم.
در این آموزش به تکمیل لایهٔ Controller در معماری MVC پرداختیم که این وظیفه را دارا است تا نقش پلی ارتباطی مابین ویو و مدل را بازی نماید به طوری که در تکمیل اَکشن مرتبط با لیست کاربران، به بررسی این موضوع پرداختیم که به چه شکل میتوان ابتدا دیتا را از طریق مدل از دیتابیس فراخوانی کرده سپس آن را در اختیار ویو گذاشته و ویو هم در قالب یک صفحهٔ اچتیاماس ساده لیست کاربران را به نمایش بگذارد.