نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی پرتال اطلاعاتی

الگوی طراحی MVC در جاوا چیست؟ MVC: چیست و چگونه با رابط کاربری ارتباط دارد.

در این مقاله ما یک "اسکلت" از پروژه خود خواهیم نوشت. منظور من از کلمه Framework کد کاری است که مبتنی بر رویکرد MVC خواهد بود، یعنی تقسیم منطقی واضحی به کنترلرها، اکشن ها، قالب ها (نماها) و مدل ها خواهد داشت.

و بنابراین بیایید شروع کنیم، همانطور که قبلاً در مقاله قبلی نوشتم، الگوی MVC به یک نقطه ورودی اشاره می کند - index.php، همه درخواست ها از طریق این اسکریپت می روند، تمام منطق پروژه از طریق آن کار می کند. برای پیاده سازی این رویکرد، لازم است سرور را پیکربندی کنید، فرض بر این است که سایت روی یک سرور آپاچی در حال اجرا است، بنابراین فقط باید یک فایل htaccess ایجاد کنیم که در آن قوانین مسیریابی URL را مشخص کنیم. علاوه بر تعریف نقطه ورودی، مسیریابی به شما امکان می دهد CNC (URL های قابل خواندن توسط انسان) ایجاد کنید. یعنی بعد از تنظیمات صحیح آدرس های صفحه شبیه به این site.ru/article/new می شود.
ابتدا اجازه دهید یک .htaccess ایجاد کنیم که پردازش تمام صفحات را به اسکریپت index.php هدایت می کند. کد به شکل زیر است:

RewriteEngine در RewriteCond% (REQUEST_FILENAME) -F RewriteCond% (REQUEST_FILENAME) -D RewriteRule ^ (. *) $ Index.php؟ مسیر = 1 دلار

فایل htaccess باید در پوشه ریشه سایت قرار داشته باشد و بلافاصله باید اسکریپت index.php که محل ورود است ایجاد شود. بیایید یک خط در index.php قرار دهیم تا بررسی کنیم که آیا تغییر مسیر کار می کند یا خیر:

اکو "تست"؛

اکنون می توانید تغییر مسیر را بررسی کنید، هر آدرسی را وارد کنید و ببینید چه اتفاقی می افتد: test-mvc.web / sdf / sdf / یا test-mvc.web / sdf / sdf / 2342 / مهم نیست، در هر صورت روی صفحه نمایش ، باید "تست" را ببینید. اگر این کتیبه را دیدید به این معنی است که ما موفق شده ایم.
بیایید ادامه دهیم، برای راحتی، اجازه دهید یک فایل config.php در ریشه سایت ایجاد کنیم، که در آن ثابت های مختلفی را تنظیم می کنیم که سفارشی کردن سایت را آسان تر می کند. اینها می توانند مسیرهای مختلف به اسکریپت ها، دسترسی به پایگاه داده و غیره باشند. اکنون در تنظیمات، موارد زیر را تنظیم می کنیم:

// تنظیم ثابت ها: تعریف ("DS"، DIRECTORY_SEPARATOR); // جداکننده مسیرهای فایل $ sitePath = realpath (dirname (__ FILE__). DS); تعریف کنید ("SITE_PATH"، $ sitePath); // مسیر به پوشه ریشه سایت // برای اتصال به پایگاه داده تعریف کنید ("DB_USER", "root"); تعریف کنید ("DB_PASS"، ""); تعریف کنید ("DB_HOST"، "localhost"); تعریف کنید ("DB_NAME"، "blog_mvc");

برای اینکه ثابت ها و سایر داده های پیکربندی در سراسر پروژه استفاده شوند، لازم است اسکریپت config.php را در فایل index.php قرار دهید.
علاوه بر اتصال فایل با تنظیمات، در index.php باید یک اتصال به پایگاه داده ایجاد کنید، یک اسکریپت را با هسته سایت وصل کنید و یک روتر راه اندازی کنید که در آن مسیریابی انجام می شود.
حال به ترتیب ایجاد اتصال پایگاه داده در index.php خواهد بود تا اتصال فقط یک بار باز شود. پس از یک بار باز کردن اتصال، می‌توانیم آن را در همه کنترل‌کننده‌ها و مدل‌ها استفاده کنیم، اما بعداً در مورد آن بیشتر توضیح خواهیم داد. در حال حاضر، اجازه دهید فقط یک اتصال به پایه ایجاد کنیم. برای کار با پایگاه داده تصمیم گرفتم از PDO استفاده کنم. می توانید در مورد PDO بیشتر بخوانید.
هسته سایت را در پوشه core قرار می دهیم و نام اسکریپت را core.php می گذاریم، در اینجا تابعی می نویسیم که خودش متصل می شود، کلاس ها برای کار ضروری هستند. چنین عملکردی کار ما را با کنترلرها، مدل ها و غیره بسیار تسهیل و ساده می کند. زیرا با نگاهی به آینده، می گویم که هر کنترلر و هر مدل یک کلاس جداگانه خواهد بود.
علاوه بر اتصال خودکار کلاس ها، ما یک مخزن (رجیستری) به هسته ایجاد یک مخزن اضافه می کنیم که در آن تمام اشیاء و متغیرهای لازم را که می توانند در هر نقطه از پروژه مفید باشند، ذخیره می کنیم.
ما همچنین روتر را در فایل فهرست وصل می کنیم، URL را تجزیه می کند و کنترلر و اکشن لازم را وصل می کند. من در مقاله قبلی نوشتم که یک کنترلر چیست، اما به عمد از اطلاعات مربوط به عملکرد صرفنظر کردم، بدون اینکه با اطلاعات غیر ضروری بارگیری کنم. پس عمل چیست؟
کنترلر کلاسی است که شامل متدهای مختلفی است که با رویکرد MVC هر متد یک عمل خواهد بود. یعنی یک اکشن یک متد کلاسی است که داده ها را پردازش کرده و به view (به الگو) ارسال می کند. ممکن است هنوز کاملاً مشخص نباشد، اما پس از مثال همه چیز سر جای خود قرار می گیرد.
در این مرحله تئوری کافی است، بیایید به سراغ عمل برویم. کد فایل هایی که کارشون رو بالا توضیح دادم میدم.
کد اسکریپت Index.php:

// فعال کردن نمایش تمام خطاها error_reporting (E_ALL); // شامل پیکربندی include ("/config.php"); // اتصال به پایگاه داده $ dbObject = PDO جدید ("mysql: host =". DB_HOST. "; Dbname =". DB_NAME، DB_USER، DB_PASS); // شامل هسته سایت شامل (SITE_PATH. DS. "core". DS. "core.php"); // بارگذاری روتر $ روتر = روتر جدید ($ رجیستری); // نوشتن اطلاعات در رجیستری $ registry-> set ("router", $ router); // مسیر پوشه کنترلرها را تنظیم کنید. $ router-> setPath (SITE_PATH. "controllers"); // راه اندازی روتر $ router-> start ();

اسکریپت Core.php:

// بارگذاری کلاس ها در تابع fly __autoload ($ className) ($ filename = strtolower ($ className). ".Php"؛ // کلاس را تعریف کرده و مسیر آن را پیدا کنید $ expArr = explode ("_"، $ className ) ؛ if (خالی ($ expArr) یا $ expArr == "Base") ($ folder = "classes";) other (سوئیچ (strtolower ($ expArr)) (مورد "کنترل کننده": $ folder = "کنترل کننده ها"; break ؛ case "model": $ folder = "models"؛ break; default: $ folder = "classes"; break;)) // مسیر کلاس $ file = SITE_PATH. پوشه $. DS. $ نام فایل؛ // بررسی برای فایل موجود اگر (file_exists ($ file) == false) (return false;) // شامل فایل با کلاس include ($ file);) // شروع رجیستری (ذخیره سازی) $ registry = new Registry;

کلاس مخزن Registry.php در پوشه / classes / قرار خواهد گرفت

