• 5 رای - 3 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
منطق MVC و ساخت آن
#1
چند روز پیش یکی از بچه ها از من درخواست کرد که یه آموزش در این رابطه بزارم.
اول از همه یه نگاه کلی به ام وی سی می اندازیم.

[عکس: mvc-php.png]

یکی یکی مراحل رو توضیح میدم.
1. توسط Browser یک در خواست به وب سرور صادر می شه.
2. وب سرور درخواست رو به Routes منتقل می کنه
{ توجه داشته باشید که وظیفه یک Routes این هست که URL رو بررسی کنه }
3. بعد از بررسی URL برای فراخوانی توابع اطلاعات به Dispatcher انتقال داده می شه
{ وظیفه Dispatcher در ابتدا لود لایبراری های لازم مودل و ... هست }
4. Dispatcher بسته به اطلاعات دریافتی کنترلر مورد نظر رو فراخوانی می کنه.
5. کلاس کنترلر لایبراری ها و مودل های مورد نیاز رو در اختیار برنامه نویس قرار می ده
6. کنترل بعد از تبادل اطلاعات با مودل ( وظیفه مودل برقراری ارتباط با دیتابیس و انجام کوئری هست ) اطلاعات مورد نیاز رو برای VIEW می فرسته.
7. در نهایت بعد اجرا شدن VIEW کلاس کنترلر اطلاعات حاصل شده رو به وب سرور و بعد از اون وب سرور هم اطلاعات رو برای Browser می فرسته.

شاید اولین سوالی که برای شما پیش این باشه که چرا این همه دردسر بکشیم ، همونجا می نویسیم می ره.

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

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

چرا انعطاف پذیری رو بیشتر می کنه ؟
به این دلیل. فرض رو بر این میگیریم که شما نیاز به یک سیستم درختی دارید. یه تابعی که اطلاعات رو به صورت درختی نشون می ده. اگر شما بصورت Line کد نویسی می کنید مجبورید در تمام صفحاتی که به این تابع نیاز دارید فایل مورد نظر رو Include کنید و وای به اون روزی که اسم اون فایل به هر دلیلی نیاز به تغییر داشته باشه حالا یکی یکی تمام صفحات رو باید ادیت کنید. در حالی که در MVC برای گسترش VIEW می تونید Helper بسازید و تعریف کنید که این لودر در تمامی VIEW ها لود بشه و استفاده کنید. در اکثر فریم ورک ها به چنین توابعی هلپر گفته می شه.

و هزاران دلیل دیگه.

در آینده با هم یک MVC می سازیم تا بهتر بتونید این مفهوم رو درک کنید.
  پاسخ
#2
نقل قول:منظورم اینه که غلط املاییه یا همون وب سرویس منظورته
ولی آخه وب سرویس چیز دیگه ایه - ربطی به این نداره؟ داره؟
بله درسته غلط املایی نبود اما اشتباه تایپی بود . جهت اطلاع :
کد:
A web server is a computer program that delivers (serves) content, such as this web page, using the Hypertext Transfer Protocol. The term web server can also refer to the computer or virtual machine running the program.
چند تا وب سرور هم برات مثال می زنم
کد:
||||||||||||||||||||||||||||||||||
|||  Vendor  |||||    Product  |||
|||----------|||||-------------|||
|||  Apache  |||||    Apache   |||
|||----------|||||-------------|||
||| Microsoft|||||      IIS    |||
|||----------|||||-------------|||
|||Igor Sysoev |||   nginx     |||
|||----------|||||-------------|||
|||  Google  |||||     GWS     |||
|||----------|||||-------------|||
||| lighttpd |||||  lighttpd   |||
||||||||||||||||||||||||||||||||||

نقل قول:انشا الله کی استارت نوشتن MVC رو میزنید ؟

امشب اگر بتونم.
  پاسخ
تشکر شده توسط : molana php ARA moh3nmir farzin764
#3
می گم بچه ها بیاین فعلن اسکوتر رو سرگرم کنیم تا هایدن پیداش بشه.

البته بنده خدا به شدت حالش بده. دیروز که با وحید باهاش می چتیدیم عنوان کرد که به شدت حالش بده.

امیدواریم هرچه زودتر حالش بهتر بشه.
واقعن جای خالیش احساس می شه
همه جوره اش رو داریم ظاهرن
  پاسخ
تشکر شده توسط :
#4
اي كاش يه تاييك به عنوان سوالات ميزدي كه آموزشهات فاصله بهش نمي خورد ايشالله هر چه زودتر خوب شي و ما منتظريم
  پاسخ
تشکر شده توسط :
#5
ما شدیدا منتظر آموزش هستیم ... Rolleyes
  پاسخ
تشکر شده توسط :
#6
این ام وی سی فقط و فقط برای آموزش طراحی شده. بدیهی است که استفاده تجاری از آن به عهده خود شخص خواهد بود
توجه داشته باشید که این ام وی سی بصورت خیلی ساده و فقط برای آموزش مفهوم آن پیاده سازی شده است

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

