Skip to content

2. یک رویکرد توسعه MVC برای وب/PHP

در اینجا ما رویکردی برای توسعه برنامه‌های وب/PHP پیشنهاد می‌کنیم که با معماری MVC مطابقت دارد. این صرفاً برای پیشنهاد راه‌های ممکن است. خواننده باید آن را با ترجیحات و نیازهای خود تطبیق دهد.

  1. ما کار را با تعریف تمام نماهای برنامه شروع خواهیم کرد. این‌ها صفحات وبی هستند که به کاربر ارائه می‌شوند. ما هنگام طراحی نماها از دیدگاه کاربر استفاده خواهیم کرد. سه نوع نما وجود دارد:
    • فرم ورودی، که برای دریافت اطلاعات از کاربر طراحی شده است. این معمولاً شامل دکمه‌ای برای ارسال اطلاعات وارد شده به سرور است.
    • صفحه پاسخ، که صرفاً برای ارائه اطلاعات به کاربر است. این صفحه اغلب شامل یک یا چند پیوند است که به کاربر امکان می‌دهد با رفتن به صفحه دیگر، به استفاده از برنامه ادامه دهد.
    • صفحهٔ ترکیبی: کنترل‌کننده صفحه‌ای حاوی اطلاعاتی را که خود تولید کرده است برای کلاینت ارسال می‌کند. کلاینت از همین صفحه برای ارائهٔ اطلاعات جدید کاربر به کنترل‌کننده استفاده خواهد کرد.
  1. هر ویو صفحه‌ای با نام PHP تولید می‌کند. برای هر یک از این‌ها:
    • ما طرح‌بندی صفحه را طراحی خواهیم کرد
    • تعیین خواهیم کرد که کدام بخش‌های آن پویا هستند:
      • اطلاعاتی که برای کاربر در نظر گرفته شده است، که باید توسط کنترلر به عنوان پارامتر به ویوی PHP ارائه شود. یک راه‌حل ساده به شرح زیر است:
        • کنترلر اطلاعاتی را که می‌خواهد در ویو V قرار دهد، در یک دیکشنری $dReponse قرار می‌دهد
        • کنترل‌کننده نما V را نمایش می‌دهد. اگر این مربوط به فایل منبع V.php باشد، این نمایش به سادگی با دستور include V.php انجام می‌شود.
        • واردسازی فوق، یک واردسازی کد در داخل کنترلر است. دیکشنری $dReponse که توسط کنترلر پر شده است، از طریق کد در V.php به طور مستقیم قابل دسترسی است.
      • داده‌های ورودی که باید برای پردازش به برنامهٔ اصلی ارسال شوند. این داده‌ها باید بخشی از یک فرم HTML (برچسب <form>) باشند.
  1. ورودی/خروجی برای هر نما را می‌توان به صورت زیر خلاصه کرد
  • ورودی‌ها داده‌هایی هستند که کنترل‌کننده باید در اختیار صفحه PHP قرار دهد
  • خروجی‌ها داده‌هایی هستند که صفحه PHP باید در اختیار کنترل‌کننده برنامه قرار دهد. آنها بخشی از یک فرم HTML را تشکیل می‌دهند و کنترل‌کننده آنها را از طریق عملیاتی از نوع $_GET["param"] بازیابی خواهد کرد (روش GET) یا $_POST["param"] (روش POST).
  1. اغلب، صفحهٔ نهایی که به کلاینت ارسال می‌شود، یک نمای واحد نیست بلکه ترکیبی از نماها است. برای مثال، صفحه‌ای که برای کاربر ارسال می‌شود ممکن است شکل زیر را داشته باشد:

منطقه ۱ ممکن است یک بنر سربرگ، منطقه ۲ یک بنر منو و منطقه ۳ یک ناحیه محتوا باشد. در PHP، این ترکیب را می‌توان با استفاده از کد زیر HTML/PHP به دست آورد:

<table>
    <tr>
        <td><?php include zone1.php ?></td>
    </tr>
    <tr>
        <td><?php include zone2.php ?></td>
        <td><?php include zone3.php ?></td>
    </tr>
</table>

می‌توانید این کد را با نوشتن زیر پویا کنید:

<table>
    <tr>
        <td><?php include $dReponse['urlZone1'] ?></td>
    </tr>
    <tr>
        <td><?php include $dReponse['urlZone2'] ?></td>
        <td><?php include $dReponse['urlZone3'] ?></td>
    </tr>