// کلاس ذخیره سازی رجیستری کلاس (vars خصوصی $ = آرایه ()؛ // نوشتن مجموعه تابع داده (کلید $، $ var) (if (isset ($ this-> vars [$ key]) == true) (پرتاب جدید استثنا ("نمیتوان var" را تنظیم کرد ". کلید $." ". قبلاً تنظیم شده است.")) $ This-> vars [$ key] = $ var; return true;) // دریافت تابع داده دریافت (کلید $) (اگر (isset ($ this-> vars [$ key]) == false) (return null;) return $ this-> vars [$ key];) // remove data function remove ($ var) (unset ($) this-> vars [کلید $])))

کد فایل router.php که در پوشه / classes / قرار دارد

// کلاس روتر کلاس روتر (رجیستری $ خصوصی، مسیر $ خصوصی، $ args خصوصی = آرایه ()؛ // تابع ذخیره سازی __construct ($ رجیستری) را دریافت کنید ($ this-> registry = $ رجیستری؛) // مجموعه مسیر پوشه با تابع کنترل‌کننده setPath ($ path) ($ path = trim ($ path, "/ \\")؛ $ path. = DS؛ // اگر مسیر وجود ندارد، به آن علامت دهید اگر (is_dir ( مسیر $) == false ) (پرتاب جدید Exception ("مسیر کنترل کننده نامعتبر:` ". مسیر $." '");) $ this-> path = مسیر $;) // تعریف کنترل کننده و عملکرد از تابع خصوصی url getController (& $ file, & $ controller, & $ action, & $ args) ($ route = (خالی ($ _ GET ["route"]))؟ "": $ _GET ["route"]؛ تنظیم نشده ($ _ GET ["مسیر"])؛ اگر (خالی ($ مسیر)) ($ route = "index";) // دریافت بخش هایی از URL $ route = trim ($ route, "/ \\")؛ $ part = explode ("/" $ route)؛ // کنترلر را پیدا کنید $ cmd_path = $ this-> path; foreach ($ parts as $ part) ($ fullpath = $ cmd_path. $ Part; // بررسی کنید آیا پوشه وجود دارد if (is_dir ($ fullpath)) ($ cmd_path. = $ part DS; array_shift ($ قطعات)؛ ادامه هید؛ ) // فایل را بیابید if (is_file ($ fullpath. ".Php")) ($ controller = $ part; array_shift ($ parts); break;)) // اگر url یک کنترل کننده را مشخص نمی کند، از ایندکس پیش فرض if (خالی ($ controller)) ($ controller = "index";) // دریافت عمل $ action = array_shift ($ part); if (خالی ($ action)) ($ action = "index";) $ file = $ cmd_path. کنترلر $. ".php"; $ args = $ قطعات; ) تابع start () (// مسیر $ this-> getController را تجزیه کنید ($ file, $ controller, $ action, $ args)؛ // بررسی کنید آیا فایل وجود دارد یا خیر، در غیر این صورت 404 اگر (is_readable ($ file) == false ) (مرگ ("404 یافت نشد");) // شامل فایل شامل ($ file) می شود؛ // یک نمونه از کنترلر $ class = "Controller_" ایجاد کنید. $ Controller؛ $ controller = کلاس $ جدید ($ this -> رجیستری)؛ // اگر اکشن وجود نداشته باشد - 404 if (is_callable (آرایه ($ controller, $ action)) == false) (die ("404 Not Found");) // عمل $ را اجرا کنید کنترلر -> عمل $ ();))

اکنون باید پوشه هایی برای ذخیره کنترلرها، الگوها و مدل ها ایجاد کنیم - در ریشه سه کنترلر، نما و مدل پوشه ایجاد خواهیم کرد. و اجازه دهید چند فایل آزمایشی /controllers/index.php، /views/index/index.php و /models/model_users.php ایجاد کنیم و اکنون فایل‌ها را پر کنید:
برای کنترلر:

// controller Class Controller_Index Extends Controller_Base (// template public $ layouts = "first_layouts"; // action index () ($ model = new Model_Users (); $ userInfo = $ model-> getUser (); $ this-> template-> vars ("userInfo"، $ userInfo)؛ $ this-> template-> view ("index");))

برای نمایش (/views/index/index.php)

نمای آزمایشی
شناسه:
نام:

و مدل:

// مدل کلاس Model_Users (تابع عمومی getUser () (آرایه بازگشتی ("id" => 1، "name" => "test_name");))

همانطور که متوجه شده اید، کلاس کنترلر از کلاس والد Controller_Base به ارث می برد. این کار به منظور ساده سازی کلاس کنترلر انجام می شود. از آنجایی که هنوز باید کلاس را برای کار با قالب ها وصل کنیم، اتصال آن به Controller_Base منتقل می شود.
کد آن را می‌دهم، در پوشه / classes / قرار دارد و controller_base.php نام دارد:

// کلاس کنترلر انتزاعی Abstract Class Controller_Base (رجیستری $ محافظت شده؛ الگوی $ محافظت شده؛ طرح بندی $ محافظت شده؛ // الگوی عمومی $ vars = آرایه ()؛ // شامل الگوها در تابع سازنده __construct ($ رجیستری) ($ this-> رجیستری = $ رجیستری؛ // الگوهای $ this-> template = الگوی جدید ($ this-> طرح‌بندی‌ها، get_class ($ this))؛) نمایه تابع انتزاعی ();)

اکنون تنها چیزی که باقی می ماند پرداختن به قالب هاست. در کلاس انتزاعی Controller_Base، کلاس Template را صدا می زنیم و نام قالب و نام کنترلر را به آن منتقل می کنیم.
کد کلاس Template که در اینجا / classes / قرار دارد و template.php نامیده می شود

// کلاس برای اتصال الگوها و ارسال داده به نمایشگر Class Template (قالب خصوصی $؛ کنترل کننده خصوصی $؛ طرح بندی $ خصوصی؛ خصوصی $ vars = آرایه ()؛ تابع __construct ($ layouts, $ controllerName) ($ this-> layouts = طرح‌بندی‌های $؛ $ arr = انفجار ("_"، $ controllerName؛ $ this-> controller = strtolower ($ arr);) // تنظیم متغیرها برای نمایش vars تابع ($ varname، $ مقدار) (if (isset ( $ this-> vars [$ varname]) == true) (trigger_error ("Unable to set var" ". $ varname." ". قبلا تنظیم شده است و رونویسی مجاز نیست."، E_USER_NOTICE)؛ false;) $ this -> vars [$ varname] = $ value؛ return true;) // نمایش تابع نمایش ($ name) ($ pathLayout = SITE_PATH. "views". DS. "layouts". DS. $ this-> layouts. ". php "; $ contentPage = SITE_PATH." views ". DS. $ this-> controller. DS. $ name." .php "; if (file_exists ($ pathLayout) == false) (trigger_error (" Layout `". $ این-> طرح‌بندی‌ها. ""وجود ندارد."، E_USER_NOTICE؛ بازگشت false؛) اگر (file_exists) ($ contentPage) == نادرست) (trigger_error ("Template"". نام دلار "` وجود ندارد."، E_USER_NOTICE); بازگشت نادرست؛ ) foreach ($ this-> vars as $ key => $ value) ($$ key = $ value;) شامل ($ pathLayout); ))

اگر کد را با دقت بخوانید، احتمالاً متوجه شده اید که برای نمایش در صفحات از قالب first_layouts و نمای index.php (نمایش) استفاده می کنیم - کد آن را دقیقاً در بالا دادم. تنها چیزی که باقی مانده این است که فایل قالب first_layouts را ایجاد کنیم. آن را در پوشه /views/layouts/first_layouts.php قرار دهید
قالب حاوی کد زیر خواهد بود:

سرتیتر

پاورقی

این همه چیز است، این ایجاد "قاب" را کامل می کند. اکنون ما ساده ترین ساختار را بر اساس الگوی MVC داریم. در این مقاله، من به کار با پایگاه داده اشاره نکردم، فقط به صورت گذرا به آن اشاره کردم، زیرا مقاله قبلا طولانی بود. در مقاله بعدی کار مستقیم با پایگاه داده را شرح خواهم داد.
در پایان مقاله، می توانید منابع را در آرشیو دانلود کنید.

الگو Model-View-Controller (MVC)، که در اواخر دهه 1970 کشف شد، یک الگوی طراحی معماری نرم افزار است که بر جدا کردن توابع داده از ارائه آنها تمرکز دارد. در تئوری، یک برنامه MVC که به خوبی طراحی شده است به توسعه دهندگان جلویی و بک اند اجازه می دهد تا در حین کار خود در حوزه مسئولیت یکدیگر دخالت نکنند، یعنی توسعه دهنده فرانت اند نیازی به دانستن چیزی در مورد «آشپزخانه» ندارد. از همکار بک‌اند خود و بالعکس.

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

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

آشنایی با MVC

همانطور که قبلا ذکر شد، نام الگو از مخفف سه کلمه آمده است: مدل چشم اندازو کنترل کننده... به طور خلاصه، اصل الگو را می توان با یک نمودار نشان داد (در ویکی پدیا یافت می شود):

این نمودار به وضوح جریان یک طرفه اطلاعات در الگو را نشان می دهد و همچنین نقش هر جزء را توصیف می کند.

مدل

این مدل برای دسترسی و دستکاری داده ها استفاده می شود. در بیشتر موارد، مدل چیزی است که برای دسترسی به یک ذخیره‌سازی داده (مانند پایگاه داده) استفاده می‌شود. این مدل یک رابط برای بازیابی، ایجاد، اصلاح و حذف داده ها از ذخیره سازی فراهم می کند. در زمینه الگوی MVC، مدل بین نما و کنترل کننده واسطه می شود.

یکی از ویژگی‌های بسیار مهم مدل این است که از نظر فنی هیچ اطلاعی از آنچه با داده‌های موجود در کنترلر و نمای می‌گذرد ندارد. مدل هرگز نباید درخواستی از / از سایر اجزای الگو داشته باشد یا انتظار داشته باشد.

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

نمایندگی

نما جایی است که داده های دریافتی از مدل به شکل دلخواه نمایش داده می شود. در برنامه‌های کاربردی وب سنتی که با الگوی MVC توسعه می‌یابند، نمای بخشی از سیستم است که HTML در آن تولید می‌شود. View همچنین مسئول دریافت اقدامات از کاربر به منظور ارسال آنها به کنترلر است. به عنوان مثال، یک view یک دکمه را در رابط کاربری رندر می کند و با کلیک بر روی آن، عملکرد کنترلر مربوطه را فراخوانی می کند.

برخی تصورات غلط در مورد هدف این view وجود دارد، به خصوص در میان توسعه دهندگان وب که به تازگی شروع به ساخت برنامه های خود با استفاده از MVC کرده اند. یکی از قوانینی که اغلب نقض می شود این است نما به هیچ وجه نباید با مدل ارتباط برقرار کند، و همه داده های دریافت شده توسط view فقط باید از کنترل کننده باشد... در عمل، توسعه دهندگان اغلب این مفهوم را که هسته اصلی الگوی MVC است نادیده می گیرند. مقاله Fabio Cevasco این رویکرد گیج کننده به MVC را با استفاده از CakePHP، یکی از بسیاری از چارچوب های غیر استاندارد MVC نشان می دهد:

درک این نکته بسیار مهم است که برای به دست آوردن معماری صحیح MVC، نباید هیچ گونه تعامل مستقیمی بین نماها و مدل ها وجود داشته باشد. تمام منطق تبادل داده بین آنها باید در کنترلرها پیاده سازی شود.

علاوه بر این، یک تصور غلط رایج وجود دارد که یک View فقط یک فایل الگو است. همانطور که تام باتلر خاطرنشان کرد، این تصور غلط مقیاس بزرگی دارد زیرا بسیاری از توسعه دهندگان از همان ابتدا ساختار MVC را اشتباه درک می کنند و پس از آن شروع به ریختن این "دانش" بیشتر، انبوه توسعه دهندگان تازه کار می کنند. در واقعیت، یک view خیلی بیشتر از یک الگو است، اما بسیاری از فریم ورک‌ها که بر اساس الگوی MVC ساخته شده‌اند، مفهوم یک View را چنان تحریف کرده‌اند که هیچ‌کس اهمیتی نمی‌دهد که کاربردهای آن‌ها از نظر الگوی MVC چقدر درست است.

همچنین مهم است که view هرگز با داده‌های «خالص» از کنترل‌کننده کار نکند، یعنی کنترل‌کننده هرگز با نمای دور زدن مدل کار نمی‌کند. در فرآیند تعامل بین کنترلر و نما، مدل باید همیشه بین آنها باشد.

کنترل کننده

کنترلر آخرین قطعه از دسته MVC است. وظیفه کنترلر دریافت داده از کاربر و دستکاری مدل است. این کنترل کننده است و فقط او بخشی از سیستم است که با کاربر تعامل دارد.

به طور خلاصه، یک کنترلر را می توان به عنوان جمع آوری اطلاعات توصیف کرد که آن را به یک مدل برای پردازش و ذخیره سازی منتقل می کند. او نباید با داده ها کاری انجام دهد، بلکه فقط بتواند آن را از کاربر دریافت کند. کنترل کننده با یک نما و یک مدل مرتبط است، بنابراین یک جریان داده یک طرفه را سازماندهی می کند و آن را در هر مرحله کنترل می کند.

بسیار مهم است که به یاد داشته باشید که کنترل کننده کار خود را فقط در نتیجه تعامل کاربر با view شروع می کند که عملکرد مربوطه کنترلر را فراخوانی می کند. رایج ترین اشتباه در میان توسعه دهندگان این است که یک کنترلر را به عنوان یک دروازه بین view و مدل در نظر می گیرند. در نتیجه، کنترل کننده دارای عملکردهایی است که view باید انجام دهد (به هر حال، این ایده که view فقط یک فایل الگو است از اینجا می آید). علاوه بر این، بسیاری از مردم تمام منطق پردازش داده ها را به طور کلی حذف می کنند و فراموش می کنند که مدل در الگوی MVC برای چه منظوری در نظر گرفته شده است.

MVC در PHP

پیشنهاد می کنم سعی کنید موارد فوق را در یک برنامه کوچک پیاده سازی کنید. بیایید با ایجاد کلاس های Model، View و Controller شروع کنیم:

string = "MVC + PHP = عالی!"; ))کنترلر = کنترلر $; $ this->

". $ this-> model-> string."

"; } } مدل = مدل $; ))

کلاس های اصلی آماده است. حالا بیایید آنها را با هم پیوند دهیم و برنامه خود را اجرا کنیم:

خروجی ();

همانطور که می بینید، کنترلر هیچ عملکردی ندارد زیرا کاربر به هیچ وجه با برنامه ارتباط برقرار نمی کند. همه عملکردها در نما قرار می گیرند، زیرا برنامه ما صرفاً برای نمایش داده ها است.

بیایید با افزودن مقداری تعامل، برنامه را کمی گسترش دهیم تا ببینیم کنترلر چگونه کار می کند:

string = "MVC + PHP = عالی، اینجا را کلیک کنید!"; ))کنترلر = کنترلر $; $ this-> model = $ model; ) خروجی تابع عمومی () (بازگشت"

مدل-> رشته. "

"; } } مدل = مدل $; ) روی تابع عمومی کلیک کرد () ($ this-> model-> string = "به روز رسانی داده ها، به لطف MVC و PHP!"))

در نهایت، اجازه دهید کد چسب را کمی به روز کنیم:

($ _GET ["عمل"]) (); ) echo $ view-> output ();

عواقب

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

در این آموزش، نحوه ساخت یک سیستم معماری ساده MVC (Model-View-Controller) در PHP 5.1 با استفاده از قابلیت های کتابخانه SPL (کتابخانه استاندارد PHP) را خواهید آموخت.

