.NET

PHP MVC & .NET

article

Introduction

ส่วนใหญ่ผมทำงานกับ ASP.NET และดังนั้นจึงตกหลุมรักกับความเรียบง่ายของรูปแบบ MVC ของพวกเขา คุณเพียงแค่คลิกที่ตัวควบคุมใหม่ใช่โปรดให้สร้างมุมมองและคุณจะพบกับชิ้นส่วนของรหัสควบคุมที่ไม่สามารถจะง่ายขึ้น

แต่อินเทอร์เน็ตเป็นส่วนใหญ่สร้างจาก PHP / MySQL และเมื่อคุณกำลังสร้างเว็บไซต์สำหรับเบเกอรี่ที่มุมรวมทั้ง Zend หรือบางขนาดใหญ่อื่น ๆ MVC, อาจจะมีบิตกว่าด้านบน ฉันอยากจะสร้างคำกริยา MVC ง่ายใน PHP ที่ชั้นควบคุมอาจเป็นเพียงแค่ง่ายๆเป็น NET. ที่แตกต่างกัน

ใน. NET คุณสามารถเลือกหลายแม่แบบเครื่องยนต์ ในกิริยาที่ผมนำเสนอให้คุณได้อย่างง่ายดายสามารถ plug-in แม่แบบเครื่องยนต์ใด ๆ ที่คุณต้องการ ฉันไปสำหรับ Smarty http://www.smarty.net/

ฉันอยู่ในขณะนี้วิธีการที่อ้างว่านี้จะไม่ซ้ำกันมีจำนวนมากของกรอบที่ดีออกมีที่ทำตรงเดียวกัน เช่น CodeIgniter แต่ฉันคิดว่ามันจะสนุกกับการดูว่าคุณสามารถม้วนของคุณเอง

อันดับแรก เนื่องจากเราต้องการรุ่น MVC เราต้องขอทั้งหมดจะถูกส่งผ่านแหล่งเดียว นี้จะกระทำโดยการเปลี่ยนไฟล์ htaccess.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.jpg|\.jpeg|\.png|\.gif|\.flv|\.swf)$
RewriteRule ^.*$ index.php

Bootstrapping

[settings]
controller_path="controllers/"
view_path="views/"
baseURL="/subdir"

baseUrl อาจจะว่างเปล่า ถ้าได้รับการติดตั้งที่ root ของเว็บไซต์

index.php เป็นแล้วจะไปรวมถึง Smarty และทำบางสิ่งพื้นฐาน แล้วทำส่วนที่สำคัญที่สุดของการแยกวิเคราะห์ URL ที่ร้องขอเข้ามา

หาก URL เป็น home แล้ว homeController.php ควรมีการควบคุมที่ ดังนั้นหาก URL ที่เป็น products/details/10, productsController.php ควรจะโหลด

<?php

require_once('libs/Smarty.class.php');    

$config = parse_ini_file("config.ini", TRUE); 

if (isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD'])) {
    //This will hold the request data. If there is any.
    $requestData = '';
    //The method
    $method = $_SERVER['REQUEST_METHOD'];

    if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) {
        //There is some data in the request. We would like to have this.
        $httpContent = fopen('php://input', 'r');
        while ($data = fread($httpContent, 1024)) {
            $requestData .= $data;
        }
        fclose($httpContent);
    }    

    //If we are installed in a subdirectory, we'd like to analyse the part after this directory
    $urlString = substr($_SERVER['REQUEST_URI'], strlen($config['settings']['baseURL']));
    //Split the url in pieces
    $urlParts = explode('/', $urlString); 

    if (isset($urlParts[0]) && $urlParts[0] == '') {
    	array_shift($urlParts);
    }

    if (!isset($urlParts[0]) || $urlParts[0] == '') {
        //If the url does not contain more then / we're going to start the default controller. Which is home
        $mainViewPath="home/";
        $currentController = "HomeController";
        $controllerFile = "homeController.php";	    		
    	}
    else	{
        //There is a directive after the / so that is going to be our controller
        $mainViewPath=strtolower($urlParts[0]);
        $currentController = ucfirst($urlParts[0]) . "Controller";
        $controllerFile = $urlParts[0] . "Controller.php";	    			
        //This will make the 'action' part of the url the first directive
        array_shift($urlParts);
    	}    

}
else    {
    header($_SERVER["SERVER_PROTOCOL"] . " 400 Bad request");      
}
?>

Abstract class Controller

ตอนนี้เรา รู้ว่าที่ ชั้นควบคุม เรา อยากจะเริ่มต้น ถ้ามีคน ให้เราขอ URL / ผลิตภัณฑ์ที่ เรา ต้องการ ที่จะโหลด productsContoller.php และ สร้างตัวอย่างของ ProductsController