</table>

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

  • قالب مورد استفاده را مشخص کند
  • تعیین عناصر مورد نظر برای درج در آن
  • درخواست نمایش قالب را بدهد
  1. ما برای هر قالب پاسخ، کد PHP/HTML را می‌نویسیم. این کد به طور کلی ساده است. کد برای مثال بالا می‌تواند به این صورت باشد:
<?php
    // ابتکاریات برای تست بدون کنترلر
...
?>
<html>
    <head>
      <title><?php echo $dReponse['titre'] ?></title>
      <link type="text/css" href="<?php echo $dReponse['style']['url'] ?>" rel="stylesheet" />    
    </head>
  <body>      
    <table>
        <tr>
            <td><?php include $dReponse['urlZone1'] ?></td>
        </tr>
        <tr>
            <td><?php include $dReponse['urlZone2'] ?></td>
            <td><?php include $dReponse['urlZone3'] ?></td>
        </tr>
    </table>
  <body>
</html>

در هر جا که امکان داشته باشد، از یک صفحهٔ سبک استفاده خواهد شد تا «ظاهر» پاسخ را بتوان بدون نیاز به تغییر کد PHP/HTML تغییر داد.

  1. ما برای هر نمای پایه کد PHP/HTML را خواهیم نوشت. این کد معمولاً شکل زیر را خواهد داشت:
<?php
     //احتمالاً برخی راه‌اندازی‌ها، به‌ویژه در فاز اشکال‌زدایی
    ...
?>

<balise>
...
         //هدف در اینجا به حداقل رساندن کد PHP است
</balise>

شایان ذکر است که یک نمای پایه در یک قالب جاسازی شده است. کد آن، HTML، در کد قالب جاسازی شده است. در اکثر موارد، قالب از قبل شامل تگ‌های <html>، <head> و <body> است. بنابراین یافتن این تگ‌ها در یک نمای پایه نادر است.

  1. قالب‌های پاسخ مختلف و نماهای پایه را می‌توان آزمایش کرد
  • هر قالب پاسخ آزمایش می‌شود. اگر قالبی با نام modele1.php فراخوانی شود، ما از طریق مرورگر URL را درخواست خواهیم کرد: http://localhost/chemin/modele1.php. این قالب انتظار مقادیری را از کنترل‌کننده دارد. در اینجا، این کار مستقیماً و نه از طریق کنترلر فراخوانی می‌شود. مدل پارامترهای مورد انتظار را دریافت نخواهد کرد. برای اطمینان از اینکه تست همچنان امکان‌پذیر است، ما پارامترهای مورد انتظار را به‌صورت دستی با استفاده از ثابت‌ها در صفحه PHP مدل مقداردهی اولیه خواهیم کرد.
  • هر مدل و همچنین تمام ویوهای پایه تست می‌شوند. این زمان مناسبی برای توسعه عناصر اولیهٔ استایل‌شیت‌های مورد استفاده نیز هست.
  1. سپس منطق برنامه را می‌نویسیم:
  • کنترل‌گر، یا برنامه اصلی، معمولاً چندین اقدام را مدیریت می‌کند. اقدامی که باید انجام شود باید در درخواست‌هایی که دریافت می‌کند، تعریف شده باشد. این کار را می‌توان با استفاده از یک پارامتر درخواست انجام داد که در اینجا آن را «اقدام» (action) می‌نامیم:
    • اگر درخواست از یک فرم (<form>) بیاید، این پارامتر می‌تواند یک پارامتر مخفی فرم باشد:
<form ... action="/C/main.php" method="post"  ...>
<input type="hidden" name="action" value="uneAction">
...
</form>
  • (ادامه)
    • اگر درخواست از یک لینک بیاید، می‌توانید آن را به شرح زیر پیکربندی کنید:
 <a href="/C/main.php?action=uneAction">lien</a>

