PHP的MVC模式实现原理分析(一相简单的MVC框架范例)
他们的工作原理大家应该也比较感兴趣,下面我说说一个mvc框架长什么样。
路由机制
在互联网我们都是通过url提供服务,因此不同的url有不同的服务。用户访问不同的页面也就获得了不同的服务。那么我们的服务是如何通过url来区分不同的服务呢。
我们的web程序就要通过url寻找到不同的文件,进行不同的业务逻辑处理。我们的路由机制就是根据url,寻找到对应的controller,和action,然后由action进行具体的业务逻辑处理。
一个简单的controller
复制代码 代码如下:
//定义一个controller
class UserControler extends Controller{
//定义一个action方法,注意一定是public的
public function index(){
// do business code
}
}
具体的对应规则不同的框架映射不同。以下是CodeIgniter框架的URL路由,它会尽力的尝试各种的可能,来分析URL的情况。
文件路径/system/core/URI.php
复制代码 代码如下:
// 看看是否是从命令行运行的
if (php_sapi_name() == 'cli' or defined('STDIN')){
$this->_set_uri_string($this->_parse_cli_args());
return;
}
// 首先尝试 REQUEST_URI 这个适应大部分的情况
if ($uri = $this->_detect_uri()){
$this->_set_uri_string($uri);
return;
}
// 看看PATH_INFO变量是否存在?nginx需要配置
// Note: some servers seem to have trouble with getenv() so we'll test it two ways
$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path, '/') != '' && $path != "/".SELF){
$this->_set_uri_string($path);
return;
}
// 没有PATH_INFO,看看 QUERY_STRING?
$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') != ''){
$this->_set_uri_string($path);
return;
}
//尝试去从 $_GET 获取信息
if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != ''){
$this->_set_uri_string(key($_GET));
return;
}
// 尽力了,放弃了路由
$this->uri_string = '';
return;
通过上面的尝试,接下来就是如何利用路由机制加载正确的controller了。
Controller加载机制
我们来看看Codeigniter框架是如何加载到controller并且调用action的。
在/system/core/Codeigniter.php中有如下的代码。Codeigniter在这之前会根据$_SERVER['PATH_INFO]里面的值来进行赋值(这个都是靠自己的设定的,默认的话CI他会有许多的if分支进行判断)。
复制代码 代码如下:
//大约在250行
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
$class = $RTR->fetch_class();
$method = $RTR->fetch_method();
//大约在308行
$CI = new $class();
//大约在359行
call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
就这样,通过这个就调用到了我们的controller及其方法了,接下来就是编写自己的业务逻辑代码了。
视图view的显示
当我们的业务逻辑代码写完后,就需要页面的展示了。很多常见的MVC框架在页面的调用是这么写的。
复制代码 代码如下:
//controller中action的方法
public function index(){
// ... 许多的业务逻辑代码
$data = array('name'=>'abc', 'age'=>12, .... );
return $this->render('view/path/file.html',$data);
}
接着在视图文件view/path/file.html里写上一下代码。
复制代码 代码如下:
姓名 : =$name ?>
年龄 :
这段如何将数据渲染到视图中,这段代码以前我一直很好奇,现在我明白了,我们来看看是如何实现的。
复制代码 代码如下:
protected function render($template, array $var = array() )
{
extract($var); // 抽取数组中的变量
ob_end_clean (); //关闭顶层的输出缓冲区内容
ob_start (); // 开始一个新的缓冲区
require TEMPLATE_ROOT . $template . '.html'; //加载视图view
$content = ob_get_contents (); // 获得缓冲区的内容
ob_end_clean (); // 关闭缓冲区
//ob_end_flush(); // 这个是直接输出缓冲区的内容了,不用再次缓存起来。
ob_start(); //开始新的缓冲区,给后面的程序用
return $content; // 返回文本,此处也可以字节echo出来,并结束代码。
}
在这短短的几行代码中,全都是精华,就是这些非常重要的,全是php的内置函数,接下来我们来具体分析分析。
看看第一个extract($var)。这个函数从数组中将变量导入到当前的符号表。刚刚就将$data数组里面的name、age抽取出来,这样就可以在视图view中使用$name $age。更详细的请参考http://www.php.net/manual/zh/function.extract.php
第二个ob_end_clean()的作用是关闭顶层的缓冲区,为了是之前的程序不小心echo出的一些文字给清楚了,为了下一行的重新开辟一块缓冲区。
第三个ob_start()是开启一块新的缓冲区,为了是将视图的内容放到缓冲区。当然了,缓冲区有一定的大小,如果内容超出了缓冲区的设定值,那么会自动的发送给server。
第四个require file,这个就是第一个参数,根据自己的规则去加载视图的文件。其中文件里可以夹杂php、html的代码。你在这个render()函数声明的任何局部变量或者这里能访问到的任何全局变量,都可以在require的file文件中访问到。
第五个$content = ob_get_contents ()很重要,是为了将缓冲区的内容取出来,但不清除它。
第七个ob_start()是重新开启一个缓冲区,为了是下面的程序需要使用缓冲区。有写框架可能不用对$content的内容进行操作了,那么直接ob_end_flush()将缓冲区的内容输出出来就行了。
这个是一个很简单的展示视图的过程。如果直接使用这个不方便对视图view进行模块化,因此一些框架都不会这么直接用的。
我们从这个函数也可以看到程序有点类似程序中断保护现场的感觉。只不过中断保护现场会先保存数据,然后在返回的时候恢复回来。这里只有关闭上一个缓冲区,开启一个新的缓冲区,关闭这个缓冲哦过去,开启另外一个缓冲区。
至此,我们看到一个简单的PHP的MVC框架。如果你有兴趣可以自己开发一个MVC框架,或者更深入点的HMVC。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

在PHP8 中,match表達式是一種新的控制結構,用於根據表達式的值返回不同的結果。 1)它類似於switch語句,但返回值而非執行語句塊。 2)match表達式使用嚴格比較(===),提升了安全性。 3)它避免了switch語句中可能的break遺漏問題,增強了代碼的簡潔性和可讀性。
