English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP 프레임워크를 작성하는 방법, MVC 운영 원리를 깊이 이해하기

1 MVC는 무엇인가요 

MVC 패턴(Model-View-Controller는 소프트웨어 엔지니어링의 하나의 소프트웨어 아키텍처 패턴으로, 소프트웨어 시스템을 세 가지 기본 부분으로 나눕니다: 모델(Model), 뷰(View), 컨트롤러(Controller). 

PHP의 MVC 패턴은 Web MVC라고도 불리며, 20세기 말부터70년대에서 진화해 왔습니다. MVC의 목적은 동적 프로그램 설계를 실현하고, 프로그램의 수정과 확장을 간소화하며, 프로그램의 일부를 재사용할 수 있게 만드는 것입니다. 이 밖에도, 복잡성을 간소화하여 프로그램 구조를 더 직관적으로 만듭니다. 소프트웨어 시스템은 기본 부분을 분리하면서 동시에 각 기본 부분에 해당하는 기능을 부여합니다。 

MVC 각 부분의 역할:
 •모델 Model – 대부분의 비즈니스 로직과 모든 데이터베이스 로직을 관리합니다. 모델은 데이터베이스와 연결 및 작업을 위한 추상 계층을 제공합니다。
 •컨트롤러 Controller - 사용자 요청에 응답하고, 데이터를 준비하고, 데이터를 어떻게 표시할지 결정합니다。
 •뷰 View – 데이터를 렌더링하고, 사용자에게 HTML 방식으로 제공합니다。 

특히나 표준적인 Web MVC 프로세스:
 1.Controller는 사용자가 보낸 요청을 잡습니다;
 2.Controller는 Model을 호출하여 상태의 읽기/쓰기 작업을 수행합니다;
 3.Controller는 데이터를 View에 전달합니다;
 4.View는 최종 결과를 렌더링하고 사용자에게 제공합니다。 

2 왜 MVC 프레임워크를 직접 개발하는가 

인터넷에는 많은 훌륭한 MVC 프레임워크가 사용할 수 있으며, 이 튜토리얼은 완벽한, 최종의 MVC 프레임워크 솔루션을 개발하기 위한 것이 아니라, PHP를 내부에서 배우는 좋은 기회로 볼 수 있습니다. 이 과정에서, 당신은 객체 지향 프로그래밍과 MVC 설계 패턴을 배우며, 개발 중의 몇 가지 주의사항도 배울 수 있습니다. 

가장 중요한 것은, 당신은 자신의 프레임워크를 완전히 제어할 수 있으며, 자신의 아이디어를 개발하는 프레임워크에 통합할 수 있습니다. 최고가 아니더라도, 당신의 방식으로 기능과 모듈을 개발할 수 있습니다. 

3 자신의 MVC 프레임워크를 개발하기 시작하기 

3。1 디렉토리 준비 

개발을 시작하기 전에, 먼저 프로젝트를 설정해 보겠습니다. 예를 들어, todo 프로젝트를 만들고, MVC 프레임워크를 FastPHP로 명명하면, 다음 단계는 디렉토리 구조를 설정하는 것입니다.

 

이 튜토리얼에서는 위의 모든 디렉토리를 사용하지 않을 것이라고 생각하지만, 프로그램의 확장성을 위해 초기에 프로그램 디렉토리를 설정하는 것은 매우 중요합니다. 아래에서 각 디렉토리의 역할을 자세히 설명하겠습니다:
 •application – 애플리케이션 코드
 •config – 프로그램 설정 또는 데이터베이스 설정
 •fastphp - 프레임워크 핵심 디렉토리
 •public – 정적 파일
 •runtime - 임시 데이터 디렉토리
 •scripts – 명령행 도구 

3。2 코드 표준

디렉토리 설정을 완료한 후, 다음으로 코드 표준을 정의해야 합니다:
 1. MySQL 테이블 이름은 소문자로 합니다. 예를 들어: item, car
 2. 모듈명(Model)은 이름의 첫 글자를 대문자로 하고 'Model'를 추가해야 합니다. 예를 들어: ItemModel, CarModel
 3. 제어자(Controller)는 이름의 첫 글자를 대문자로 하고 'Controller'를 추가해야 합니다. 예를 들어: ItemController, CarController
 4. 뷰(Views) 배치 구조는 "제어자이름"/이름/view.php, car/buy.php 

위의 일부 규칙은 프로그램에서 더 나은 상호 호출을 위해 필요합니다. 이제 진정한 PHP MVC 프로그래밍을 시작합니다. 

3。3 재정향 

모든 데이터 요청을 index.php 파일로 재정향하려면 todo 디렉토리에 .htaccess 파일을 새로 만들어야 합니다. 파일 내용은 다음과 같습니다: 

<IfModule mod_rewrite.c>
  RewriteEngine On
  # 요청 경로가 파일 이름이나 디렉토리가 아니라는 것을 보장
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  # 모든 요청을 index.php에 재정향63;url=PATHNAME
  RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>

이렇게 한 이유는 다음과 같습니다:
 1프로그램은 단일 엔트리를 가집니다;
 2불러온 프로그램은 모두 index.php에 재정향됩니다;
 3을 사용하여 SEO에 유리한 URL을 생성할 수 있습니다. URL을 더 잘 설정하려면 나중에 URL 라우팅이 필요할 수 있습니다. 이를 이제 설명하지 않습니다. 

3。4 엔트리 파일 

위의 작업을 완료하면 무엇을 해야 하는지 알게 될 것입니다. 맞습니다! public 디렉토리에 index.php 파일을 추가하고, 파일 내용은 다음과 같습니다:

 <63;php
// 응용 프로그램 디렉토리는 현재 디렉토리입니다
define('APP_PATH', __DIR__.'/');
// 디버깅 모드 활성화
define('APP_DEBUG', true);
// 웹 루트 URL
define('APP_URL', 'http://localhost/fastphp');
// 로드 프레임워크
require '.'/fastphp/FastPHP.php';

주의하세요. 위의 PHP 코드에서는 PHP 종료 기호(“?>”,이렇게 한 이유는 PHP 코드만 있는 파일에 대해서는 종료 기호(“?>”)가 없는 것이 좋습니다. PHP는 종료 기호가 필요하지 않으며, 종료 기호를 추가하지 않으면 추가적인注入 내용이 추가되는 것을 크게 방지할 수 있어 프로그램이 더 안전해집니다. 

3。5 설정 파일과 주 요청 

index.php 파일에서 fastphp 폴더 아래의 FastPHP.php 파일에 요청을 보냈습니다. 그렇다면 FastPHP.php 이 시작 파일은 무엇을 포함할까요?

<63;php
// 상수 초기화
defined('FRAME_PATH') or define('FRAME_PATH', __DIR__.'/');
defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/');
defined('APP_DEBUG') or define('APP_DEBUG', false);
defined('CONFIG_PATH') or define('CONFIG_PATH', APP_PATH.'config/');
defined('RUNTIME_PATH') or define('RUNTIME_PATH', APP_PATH.'runtime/');
// 설정 파일 포함
require APP_PATH . 'config/config.php';
//핵심 프레임워크 클래스 포함
require FRAME_PATH . 'Core.php';
// 핵심 클래스 인스턴스화
$fast = new Core;
$fast->run();

이 파일들은 모두 index.php 파일에서 직접 포함할 수 있지만, 상수들은 index.php에서 직접 정의할 수 있습니다. 이렇게 한 이유는 후속 관리와 확장을 더 쉽게하기 위해서입니다. 따라서 초기에 즉시 실행해야 하는 프로그램을 모두 하나의 별도의 파일에 담아서 참조하도록 했습니다.

먼저 config 파일 아래의 config.php 파일을 확인해 보겠습니다. 이 파일의 주요 기능은 프로그램 설정 항목 및 데이터베이스 연결 등을 설정하는 것입니다. 주요 내용은 다음과 같습니다: 

 <63;php
/** 변수 설정 **/
define('DB_NAME', 'todo');
define('DB_USER', 'root');
define('DB_PASSWORD', 'root');
define('DB_HOST', 'localhost');

config.php에서涉及到하는 내용은 많지 않습니다. 기본 데이터베이스 설정 등 일부만 있으며, fastphp하의 공용 프레임워크 엔트리 파일 Core.php는 어떻게 작성되어야 할까요.
 

<63;php
/**
 * FastPHP 핵심 프레임워크
 */
class Core
{
  // 프로그램 실행
  function run()
  {
    spl_autoload_register(array($this, 'loadClass'));
    $this->setReporting();
    $this->removeMagicQuotes();
    $this->unregisterGlobals();
    $this->Route();
  }
  // 루트 처리
  function Route()
  {
    $controllerName = 'Index';
    $action = 'index';
    if (!empty($_GET['url'])) {
      $url = $_GET['url'];
      $urlArray = explode('/', $url);
      // 제어기 이름 가져오기
      $controllerName = ucfirst($urlArray[0]);
      // 동작 이름 가져오기
      array_shift($urlArray);
      $action = empty($urlArray[0]) ?63; 'index' : $urlArray[0];
      //URL 파라미터 가져오기
      array_shift($urlArray);
      $queryString = empty($urlArray) ?63; array() : $urlArray;
    }
    // 데이터가 비어있는 처리
    $queryString = empty($queryString) ?63; array() : $queryString;
    // 제어기 인스턴스화
    $controller = $controllerName . 'Controller';
    $dispatch = new $controller($controllerName, $action);
    // 제어기와 동작이 존재하면, 이를 호출하고 URL 파라미터를 전달합니다
    if ((int)method_exists($controller, $action)) {
      call_user_func_array(array($dispatch, $action), $queryString);
    } else {
      exit($controller . "제어자가 존재하지 않습니다");
    }
  }
  // 개발 환경을 검출합니다
  function setReporting()
  {
    if (APP_DEBUG === true) {
      error_reporting(E_ALL);
      ini_set('display_errors','On');
    } else {
      error_reporting(E_ALL);
      ini_set('display_errors','Off');
      ini_set('log_errors', 'On');
      ini_set('error_log', RUNTIME_PATH. 'logs/error.log');
    }
  }
  // 감사한 문자를 제거합니다
  function stripSlashesDeep($value)
  {
    $value = is_array($value) ? array_map('stripSlashesDeep', $value) : stripslashes($value);
    return $value;
  }
  // 감사한 문자를 검출하여 제거합니다
  function removeMagicQuotes()
  {
    if ( get_magic_quotes_gpc()) {
      $_GET = stripSlashesDeep($_GET );
      $_POST = stripSlashesDeep($_POST );
      $_COOKIE = stripSlashesDeep($_COOKIE);
      $_SESSION = stripSlashesDeep($_SESSION);
    }
  }
  // 검출된 사용자 정의 전역 변수(register globals)을 제거합니다
  function unregisterGlobals()
  {
    if (ini_get('register_globals')) {
      $array = array('_SESSION', '_POST', '_GET', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES');
      foreach ($array as $value) {
        foreach ($GLOBALS[$value] as $key => $var) {
          if ($var === $GLOBALS[$key]) {
            unset($GLOBALS[$key]);
          }
        }
      }
    }
  }
  // 自动加载控制器和模型类 
  static function loadClass($class)
  {
    $frameworks = FRAME_PATH . $class . '.class.php';
    $controllers = APP_PATH . 'application/controllers/' . $class . '.class.php';
    $models = APP_PATH . 'application/models/' . $class . '.class.php';
    if (file_exists($frameworks)) {
      // 加载框架核心类
      include $frameworks;
    } elseif (file_exists($controllers)) {
      // 加载应用控制器类
      include $controllers;
    } elseif (file_exists($models)) {
      //加载应用模型类
      include $models;
    } else {
      /* 错误代码 */
    }
  }
}

下面重点讲解主请求方法 callHook(),首先我们想看看我们的 URL 会这样:
yoursite.com/controllerName/actionName/queryString

callHook()的作用就是,从全局变量  GET[ ′ url ′ ]变量中获取URL,并将其分割成三部分: GET[′url′]变量中获取URL,并将其分割成三部分:controller、action和queryString。 

例如,URL链接为:todo.com/item/view/1/first-item,那么
 •$controller 就是:item
 •$action 就是:view
 •查询字符串Query String就是:array(1, first-item) 

分割完成后,会实例化一个新的控制器:$controller.'Controller'(其中“.”是连字符),并调用其方法 $action。 

3。6 控制器/Controller基类 

接下来的操作就是在 fastphp 中建立程序所需的基类,包括控制器、模型和视图的基类。 

新建控制器基类为 Controller.class.php,控制器的主要功能就是总调度,具体内容如下:
 

<63;php 
/**
 * 컨트롤러 기본 클래스
 */
class Controller
{
  protected $_controller;
  protected $_action;
  protected $_view;
  // 생성자, 속성을 초기화하고 해당 모델을 인스턴스화합니다
  function __construct($controller, $action)
  {
    $this->_controller = $controller;
    $this->_action = $action;
    $this->_view = new View($controller, $action);
  }
  // распределение переменных
  function assign($name, $value)
  {
    $this->_view->assign($name, $value);
  }
  // 뷰 렌더링
  function __destruct()
  {
    $this->_view->render();
  }
}
 

Controller 클래스는 모든 컨트롤러, 모델, 뷰(View 클래스)의 통신을 구현합니다. 디스트럭터 함수를 호출할 때, render()를 호출하여 뷰 파일을 표시할 수 있습니다.

3。7 모델 Model 기본 클래스

모델 기본 클래스를 Model.class.php로 새로 만들었습니다. 모델 기본 클래스 Model.class.php의 코드는 다음과 같습니다:

 <63;php
class Model extends Sql
{
  protected $_model;
  protected $_table;
  function __construct()
  {
    // 데이터베이스 연결
    $this->connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    // 모델 이름을 가져옵니다
    $this->_model = get_class($this);
    $this->_model = rtrim($this->_model, 'Model');
    // 데이터베이스 테이블 이름과 클래스 이름이 일치합니다
    $this->_table = strtolower($this->_model);
  }
  function __destruct()
  {
  }
}

 모델이 데이터베이스를 처리해야 하는 경우를 고려하여, 독립적인 데이터베이스 기본 클래스 Sql.class.php를 만들었으며, 모델 기본 클래스는 Sql.class.php를 상속합니다. 코드는 다음과 같습니다:

 <63;php
class Sql
{
  protected $_dbHandle;
  protected $_result;
  // 데이터베이스 연결
  public function connect($host, $user, $pass, $dbname)
  {
    try {
      $dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8"$host, $dbname);
      $this->_dbHandle = new PDO($dsn, $user, $pass, array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC));
    } catch (PDOException $e) {
      exit('오류: ' . $e->getMessage());
    }
  }
  // 모든 데이터 검색
  public function selectAll()
  {
    $sql = sprintf("select * from `%s`", $this->_table);
    $sth = $this->_dbHandle->prepare($sql);
    $sth->execute();
    return $sth->fetchAll();
  }
  // 조건(id)에 따라 데이터 검색
  public function select($id)
  {
    $sql = sprintf("select * from `%s` where `id` = '%s'", $this->_table, $id);
    $sth = $this->_dbHandle->prepare($sql);
    $sth->execute();
    return $sth->fetch();
  }
  // 조건(id)에 따라 데이터 삭제
  public function delete($id)
  {
    $sql = sprintf("delete from `%s` where `id` = '%s'", $this->_table, $id);
    $sth = $this->_dbHandle->prepare($sql);
    $sth->execute();
    return $sth->rowCount();
  }
  // 사용자 정의 SQL 쿼리, 영향을 받은 행 수 반환
  public function query($sql)
  {
    $sth = $this->_dbHandle->prepare($sql);
    $sth->execute();
    return $sth->rowCount();
  }
  // 데이터 추가
  public function add($data)
  {
    $sql = sprintf("insert into `%s` %s", $this->_table, $this->formatInsert($data));
    return $this->query($sql);
  }
  // 데이터 수정
  public function update($id, $data)
  {
    $sql = sprintf("update `%s` set %s where `id` = '%s'", $this->_table, $this->formatUpdate($data), $id);
    return $this->query($sql);
  }
  // 배열을 삽입 형식의 SQL 문으로 변환합니다
  private function formatInsert($data)
  {
    $fields = array();
    $values = array();
    foreach ($data as $key => $value) {
      $fields[] = sprintf("`%s`", $key);
      $values[] = sprintf("'%s'", $value);
    }
    $field = implode(',', $fields);
    $value = implode(',', $values);
    return sprintf("(%s) values (%s)", $field, $value);
  }
  // Преобразование массива в строку SQL для обновления
  private function formatUpdate($data)
  {
    $fields = array();
    foreach ($data as $key => $value) {
      $fields[] = sprintf("`%s` = '%s'", $key, $value);
    }
    return implode(',', $fields);
  }
}

Следует сказать, что Sql.class.php является ядром фреймворка. Почему? Потому что через него мы создали абстрактный слой SQL, который значительно уменьшает работу с базой данных.虽然说 PDO интерфейс уже очень краток, но после абстракции фреймворк становится более гибким. 

3。8 Класс представления View 

Содержимое класса View.class.php следующим образом:

 <63;php
/**
 * Базовый класс представления
 */
class View
{
  protected $variables = array();
  protected $_controller;
  protected $_action;
  function __construct($controller, $action)
  {
    $this->_controller = $controller;
    $this->_action = $action;
  }
  /** распределение переменных **/
  function assign($name, $value)
  {
    $this->variables[$name] = $value;
  }
  /** рендеринг отображения **/
  function render()
  {
    extract($this->variables);
    $defaultHeader = APP_PATH . 'application/views/header.php';
    $defaultFooter = APP_PATH . 'application/views/footer.php';
    $controllerHeader = APP_PATH . 'application/views/' . $this-}_controller . '/header.php';
    $controllerFooter = APP_PATH . 'application/views/' . $this-}_controller . '/footer.php';
    // 페이지 헤더 파일}}
    if (file_exists($controllerHeader)) {
      include ($controllerHeader);
    } else {
      include ($defaultHeader);
    }
    // 페이지 내용 파일
    include (APP_PATH . 'application/views/' . $this-}_controller . '/' . $this-}_action . '.php');
    // 페이지 푸터 파일
    if (file_exists($controllerFooter)) {
      include ($controllerFooter);
    } else {
      include ($defaultFooter);
    }
  }
}
 