کنترل‌کننده می‌تواند با خواندن مقدار این پارامتر شروع کرده و سپس پردازش درخواست را به ماژولی که مسئول رسیدگی به این نوع درخواست است، واگذار کند. در اینجا، ما فرض کرده‌ایم که همه چیز توسط یک اسکریپت واحد به نام main.php کنترل می‌شود. اگر برنامه نیاز به رسیدگی به اقدامات action1، action2، ... داشته باشد، actionx، می‌توان برای هر اقدام یک تابع جداگانه درون کنترلر ایجاد کرد. اگر اقدامات زیادی وجود داشته باشد، این امر می‌تواند منجر به ایجاد یک کنترلر «دایناسوری» شود. به عنوان جایگزین، می‌توان اسکریپت‌هایی مانند action1.php، action2.php، …، ایجاد کرد،actionx.php برای رسیدگی به هر یک از اقدامات. کنترل‌کننده‌ای که مسئول رسیدگی به اقدام actionx است، به سادگی کد را از اسکریپت مربوطه با استفاده از دستوری مانند **include &quot;actionx.php&quot; بارگذاری می‌کند. مزیت این روش این است که کار خارج از کد کنترل‌کننده انجام می‌شود. بنابراین هر عضو تیم توسعه می‌تواند به طور نسبتاً مستقلی روی اسکریپت مربوط به انجام عمل «actionx» کار کند. همچنین، شامل کردن کد اسکریپت actionx.php** در کد کنترل‌کننده در زمان اجرا، این مزیت را دارد که مقدار کد بارگذاری‌شده در حافظه را کاهش می‌دهد. فقط کد مربوط به پردازش اکشن جاری بارگذاری می‌شود. این فراخوانی کد به این معناست که متغیرهای کنترلر ممکن است با متغیرهای موجود در اسکریپت اکشن تداخل داشته باشند. خواهیم دید که می‌توانیم اطمینان حاصل کنیم که متغیرهای کنترلر به چند متغیر کاملاً مشخص محدود شوند، که سپس باید در اسکریپت‌ها از آن‌ها اجتناب کرد.

  • ما به طور سیستماتیک در پی آن خواهیم بود که منطق کسب‌وکار یا کد مربوط به دسترسی به داده‌های پایدار را در ماژول‌های جداگانه‌ای ایزوله کنیم. کنترل‌کننده مانند یک سرپرست تیم عمل می‌کند که درخواست‌ها را از مشتریان خود (مشتریان وب) دریافت کرده و آنها را توسط مناسب‌ترین طرف‌ها (ماژول‌های کسب‌وکار) اجرا می‌سازد. هنگام نوشتن کنترل‌کننده، رابط (interface) ماژول‌های کسب‌وکاری را که باید نوشته شوند، مشخص خواهیم کرد. این امر در صورتی اعمال می‌شود که این ماژول‌های کسب‌وکار قرار باشد ساخته شوند. اگر آن‌ها از قبل وجود داشته باشند، آنگاه کنترل‌کننده خود را با رابط این ماژول‌های موجود تطبیق خواهد داد.
  1. ما ساختار پایهٔ ماژول‌های کسب‌وکاری مورد نیاز کنترل‌کننده را خواهیم نوشت. برای مثال، اگر کنترل‌کننده از ماژولی به نام getCodes استفاده کند که یک آرایه از رشته‌های کاراکتری را بازمی‌گرداند، در ابتدا می‌توانیم به سادگی بنویسیم:
function getCodes(){
    return array("code1","code2","code3");
}
  1. سپس می‌توانیم به تست کنترلر و اسکریپت‌های مرتبط PHP بپردازیم:
  • کنترلر، اسکریپت‌های اکشن، مدل‌ها، ویوها و منابع مورد نیاز برنامه (تصاویر و غیره) در پوشه DC که با زمینه برنامه C مرتبط است، قرار می‌گیرند.
  • پس از انجام این کار، برنامه آزمایش شده و هرگونه خطاهای اولیه اصلاح می‌شوند. اگر main.php کنترل‌کننده و C زمینه برنامه باشد، http://localhost/C/main.php درخواست خواهد شد. در پایان این مرحله، معماری برنامه عملیاتی می‌شود. این مرحله آزمایشی می‌تواند دشوار باشد، زیرا ابزارهای اشکال‌زدایی کمی در دسترس هستند، مگر اینکه از محیط‌های توسعه پیشرفته استفاده شود که معمولاً پولی هستند. می‌توانید از دستورات `echo "message"` استفاده کنید که خروجی را به جریان HTML ارسال‌شده به کلاینت می‌نویسد و در نتیجه در صفحه وب نمایش‌داده‌شده توسط مرورگر ظاهر می‌شود.
  1. در نهایت، کلاس‌های کسب‌وکار مورد نیاز کنترل‌کننده را می‌نویسیم. این کار معمولاً شامل توسعه استاندارد یک کلاس PHP است که معمولاً از هر برنامه وب مستقِل است. این کلاس ابتدا خارج از این محیط، برای مثال با استفاده از یک برنامه کنسول، آزمایش می‌شود. پس از نوشتن یک کلاس کسب‌وکار، آن را در معماری استقرار برنامه وب ادغام کرده و برای اطمینان از یکپارچگی صحیح آن، تست می‌کنند. این فرآیند برای هر کلاس کسب‌وکار تکرار می‌شود.