معرفی

به اولین آموزش کامل PHP 5 خوش آمدید. شما به PHP 5.1 با نصب SPL نیاز دارید زیرا ما از برخی از آخرین ویژگی های PHP 5 استفاده خواهیم کرد.

در این آموزش، من قصد دارم به شما نشان دهم که چگونه یک سیستم MVC ساده بسازید (معماری MVC رایج ترین الگوی طراحی برای برنامه های کاربردی وب بزرگ است). من شما را در تمام مراحل از ابتدا تا انتها برای ایجاد یک سیستم کامل MVC راهنمایی خواهم کرد.

یک نقطه ورودی

یکی از نکات مهم در مورد MVC یک نقطه ورود به برنامه به جای یک دسته از فایل های PHP است که چیزی شبیه به این را انجام می دهند:

ما یک فایل خواهیم داشت که به همه درخواست ها رسیدگی می کند. این بدان معناست که هر بار که نیاز به ایجاد یک صفحه جدید داریم، لازم نیست نگران اتصال global.php باشیم. این "نقطه ورودی واحد" index.php نامیده می شود و در حال حاضر به صورت زیر خواهد بود:

همانطور که می بینید، این اسکریپت هنوز کاری انجام نمی دهد، اما یک دقیقه صبر کنید.

برای هدایت همه درخواست‌ها به صفحه اصلی، از mod_rewrite استفاده می‌کنیم و دستور RewriteRule را در htaccess. تنظیم می‌کنیم. بیایید کد زیر را در فایل .htaccess قرار داده و در همان دایرکتوری index.php ذخیره کنیم:

RewriteEngine در RewriteCond% (REQUEST_FILENAME) -F RewriteCond% (REQUEST_FILENAME) -D RewriteRule ^ (. *) $ Index.php؟ مسیر = 1 دلار

ابتدا بررسی می کنیم که آیا فایل درخواستی با استفاده از دستور RewriteCond وجود دارد یا خیر، و اگر نه، سپس درخواست را به index.php هدایت می کنیم. این بررسی برای وجود فایل ضروری است، زیرا در غیر این صورت index.php سعی می کند تمام درخواست های سایت، از جمله درخواست های تصاویر را پردازش کند. و ما فقط به این نیاز نداریم.

اگر نمی توانید از .htaccess یا mod_rewrite استفاده کنید، باید به صورت دستی همه درخواست ها را به index.php آدرس دهی کنید. به عبارت دیگر، همه پیوندها باید به شکل "index.php? Route = [درخواست به اینجا می رود]" باشند. به عنوان مثال، "index.php؟ مسیر = چت / فهرست".

اکنون که همه درخواست‌ها از یک نقطه ورودی عبور می‌کنند، می‌توانیم شروع به نوشتن اسکریپت index.php کنیم. اولین کاری که باید انجام دهیم این است که سیستم را مقداردهی اولیه کنیم. بیایید دایرکتوری include و در آن فایل startup.php ایجاد کنیم (آن را به عنوان فایل اولیه خواهیم داشت). بیایید کد زیر را در index.php قرار دهیم:

در این مثال، مقداری ثابت اعلام می‌کنیم، متوجه می‌شویم که فایل‌های سیستم کجا هستند، و همچنین بررسی می‌کنیم که نسخه PHP، خوب، حداقل 5.1 باشد.

کار بعدی یک شی Registry برای ذخیره مقادیر سراسری است. به اشیاء مجزا در سیستم ارسال می شود و برای دسترسی به مقادیر سراسری و بدون نیاز به تعیین متغیرها به عنوان "جهانی" یا دسترسی به آرایه $ GLOBALS استفاده می شود. برای اطلاعات بیشتر در مورد شی رجیستری به مقاله "استفاده از مقادیر جهانی در PHP" مراجعه کنید.

کد زیر را بعد از مثال قبلی به فایل startup.php خود اضافه کنید:

$ رجیستری = رجیستری جدید.

اگر اکنون سعی کنید سیستم را راه اندازی کنید، خطای زیر را مشاهده خواهید کرد:

خطای مهلک: کلاس "رجیستری" در g: \ پروژه‌ها \ PHP \ محتوا \ ساده mvc php5 \ دمو \ شامل \ startup.php در خط 12 یافت نشد

البته این برای ما تعجب بزرگی نیست، زیرا هنوز خود کلاس Registry را ننوشته ایم. فایل با کلاس می‌تواند به سادگی با استفاده از تابع include () گنجانده شود (توجه داشته باشید: به هر حال، include () چنین تابعی نیست، اما همچنان یک عبارت زبان، یک ساختار کنترلی است، اگر به کتابچه راهنمای کاربر نگاه کنید). اما بیایید از یکی از ویژگی های جدید در PHP 5 استفاده کنیم: __autoload ().

تابع جادویی __autoload () برای بارگذاری پویا کلاس ها استفاده می شود. هنگامی که PHP یک کلاس غیرموجود را شناسایی می کند، ابتدا تابع __autoload () را فراخوانی می کند و تنها پس از آن خطا می دهد. ما می توانیم از این فرصت برای بارگیری کلاس ها در پرواز استفاده کنیم.

این کد را قبل از کد مثال قبلی قرار دهید:

// بارگذاری کلاس‌ها در تابع fly __autoload ($ class_name) ($ filename = strtolower ($ class_name). ".Php"؛ $ file = site_path. "Classes". DIRSEP. $ Filename; if (file_exists ($ file) = = نادرست) (کاذب برگرداند؛) شامل (فایل $)؛)

تابع __autoload () ما نام کلاس را به عنوان آرگومان می گیرد و بررسی می کند که آیا فایلی با نام مشابه در دایرکتوری کلاس وجود دارد یا خیر. اگر فایلی وجود نداشته باشد، تابع به سادگی false را برمی گرداند و یک خطای مرگبار ظاهر می شود. اما اگر فایل وجود داشته باشد، بارگذاری می شود. آن ها کلاس مورد نیاز اعلام خواهد شد و هیچ خطایی وجود نخواهد داشت.

ما هنوز خود کلاس Registry را ایجاد نکرده ایم، بنابراین خطا همچنان ظاهر می شود. بیایید به آن بپردازیم.

ایجاد کلاس Registry

کلاس Registry برای انتقال مقادیر جهانی بین اشیاء جداگانه استفاده می شود. این در واقع یک کلاس بسیار ساده است که نیاز به پیاده سازی چند روش کوچک دارد.

ابتدا یک دایرکتوری کلاس ها و یک فایل registry.php در آن ایجاد می کنیم. بیایید کد زیر را در registry.php قرار دهیم:

اکنون یک "اسکلت" از کلاس Registry داریم و باید آن را با متدهایی بارگذاری کنیم. بیایید 2 روش بنویسیم: set () برای تنظیم مقادیر و دریافت () برای بدست آوردن مقادیر. همچنین می توانید یک متد remove () برای حذف مقادیر بنویسید. بیایید این متدها را به کلاس Registry اضافه کنیم:

مجموعه تابع (کلید $، $ var) (اگر (isset ($ this-> vars [$ key]) == true) (Exception جدید ("Unable to set var" ". $ Key." ". قبلاً تنظیم شده است. ");) $ this-> vars [$ key] = $ var; return true;) تابع get ($ key) (if (isset ($ this-> vars [$ key]) == false) (return null; ) بازگشت $ this-> vars [$ key];) function remove ($ var) (unset ($ this-> vars [$ key]);)?>

این متدها ساده هستند، عناصر را از آرایه $ vars که یک ویژگی کلاس است، تنظیم، دریافت و حذف می کنند. در متد set () همچنین بررسی می کنیم که آیا مقدار با کلید مشخص شده از قبل وجود دارد یا خیر و اگر وجود داشت، یک استثنا می اندازیم. این برای جلوگیری از بازنویسی تصادفی مقادیر است.

ما اکنون یک کلاس Registry کامل داریم، اما به آن نمی پردازیم. بیایید از یکی از ویژگی های کتابخانه SPL استفاده کنیم: ArrayAccess. SPL (مخفف Standard PHP Library) مجموعه ای از رابط ها و کلاس ها است که برای حل مشکلات رایج طراحی شده است. یکی از رابط های SPL، ArrayAccess، می تواند برای دسترسی به یک شی مانند یک آرایه معمولی استفاده شود. بیایید به مثالی مانند این نگاه کنیم:

مجموعه ("نام"، "دنیس پالت")؛ // مقدار را با استفاده از get () echo $ registry-> get ("name"); // مقدار را با استفاده از دسترسی به آرایه echo $ رجیستری ["name"]؟> دریافت کنید

ترفند این است که رجیستری $ مانند یک آرایه می شود، در حالی که در واقع یک شی است. البته، ArrayAccess هیچ مزیت خاصی ارائه نمی دهد، اما به شما امکان می دهد مقدار کد را کاهش دهید، زیرا لازم نیست هر بار "-> get ()" بنویسید. برای استفاده از این رابط، باید خط اول کلاس ("Class Registry") را به صورت زیر اصلاح کنید:

رجیستری کلاس ArrayAccess را پیاده سازی می کند (

کلمه کلیدی Implements به مفسر می گوید که این کلاسی است که ما رابط را پیاده سازی می کنیم، یعنی همان ArrayAccess.

کلاسی که رابط ArrayAccess را پیاده سازی می کند باید متدهای زیر را داشته باشد:

تابع offset وجود دارد ($ offset) (return isset ($ this-> vars [$ offset])؛) تابع offsetGet ($ offset) (بازگشت $ this-> get ($ offset)؛) تابع offsetSet ($ offset، $ مقدار) ($ this-> set ($ offset، $ value);) تابع offsetUnset ($ offset) (unset ($ this-> vars [$ offset]);)

این روش ها باید خود توضیحی باشد. اطلاعات بیشتر را می توان در اسناد SPL یافت.

اکنون که رابط ArrayAccess را پیاده سازی کرده ایم، می توانیم به شیء مانند یک آرایه معمولی دسترسی داشته باشیم. این به وضوح هم در مثال قبلی و هم در این مثال نشان داده شده است:

دریافت ("نام")؛ // مقدار را با استفاده از دسترسی به آرایه echo $ رجیستری ["name"]؟> دریافت کنید

کلاس Registry اکنون کامل شده است، و اگر بخواهید سیستم را راه اندازی کنید، همه چیز باید کار کند (اگرچه هنوز چیزی خروجی نخواهد شد). ما با فایل اولیه تمام شده ایم و می توانیم به مرحله بعدی در نوشتن سیستم MVC خود برویم: پیاده سازی دسترسی به پایگاه داده، که در معماری MVC "Model" نامیده می شود.

مدل

"M" یا مدل بخشی از سیستم MVC است که مسئول پرس و جو از پایگاه داده (یا منبع خارجی دیگر) و ارائه اطلاعات به کنترل کننده است. بسته به درخواست می‌توان مدل مورد نیاز را بارگیری کرد، اما من ترجیح می‌دهم مرزهای بین مدل و کنترل‌کننده را دقیقاً در این نقطه پاک کنم، یعنی. کنترلر مستقیماً از طریق کتابخانه تعامل پایگاه داده با پایگاه داده کار می کند نه از طریق یک مدل جداگانه. شاید بخواهید آن را متفاوت انجام دهید، این یک موضوع سلیقه ای است.

باید کد مورد نیاز برای ایجاد اتصال پایگاه داده را بنویسیم و در index.php قرار دهیم. کتابخانه های بسیار خوبی برای کار با پایگاه های داده (از جمله خودم، AutoCRUD) وجود دارد، اما PHP 5 قبلاً چنین کتابخانه ای دارد - PDO. بنابراین نیازی به استفاده از دیگری نیست.

بیایید کد زیر را در فایل index.php وارد کنیم (پس از اتصال فایل اولیه):

# اتصال به پایگاه داده $ db = PDO جدید ("mysql: host = localhost; dbname = demo"، ""، "")؛ $ registry-> set ("db"، $ db);

در این مثال، ابتدا یک نمونه جدید از کتابخانه PDO ایجاد می کنیم و به پایگاه داده MySQL خود متصل می شویم. سپس با استفاده از کلاس Registry، متغیر $ db را در سطح جهانی در دسترس قرار می دهیم.

مؤلفه مدل سیستم ما آماده است، پس بیایید به نوشتن کنترلر برویم.

نوشتن یک کنترلر همچنین به معنای نوشتن یک کلاس روتر است که بسته به درخواست، مسئول بارگذاری کنترلر مورد نظر است (به یاد داشته باشید، در index.php، متغیر route $ از طریق URL ارسال می شود).

کلاس روتر

کلاس Router درخواست را تجزیه می کند و سپس کنترلر مورد نیاز را بارگذاری می کند. بیایید یک "اسکلت" از کلاس ایجاد کنیم:

رجیستری = رجیستری $; ))؟>

سپس خطوط زیر را به index.php اضافه کنید:

# بارگذاری روتر $ روتر = روتر جدید ($ رجیستری). $ registry-> set ("روتر"، روتر $);

اولین چیزی که می نویسیم متد setPath () برای تنظیم دایرکتوری است که همه کنترلرهای ما در آن قرار خواهند گرفت. متد شبیه به این است و باید به کلاس Router اضافه شود:

تابع setPath ($ path) ($ path = trim ($ path, "/ \\")؛ $ path. = DIRSEP; if (is_dir ($ path) == false) (exception جدید ("مسیر کنترل کننده نامعتبر:" ". مسیر $." `");) $ this-> path = مسیر $;)

سپس خطوط زیر را به index.php اضافه کنید:

$ router-> setPath (site_path. "controllers");

اکنون که مسیر کنترلرهای خود را تعیین کرده ایم، خود متد را که مسئول بارگذاری کنترلر است، می نویسیم. این متد delegate () نامیده می شود و درخواست را تجزیه می کند. اولین بیت این روش این است:

تابع delegate () (// مسیر $ this-> getController را تجزیه کنید ($ file, $ controller, $ action, $ args);

همانطور که می بینید، از روش دیگری، getController () برای دریافت نام کنترلر و چند متغیر دیگر استفاده می کند. این روش به شکل زیر است:

تابع خصوصی getController (& $ file, & $ controller, & $ action, & $ args) ($ route = (خالی ($ _ GET ["route"]))؟ "": $ _GET ["route"]؛ اگر ( خالی ($ مسیر)) ($ route = "index";) // قسمت های تقسیم شده را دریافت کنید $ route = trim ($ route, "/ \\")؛ $ parts = explode ("/", $ route); // کنترلر صحیح $ cmd_path = مسیر $ this-> را پیدا کنید؛ foreach ($ بخش‌های $ به عنوان قسمت) ($ fullpath = $ cmd_path. $ Part; // آیا پوشه‌ای با این مسیر وجود دارد؟ اگر (is_dir ($ fullpath) ) ($ cmd_path . = $ part. DIRSEP; array_shift ($ part); continue;) // فایل را پیدا کنید if (is_file ($ fullpath. ".php")) ($ controller = $ part; array_shift ($ part) ؛ شکستن index";) $ file = $ cmd_path. $ controller. ".php"؛ $ args = $ قطعات؛)

بیایید به این روش بپردازیم. ابتدا مقدار متغیر مسیر $ را از درخواست دریافت می کند، سپس با استفاده از تابع explode () آن را به قطعات تقسیم می کند. به عنوان مثال، درخواست "اعضا / مشاهده" به آرایه ای مانند این تبدیل می شود: آرایه ('اعضا'، 'نما').

سپس با استفاده از یک حلقه foreach در هر قسمت حلقه می زند و بررسی می کند که آیا آن قسمت یک دایرکتوری است یا خیر. اگر هست، آن را به مسیر فایل متصل می کند و قسمت بعدی را بررسی می کند. این به شما اجازه می دهد تا کنترلرها را در زیر شاخه ها قرار دهید و در نتیجه سلسله مراتبی از کنترلرها را بدست آورید. اگر قسمت فعلی درخواست یک دایرکتوری نیست، بلکه یک فایل باشد، در متغیر کنترلر $ ذخیره می شود و ما از حلقه خارج می شویم، زیرا کنترل کننده مورد نیاز ما پیدا شده است.

بعد از حلقه، متغیر را با نام کنترلر بررسی می کنیم. اگر خالی باشد، از کنترلر "index" استفاده می کنیم که کنترل کننده پیش فرض ما خواهد بود. سپس روش اقدامی را که باید انجام شود مشخص می کند. کنترلر کلاسی است که از چندین متد تشکیل شده است. عمل به یک روش خاص اشاره دارد. اگر هیچ اقدامی مشخص نشده باشد، از "index" - عمل پیش فرض استفاده می کنیم.

در نهایت، با به هم پیوستن سه متغیر مسیر، نام کنترلر و پسوند "php" مسیر کامل فایل کنترلر را دریافت می کنیم.

اکنون که درخواست را تجزیه و تحلیل کردیم، زمان فراخوانی متد delegate () برای بارگذاری کنترلر و اجرای اکشن است. متد کامل delegate () به شکل زیر است:

تابع delegate () (// مسیر $ this-> getController را تجزیه کنید ($ file, $ controller, $ action, $ args); // آیا فایل موجود است؟ اگر (is_readable ($ file) == false) (die ( "404 یافت نشد");) // شامل فایل شامل ($ file); // یک نمونه از کنترلر $ class =" Controller_ " ایجاد کنید. $ Controller؛ $ controller = کلاس $ جدید ($ this-> رجیستری) ؛ // آیا اکشن موجود است؟ If (is_callable (array ($ controller, $ action)) == false) (die ("404 Not Found")); )

پس از تجزیه و تحلیل درخواست با استفاده از متد ()getController، بررسی می کنیم که آیا فایل واقعا وجود دارد یا خیر، و در غیر این صورت، یک پیغام خطای ساده برمی گردانیم.

پس از آن، فایل را با کنترلر متصل می کنیم و یک نمونه از کلاس آن ایجاد می کنیم که باید "Controller_ [name]" نامیده شود. بعداً در مورد کنترلرها با جزئیات بیشتر صحبت خواهیم کرد.

سپس بررسی می کنیم که آیا اکشن مشخص شده (یعنی متد) وجود دارد و آیا امکان فراخوانی آن وجود دارد یا خیر (برای این کار از تابع is_callable () استفاده می کنیم. در نهایت خود عمل را انجام می دهیم که نقش کلاس Router است و به پایان می رسد.

اکنون که کل متد delegate () را نوشتیم، خط زیر را به فایل index.php خود اضافه کنید:

$ router-> delegate ();

اگر اکنون بخواهیم سیستم را راه اندازی کنیم، با خطای زیر مواجه خواهیم شد (البته اگر فهرست کنترلرها هنوز وجود نداشته باشد):

خطای مهلک: استثنا کشف نشده "Exception" با پیام "مسیر کنترل کننده نامعتبر:" g: \ پروژه ها \ PHP \ محتوا \ ساده mvc php5 \ نسخه نمایشی \ کنترلرها \ `" در g: \ پروژه ها \ PHPit \ محتوا \ mvc php5 ساده \ نسخه نمایشی \ classes \ router.php: 18 Stack Trace: # 0 g: \ Projects \ PHP \ content \ simple mvc php5 \ demo \ index.php (13): Router-> setPath ("g: \ Projects \ PHP ... ") شماره 1 (اصلی) در g: \ پروژه‌ها \ PHP \ محتوا \ mvc ساده php5 \ دمو \ کلاس‌ها \ router.php در خط 18

یا خطای "404 Not Found" را خواهیم دید، زیرا هنوز هیچ کنترلی وجود ندارد. اما این همان کاری است که ما اکنون می خواهیم انجام دهیم.

کنترل کننده

کنترل‌کننده‌های سیستم MVC ما نسبتاً ساده هستند و زمان بسیار کمی می‌برند. ابتدا مطمئن شوید که دایرکتوری کنترلرها وجود دارد. بیایید یک فایل controller_base.php در دایرکتوری classes ایجاد کنیم و کد زیر را در آن قرار دهیم:

رجیستری = رجیستری $; ) شاخص تابع انتزاعی (); )؟>

این کلاس انتزاعی، کلاس والد برای همه کنترلرهای ما خواهد بود. این فقط دو کار را انجام می دهد: یک کپی محلی از کلاس Registry نگه می دارد و از متد abstract index () استفاده می کند تا همه کنترل کننده های فرزند را مجبور به پیاده سازی این روش کند.

بیایید اولین کنترلر خود را بنویسیم. بیایید یک فایل index.php در پوشه کنترلرها ایجاد کنیم و کد زیر را در آن قرار دهیم:

ما به تازگی اولین کنترلر خود را ایجاد کرده ایم، و اگر بخواهید سیستم را راه اندازی کنید، می توانید موارد زیر را مشاهده کنید:

این بدان معناست که کلاس Router کار خود را انجام داده و عمل مورد نیاز را از کنترلر مورد نیاز آغاز کرده است. بیایید کنترلر دیگری بنویسیم که با درخواست "اعضا / مشاهده" مطابقت داشته باشد. بیایید یک فایل Member.php در پوشه کنترلرها ایجاد کنیم و کد زیر را در آن وارد کنیم:

حال اجازه دهید به سیستم MVC خود با درخواست "اعضا / مشاهده" یا "index.php؟ مسیر = اعضا / مشاهده" برویم. ما باید نتیجه ای مانند این را ببینیم:

فقط با نوشتن یک کنترلر جدید و اضافه کردن یک متد به آن، توانستیم یک صفحه جدید ایجاد کنیم و در خود سیستم چیزی تغییر نمی کرد. همچنین، کنترل‌کننده‌های ما نیازی به گنجاندن فایل global.php یا هر چیز دیگری ندارند.

اکنون که کنترلرهای خود را داریم، تنها یک چیز باقی مانده است: "V" یا "View".

نمایش دادن

مانند مدل ها، چندین گزینه مختلف برای ایجاد یک کامپوننت View در یک سیستم MVC وجود دارد. ما می‌توانیم به کلاس روتر آموزش دهیم که فایل دیگری با نام چیزی مانند "view_ (name) .php را به طور خودکار بارگذاری کند. اما برای واضح تر شدن آموزش، اجازه دهید یک کلاس Template بنویسیم که رندر قالب ها را انجام می دهد.

ابتدا یک فایل template.php در دایرکتوری classes ایجاد کنید و کد زیر را در آن قرار دهید:

رجیستری = رجیستری $; ))؟>

ما اکنون ساختار اصلی کلاس Template خود را داریم. مرحله بعدی این است که این کد را درست قبل از خطوط مرتبط با کلاس Router به فایل index.php خود اضافه کنیم:

# ایجاد یک شی الگو $ template = الگوی جدید ($ رجیستری); $ registry-> set ("الگو"، قالب $);

از آنجایی که باید از مقادیر مدل ها و کنترلرها استفاده کنیم، یک متد set () برای تنظیم متغیرهای موجود در قالب ها می نویسیم. بیایید به یک مثال نگاه کنیم:

مجموعه تابع ($ varname، مقدار $، $ overwrite = false) (if (isset ($ this-> vars [$ varname]) == true AND $ overwrite == false) (trigger_error ("Unable to set var` ". $ varname. "'. قبلا تنظیم شده است، و رونویسی مجاز نیست."، E_USER_NOTICE؛ return false;) $ this-> vars [$ varname] = $ value; return true;) تابع remove ($ varname) (تنظیم نشده ($) this-> vars [$ varname])؛ بازگشت true;)