이렇게 하면 우리의 핵심 PHP MVC 프레임워크가 작성되었습니다. 그런 다음, 프레임워크 기능을 테스트하기 위해 애플리케이션을 작성하기 시작합니다.

4 애플리케이션

4。1 데이터베이스 배포

SQL에서 새로운 todo 데이터베이스를 생성하고 다음 명령어로 item 테이블을 추가하고 삽입합니다:2개의 기록:

CREATE DATABASE `todo` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `todo`;
CREATE TABLE `item` (
  `id` int(11) NOT NULL auto_increment,
  `item_name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO `item` VALUES(1, 'Hello World.');
INSERT INTO `item` VALUES(2, 'Lets go!'); 

4。2 모델 배포 

그런 다음, models 디렉토리에서 ItemModel.php 모델을 생성해야 합니다. 내용은 다음과 같습니다:

 <63;php
class ItemModel extends Model
{
  /* 비즈니스 로직 레이어 구현 */
}

모델 내용이 비어 있습니다. Item 모델이 Model을 상속받았기 때문에 Model의 모든 기능을 가집니다.

4。3 컨트롤러 배포 

controllers 디렉토리 아래에 ItemController.php 컨트롤러를 생성하십시오. 내용은 다음과 같습니다:

 <63;php
class ItemController extends Controller
{
  // 首页方法,测试框架自定义DB查询
  public function index()
  {
    $items = (new ItemModel)->selectAll();
    $this->assign('title', '全部条目');
    $this->assign('items', $items);
  }
  // 添加记录,测试框架DB记录创建(Create)
  public function add()
  {
    $data['item_name'] = $_POST['value'];
    $count = (new ItemModel)->add($data);
    $this->assign('title', '添加成功');
    $this->assign('count', $count);
  }
  // 查看记录,测试框架DB记录读取(Read)
  public function view($id = null)
  {
    $item = (new ItemModel)->select($id);
    $this->assign('title', '正在查看' . $item['item_name']);
    $this->assign('item', $item);
  }
  // 更新记录,测试框架DB记录更新(Update)
  public function update()
  {
    $data = array('id' => $_POST['id'], 'item_name' => $_POST['value']);
    $count = (new ItemModel)->update($data['id'], $data);
    $this->assign('title', '修改成功');
    $this->assign('count', $count);
  }
  // 删除记录,测试框架DB记录删除(Delete)
  public function delete($id = null)
  {
    $count = (new ItemModel)->delete($id);
    $this->assign('title', '删除成功');
    $this->assign('count', $count);
  }
}

4。4 部署视图 

在 views 目錄下新建 header.php 和 footer.php 两个页头页脚模板,內容如下。 

header.php,內容:

 <html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title><?php echo $title "63;></title>
  <style>
    .item {
      width:400px;
    }
    input {
      color:#222222;
      font-family:georgia,times-serif;
      font-size:24px;
      font-weight:normal;
      line-height:-height:1。2em;
      color:black;
    }
    a {
      color:blue;
      font-family:georgia,times-serif;
      font-size:20px;
      font-weight:normal;
      line-height:-height:1。2em;
      text-decoration:none;
     }
    a:hover {
      text-decoration:underline;
    }
    h1 {
      color:#000000;
      font-size:41px;
      letter-spacing:-spacing:-2px;
      line-height:-height:1em;
      font-family:helvetica,arial,sans-serif;-serif;
      border-bottom:1px dotted #cccccc;
    }
    h2 {
      color:#000000;
      font-size:34px;
      letter-spacing:-spacing:-2px;
      line-height:-height:1em;
      font-family:helvetica,arial,sans-serif;-serif;
    }
  </style>
</>head>
<body
  <h1><<63;php echo $title "63;></h1>
footer.php,内容:
 </body>
</html>

然后,在 views/item 创建以下几个视图文件。 

index.php,浏览数据库内 item 表的所有记录,内容:

 <form action="<"63;php echo APP_URL &63;>/item/add" method="post">
  <input type="text" value="点击添加" onclick="this.value=''" name="value">
  <input type="submit" value="添加">
</form>
<br/><br/>
<63;php $number = 0"63;>
<63;php foreach ($items as $item): "63;>
  <a class="big" href="<&63;php echo APP_URL &63;>/item/view/<63;php echo $item['id'] &63;>" title="[#1#]">
    <span class="item">
      <63;php echo ++$number "63;>
      <63;php echo $item['item_name'] "63;>
    </span>
  </a>
  ----
  <a class="big" href="<&63;php echo APP_URL &63;>/item/delete/<63;php echo $item['id']"63;>>删除</a>
<br/>
<63;php endforeach "63;>

add.php,添加记录,内容:
 <a class="big" href="<&63;php echo APP_URL &63;>/item/index">成功添加<63;php echo $count &63;>条记录,点击返回</a> 

view.php,查看单条记录,内容:

 <form action="<"63;php echo APP_URL &63;>/item/update" method="post">
  <input type="text" name="value" value="<"63;php echo $item['item_name'] "63;>
  <input type="hidden" name="id" value="<&63;php echo $item['id'] &63;>
  <input type="submit" value="수정">
</form>
<a class="big" href="<&63;php echo APP_URL &63;>/item/;index">뒤로 가기/a>

update.php을 통해 기록을 변경하십시오. 내용:
 <a class="big" href="<&63;php echo APP_URL &63;>/item/;index">성공적으로 수정<&63;php echo $count &63;>항목, 뒤로 가기 클릭/a> 

delete.php을 통해 기록을 삭제하십시오. 내용:
 <a href="<&63;php echo APP_URL &63;>/item/;index">성공적으로 삭제<&63;php echo $count &63;>항목, 뒤로 가기 클릭/a> 

4。5 응용 프로그램 테스트 

이렇게 하면, 브라우저에서 todo 프로그램에 접근할 수 있습니다: http://localhost/todo/item/index/,결과를 볼 수 있습니다. 

이 코드는 모두 github에发布了,주요 부분에 주석이 추가되었으며, 저장소 주소는https://github.com/yeszao/fastphp,크론을 복제하고 제출하십시오.

더 나은 MVC를 설계하거나 더 정확하게 사용하려면, 다음을 참조하십시오《MVC 아키텍처의 역할 분담 원칙》

이것이 본문의 전체 내용입니다. 여러분의 학습에 도움이 되길 바라며, 다른 사람들도 더 많이 지지해 주시기를 바랍니다.

명시: 본문 내용은 인터넷에서 가져왔으며, 저작권자는 본인입니다. 인터넷 사용자가 자발적으로 기여하고 자체로 업로드한 내용으로, 본 사이트는 소유권을 가지지 않으며, 인공적으로 편집한 것도 아니며, 관련 법적 책임도 부담하지 않습니다. 저작권 문제가 의심되는 내용이 있다면, 이메일을 notice#w로 보내 주시기 바랍니다.3codebox.com(이메일을 보내는 경우, #을 @으로 변경하십시오.) 신고를 하시고 관련 증거를 제공하시면, 해당 내용이 사실로 확인되면 즉시 해당 내용을 삭제할 것입니다.

당신이 좋아할 만한 것