کد:
File Name : index.php
Dir : root
کد پی‌اچ‌پی:
<?php
error_reporting
(E_ALL);
$site_path realpath(dirname(__FILE__));
define ('__SITE_PATH'$site_path);
include 
'includes/init.php';
$registry->router = new router($registry);
$registry->router->setPath (__SITE_PATH '/controller');
$registry->template = new template($registry);
$registry->router->loader();
?>
همونطور که مشاده می کنید این فایل اولین فایلی هست که اجرا می شه و معمولا در فریم ورک ها این فایل با واسطه یک یا چند فایل دیگر شکل کلی فریم ورک رو می سازه.

مرور خط به خط
۱. در ابتدا با استفاده از تابع error_reporting از مفسر PHP تقاضای نمایش تمامی خطا هارو می کنیم. ( اطلاعات بیشتر )
۲. با استفاده از تابع dirname و realpath مکان فعلی فایل رو درون متغیر site_path میریزیم. ۰( اطلاعات بیشتر )
۳. مکان فعلی فایل را با استفاده از define درون یک ثابت می ریزیم تا بتونیم هرجا که نیاز بود ازش استفاده کنیم. ( اطلاعات بیشتر )
۴. حالا فایل init.php که وظیفه لود کردن تمامی فایل های مورد نیاز رو داره فراخوانی می شه.
۵. در این خط router که وظیفه تغکیک URL و فراخوانی Controller رو داره فراخوانی می شه.
۶. سپس مشخص می شه که router باید کنترلر ها رو از کجا بخونه.
۷. سپس template که وظیفه جابه جایی متغیر ها بین Controller و View رو داره فراخوانی می شه.
۸. تابع اصلی router که وظیفه انجام عملیات های کلی رو داره فراخوانی می شه.

می دونم که سوال های زیادی پیش میاد برای شما مخصوصا از شماره ۵ به بعد. اما صبر کنید و این آموزش رو تا آخر بخونید.
کد:
File Name : init.php
Dir : root/include
کد پی‌اچ‌پی:
<?php
 
include __SITE_PATH '/application/' 'controller_base.class.php';
 include 
__SITE_PATH '/application/' 'registry.class.php';
 include 
__SITE_PATH '/application/' 'router.class.php';
 include 
__SITE_PATH '/application/' 'template.class.php';
 
 function 
__autoload($class_name) {
    
$filename strtolower($class_name) . '.class.php';
    
$file __SITE_PATH '/model/' $filename;

    if (
file_exists($file) == false)
    {
        return 
false;
    }
 include (
$file);
}
 
$registry = new registry;
?>

همونطور که قبلا اشاره کرده بودم تمام فریم ورک ها دارای یک یا چند فایل هستد که فایل های اصلی توسط اون فایل یا فایل ها فراخوانی می شوند. اینجا از این فایل برای فراخوانی هسته فریم ورک استفاده شده. در خط های ابتدایی همه چیز ساده هست چند تا کلاس رو فراخوانی کردیم که به ترتیب وظایفشون مدیریت کنترلر و مدیریت متغیر ها و مدیریت URL و فراخوانی ها و در نهایت مدیریت قالب هست. اما چرا از تابع autoload استفاده شد ؟ اینجا به دلیل اینکه فقط کار باید ساده باشه از این تابع استفاده شده وگر نه بهتر هست که یک کلاس به عنوان loader وجود داشته باشه. همونطور که مشخصه این تابع برای لود کردن Model ها کارایی داره برای اطلاعات بیشتر در مورد این تابع به اینجا مراجعه کنید

این آموزش ادامه داره. برای یک پارچه سازی و هدفمند کردن این تاپیک کلیه تاپیک های غیر مرتبط حدف می شوند. از دوستان معذرت خواهی می کنم.
  پاسخ
#7
قسمت دوم
کد:
File Name : controller_base.class.php
Dir : root/application
کد پی‌اچ‌پی:
<?php
Abstract Class baseController {
protected 
$registry;
function 
__construct($registry) {
    
$this->registry $registry;
}
abstract function 
index();
}
?>
این کلاس وظیفه مدیریت کنترلر ها رو به عهده داره. البته بیشتر می شه گفت ساختار کنترلر رو مشخص می کنه. شما می تونید با اضافه کردن متد به این کلاس توانایی اون رو بالا ببرید در آینده این کار رو انجام خواهیم داد.
کاراین کلاس خیلی سادست فقط اگر کسی در مورد Abstract براش سوال پیش اومد اینجا رو بخونه اگر متوجه نشد اینجا بپرسه.
این کلاس از نوع Abstract تعریف شده و یک تابع به نام index داره که اون هم از همین نوع هست ( طبق قوانین یک تابع اگر Abstract باشه باید کلاس اون هم Abstract باشه ) و این باعث می شه تا تمامی کلاس های فرزند حتما یک تابع index داشته باشند.


کد:
File Name : registry.class.php
Dir : root/application
کد پی‌اچ‌پی:
<?php
Class Registry {
 private 
$vars = array();
 public function 
__set($index$value)
 {
    
$this->vars[$index] = $value;
 }
 public function 
__get($index)
 {
    return 
$this->vars[$index];
 }
}
?>