متدهای set () و remove () نسبتا ساده هستند و به ترتیب برای تنظیم و حذف متغیرها استفاده می شوند.

بیایید شروع به نوشتن یک متد show () کنیم که قالب ها را نمایش می دهد. ساده ترین راه این است که یک دایرکتوری قالب جداگانه ایجاد کنید تا تمام فایل های قالب را ذخیره کنید و از include () برای ارائه الگو استفاده کنید. البته روش show () خود شما می تواند کاملاً متفاوت باشد و قالب ها را از پایگاه داده بارگیری کند یا کار دیگری انجام دهد. بیایید به کوسو نگاه کنیم

آرا: 745 | بازدید: 8080

با وجود اینکه ممکن است معنای عبارت معماری سایت برای شما شهودی باشد، سعی می کنیم مطالعه کنیم تعدادی از تعاریفمتعلق به منابع معتبر

معماری- این سازمان اساسی سیستم است که در اجزای آن، روابط آنها با یکدیگر و با محیط، و همچنین اصولی که طراحی و توسعه سیستم را تعیین می کند، تجسم یافته است.

معمارییک برنامه یا یک سیستم کامپیوتری ساختار یا ساختارهای یک سیستم است که شامل عناصر یک برنامه، ویژگی های این عناصر از بیرون قابل مشاهده و رابطه بین آنها [Bas] است.

معماریساختار سازمان و رفتار مرتبط با آن سیستم است. یک معماری را می توان به صورت بازگشتی به قطعاتی تقسیم کرد که از طریق رابط ها، روابطی که قطعات را به هم متصل می کنند و شرایط مونتاژ قطعات با یکدیگر تعامل دارند. بخش هایی که از طریق رابط ها با هم تعامل دارند شامل کلاس ها، اجزا و زیرسیستم ها هستند.

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

پس معماری برنامه چیست؟

تعاریف ارائه شده در بخش قبل برای درک آنها توسط یک خواننده ناآماده بسیار خشک است. ما سعی خواهیم کرد که اصل را به ساده ترین شکل ممکن توضیح دهیم.

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

بنابراین، اولین سوال در حال آماده شدن است: چگونه برنامه را به فایل ها تقسیم کنیم. معماری فایل یک برنامه یکی از جنبه های ساختار آن است.

در حین برجسته کردن ماژول های سیستم، باید درک کرد که آنها در چه رابطه ای با یکدیگر خواهند بود. به عنوان مثال، ماژول های دسترسی به پایگاه داده و پردازش تصاویر گرافیکی به سختی نیاز به دانستن چیزی در مورد وجود یکدیگر دارند. اما ماژول UI در مورد هر دوی آنها می‌داند (و نمی‌دانند).

رابطه بین اجزای یک سیستم نیز توسط معماری آن تعیین می شود.

به طور کلی، تمام تصمیمات مهم با هدف سازماندهی یک برنامه، و نه مشکلات حل شده با کمک آن، را می توان به معماری نسبت داد.

سطوح انتزاع

هنگام طراحی ماژول ها (انتخاب گروه هایی از توابع و توزیع آنها بین فایل ها در مورد رویکرد رویه ای)، مهم است که انتزاع ها را انتخاب کنید و سعی کنید آنها را به چندین سطح تجزیه کنید.

ماژول های سطح پایین تا حد امکان مستقل هستند، آنها به بخش های دیگر برنامه وابسته نیستند. ماژول های خوب طراحی شده، "دنیای بیرون" را از پیچیدگی های کار در دست جدا می کند. تماس گیرنده فقط رابط ماژول (عملکردهای خارجی) را می داند، قسمت داخلی به آن بسته است.

بیایید یک گالری عکس را به عنوان نمونه در نظر بگیریم. اطلاعات مربوط به تصاویر و کاربران در پایگاه داده ذخیره می شود، رابط کاربری به بخش مشتری و پنل مدیریت تقسیم می شود.

ساختار برنامه می تواند مانند شکل زیر باشد:


این مثال ردیابی می کند سه سطح انتزاع.

هر برنامه ای که برای استفاده انسانی در نظر گرفته شده است را می توان حداقل به دو سطح تقسیم کرد: رابط کاربری و مدل. ماژول رابط کاربری برای ارائه و تجسم داده ها و پردازش واکنش های کاربر طراحی شده است. مدل حاوی منطق مشکل در حال حل است و به هیچ وجه نباید به نحوه نمایش داده ها وابسته باشد. مدل باید به راحتی بین انواع مختلف رابط کاربری قابل حمل باشد.

معماری MVC

اکنون محبوب است الگوی طراحی MVC... این برای جدا کردن منطق برنامه از رابط کاربری است. اما ابتدا اجازه دهید روشن کنیم که الگوی طراحی چیست.

این مجموعه ای از راه حل های طراحی معمولی، چارچوبی از یک معماری یا قطعه آن است. اگر یک کتابخانه بسته ای از کدهای قابل استفاده مجدد است، پس یک الگوی طراحی بسته ای از راه حل های قابل استفاده مجدد است.

بنابراین MVC برای جدا کردن منطق برنامه از رابط کاربری چه چیزی به ما ارائه می دهد؟

نمونه MVC به شما امکان تقسیم می دهدداده ها، ارائه و پردازش اقدامات کاربر به سه جزء مجزا:

  1. مدل... مدل داده ها را ارائه می دهد (معمولاً برای View) و همچنین با تغییر وضعیت به درخواست ها (معمولاً از کنترل کننده) پاسخ می دهد.
  2. چشم انداز... مسئول نمایش اطلاعات (رابط کاربری)؛
  3. کنترل کننده... ورودی کاربر را تفسیر می کند و مدل و دیدگاه را از نیاز به پاسخ مناسب آگاه می کند.

شکل زیر روابط بین اجزای یک وایرفریم را نشان می دهد. بیایید تصویر را با یک مثال کوچک نشان دهیم.


فرمی را تصور کنید که در آن می‌توانید متن را وارد کنید، روی دکمه ویرایش کلیک کنید و نویسه‌گردانی آن را دریافت کنید:


بیایید مراحل نشان داده شده در نمودار را تکرار کنیم:

  1. کاربر روی دکمه Edit کلیک می کند و نمایندگی(مشاهده) یک پیام ارسال می کند کنترل کننده(کنترل کننده): "فرمان: ویرایش"
  2. کنترل کننده قبول می کندپیام داده و با فراخوانی متد Edit () به مدل دسترسی پیدا می کند.
  3. در نتیجه تغییرات مدلوضعیت آن (متن نویسه‌گردانی شده ذخیره شده در آن) و دیدگاه مربوط به آن را مطلع می‌کند: "رویداد: تغییر کرد".
  4. ارسال طول می کشدسیگنال می دهد و با فراخوانی متد Get () آن به مدل برای یک مقدار نتیجه جدید اشاره می کند.

پیاده سازی MVC

پیاده سازی MVC یک رویکرد شی گرا (OOP) را در نظر می گیرد. با این حال، یک الگوی طراحی فقط مجموعه ای از راه حل ها است. بیایید بدون استفاده از OOP آنها را برای PHP تطبیق دهیم. ساده سازی به منظور تمرکز بر ماهیت جداسازی منطق انجام می شود و همچنین به این ترتیب که مطالب توسط خواننده ای که با OOP آشنایی ندارد قابل استفاده باشد.

دوباره در نظر بگیرید مثال با گالری عکس.
دارای دو حالت نمایش است:

  1. حالت نمایش بند انگشتی (همه به یکباره)؛
  2. حالت نمایش عکس در اندازه کامل (تک).

احتمال هم هست عکس ها را آپلود کنیدبه سرور علاوه بر این، برای درک انعطاف‌پذیری چارچوب، پشتیبانی از انواع تجسم را اجرا خواهیم کرد.

