logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

1.4. 开始编写 MVC 框架

07/10/2025, by Ivan

我们已经详细规划了框架应具备的结构,现在是时候开始实现我们的 MVC 框架了。首先,你需要一个 Web 服务器。你可以使用 Denwer,不过可能需要更新 PHP 版本。

你可以在此页面下载带有 PHP 5.5.20 的 Denwer:

https://drupalbook.org/ru/drupal/denwer-obnovlenie-php

或者从 GitHub 下载:

https://github.com/levmyshkin/denwer-php-5.5.20

我们的框架将从 index.php 文件开始运行,该文件会从注册器中获取实例,调用所需的控制器并将注册器结果传递给它。控制器反过来可以调用所需的模型。

MVC

模式实现

实现我们讨论过的设计模式有多种方式。我们将选择其中一种实现方法,以后你可以根据需要更改某些模式的实现方式。

首先,在之前的章节中我们已经讨论了框架的目录结构,因此现在你需要根据该结构创建相应的文件夹。

接下来创建文件 Registry/registry.class.php。在其中我们将编写注册器类:

<?php
/**
 * 注册器对象
 * 实现注册器(Registry)和单例(Singleton)模式
 */
class Registry {
     
    /** 存储对象的数组 */
    private static $objects = array();
     
    /** 存储设置的数组 */
    private static $settings = array();
     
    /** 框架名称 */
    private static $frameworkName = 'Framework version 0.1';
     
    /** 注册器实例 */
    private static $instance;
     
    /** 构造函数(私有) */
    private function __construct() { }
         
    /** 单例访问方法 */
    public static function singleton()
    {
        if( !isset( self::$instance ) )
        {
            $obj = __CLASS__;
            self::$instance = new $obj;
        }
        return self::$instance;
    }
     
    /** 防止克隆对象 */
    public function __clone()
    {
        trigger_error( '禁止克隆注册器对象', E_USER_ERROR );
    }
     
    /** 将对象存入注册器 */
    public function storeObject( $object, $key )
    {
        require_once('objects/' . $object . '.class.php');
        self::$objects[ $key ] = new $object( self::$instance );
    }
     
    /** 从注册器中获取对象 */
    public function getObject( $key )
    {
        if( is_object ( self::$objects[ $key ] ) )
        {
            return self::$objects[ $key ];
        }
    }
     
    /** 存储注册器设置 */
    public function storeSetting( $data, $key )
    {
        self::$settings[ $key ] = $data;
    }
     
    /** 获取注册器设置 */
    public function getSetting( $key )
    {
        return self::$settings[ $key ];
    }
     
    /** 获取框架名称 */
    public function getFrameworkName()
    {
        return self::$frameworkName;
    }
}
?>

那么注册器是如何工作的?它如何存储对象?

  • 所有对象都保存在一个数组中。
  • 当一个新对象被添加到注册器时,其对应的类文件会被引入,并创建该对象的实例,随后存入数组。
  • 通过向 getObject 方法传递键名即可返回该对象。

如何防止创建注册器类的其他副本?

  • 构造函数被声明为 private,防止从外部直接实例化。
  • 克隆对象会触发错误。
  • 如果你需要在框架中访问注册器实例,可以通过静态方法 Registry::singleton() 获取它。

现在我们已经创建了注册器类,接下来编写 index.php 文件,它将作为框架的入口点并与注册器交互。

Index.php

index.php 是框架的启动文件。

稍后我们将通过 .htaccess 文件实现友好 URL(ЧПУ),但现在先来看看 index.php 的基本代码:

<?php
/**
 * Framework
 * 框架加载器 - 框架的单一入口点
 */

// 启动会话
session_start();
 
// 定义常量
define( "APP_PATH", dirname( __FILE__ ) ."/" );
define( "FW", true );
 
/**
 * 自动加载函数
 * 当调用控制器时自动引入所需类
 */
function __autoload( $class_name )
{
    require_once('Controllers/' . $class_name . '/' . $class_name . '.php' );
}
 
// 引入注册器
require_once('Registry/registry.class.php');
$registry = Registry::singleton();
 
// 输出框架名称(用于测试)
print $registry->getFrameworkName();
 
exit();
?>

如果一切正常,页面上将显示以下信息:

Framework version 0.1

让我们来分析当前 index.php 的工作原理:

  • 启动会话,以便在整个框架中读写数据。
  • 定义框架的根目录常量,便于在任何地方引用路径。
  • 设置自动加载机制,以便在调用控制器时自动引入对应文件。
  • 引入并初始化注册器类。
  • 输出框架名称以确认系统正常运行。