แต่ก่อนอื่น เราจำเป็นต้อง มุ่งเน้นไปที่ การสร้างตัวควบคุม ระดับนามธรรม เพื่อให้ได้รับ การควบคุม ของเรา ได้เช่นโครงสร้างง่าย ที่เรา จะต้องมี ชั้นยอด ที่จะทำ อัลยกของหนัก

ตัวควบคุม ทั้งหมด จะได้รับมรดก จาก ชั้นนี้ ชั้น ควบคุมความต้องการ ที่จะทำ บางสิ่ง จะต้องมีการ มองไปที่ สิ่งที่เหลืออยู่ ของ URL คำขอและ ตรวจสอบว่า การดำเนินการ ควบคุม ภายในควรจะเริ่มต้น ดังนั้น ถ้าเราได้รับ / ผลิตภัณฑ์ที่ มี การดำเนินการ ที่กำหนดไว้ ไม่ได้และ เราจะเริ่มต้น การกระทำ ดัชนี ถ้าเราได้รับ / products / รายละเอียด ที่เรา wil เริ่มต้น การดำเนินการ รายละเอียด

สิ่งที่สองที่ ชั้น ควบคุม ความต้องการที่จะ ทำคือการสร้าง viewBag นี่คือ ‘ กระเป๋า ‘ ของข้อมูลที่สามารถ ควบคุม การดำเนินการ เพิ่มข้อมูลไปยัง แต่ ถัดไปที่ ผมชอบที่จะ ถือว่า ข้อมูล ยัง โพสต์ ที่เป็น JSON และ ว่าข้อมูลที่ โพสต์ ทั้งหมด จะถูกเพิ่ม viewBagก่อนที่จะเริ่ม การดำเนินการ ควบคุม นี้จะช่วยให้ การตั้งค่า ตัวแปร แม่แบบ จาก JavaScript ( แต่ ที่อาจจะ ดีกว่าสำหรับครั้งต่อไป )

สิ่งที่สาม ที่เขาทำ คือการ ตรวจสอบ ไฟล์ view.html

 

public function __construct($controllerName, $urlParts, $data)
{
    $this->fullActionPath=implode("/", $urlParts);

    $this->method=$_SERVER['REQUEST_METHOD'];

    //We are assuming the data to be a JSON string. In a final version this should have some error handling
    if($data=='')   {
        $data='{}';
    }
    $this->viewBag=json_decode($data);

    //The action is the first part	
    $action=$urlParts[0];

    if (count($urlParts) > 1 && $urlParts[1] != '') {
        //Now we need to find the identifiers
        array_shift($urlParts);
        foreach ($urlParts as $uid) {
            if ($uid != '') {
                $this->uid[] = $uid;
            }
        }
    }			
    if(!isset($action) || $action=='')	{
        //If there is no action, we'll start the default action.
        $action="index";
    }

    //The view html
    $this->viewHtml=strtolower($action) . ".html";

    try	{
        //call_user_func gives a fatal error, which we cannot catch.
        //So we cannot handle asking for a unknown action
        //This is why we'll use the ReflectionClass's getMethod which will throw an exception
        $reflector = new ReflectionClass($this);
        $method=$reflector->getMethod($action);
        //If all works. We'll start the action.
        call_user_func($controllerName . "::" . $action, $this->uid);
    }
    catch(Exception $exc)	{
        //If the view doesn't exists, we'll start the default view.
        //In a final version this should start the ViewUnknown action.
        call_user_func($controllerName . "::index");
    }
}

View function

Collapse | Copy Code
//@method View 
//@description Combines the view with the viewBag data. 
public function View()
{
    //Detertime the full path to the view file
    $viewPath=$GLOBALS['config']['settings']['view_path'] . $this->viewHtml;

    if	(file_exists($viewPath))	{
        //If the file exists use the smart engine
        //This would be the place to use some other engine like Mustache
        $this->smarty = new Smarty();

        foreach($this->viewBag as $key => $value) {
        	$this->smarty->assign($key, $value);
        }

        $this->smarty->display($viewPath);
    }
    else	{
        header('HTTP/1.0 404 Not Found');
        echo "404 Not Found";
        echo "The page that you have requested could not be found.";					
    }
}

HomeController

Collapse | Copy Code
<?php
/*
    @class HomeControlelr
    @extends Controller
    @description Dit is de controller for home
*/
class HomeController extends Controller
{

    //@method index De index action
    public function index()	
    {
        //Lets set some variable to test the template
        $this->viewBag->hellomessage="Hello world!";
        return $this->View();
    }
}
?>

home/index.html

Collapse | Copy Code
<html>
<head>
    <title>Index</title>
</head>
<body>
    <h1>{$hellomessage}</h1>
</body>
</html>