این کلاس وظیفه دست به دست کردن کلاس های دیگر رو به عهده داره و چیز زیادی هم نداره می تونید برای اطلاعات بیشتر در مورد get , set اینجا رو مطالعه بفرمایید.

کد:
File Name : router.class.php
Dir : root/application
کد پی‌اچ‌پی:
<?php

class router {
 private 
$registry;
 private 
$path;
 private 
$args = array();
 public 
$file;
 public 
$controller;
 public 
$action
 function 
__construct($registry) {
        
$this->registry $registry;
 }
 function 
setPath($path) {
    if (
is_dir($path) == false)
    {
        throw new 
Exception ('Invalid controller path: `' $path '`');
    }
     
$this->path $path;
}

 public function 
loader()
 {
    
$this->getController();
    if (
is_readable($this->file) == false)
    {
        
$this->file $this->path.'/error404.php';
                
$this->controller 'error404';
    }
    include 
$this->file;
    
$class $this->controller 'Controller';
    
$controller = new $class($this->registry);
    if (
is_callable(array($controller$this->action)) == false)
    {
        
$action 'index';
    }
    else
    {
        
$action $this->action;
    }
    
$controller->$action();
 }

private function 
getController() {

    
$route = (empty($_GET['rt'])) ? '' $_GET['rt'];

    if (empty(
$route))
    {
        
$route 'index';
    }
    else
    {
        
$parts explode('/'$route);
        
$this->controller $parts[0];
        if(isset( 
$parts[1]))
        {
            
$this->action $parts[1];
        }
    }
    if (empty(
$this->controller))
    {
        
$this->controller 'index';
    }
    if (empty(
$this->action))
    {
        
$this->action 'index';
    }
    
$this->file $this->path .'/'$this->controller 'Controller.php';
}


}

?>
این کلاس اصلی ترین کلاس در این ام وی سی هست. وظیفه این کلاس فراخوانی کنترلر موبوطه هست.
تابع setPath نگاه می کنه که آیا مسیر کنترلر ها به درسته انتخاب شده یا نه و اگر جواب منفی هست یک خطا رو نشون می ده
تابع getController باید کنترلری که باید فراخوانی بشه رو از روی URL تشخیص بده. همونطور که می بینید اینجا برای اینکه کار ساده باشه از GET استفاده شده.
تابع loader نگاه می کنه که آیا کنترلری که باید فراخوانی بشه وجود داره یا خیر و اگر این طور بشه خطای ۴۰۴ رو نمایش می ده که اون هم یک کلاس هست مثل کنترلر

کد:
File Name : template.class.php
Dir : root/application
کد پی‌اچ‌پی:
<?php

Class Template {
private 
$registry;
private 
$vars = array();
function 
__construct($registry) {
    
$this->registry $registry;

}
 public function 
__set($index$value)
 {
        
$this->vars[$index] = $value;
 }
function 
show($name) {
    
$path __SITE_PATH '/views' '/' $name '.php';

    if (
file_exists($path) == false)
    {
        throw new 
Exception('Template not found in '$path);
        return 
false;
    }

    
// Load variables
    
foreach ($this->vars as $key => $value)
    {
        $
$key $value;
    }

    include (
$path);               
}
}

?>
این کلاس وظیفه فراخوانی VIEW رو به عهده داره. اگر فایل مورد نظر وجود نداشته باشه خطا نشون می ده.
متغیر هایی که ست شده باشند رو می سازه و بعد از اون VIEW رو اینکلود می کنه خیلی ساده.
قسمت سوم : ساخت اولین کنترلر و ویو
کد:
File Name : indexController.php
Dir : root/controller
کد پی‌اچ‌پی:
<?php

Class indexController Extends baseController {

public function 
index() {
    
        
$this->registry->template->welcome 'Welcome to PHPRO MVC';
    
        
$this->registry->template->show('index');
}

}

?>

این هم ویو
کد:
File Name : index.php
Dir : root/views
کد پی‌اچ‌پی:
<h1><?php echo $welcome?></h1> 

توضیح نمی دم . چیز خاصی نیست. از ابتدا آموزش رو بخونید. فایل رو هم می گذارم اینجا که دانلود کنید.


فایل‌های پیوست
.zip   mvc.zip (اندازه 6.42 KB / تعداد دانلود: 172)
  پاسخ
#8
ای کاش وظیفه هر یک از app مثل router , registery , controller_base ... را هم توضیح می دادین .
و ممنون میشم بگین وقتی یه مدل داشته باشیم که آرگومان های برای اتصال به دیتا رو داشته باشه ، چطوری میشه در کنترولر ها مون استفاده کرد
  پاسخ
تشکر شده توسط :
#9
این مدل و کار با دیتابیسش چی شد پس ؟
---------------------------------------------------------------------------
خدایا ، مگر می شود تو باشی و ما تنها باشیم ؟
  پاسخ
تشکر شده توسط : shgninc
#10
تو فایل controller_base.class.php
Abstract چیکارست؟ یه توضیح میدین UndecidedUndecided
  پاسخ
تشکر شده توسط :


پرش به انجمن:


کاربران در حال بازدید این موضوع: 2 مهمان