PDA

View Full Version : آموزش: آموزش ساخت فریم ورک MVC



Mr.Moghadam
سه شنبه 17 اسفند 1389, 12:24 عصر
آموزش ساخت فریم ورک MVC

سلام

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

اینجا میتونید در مورد اینکه MVC چی هست اطلاعات بیشتری به دست بیارید (http://barnamenevis.org/showthread.php?277873-%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-%D9%85%D9%81%D9%87%D9%88%D9%85-MVC)




قبل از هر چیز باید یه سری قوانین نامگذاری برای فریم ورکمون قرار بدیم :

1- نام کلاس کنترلرها باید با حرف بزرگ شروع بشه وبا Controller ادامه پیدا کنه.
class UserController extends Controller

2- نام فایل کنترلر ها که در پوشه app/Controllers/ قرار میگیره باید به صورت زیر باشه
user_controller.php

3- نام کلاس model که داخل پوشه app/Models قرار میگیره باید با نام جدولمون یکی باشه و با حروف بزرگ نوشته بشه.

خوب میگم تا اینجا اینارو داشته باشید کم کم که رفتیم جلو با کمک شما قوانین رو اضافه میکنیم.

خوب ابتدا از ساختار پوشه ها شروع میکنیم




Root/
app/
/Controllers
/Models
/Views
core/
config/
library/
.htaccess
Index.php
حالا میریم سراغ فایل .htaccess و کدهای زیر داخلش مینویسیم :

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?rt=$1 [L,QSA]

توی کدهای بالا خط اول و دوم چک میکنه که اگر url که درخواست شده فایل یا پئشه نبود اونوقت نام فایل index.php رو بیا از url حذف کن.

حالا فایل index.php که شامل کدهای زیر میشه :




<?php

define("ROOT",dirname(__FILE__));
define("DS",DIRECTORY_SEPARATOR);
define("BASE_URL","http://127.0.0.1/ar/");
$base = "/";

include (ROOT.DS."core".DS."Sql.php");
include (ROOT.DS."core".DS."Model.php");
include (ROOT.DS."core".DS."Base.php");
include (ROOT.DS."core".DS."Controller.php");

include (ROOT.DS."core".DS."load.php");

$url = $_SERVER['REQUEST_URI'] ;
$url = str_replace($base,"",$url);
$url = explode("/",$url);
$uri['controller'] = $url[0];
$uri['model'] = ($uri['controller']);
array_shift($url);
$uri['action']= $url[0];
array_shift($url);
$uri['param'] = $url;
$base = new Base();
$base->uri = $uri;
$base->load_controller();




فکر میکنم توی این فایل همه چیز واضح باشه .

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

http://www.example.com/user/login

که user نام کنترلرمون هست و login نام اکشن یا تابع .

ما اومدیم از خط 8 تا خط 16 url رو با کاراکتر "/" از هم جدا کردیم و قسمت اولش رو کنترلر ، قسمت دومش رو اکشن و باقیش رو پارامترهای ارسالی به اکشن در نظر گرفتیم.

در خط 19 هم درون متغیر uri از کلاس base قرار دادیم.

ودر خط 20 اومدیم کنترلر مورد نظرمون رو لود کردیم.


خوب تا اینجاش رو داشته باشید تا قسمت دوم رو هم قرار بدم


موفق باشید

Mr.Moghadam
سه شنبه 17 اسفند 1389, 16:39 عصر
سلام

محتویات فایل Base.php که در پوشه core قرار داره




<?php

class Base
{
var $library;
var $model;
var $uri;

function __construct()
{

}

function load_controller()
{
$controller_name = $this->uri['controller'];
$action = $this->uri['action'];
$param = $this->uri['param'];
$model = $this->uri['model'];
$file = ROOT.DS.'app'.DS.'controllers'.DS.$controller_name .'_controller.php';

if(file_exists($file))
{
require_once($file) ;
$controller_name = ucwords($controller_name)."Controller";
$controller = new $controller_name ;
}
else
{
die("Controller ".$controller_name." not found");
}

if(method_exists($controller,$action))
{
$controller->{$action}($param[0],$param[1],$param[2],$param[3],
$param[4],$param[5],$param[6],$param[7]);
}
else
{
$controller->index();
}
}

/*********************************
* Load View
*********************************/
function view($view,$vars="")
{
if(is_array($vars) && count($vars) > 0)
extract($vars, EXTR_PREFIX_SAME, "wddx");
include (ROOT.DS.'app'.DS.'views'.DS.$view.'.php');
}

/*********************************
* Load Model
*********************************/
function model($model)
{
if(is_array($model))
{
array_map(array('Base','load_model'),$model);
}
else
{
$this->load_model($model);
}
}

private function load_model($model)
{
$file = ROOT.DS.'app'.DS.'models'.DS.$model.'.php';
if(file_exists($file))
{
require_once('app/models/'.$model.'.php') ;
$this->$model = new $model();
}
else
{
echo "NO";
}
}
/*********************************
* End Load Model
*********************************/
///////////////////////////////////////////////////////////////////////////
/*********************************
* Load Library
*********************************/
function library($library)
{
if(is_array($library))
{
array_map(array('Base','_load_lib_array'),$library );
}
else
{
$this->_load_lib_array($library);
}
}

function _load_lib_array($library)
{
$file = ROOT.DS.'library'.DS.$library.'.php';
if(file_exists($file))
{
require_once('library'.DS.$library.'.php') ;
$this->$library = new $library();
}
else
{
echo "Library not found";
}
}
/*********************************
* End Load Library
*********************************/

}

Mr.Moghadam
سه شنبه 17 اسفند 1389, 17:17 عصر
دوستان توضیحات کلی رو میذارم اگر سوال خواصی داشتن همینجا بپرسن .

توضیحاتش رو توی این پست میذارم تا زیاد شلوغ نشه

تابع load_controller با توجه یه urlی که در خواست شده میادو کنترلر مورد نظر رو لود میکنه.و همینطور میاد اکشنی رو که در url فراخوانی شده رو به همراه پارامترهاش اجرا میکنه.

همینطور که میبینید سه تا تابع دیگه هم داریم که برای لود کردن Model , View , Library هستش که میتونیم ازشون توی کنترلرها و ویوهامون استفاده کنیم.

یه فایل دیگه توی پوشه core ایجاد کنید و اسمش رو بذارید Controller.php و کد زیر رو داخلش بنویسید :

<?php class Controller extends Base } {


یک فایل با نام Model.php داخل پوشه core ایجاد کنید.همینطور که میدونید این لایه وظیفه کار با دیتابیس رو داره :




<?php




class Model extends Sql
{
var $name ;
function __construct()
{
$this->_connect();
}

function _connect()
{
include(ROOT.DS."config".DS."database.php");
mysql_connect($db['host'],$db['username'],$db['password']);
mysql_select_db($db['database']);
}
}




میبینید که کلاس Model از کلاس Sql ارث بری کرده.که این میتونه سلیقه ای باشه.من برای این اینکار رو انجام دادم که مثلا بیام و دستورات CURD رو داخل کلاس Sql قرار بدم و توی کلاس Model قسمت امنیت و چک کردن داده های ورودی به دیتابیس رو مدیریت کنم.

قسمت بعدی هم دوباره داخل پوشه core یه فایل با نام Sql.php بسازید و کد زیر رو توش بنویسید :

<?php class Sql { var $vars = array(); function insert($data) { } function update($tbl,$conditions,$value) { } function delete() { } function find() { } function num_rows() { } }
میبینید که هیچ کدوم از توابع رو کامل ننوشتم.
این قسمت دستورات SQL رو در آینده اگه دوستان همراهی کنن با کمک هم تکمیلش میکنیم.البته این یکی از قسمتهاشه.


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

yakouza
سه شنبه 17 اسفند 1389, 18:44 عصر
آموزشت خیلی عالیه. روان و قابل فهمه.
دنبالش بودم.
خدا خیرت بده.ادامه بده...

Mr.Moghadam
چهارشنبه 18 اسفند 1389, 08:49 صبح
خوب توی پوشه config که توی شاخه اصلی بود یه فایل با نام database.php میسازیم با کدهای زیر :


<?php

$db = array("database"=>"address",

"username"=>"root",

"password"=>"",

"host"=>"127.0.0.1");

?>



داخل پوشه library یه فایل با نام Html.php بسازید و کدهای زیر داخلش قرار بدید :


<?php



class Html

{

function link($text,$link)

{

echo "<a href='$link'>$text</a>";

}



function image($param)

{



extract($param);

return "<img src='".BASE_URL."public/image/".$image."' alt='$alt' name='$name' width='$width' height='$height'/>";

}

}

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



خیلی خوب تقریبا کار ما تمومه حالا میریم داخل پوشه app سپس پوشه controllers یه کنترلر واسه فریم ورکمون میسازیم مثلا home_controller.php



<?php


class HomeController extends Controller

{

function __construct()

{



$this->library("Html");

}



function index()

{



}





function hello($world)

{



$data['world'] = $world;

$this->view("hello/index",$data);

}



}





توی تابع سازنده این کنترلر کتابخانه Html رو که در مرحله قبل ساختیم لود کردیم.

توی اکشن hello هم اومدیم و یه view رو که در مسیر app/views/hello قرار داره و اسمش index.php فراخوانی کردیم و متغیر $world رو بهش پاس دادیم.



حالا باید view مورد نظر رو ایجاد کنیم .

میریم به پوشه app/views/hello و یه فایل با نام index.php میسازیم و کدهای زیر توش قرار میدیم.




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<?php echo $this->Html->image(array("image"=>"1.jpg",
"alt"=>"saeed",
"width"=>150,
"height"=>150));?><br />
<br />
<?php echo $this->Html->link("لینک","http://google.com");?>
</body>
</html>




برای اینکه عکسها و استایلها و js ها همه یه جا باشن توی پوشه اصلی یه پوشه به نام public قرار بدید و مثل زیر همل کنید :
Root/
app/
/Controllers
/Models
/Views
core/
config/
library/
public/
/image
/css
/js
.htaccess
Index.php


حالا یه عکس با نام jpg رو توی پوشه public/image قرار بدین وسپسبه آدرس زیر برید



http://localhost/home/hello/Hello World


موفق باشید

yakouza
چهارشنبه 18 اسفند 1389, 11:28 صبح
فقط یه سوال اینکه مازول ها کجا باید قرار بگیرن؟

Mr.Moghadam
چهارشنبه 18 اسفند 1389, 21:13 عصر
منظورت از ماژول چیه؟
خوبی فریم ورکها اینه که شما میتونید براشون کتابخانه بنویسید.
مثلا در این آموزش ما یک کتابخانه Html ساختیم که میاد یه سری کارارو برامون انجام میده.

شما هم میتونید بنا به نیازی که دارید یه کتابخانه Library بسازید و توی کنترلرتون لود و ازش استفاده کنید.
این کتابخانه ای که ساختید باید در پوشه library قرار بگیره.
موفق باشید

maysam.m
سه شنبه 24 اسفند 1389, 13:31 عصر
سلام

ابتدا تشکر کنم از مقاله ی بسیار خوبتون . به نظرم برای اینکه این معماری رو بهتر متوجه بشیم بد نیست یه پروژه خیلی ساده مثل یک لینک باکس ساده رو باهاش پیاده کنید.

ممنون