سایت خواهد شد دو نقطه ورود:

  1. index.php (مشاهده گالری);
  2. photo.php (مشاهده عکس در اندازه کامل).
این دو فایل در نظر گرفته خواهد شد کنترل کننده ها.

مانند مدل هاماژولی وجود خواهد داشت که کار با ذخیره سازی تصویر را فراهم می کند. بیایید آن را صدا کنیم gallery.phpو در پوشه قرار دهید مدل.

در نقش نمایندگیقالب های HTML ارائه خواهند شد، آنها در پوشه قرار خواهند گرفت قالب ها... قالب ها چیست و برای چه هستند - در ادامه مشاهده خواهد شد.

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

نمای گالری دو نوع تصویرسازی خواهد داشت:

  1. به عنوان یک جدول (پیش فرض)؛
  2. نمای فهرستی.
ما به چهار قالب نیاز داریم:
  1. main.php (اسکلت صفحه);
  2. content_index_table.php (نمایش جدولی محتوای گالری);
  3. content_index_list.php (نمای لیست محتوای گالری)؛
  4. content_photo.php (محتوای صفحه مشاهده عکس).

به نظر می رسد ساختار سایت زیر است:


ساختار فایل با دو خط افقی تقسیم می شود که سه بخش را تشکیل می دهند. فایل های قسمت بالا به Model، فایل های قسمت میانی به View و فایل های قسمت پایین به Controller اشاره دارند.

مدل

بیایید با پیاده سازی Model شروع کنیم. کد زیر به طور کامل برای کمینه سازی و وضوح بهتر مثال ارائه نشده است.

ما فقط رابط مدل را تعریف کرده‌ایم و اجرای آن را نادیده می‌گیریم. با این حال، برای اجرای مثال چارچوب MVC، اصلاً نیازی به آن نیست.

نمایندگی

حالا بیایید به الگوها نگاه کنیم. بیایید با یک اسکلت کلی صفحه شروع کنیم:

<?=$title?>

شما نباید با این واقعیت گیج شوید که این الگو از منبع ناشناخته متغیرهای $ title و $ content استفاده می کند. آنها توسط کنترلر جایگزین خواهند شد. اما در ادامه بیشتر در مورد آن.

علامت اختصاری است .

استفاده از آن در قالب ها راحت است. همچنین استفاده از انواع جایگزین برای نوشتن ساختارهای if-else, foreach, for, while در قالب‌ها نیز راحت‌تر است. آنها به این شکل هستند:

اگر (<условие>): <тело>endif; برای هر (<инициализация цикла>): <тело>endforeach;

بقیه قالب ها به این صورت در main.php قرار می گیرند:

در مثال های زیر کد آنها نشان داده شده است:

الگوها / content_index_table.php

جدول| فهرست کنید

"> " />



الگوها / content_index_list.php

جدول | فهرست کنید

"> " />



templates / content_photo.php: برگشت

" />

کنترل کننده

در نهایت، بیایید همه آن ها را با توصیف دو کنترلر خود کنار هم بگذاریم. وظیفه آنها پردازش درخواست، انتخاب یک الگو و جایگزینی داده های مورد نیاز الگو است. داده ها، به عنوان یک قاعده، از مدل گرفته می شود.

اگر کاربر فایلی را آپلود کرده باشد، کنترل کننده گالری عکسی را آپلود می کند. در غیر این صورت، لیستی از عکس ها را از مدل استخراج می کند، قالب مورد نظر را انتخاب می کند (بسته به میل کاربر) و این الگو را نمایش می دهد و لیستی از عکس ها را به آن می دهد:

کد Index.php

کنترلر نمای عکس حتی ساده تر است:

کد Photo.php

سرانجام

سعی کنید به معماری اپلیکیشن خود توجه کافی داشته باشید. اگر در ابتدا یک چارچوب قوی و قابل توسعه ایجاد می کنید، تلاش نتیجه خواهد دادصد برابر

برای پیاده سازی مدل MVC بهتر است انتخاب کنید رویکرد شی گرا .

راه حل های فریمورک خارج از جعبه زیادی وجود دارد، به عنوان مثال در چارچوب Zend. با این حال، اطلاعات موجود در درس فعلی برای درک راه حل های معماری MVC و شروع استفاده از آنها کافی است.

MVC چیست؟

بنابراین، MVC همه چیز در مورد رابط کاربری (UI) است. لزوماً گرافیکی نیست، کنترل صدا نیز خوب است. فراموش نکنیم که یک برنامه ممکن است رابط کاربری نداشته باشد، ممکن است رابط برنامه نویسی (API) داشته باشد یا اصلا نداشته باشد و همچنان مفید باشد.

اما اگر یک کاربر داریم، پس باید یک رابط کاربری وجود داشته باشد. رابط چیست؟ این مرز مجاور بین دو سیستم است. در مورد ما: از یک طرف - برنامه، از سوی دیگر - کاربر. اینجا اند.

برنامه کاملاً انتزاعی است، هر کد موضوعی. او می داند که چگونه کار مفیدی انجام دهد و کاربر نیازهایی دارد که می تواند با این برنامه ارضا شود. سپس بخش‌هایی از منطق ظاهر می‌شود که «می‌دانند» چگونه با استفاده از این برنامه، مستقیماً آنچه کاربر می‌خواهد انجام دهند. قطعات موضوعی نیستند، منطق موضوعی در برنامه است. آنها بیشتر به کاربر با نیازهای خاص او مرتبط هستند و ترکیبی از تماس ها و تماس های برنامه هستند.

موارد استفاده کنید

به عنوان مثال، ترمینالی را برای تجارت در بورس تصور کنید. کاربر ترمینال برنامه ای را قرار می دهد که در آن نشان می دهد که می خواهد 20 سهم شرکت Svetlyi Put را به قیمت هر سهم 1500 روبل بخرد. همچنین نشان می دهد که برنامه به مدت چهار ساعت اعتبار دارد و در صورت موفقیت آمیز بودن تراکنش باید از کدام یک از حساب های وی پول برداشت شود.

تعداد قابل لمسی از ویژگی ها. مدتی می گذرد و او متوجه می شود که خرید با چنین قیمتی امکان پذیر نخواهد بود و آماده است تا قیمت را به 1550 روبل افزایش دهد و تمام مقادیر دیگر را ترک کند. سپس این برنامه را انتخاب می کند، روی دکمه "تغییر" کلیک می کند، قیمت جدید را نشان می دهد، بله. راحت است.

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

بیایید نمودار خود را با مکانی برای موارد استفاده تکمیل کنیم.

همچنین باید به کاربر فرصت داده شود تا این موارد استفاده را بکشد و نتیجه را بگیرد. اینها می توانند دکمه ها و سایر عناصر ورودی-خروجی گرافیکی، حرکات، تشخیص و ترکیب گفتار باشند. هر گزینه ای برای تبادل داده و دستور. Voila:

کاربر برخی از موارد استفاده را می کشد، که به نوبه خود، برنامه را دستکاری می کند. برنامه نتیجه یا تغییرات در وضعیت خود را منتشر می کند.

پس MVC کجاست؟

تنها چیزی که باقی می‌ماند این است که نام‌های آشنا را برای اجزای به‌دست‌آمده بگذاریم.

وقتی مدل تغییرات را منتشر می کند، برای چه کسی مهم نیست، چیزی در مورد View نمی داند. به جای View یا همراه با آن، ممکن است زیرسیستم دیگری در انتهای دیگر وجود داشته باشد.

حالا چند جزئیات.

این یک نوع کلاسیک MVC - Active Model بود. همچنین اتفاق می افتد که مدل در مورد تغییرات اطلاع نمی دهد. سپس کنترلر این مسئولیت را بر عهده می گیرد. او می داند که چه نوع دستکاری هایی روی مدل انجام می دهد، و بدیهی است که می داند چه تغییراتی در وضعیت مدل ممکن است به دنبال داشته باشد. این مدل منفعل است.

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

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

مقالات مرتبط برتر