主要針對這篇轉載博文無法正常運行的bug修訂https://blog.csdn.net/chengshaolei2012/article/details/72675124
這篇博文的原始作者在http://www.awaimai.com/128.html#1MVC
不過我看了下上面那篇並沒有完全照搬,有些細節地方不同,比如他沒有用命名空間
1. 重定向
我只試了Apache,代碼改進
Options +Indexes +FollowSymLinks +ExecCGI
<IfModule mod_rewrite.c>
# 打開Rerite功能
RewriteEngine On
# 如果請求的是真實存在的文件或目錄,直接訪問
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# 如果訪問的文件或目錄不是真事存在,分發請求至 index.php
RewriteRule . index.php
</IfModule>
2. 配置文件
這個地方錯的比較離譜,他把原作者的數組改成了常量,但是在其他文件中他用的還是數組,導致不能正常運行,參考這個轉載的https://blog.csdn.net/qq_35524813/article/details/52692257可以發現一些問題,數據庫配置。
<?php
//數據庫配置
/*
define('DB_NAME','study');
define('DB_USER','root');
define('DB_PASSWORD','root');
define('DB_HOST','localhost');
*/
$config['db']['host'] = 'localhost';
$config['db']['username'] = 'root';
$config['db']['password'] = 'root';
$config['db']['dbname'] = 'study';
//默認控制器和操作名
$config['defaultController']='Item';
$config['defaultAction']='index';
return $config;
3. 框架核心類
此處的問題是loadClass方法,自動加載類,調用子類會自動加載父類,但是前提是類文件的命名方式要一樣。他這裏改變了原作者的命名方式,基類命名方式爲XXX.class.php
,普通類命名方式爲XXX.php
,所以他的寫法導致基類沒有加載,我們可以改變命名規則,也可以像下面一樣把加載基類的代碼添進去。
<?php
//fast核心框架
class Fastphp{
protected $_config=[];
public function __construct($config){
$this->_config=$config;
}
//運行程序
public function run(){
spl_autoload_register(array($this,'loadClass'));
$this->setDbConfig();
$this->setReporting();
$this->removeMagicQuotes();
$this->unregisterGlobals();
$this->route();
}
//路由處理
public function route(){
$controllerName=$this->_config['defaultController'];
$actionName=$this->_config['defaultAction'];
$param=array();
$url=$_SERVER['REQUEST_URI'];
/*$_SERVER $_SERVER 是一個包含了諸如頭信息(header)、路徑(path)、以及腳本位置(script locations)等等信息的數組。這個數組中的項目由 Web 服務器創建。不能保證每個服務器都提供全部項目;服務器可能會忽略一些,或者提供一些沒有在這裏列舉出來的項目。$_SERVER["REQUEST_URI"] 當前腳本路徑,根目錄之後的目錄。$_SERVER["SCRIPT_NAME"] 當前腳本的路徑。這在頁面需要指向自己時非常有用。
$_SERVER["PHP_SELF"] 當前正在執行腳本的文件名。$_SERVER["SCRIPT_FILENAME"] 當前執行腳本的絕對路徑。
*/
//清除?之後的內容
$position=strpos($url,'?');//strpos() f函數查找字符串在另一字符串中第一次出現的位置(區分大小寫),如果沒有找到字符串則返回 FALSE。
$url=$position===false?$url:substr($url,0,$position);
//刪除前後的/斜槓
$url=trim($url,'/');
if($url){
//使用/斜槓分割字符串,並保存在數組中
$urlArray=explode('/',$url);
//刪除空的數組元素
$urlArray=array_filter($urlArray);//array_filter — 用回調函數過濾數組中的單元如果沒有提供 callback 函數, 將刪除 array 中所有等值爲 FALSE 的條目。
//獲取控制器名
$controllerName=ucfirst($urlArray[0]);//ucfirst() 函數把字符串中的首字符轉換爲大寫。
//獲取動作名
array_shift($urlArray);//array_shift() 函數用於刪除數組中的第一個元素,並返回被刪除的元素,如果數組爲空則返回 NULL。
$actionName=$urlArray?$urlArray[0]:$actionName;
//獲取URL參數
array_shift($urlArray);
$param=$urlArray?$urlArray:array();
//判斷控制器和方法是否存在
$controller=$controllerName.'Controller';
if(!class_exists($controller)){//class_exists — 檢查類是否已定義,名字的匹配是不分區大小寫的。
exit($controller.'控制器不存在');
}
if(!method_exists($controller,$actionName)){//method_exists,檢查類的方法是否存在於指定的 object中。
exit($actionName.'方法不存在');
}
/*如果控制器和操作方法存在,則實例化控制器,因爲控制器對象裏面還會用到控制器名和方法名,所以實例化的時候把他們倆的名稱也傳進去,結合Controller基類一起
*/
$dispatch=new $controller($controllerName,$actionName);
/* $dispatch保存控制器實例化後的對象,我們就可以調用它的方法,也可以像方法中傳入參數,以下等同於:$dispatch->$actionName($param); */
call_user_func_array(array($dispatch,$actionName),$param);//call_user_func_array — 調用回調函數,並把一個數組參數作爲回調函數的參數
}
}
//檢測開發環境
public function setReporting(){
if(APP_DEBUG===true){
error_reporting(E_ALL);//error_reporting — 設置報告何種 PHP 錯誤,E_ALL報告所有 PHP 錯誤,ini_set('error_reporting', E_ALL);和 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');
}
}
//刪除敏感字符
public function stripSlashesDeep($value){
$value=is_array($value)?array_map(array($this,'stripSlashesDeep'),$value):stripslashes($value);//array_map — 爲數組的每個元素應用回調函數,stripslashes 去掉反斜槓,addslashes() 加反斜杆,爲了防止雙層轉義請使用get_magic_quotes_gpc() 進行檢測
return $value;
}
//檢測敏感字符並刪除
public function removeMagicQuotes(){
if(get_magic_quotes_gpc()){
$_GET=isset($_GET)?$this->stripSlashesDeep($_GET):'';// isset 檢測變量是否已設置並且非 NULL
$_POST=isset($_POST)?$this->stripSlashesDeep($_POST):'';
$_COOKIE=isset($_COOKIE)?$this->stripSlashesDeep($_COOKIE):'';
$_SESSION=isset($_SESSION)?$this->stripSlashesDeep($_SESSION):'';
}
}
/* 檢測自定義全局變量並移除。因爲register_globals已經棄用,如果已經棄用的register_globals指令被設置爲On,那麼局部變量也將在腳本的全局作用域中可用。例如,$_POST['foo']也將以$foo的形式存在,這樣寫是不好地地道道的實現,會影響代碼中其他變量。相關信息,參考http://php.net/manual/zh/faq.using.php#faq.register-globals */
public 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]);
}
}
}
}
}
//配置數據庫信息
public function setDbConfig(){
if($this->_config['db']){
Model::$dbConfig=$this->_config['db'];
}
}
//自動加載控制器和模型類
public static function loadClass($class){
$frameworks=__DIR__.'/'.$class.'.php';
$controllers=APP_PATH.'application/controllers/'.$class.'.php';
$models=APP_PATH.'application/models/'.$class.'.php';
$modelsclass=APP_PATH.'application/models/'.$class.'.class.php';
$controllersclass=APP_PATH.'application/controllers/'.$class.'.class.php';
$views=APP_PATH.'application/views/'.$class.'.class.php';
if(file_exists($frameworks)){//file_exists — 檢查文件或目錄是否存在
//加載框架核心類
include($frameworks);
}elseif(file_exists($controllers)){
//加載應用控制器類
include($controllers);
}elseif(file_exists($models)){
//加載應用模型類
include($models);
}elseif(file_exists($modelsclass)){
//加載應用模型基類
include($modelsclass);
}elseif(file_exists($controllersclass)){
//加載應用控制器基類
include($controllersclass);
}elseif(file_exists($views)){
//加載視圖基類
include($views);
}else{
echo '錯誤處理代碼!';
}
}
}
?>
其他代碼都沒有問題了,就這樣吧。