程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP框架原理

PHP框架原理

編輯:關於PHP編程

  本文主要來聊聊框架理論,但不針對任何一款框架,不過任何一款框架都離不開這個理論,首先我們了解下框架的來龍去脈,任何技術的出現都是為了解決某個問題,之前的博客有講過smarty,其存在就是為了html和php更好地分離開來。而所謂的“框架”是一種為了統一書寫格式,訪問方式而進行的自我約束行為,其實按照這個說法我們每個人基本上都或多或少的使用過自己定義的框架,比如說在沒使用框架之前自己開發一個項目,有時候是一天無法完成的,我們為了防止混亂,為了更好地記憶我們會進行目錄規劃和程序的規劃,潛意識的把程序分類,放到不同的文件夾,於是框架應運而生了,又比如說我們曾經做了一個CMS系統,如果我們又接手一個類似的項目,你會重復書寫代碼嗎,答案肯定不會,但如果是別人的項目你拿來改其實是一件很蛋疼的事情的,因為你根本不知道他的這個CMS的規則是什麼,即使是自己的項目時間久了如果自己沒有固定的規范的話也是很容易忘記的,那麼怎麼樣才能保證自己每次寫的代碼都可以按照一定的規范呢,把每個項目要用的東西挑出來,目錄結構挑出來,以後無論什麼項目都在這個基礎上書寫,那麼屬於自己的框架就出來了。

  但框架單純這樣是不完善的,那麼框架應該有哪些能力呢,與其這樣說我們不妨想想我們平時一定會寫的代碼一定會做的事情是什麼呢,首先解決的是什麼呢,為了減少路徑問題,目錄結構的安排其實很重要,有時候文件包含 再進行文件的移動總是一件很蛋疼的事情,最好的辦法是什麼呢,絕對路徑,但同時存在了一個類似E:\www 這樣的問題,但這個值我們可以通過預定義變量$_SERVER["DOCUMENT_ROOT"]獲得,我們可以將其定義為常量,define("ROOT_PATH", $_SERVER["DOCUMENT_ROOT"]);include ROOT_PATH . "/lib/mysql.php";類似這樣的文件夾怎麼移動都不會有事的,那麼就出現了一個固定的寫法,為了解決路徑問題而存在的寫法,幾乎每一頁都會用到,還有模板的輸出,數據庫的連接,那麼我們可以把這些代碼封裝起來,或者分離出來,每一頁包含即可,被分離的這些部分其實就是一個小框架,為什麼這麼說呢,如果我們包含它們進來,例如smarty模板,肯定是實例化好的對象,那個量名已經固定,可能是$smarty 如果我們包含了這麼個文件進來,這個量就不能再次進行賦值使用,這樣下面部分的代碼就無法進行使用了,由於包含的類,如數據類 上傳類 圖像類 分頁類 位置已經寫死在這個公共文件裡,為了不改代碼 這個目錄就成了必須存在的了,目錄格式固定,編寫代碼方式的約束,這就形成了框架。 

  多年來的程序員的總結交流及開發經驗,大家總結了一些優秀的編寫方式,最經典的是單點入口,什麼是單點入口呢,之前我們總結了一些幾乎每個程序都要用到的功能,這裡依然存在一些問題,例如 在公共文件包含之前我們還是不知道根目錄是多少,如果我們在每一個文件夾下面都放一個公共文件存在代碼重復問題,哪天修改的話需要全部修改,需要找到需要多少個這樣的文件,現在是多個程序包含一個程序,然後用戶訪問n個程序來完成各個功能,於是程序員就想可不可以反過來我用一個程序包含這些不同功能的程序,用戶只訪問這個程序就可以了呢,於是單點入口模式出現了,在網站首頁的 index.php 寫上每個程序都要用的部份 然後跟據某個量,比如一個 get 量來判斷當前實際要執行的程序是哪一個,由 index.php 把它包含進來運行,這種由一個程序。完成所有功能的方式,稱為 單點入口, 於是由這個入口程序和它對應的各個目錄結構成為了一個框架。

  出於安全在包含文件的時候往往都會固定目錄,不然就容易出漏洞 所以,往往會在路徑頭尾加個限制。例如


<?PHP
include "./app/" . $_GET['url'] . ".php";
?> 

那路徑就只能寫成類似這樣index.php?url=news/list,實際包含的是 /app/news/list.php 當然了,實際的情況,還要檢查一下這個程序文件是否存在之類的。 

 完整一點的話。我們可以這樣寫這個入口文件。
<?php

//這裡寫絕對路徑

//這裡寫數據庫連接

//這裡寫模板初始化,配置

//這裡判斷連接變量

//這裡包含文件進來運行

//這裡輸出模板

//這裡關閉數據庫
?> 
 一個面向過程的單點入口框架就完成了, 是不是有覺得每次都在地址欄帶一個 get 不方便? 那我們可以換一個寫法,例如 tp 框架最喜歡用的 http://localhost/index.php/news/list後面的 /news/list 由程序轉成 php 路徑包含進來就可以了。在 Apache 環境中,這個 /news/list 可以由服務器變量的 PATH_INFO 取得,如果沒有的話。也可以用 REQUEST_URI 取得接近的 ,IIS 下面,有 HTTP_X_REWRITE_URL 可以取得這個值 ,自從單點入口模式出現之後,而且oop開發模式從php5開始大行其道,各種oop設計的框架讓我們眼花缭亂,但是萬變不離其宗,依然是什麼入口方式,路徑結構是什麼樣的,文件名的命名規則,用什麼樣的訪問方式,可以運行哪個程序。用oop開發的框架,不外乎就是把主程序改寫成為了一個類,

例如:

//包含共用文件,實例化各個類啥的
頁面->初始化();

//把用戶發來的網址轉成要包含的路徑
頁面->處理網扯();

//在這裡包含程序運行
頁面->運行()

//輸出模板
頁面->輸出()

各種各樣的框架只是為我們准備了一個規矩罷了。。在我們的開發累計的過程中,我們常常會把一些常用的類封裝成類,例如,數據庫類,文件上傳類,圖片處理類,郵件收發類,遠程訪問類,各種接口類……這個時候,我們就會希望框架能給我們提供一個好一點調用類的方法, 也就是所謂的“擴展性” ,比如 TP 框架的 Db 類 。如果不用其自帶的類庫只用它們的核心框架,其實幾個文件就夠了。  TP 框架支持三種訪問格式。
/news/list
/index.php/news/list
/index.php?m=news&a=list  第一種需要服務器的 urlrewrite 支持,後面兩種可以直接用,  事實上,Zend 框架也差不多 文件的包含方式是。以類的形式包含,執行的其實是:/文件夾/對象/方法,這種做法有優勢。因為在同一個功能中,相似的代碼很多,封裝到同一個類裡面,可以更高效的重復使用代碼 ,
比如這樣

class NewsAction {
    public function head() {
        在這裡處理每一頁頭部
    }

    public function index() {
        $this->head();
        在這裡處理這一頁
    }

    public function show() {
        $this->head();
        在這裡處理這一頁
    }

還可以利用構造函數等,使每一個功能,在剛進來的時候就都做了同一件事情。以上就是簡單框架的理論。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved