<code><span><?php </span><span>// +-------------------------- --------------------------------------------</span><span> // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]</span><span>// +---------------------------- ------------------------------------------</span><span>// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.</span><span>// +---------------------- ------------------------------------------------</span><span>// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )</span><span>// +---------------- -------------------------------------------------- ----</span><span>// | Author: liu21st <liu21st></liu21st></span><span>// +------------------ -------------------------------------------------- --</span><span>/*** Think 系統函式庫*/</span><span>// 同學們,上課,我們已經完成了thinkphp 各種預定義變數的定義</span><span>/ / 重點可以分成以下幾點:</span><span>// 第一:對於需要web 加載的也就是項目文檔thinkphp 採取的dirname 的方式進行的組合跟加載</span><span>// 其特點是////// 這樣的斜線</span><span>// 對於需要引入的檔案也就是thinkphp 核心框架部分其載入方式採取了__DIR__的方式進行載入</span><span>// 其特點是\\ 這樣的反斜線</span><span>// ps 當然這些都是基於window 下的方向, 也就分成了兩條路徑的始祖app_PATH 跟think_PATH</span><span>// 第二:我們可以進行記錄的事情是</span><span>// 作為一個框架程序,需要有能力記錄該腳本執行的時間跟內存的消耗,所以就毫不猶豫的開啟了mirctime 跟memory_get_usage</span><span>// 此刻作為時間跟記憶體的起點。 </span><span>// 第三:值得我們注意的地方是:</span><span>// 使用了const 跟define 定義了系統常數,但是感覺就是,必須一成不變的,用了const</span> <span>// 就代表這個,徹底就固化死了,define 是可以讓使用者在創建自己的app 中進行修改的。 在系統定義之前,會判讀是否定義,</span><span>// const 是沒有辦法重新定義的</span><span>// 總結基本上沒什麼區別,這兩個, 唯一就是用法啊,編譯上的一個區別! </span><span>// 第四:對系統預定義變數[GPC] 跟文字資料流</span><span>// 基本上可以說是進行非轉義處理麼有addsalshe 之類的</span> <span>// 第五:判讀了php 跟web伺服器的通訊方式cgi</span><span>// 判讀了作業系統</span><span>// 判讀了是否脫離伺服器運作的命令列工具</span><span>// 第六: 針對於ROOT 跟_FILE_ 檔案的定義不統一,重新進行了多平台定義,增強了平台的可以移植性。 </span><span>// 總之:就是 規範了定義 以及其 跨平台特性! </span><span>// 接下來我們講針對與functions.php 這些公用函數為大家進行解說20151205</span><span>/*** 實例化多層控制器 格式:[資源://][模組/]控制器
*<span> @param</span> string $name 資源位址
*<span> @param</span> string $layer 控制層名稱
*<span> @param</span> integer $level 控制器層次
*<span> @return</span> ThinkController|false*/</span><span>// 此函數進行多層控制器實例化功能方便其內部調用,在寫app 應用的時候比較少用。</span><span><span>function</span><span>A</span><span>(<span>$name</span>,<span>$layer</span>=<span>''</span>''<span> ,</span>$level<span>=</span>0</span>)</span> {<span></span>static<span></span>$_action<span> = </span>array// 此處定義靜態化儲存陣列為其實作單列實例化模式</span><span>$layer</span> = <span>$layer</span>? : C(<span>'DEFAULT_C_LAYER' </span>); <span>//'DEFAULT_C_LAYER' => 'Controller', // 預設的控制器層名稱</span><span>$level</span> = <span>$level</span>? : ( <span>$layer</span> == C(<span>'DEFAULT_C_LAYER'</span>)?C(<span>'CONTROLLER_LEVEL'</span>):<span>1</span>); 'CONTROLLER_LEVEL' => 1,<span></span>if<span>(</span>isset<span>(</span>$_action<span>[</span>$name<span>.</span>.<span> 🎜>]))</span>// 根據傳入的控制器以及其對應的層級預設:Controller 1 層級回傳<span></span>return<span></span>$_action<span>[</span>$ name<span>.</span>$layer<span>];
</span>$class<span> = parse_res_name(</span>$name<span>,</span>$layer<span>,</span>$level<span>); </span>// 根據其傳入的控制器名稱層級類別名稱取得對應的class 名稱<span></span>if<span>(class_exists(</span>$class<span>)) { </span>// 如果說根據上述的產生class 名稱如果存在就進行實例化<span></span>$action<span> = </span>new<span></span>$class<span>(); </span>// 實例化<span></span>$_action<span>// 實例化</span><span>$_action</span>[<span>$name</span>.<span>$layer</span>] = <span>$action</span>;<span>// 存放實例化物件到靜態數組</span><span>return </span><span>$action</span>;<span>// 傳回實例化情況</span>
}<span>else</span> {
<span>return</span><span>false</span>;
}
<span>// 例如: $name = 'admin' 結果就是 $class = AdminController.class.php 檔案 下的 AdiminController 類別。 </span>
}
<span>// 總結: 其實這個,就是根據你傳入的 $name 回傳 不同的 實例化物件。 $name 可以存在的選項為:</span><span>// A('[項目://][分組/]模組','控制器層名稱') 目前感覺這個level 基本上用不到。 </span><span>// 等待拯救</span><span>// 好的,同學們我們今天繼續,昨天了解A函數,其實就是一個根據不同參數去實例化不同控制器類別的一個功能函數</span><span>// 注意A函數中加入了一個把不同輸入參數轉換的對應類別的名稱跟位置</span><span>// 接下來我們來看看B 函數的功能<span></span> /*** 執行某個行為
*<span> @param</span> string $name 行為名稱
*<span> @param</span> string $tag 標籤名稱(行為類別無需傳入)
*<span> @param</span> Mixed $params 傳入的參數
*</span> @return<span> void*/<span></span><span>function</span><span>B<span></span>(<span>$name</span>, <span>$tag</span>$標籤<span> </span>''</span>,&</span>$params<span>=NULL)</span> {<span></span>if<span>(</span>''<span>==</span>$ tag<span>){
</span>$name<span> .= </span>'Behavior'<span>;
}
</span>return<span> ThinkHook::exec(</span>$name<span>,</span>$tag<span>,</span>$params<span>);
}
</span>// 從字面上來說,這個是個執行某個行為的函數,<span></span>// 如果沒有對應的標籤,也就是預設的行為就是找到鉤子函數來執行<span></span>// 另外注意一點就是其$params 其實是一個引入傳值,並不是一個普通的複製傳值,這樣,可以無需返回就改變了傳入的參數。 <span></span>// 根據其鉤子函數的特殊情況,一般其配置在Addons 下面<span></span>// 預設為$name Behavior 聯合<span></span>// 預設的執行函數是run <span></span>// 檔案位置"Addons\{$name}\{$name}Addon";<span></span>// $class = $name.'Behavior';<span></span>/ / $tag = 'run';<span></span>// return $addon->$tag($params);<span></span>// 總結,其實B函數,就是執行插件【內部/外部】的兩種,引入插件的開始位置。執行開始函數。 <span></span>// return $class->run(參數);<span></span>// 下面繼續我們的學習,這個C函數,是一個很常用的函數,如果說AB我們可以一般的略過,這個就要我們仔細研究一下啦<span><span>//</span><span>/*** 取得和設定組態參數 支援批次定義
*</span> @param<span> string|array $name 設定變數
*</span> @param<span> mixed $value 設定值
*</span> @param</span> mixed $default 預設值
*<span> @return<span> mixed*/</span><span></span>function<span><span>C </span><span>(</span>$name<span>=null, </span>$value</span>=null,</span>$default<span>=null)</span> {<span>$default</span>=null)<span> {</span><span></span> // 定義初始化容器,只能一次初始化的<span>static$_config = array();// 經典的靜態全域變數註冊,執行單一流程時有效,其實,對於多頁面不同載入的話,效果不明顯。是一個可以優化的地方。</span><span>// 無參數時取得所有情況1</span><span>if</span> (<span>empty</span>(<span>$name</span>)) { <span>///這是一個大招,也就是,當調用C()的時候,注意,內部為空的時候, 就把你全家的都返回出去了。 </span><span>return</span><span>$_config</span>;
}
<span>// 優先執行設定取得或賦值情況2</span><span>if</span> (is_string(<span>$name</span>)) { <span>// 如果是個字串,也不下面陣列的形式</span><span>if</span> (!strpos(<span>$name</span>, <span>'.'</span>)) { <span>// 此處可以記作2.1 如果沒有連接符號,這個我覺得有點多次一舉了,但是是為了相容於陣列的保存形式。老劉啊,你真的不容易啊。 </span><span>$name</span> = strtoupper(<span>$name</span>); <span>// 無關什麼字母,統統大寫,這個其實是相容的一個好的處理方式,同學們可以藉鏡哦! </span><span>if</span> (is_null(<span>$value</span>)) <span>///return</span><span>isset</span>(<span>$_config</span>[<span>$name</span>]) ? <span>$_config</span>[<span>$name</span>] : <span>[</span>$name<span>] : $default</span>; <span>// 此處的三元,真的很高明, 可以分成2.1.1.1 跟2.1.1.2</span><span>$_config</span>[<span>$name</span>] = <span>$value</span>; <span>// 此處記作2.1.2 你懂了嗎</span><span>return</span><span>null</span>; <span>; //這些是各種中條件細分</span><span>// 總結就是C('name','zhangsan'); 就是賦值name 為張三</span><span>// 如果$name = C ('name') 是讀取name的賦值,如果剛執行過上面的語句的話</span><span>// 那麼$name 就是張三了</span>
}
<span>// 二維陣列設定與取得支援</span><span>$name</span> = explode(<span>'.'</span>, <span>$name</span>); <span>/ / 這裡只是增加了二維數組的支援這裡有個問題,就是二維數組的子元素沒有變成大寫</span><span>$name</span>[<span>0</span>] = strtoupper( <span>$name</span>[<span>0</span>]);
<span>if</span> (is_null(<span>$value</span>))
<span>return</span><span>isset</span>(<span>$_config</span>[<span>$name</span>[<span>0</span>]][<span>$name</span>$name<span>$name</span>$name<span>$name</span>$name<span>$name</span>$name<span>$name</span>$name<span>$name</span>$name<span>$name[</span>1<span>]]) ? </span>$_config<span>[</span>$name<span>[</span>0<span>]][</span>$name<span>[ </span>1<span>]] : </span>$default<span>;
</span>$_config<span>[</span>$name<span>[</span>0<span>]][</span>$name<span>[</span>1<span>]] = </span> $value<span>;
</span>return<span></span>null<span>;
}
</span>// 批量設定 情況3 直接合併數據了 其實並不很常用,原因是容易搞暈,對於我這種小智商的人,就算了,不過,偶爾會用一下。 <span></span>if<span> (is_array(</span>$name<span>)){
</span>$_config<span> = array_merge(</span>$_config<span>, array_change_key_case(</span>$name<span>,CASE_UPPER));
</span>return<span></span>null<span>;
}
</span>// 其它 情況<span>returnnull; // 避免非法參數
}
// 好的,感謝同學們,我們下節課繼續! // 其實上節課程中我們講到C函數,這裡有一思路,就函數盡量不要收到配置文件的限制,// 我們今天繼續D函數,這個函數在thinkphp的使用中,是貫穿始終的。</span><span>// 這個是一個實例化Model 類的函數</span><span>/*** 實例化模型類別 格式 [資源://][模組/]模型
*<span> @param</span> string $name 資源位址
*<span> @param</span> string $layer 模型層名稱
*<span> @return</span> ThinkModel*/</span><span><span>function</span><span>D</span><span>(<span>$name</span>=<span>''</span>,<span>$layer</span>=<span>''</span>)</span> {</span><span>if</span>(<span>empty</span>(<span>$name</span>)) <span>return</span><span>new</span> ThinkModel; <span>// 如果輸入參數為空參數為空,直接回傳預設的Model</span><span>static</span><span>$_model</span> = <span>array</span>(); <span>// 否則就可以建立靜態實例化倉庫</span><span>$layer</span> = <span>$layer</span>? : C(<span>'DEFAULT_M_LAYER'</span>); <span>// 這裡進行預設層的確認,就是</span><span>if</span>(<span>isset</span>(<span>$_model</span>[<span>$name</span>.<span>$layer</span>])) <span>// 同樣的道理存在就回,其實就是單列的應用思想</span><span>return</span><span>$_model</span>[<span>$name</span>.<span>$layer</span>];
<span>$class</span> = parse_res_name(<span>$name</span>,<span>$layer</span>); <span>//透過解析取得到對應的類別名稱這個函數是包含匯入檔案功能的,牛叉吧</span><span>if</span>(class_exists(<span>$class</span>)) { <span>// 如果存在就直接載入並且實例化</span><span>$model </span> = <span>new</span><span>$class</span>(basename(<span>$name</span>));
}<span>elseif</span>(<span>false</span> === strpos(<span>$name</span>,<span>'/'</span>)){ <span>// 如果說沒有找到類別檔案也就是沒有找到類別</span><span>// 自動載入公用模組下面的模型</span><span>if</span>(!C(<span>'APP_USE_NAMESPACE'</span>)){ <span>// 就去公共模型下面找, 如果沒有指定公共模型</span>
import(<span>'Common/'</span>.<span>$layer</span>.<span>'/'</span>.<span>$class</span>); <span>// 預設公用模型存放位置</span>
}<span>else</span>{
<span>$class</span> = <span>'\Common\'</span>.<span>$layer</span>.<span>'\'</span>.<span>$name</span>.<span>$layer</span>;<span>// 實在不行就去實例化預設的類別了</span>
}
<span>$model</span> = class_exists(<span>$class</span>)? <span>new</span><span>$class</span>(<span>$name</span>) :$class<span>(</span>$name<span>) : </span> new<span> ThinkModel(</span>$name<span>);
}</span>else<span> { </span>// 否則的日誌記錄錯誤 實例化一個基礎的類別 給 回傳<span>
ThinkLog::record(</span>'D方法實例化沒找到模型類別'<span>.</span>$class<span>,ThinkLog::NOTICE);
</span>$model<span> = </span>new<span> ThinkModel(basename(</span>$name<span>));
}
</span>$_model<span>[</span>$name<span>.</span>$layer<span>] = </span>$model<span>; </span>// 存入歷史記錄<span></span>return<span></span>$model<span>;</span>// 傳回當期實例化的類別3中方式進行的實例化<span>
}
</span>// 拋出異常 基本上就是個封裝了 直接轉的 但是在他的核心程式碼裡面 也沒什麼東西了。 <span><span>// 只是繼承了php 預設的異常類別</span><span>/*** 拋出例外處理
*</span> @param<span> string $msg 異常訊息
*</span> @param<span> integer $code 異常代碼 預設為0
*</span> @throws</span> ThinkException
*<span> @return<span> void*/</span><span></span>function<span><span></span><span>function</span><span> ></span>(</span>$msg</span>, <span>$code</span>=<span>0</span>)<span> {</span><span>throw</span><span>new</span> Think<span>Exception</span>(<span>$msg<span>, </span>$code<span>);
}
</span>// 這是一透過檔案快速 資料 儲存跟讀取操作的事情。 <span></span>/*** 快速檔案資料讀取與保存 針對簡單類型資料 字串、陣列
*<span> @param</span> string $name 快取名稱
*</span> @param<span> mixed $value 快取值
*<span> @param</span> string $path 快取路徑
*<span> @return</span> mixed*/<span><span></span>function<span></span>F<span></span>(<span>$name</span>F</span></span>(<span>$name</span> $value<span>=</span>''<span>, </span>$path<span>=DATA_PATH)</span> {<span></span>static<span></span>$_cache = <span>array</span>(); <span>// 老一套啊,看起來用的很順手啊,</span><span>$filename = $path . $ name . '.php'; // 檔案目錄,也很簡單。直接使用的php 檔案</span><span>if</span> (<span>''</span> !== <span>$value</span>) { <span>// 若有數值</span><span>) { </span>// 若有數值<span></span>if<span> (is_null(</span>$value<span>)) { </span>// 如果存在的數值為空的話<span></span>// 刪除快取<span></span>if<span>(</span>false<span> !== strpos(</span>$name<span>,</span>'*'<span>)){ </span>// 若儲存的物件中存在* 號,錯誤<span></span>return<span></span>false<span>; </span>// TODO<span>
}</span>else<span>{
</span>unset<span>(</span>$_cache<span>[</span>$name<span>]);</span>// 刪除資料快取<span></span>return<span> ThinkStorage::link (</span>$filename<span>,</span>'F'<span>); </span>// 刪除資料檔<span>
}
} </span>else<span> {
ThinkStorage::put(</span>$filename<span>,serialize(</span>$value<span>),</span>'F'<span>); </span>// 以序列化的方式寫入檔案<span></span>// 快取資料<span></span>$_cache<span>[</span>$name<span>] = </span>$value<span>; </span>// 且寫入快取<span></span>return<span></span>null<span>;
}
}
</span>// 取得快取資料<span></span>if<span> (</span>isset<span>(</span>$_cache<span>[</span>$name<span>])) </span>[<span>$name</span>])) <span> // 跟其通用C 很像啊,</span><span>return</span><span>$_cache</span>[<span>$name</span>];
<span>if</span> (ThinkStorage::has(<span>$filename</span>,<span>'F'</span>)){ <span>// 讀取存在的檔案</span><span> $value</span> = unserialize(ThinkStorage::read(<span>$filename</span>,<span>'F'</span>));
<span>$_cache</span>[<span>$name</span>] = <span>$value</span>; <span>// 回傳資料</span>
} <span>else</span> {
<span>$value</span> = <span>false</span>;
}
<span>return</span><span>$value</span>; <span>//回傳資料</span>
}
<span>// 是一個快取資料的讀取,跟file 相比差得多了// 好的, 各位同學,繼續// 這裡給大家提示一點,框架中的叫做functions.php 應用中的叫做function.php// 大家明白我此刻說的應用裡面的位置嗎?</span><span>// 如果作為一個函數的註釋來說,該函簡潔明了</span><span>/*** 記錄和統計時間(微秒)和記憶體使用情況
* 使用方法:
* <code>
* G('begin'); // 記錄開始標記位
* // ... 區間運行程式碼
* G('end'); // 記錄結束標籤位
* echo G('begin','end',6); // 統計區間運作時間 精確到小數後6位元 時間 用數字
* echo G('begin','end','m'); // 統計區間記憶體使用 記憶體以m表示
* 如果end標記位沒有定義,則會自動以目前作為標記位
* 其中統計記憶體使用需要 MEMORY_LIMIT_ON 常數為true才有效
* </code>
*<span> @param</span> string $start 開始標籤
*<span> @param</span> string $end 結束標籤
*<span> @param</span> integer|string $dec 小數位或m
*<span> @return</span> mixed*/</span><span>// 這裡不得不說thinkphp 的創始人,特別喜歡做的一個事情,就是,根據輸入參數的不同實現不同的意義</span><span>// 如C 函數F 函數,都是,如果僅輸入單一參數表示讀取數字, 2 個參數表示設定數值,3 個參數一般多加了預設值</span><span>// number_format — 以千位分隔符號方式格式化一個數字</span><span>// $nombre_format_francais = number_format($number, 2 , ',', ' ');</span><span><span>function</span><span>G</span><span>(<span>$start</span>,<span>$end</span> =<span>''</span>,<span>$dec</span>=<span>4</span>)</span> {</span><span>static</span><span>$_info</span> =<span> =</span> <span>array</span>(); <span>// 這個是時間倉庫</span><span>static</span><span>$_mem</span> = <span>array</span>(); <span> >// 這個是記憶體倉庫</span><span>if</span>(is_float(<span>$end</span>)) { <span>// 記錄時間如果傳值如此G('start',2342353234.453) ; 是記錄跟上面的風格保持一致</span><span>// 有小數傳入就是結束</span><span>$_info</span>[<span>$start</span>] = <span>$ end</span>; <span>// 或如果傳值如此G('start',microtime(TRUE));</span>
}<span>elseif</span>(!<span>empty</span>(<span>$end</span>)){ <span>// 統計時間和記憶體使用也就是其預設的優先權是時間</span><span>// 有非數字結尾就是回傳差值</span><span>if</span>(!<span>isset</span>(<span>$_info</span>[<span>$end</span>])) <span>$_info</span>[<span>$end</span>] = microtime(<span>TRUE</span>);
<span>if</span>(MEMORY_LIMIT_ON && <span>$dec</span>==<span>'m'</span>){ <span>// 如果開啟了記憶體記錄且明確是記憶體的記錄</span> <span>if</span>(!<span>isset</span>(<span>$_mem</span>[<span>$end</span>])) <span>$_mem</span>[<span>$</span>$<span>$ end</span>] = memory_get_usage(); <span>// 取得記憶體記錄</span><span>return</span> number_format((<span>$_mem</span>[<span>$end$_mem<span>[</span>$start<span>])/</span>1024<span>); </span>// 取得傳回的格式化數值<span>
}</span>else<span>{
</span>return<span> number_format((</span>$_info<span>[</span>$end<span>]-</span>$_info<span>[</span>$start<span>],</span>$dec<span>); </span>// 回傳格式化的位數預設4位小數<span>
}
}</span>else<span>{ // 記錄時間和記憶體使用// 單獨的話,就是同步記錄 記憶體 跟時間的 標誌位。</span><span>$_info</span>[<span>$start</span>] = microtime(<span>TRUE</span>);
<span>if</span>(MEMORY_LIMIT_ON) <span>$_mem</span>[<span>$start</span>] = memory_get_usage();
}
<span>return</span><span>null</span>;
}
<span>// 無 H 函數</span><span>// 今日早上面試,就到這裡了,感謝! </span><span>// 嗯,昨天有點匆忙,其實這個G就是一個記錄時間跟內存的函數,都過第二,第三個參數的屬性</span><span>// 進行區分是記錄的時間還是其它什麼的,但是不管怎麼得瑟,都是同時記錄的時間給內存</span><span>// 通過時間跟內存的記錄可以從一個角度來反映出php 程式運行的性能</span><span>// 接下來是我們強大的I輸入過濾函數,支援預設值</span><span>/*** 取得輸入參數 支援過濾和預設值
* 使用方法:
* <code>
* I('id',0); 取得id參數 自動判斷get或post // 嗯,你舉例的這幾個,確實很常用
* I('post.name','','htmlspecialchars'); 取得$_POST['name']
* I('get.'); 取得$_GET
* </code>
*<span> @param</span> string $name 變數的名稱 支援指定類型
*<span> @param</span> mixed $default 不存在的時候預設值
*<span> @param</span> mixed $filter 參數過濾方法
*<span> @param</span> mixed $datas 要取得的額外資料來源
*<span> @return</span> mixed*/</span><span><span>function</span><span>I</span><span>(<span>$name</span>,<span>$default</span>=<span>''</span>,<span>$filter</span>=null,<data>,<span>$filter</span>=null,<data>=null)</data></data></span> {</span><span>// 第一步:指定倉庫</span><span>static</span><span>$_PUT</span> = <span>null</span>null<span>; </span>// 預設單一資料倉儲<span></span>// 第二步:判定輸入型別<span></span>if<span>(strpos(</span>$name<span>,</span>' /'<span>)){ </span>// 指定修飾符<span></span>list<span>(</span>$name<span>,</span>$type<span>) = explode(</span>,<span>$type</span>) = explode(<span>'/'</span>,<span>$name</span>,<span>2</span>);
}<span>elseif</span>(C(<span>'VAR_AUTO_STRING'</span>)){ <span>// 預設強制轉換為字串</span><span>// // 輸入變數是否自動強制轉換為字串如果開啟則數組變數需要手動傳入變數修飾符取得變數</span><span>// 其實上面的這個預設是false</span><span>$type</span> = <span>'s' </span>;
}
<span>// 第三步:資料來源取得// 第三步:第一小步驟:就是分解資料來源// 在一般的程序中,上面這兩個是用不到的,也就是指定資料類型, 預設都沒有指定。</span><span>if</span>(strpos(<span>$name</span>,<span>'.'</span>)) { <span>// 指定參數來源</span><span>list</span>(<span>$method</span>,<span>$name</span>) = explode(<span>'.'</span>,<span>$name</span>,<span>2</span>2<span> );
}</span>else<span>{ </span>// 預設為自動判斷<span></span>$method<span> = </span>'param'<span>;
}
</span>// 第三步:第二小步驟:關聯資料來源<span></span>// 指定資料來源,常用的就是get post 了<span></span>switch<span>(strtolower(</span>$method<span>)) { </span>// 其實這個用的很經典比較之前先小寫<span></span>case<span></span>'get'<span> :
</span>$input<span> =& </span>$_GET<span>; </span>// 取地址 用的也不錯,很有想法<span></span>break<span>;
</span>case<span></span>'post'<span> :
</span>$input<span> =& </span>$_POST<span>;
</span>break<span>;
</span>case<span></span>'put'<span> :
</span>if<span>(is_null(</span>$_PUT<span>)){
parse_str(file_get_contents(</span>'php://input'<span>), </span>$_PUT<span>);
}
</span>$input<span> = </span>$_PUT<span>;
</span>/*
讀取POST數據
不能用於multipart/form-data類型
php://input VS $HTTP_RAW_POST_DATA
讀取POST資料 */<span></span>break<span>;
</span>case<span></span>'param'<span> :</span>// 其實這個最不科學了,為了相容懶人編程,<span></span>switch<span>(</span>$ _SERVER<span>[</span>'REQUEST_METHOD'<span>]) {
</span>case<span></span>'POST'<span>:
</span>$input<span> = </span>$_POST<span>;
</span>break<span>;
</span>case<span></span>'PUT'<span>:
</span>if<span>(is_null(</span>$_PUT<span>)){
parse_str(file_get_contents(</span>'php://input'<span>), </span>$_PUT<span>);
}
</span>$input<span> = </span>$_PUT<span>;
</span>break<span>;
</span>default<span>:
</span>$input<span> = </span>$_GET<span>;
}
</span>break<span>;
</span>// 常用的三種輸入獲取方式GET POST PUT<span></span>case<span></span>'path'<span> : </span>// 居然還有路徑獲取,我調用中從來沒用過<span></span>$input<span> = </span>array<span>();
</span>if<span>(!</span>empty<span>(</span>$_SERVER<span>[</span>'PATH_INFO'<span>])){
</span>$depr<span> = C(</span>'URL_PATHINFO_DEPR'<span>);</span>// 路徑分隔符號<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span></span>//'URL_PATHINFO_DEPR' =<span>> PIN模式下,各參數之間的分割符號</span><span>$input</span> = explode(<span>$depr</span>,trim(<span>$_SERVER</span>[<span>'PATH_INFO'PATH_INFO' </span>],<span>$depr</span>));
}
<span>break</span>;
<span>case</span><span>'request'</span> :
<span>$input</span> =& <span>$_REQUEST</span>;
<span>break</span>;
<span>case</span><span>'session'</span> :
<span>$input</span> =& <span>$_SESSION</span>;
<span>break</span>;
<span>case</span><span>'cookie'</span> :
<span>$input</span> =& <span>$_COOKIE</span>;
<span>break</span>;
<span>case</span><span>'server'</span> :
<span>$input</span> =& <span>$_SERVER</span>;
<span>break</span>;
<span>case</span><span>'globals'</span> :
<span>$input</span> =& <span>$GLOBALS</span>;
<span>break</span>;
<span>case</span><span>'data'</span> :
<span>$input</span> =& <span>$datas</span>;
<span>break</span>;
<span>default</span>:
<span>return</span><span>null</span>;
}
<span>// 第四步:明確取得變數</span><span>// 4.1 取得全部數值</span><span>if</span>(<span>''</span>==<span>$name </span>) { <span>// 取得全部變數</span><span>$data</span> = <span>$input</span>;
<span>// 用過濾函數繼續過濾</span><span>$filters</span> = <span>isset</span>(<span>$filter</span>)?<span>$filter</span>$filter<span>)?</span>$filter<span>$filter</span>)?<span>$filter</span>$filter<span>)?</span>$filter'DEFAULT_FILTER'</span>);
<span>if</span>(<span>$filters</span>) {
<span>if</span>(is_string(<span>$filters</span>)){
$filters = explode(',',$filters);
}
foreach($filtersas$filter){
$data = array_map_recursive($filter,$data); // 參數過濾
}
}
// 4.2 取得 指定數值
}<span>elseif</span>(<span>isset</span>(<span>$input</span>[<span>$name</span>])) { <span>// 取值操作如果明確取值</span><span>$data</span> = <span>$input</span>[<span>$name</span>]; <span>// 資料取得完成</span><span>// 開始執行過濾</span><span>$filters</span> = <span>isset</span>(<span>$filter</span>)?<span>$filter</span>:C(<span>'DEFAULT_FILTER' );
</span>// 存在過濾器 開始過濾<span></span>if<span>(</span>$filters<span>) {
</span>if<span>(is_string(</span>$filters<span>)){
</span>if<span>(</span>0<span> === strpos(</span>$filters<span>,</span>'/'<span>)){
</span>if<span>(</span>1<span> !== preg_match(</span>$filters<span>,(string)</span>$data<span>)){ </span>// 過濾器支援正規驗證<span></span>// 支援正規驗證<span></span>return<span></span>isset<span>(</span>$default<span>) ? </span>$defaultnull;
}
}<span>else</span>{
<span>$filters</span> = explode(<span>','</span>,<span>$filters</span>);
}
}<span>elseif</span>(is_int(<span>$filters</span>)){
<span>$filters</span> = <span>array</span>(<span>$filters</span>);
}
<span>// 進行陣列過濾</span><span>if</span>(is_array(<span>$filters</span>)){
<span>foreach</span>(<span>$filters</span><span>as</span><span>$filter</span>){
<span>if</span>(function_exists(<span>$filter</span>)) {
<span>$data</span> = is_array(<span>$data</span>) ? array_map_recursive(<span>$filter</span>,<span>$data</span>) : <span>$ter</span>$data<span>) : </span>$7> (<span>$data</span>); <span>// 參數過濾</span>
}<span>else</span>{
<span>$data</span> = filter_var(<span>$data</span>,is_int(<span>$filter</span>) ? <span>$filter</span> : filter_id(<span>$ >));
</span>if<span>(</span>false<span> === </span>$data<span>) {
</span>return<span></span>isset<span>(</span>$default<span>) ? </span>$default<span> : </span>null<span>;
}
}
}
}
}
</span>// 對輸出資料型別指定 預設 字串<span></span>if<span>(!</span>empty<span>(</span>$type<span>)){
</span>switch<span>(strtolower(</span>$type<span>)){
</span>case<span></span>'a'<span>: </span>// 陣列<span></span>$data<span> = (</span>array<span>)</span>$data<span>;
</span>break<span>;
</span>case<span></span>'d'<span>: </span>// 數字<span></span>$data<span> = (int)</span>$data<span>;
</span>break<span>;
</span>case<span></span>'f'<span>: </span>// 浮點<span></span>$data<span> = (float)</span>$data<span>;
</span>break<span>;
</span>case<span></span>'b'<span>: </span>// 布林<span></span>$data<span> = (boolean)</span>$data<span>;
</span>break<span>;
</span>case<span></span>'s'<span>: </span>// 字串<span></span>default<span>:
</span>$data<span> = (string)</span>$data<span>;
}
}
</span>//4.3 取得 預設的 數值了<span>
}</span>else<span>{ </span>// 變數預設值<span></span>$data<span> = </span>isset<span>(</span>$default<span>)?</span>)?<span> $default</span>:<span>null</span>;
}
<span>// 最後在回傳資料之前,在進行處理了,就是 如果是數組,就 執行 預設的過濾函數</span>
is_array(<span>$data</span>) && array_walk_recursive(<span>$data</span>,<span>'think_filter'</span>);
<span>return</span><span>$data</span>;
}
<span>// 總結,其實經過上述函數的分析大致可以這樣學習的地方:</span><span>// 第一:按步驟進行分支代碼書寫類似於第一步: 1.1 1.2 第二步: 2.1 2.2 這樣</span><span>// 第二:依然貫穿了其傳統,透過參數調整其輸出的特色就是各種參數的樣式進行不同的兼容</span><span>// 第三:就是各種濾波函數的方便搭配。真心不錯! </span><span>// 我看好你哦,哈哈! </span><span>// 無 J函數</span><span>// 無 K函數</span><span>// 遇到 這個 L 函數 一般情況下就是 做的 語言配置。</span><span>/*** 取得與設定語言定義(不區分大小寫)
*<span> @param</span> string|array $name 語言變數
*<span> @param</span> mixed $value 語言值或變數
*<span> @return</span> mixed*/</span><span><span>function</span><span>L</span><span>(<span>$name</span>L<span></span>(</span>$name</span>$value<span>=null)</span> {<span></span>static<span></span>$_lang<span> = </span>array<span>();</span>/<span>// 老步調,定義倉庫</span><span>// 空參數回傳所有定義</span><span>// 三種方式</span><span>// 第一種方式:為空</span><span>if</span> (<span>empty</span>(<span>$name</span>)) <span>// 老步調: 無輸入回傳全部</span><span>return</span><span>$🎜></span>return<span></span>$🎜>$ >;
<span>// 判斷語言取得(或設定)</span><span>// 若不存在,直接回傳全大寫$name</span><span>// 如果字串</span><span>// 第二種方式:字串接著在細分空數組預設記住這裡的return 其實是神器</span><span>if</span> (is_string(<span>$name</span>)) { <span>//如果是字串</span><span>$name</span> = strtoupper(<span>$name</span>); <span>// 第一步:統統轉換變成大寫</span><span>if</span> (is_null(<span>$value</span>)){ <span>// 判讀是設定還是讀取</span><span>return</span><span>isset</span>(<span>$_$_o<lang>[</lang></span>$name<span>]) ? </span>$_lang<span>[</span>$name<span>] : </span>$name<span>; </span>// 有定義返回定義,沒有定義,直接回傳<span>
}</span>elseif<span>(is_array(</span>$value<span>)){ </span>// 如果是陣列<span></span>// 支援變數<span></span>$$place<span>// 支援變數</span><span>$$$place</span> = array_keys(<span>$value</span>); <span>//傳回包含陣列中所有鍵名的新陣列:</span><span>foreach</span>(<span>$replace</span> <span>as</span> &<span>$v</span>){ <span>// 好複雜,這一節沒看懂,嘿嘿能看懂的在樓下回覆哈!感謝</span><span>$v</span> = <span>'{$'</span>.<span>$v</span>.<span>'}'</span>;
}
<span>return</span> str_replace(<span>$replace</span>,<span>$value</span>,<span>isset</span>(<span>$_lang</span>[<span>[</span>]) ? <span>$_lang</span>[<span>$name</span>] : <span>$name</span>);
}
<span>$_lang</span>[<span>$name</span>] = <span>$value</span>; <span>// 語言定義否則就定義</span><span>return</span><span>null</span>;
}
<span>// 批次定義</span><span>// 第三種方式:陣列</span><span>if</span> (is_array(<span>$name</span>)) <span>// 批次定義array_change_key_case() 函數將陣列的所有的鍵都轉換為大寫字母或小寫字母。預設大寫</span><span>$_lang</span> = array_merge(<span>$_lang</span>, array_change_key_case(<span>$name<span>, CASE_UPPER));
</span>return<span></span>null<span>;
}
</span>// 特別常用的一個函數不過我稍後會推薦D函數但是任何函數,都有自己的特點<span></span>/*** 實例化一個沒有模型檔案的Model
*</span> @param<span> string $name Model名稱 支援指定基礎模型 例如 MongoModel:User
*</span> @param<span> string $tablePrefix 表前綴
*<span> @param</span> mixed $connection 資料庫連接訊息
*<span> @return</span> ThinkModel*/<span><span>// </span><span></span>function<span></span>M<span></span>(<span>$name</span>=<span>''</span>, </span>$tablePrefix =</span>''<span>,</span>$connection<span>=</span>''<span>)</span> {<span></span>static<span></span>$mo_del = <span>array</span>();<span>// 一成不變的倉庫</span><span>if</span>(strpos(<span>$name</span>,<span>':'</span> )) { <span>// 可以組合其程式碼然後拼接成為類,跟類名</span><span>list</span>(<span>$class</span>,<span>$name</span>) = explode(<span>':'</span>,<span>$name</span>);
}<span>else</span>{
<span>$class</span> = <span>'Think\Model'</span>; <span>// 否則的話,執行 預設的 Model 類別 實例化</span>
}
<span>// 這個相當於做了一個唯一值</span><span>$guid</span> = (is_array(<span>$connection</span>)?implode(<span>''</span>,<span>$connection</span>):<span>$connection</span>).<span>$tablePrefix</span> . <span>$name</span> . <span>'_'</span> . <span> $class</span>;
<span>if</span> (!<span>isset</span>(<span>$_model</span>[<span>$guid</span>])) <span>// 單列單列</span><span> $_model</span>[<span>$guid</span>] = <span>new</span><span>$class</span>(<span>$name</span>,<span>$tablePrefix</span>$name<span>,</span>$tablePrefix<span>,</span>,<span>$tablePrefix,,$tablePrefix,,$tablePrefix,,$tablePrefix,$connection); // 實例化保存後的單列return$_model[$guid]; // 這個不多說了,就這樣了。</span>
}
<span>/*** 設定和取得統計數據
* 使用方法:
* <code>
* N('db',1); // 記錄資料庫操作次數
* N('read',1); // 記錄讀取次數
* echo N('db'); // 取得目前頁面資料庫的所有操作次數
* echo N('read'); // 取得目前頁面讀取次數
* </code>
*<span> @param</span> string $key 標識位置
*<span> @param</span> integer $step 步進值
*<span> @param</span> boolean $save 是否儲存結果
*<span> @return</span> mixed*/</span><span><span>function</span><span>N</span><span>(<span>$key</span>, <span>$step</span>=<span>0</span>,<span>$save</span>=false)</span> {</span><span>static</span><span>$_num</span>(); <span>// 倉庫</span><span>if</span> (!<span>isset</span>(<span>$_num</span>[<span>$key</span>]) ) { <span>// 如果說沒有設定當前值</span><span>$_num</span>[<span>$key</span>] = (<span>false</span> !== <span>$ save</span>)? S(<span>'N_'</span>.<span>$key</span>) : <span>0</span>; <span>// 如果設定了儲存就在S 函數中,讀取處理,否則就0了</span>
}
<span>if</span> (<span>empty</span>(<span>$step</span>)){ <span>// 如果沒有步進設定</span><span>return</span><span></span> $_num<span>[</span>$key<span>];
}</span>else<span>{ </span>// 否則按照步進的方式前進<span></span>$_num<span>[</span>$key<span>] = $_num</span>$key<span>] = $_num</span>[<span>$key</span>] + (int)<span>$step</span>;
}
<span>if</span>(<span>false</span> !== <span>$save</span>){ <span>// 儲存結果 其實 這是透過 快取 讀取 函數的。 </span>
S(<span>'N_'</span>.<span>$key</span>,<span>$_num</span>[<span>$key</span>],<span>$save</span>);
}
<span>return</span><span>null</span>;
}
<span>// 無O函數</span><span>// 無P函數</span><span>// 無Q函數</span><span>// 今日到此結束,講述了L M N 函數語言包M實例化可以指定實例化類別跟連接的資料庫N 記錄步驟</span><span>// 不好意思,糊塗了,昨天沒有更新,今天也才更新</span><span>/*** 遠端呼叫控制器的操作方法 URL 參數格式 [資源://][模組/]控制器/操作
*<span> @param</span> string $url 呼叫位址
*<span> @param</span> string|array $vars 呼叫參數 支援字串和陣列
*<span> @param</span> string $layer 要呼叫的控制層名稱
*<span> @return</span> mixed*/ </span><span>// 把查詢字串解析到變數中</span><span>// parse_str() 函數把查詢字串解析到變數中。 </span><span>// 註解:php.ini 檔案中的 magic_quotes_gpc 設定影響該函數的輸出。如果已啟用,那麼在 parse_str() 解析之前,變數會被 addslashes() 轉換。 </span><span>/**parse_str("姓名=比爾&年齡=60");
echo $name."<br>";
回顯$年齡;
*
parse_str("姓名=比爾&年齡=60",$myArray);
print_r($myArray);*/</span><span>// print_r(pathinfo("/testweb/test.txt"));</span><span>// pathinfo() 回傳一個關聯數組包含有path 的資訊。 </span><span>/**大批
(
[目錄名] => /測試網
[基本名稱] =>測試.txt
[擴展名] => TXT
)
* [目錄名]
[基本名稱]
[擴大]*/</span><span>/**A級 A級
{
函數bc($b, $c) {
$bc = $b + $c;
迴聲 $bc;
}
}
call_user_func_array(array('ClassA','bc'), array("111", "222"));
//顯示333*/</span><span><span>function</span><span>R</span><span>function<span></span>R<span></span>function<span></span>R<span></span>function<span></span> >(</span>$url</span>,<span>$vars</span>=array<span>()</span>,<span>$layer</span>=<span>''</span>)<span>)</span> {<span></span>$info<span> = pathinfo(</span>$url<span>); </span>// 解析路徑<span></span>$action<span> = </span>$info <span>[</span>'basename'<span>]; </span>// 取得檔案名稱<span></span>$module<span> = </span>$info<span>[</span>'dirname' <span>]; </span>// 取得檔案路徑<span></span>$class<span> = A(</span>$module<span>,</span>$layer<span>); </span>/ / 取得實際class 實例化多了一層級的關係如Widget<span></span>if<span>(</span>$class<span>){ </span>// 如果存在類別<span></span>if <span>(is_string(</span>$vars<span>)) { </span>// 若有變數傳入<span>
parse_str(</span>$vars<span>,</span>$vars<span>); </span>// 解析傳入參數到陣列<span>
}
</span>return<span> call_user_func_array(</span>array<span>(&</span>$class<span>,</span>$action<span>.C(</span>'ACTION__mIX'<su>$vars); <span>//</span>
}<span>else{
returnfalse;
}
}
// 總結,其實 這個R 就是 一個call_user_func_array 的升級版本,透過 url 直接進行處理。 // 還有一個半小時 今天結束。繼續今天的學習// 這個函數 其實也是個很牛叉的函數 ,好像可以 用F函數,讓我們比較一下吧,看看 這兩個鬼有什麼差別。</span><span>/*** 快取管理
*<span> @param</span> mixed $name 快取名稱,如果為陣列表示進行快取設置
*<span> @param</span> mixed $value 快取值
*<span> @param</span> mixed $options 快取參數
*<span> @return</span> mixed*/</span><span><span>function</span><span>S</span><span>(<span>$name</span>,<span></span>(<span>$name</span>,<span> $value</span>=</span>''</span>,<span>$options</span>=null)<span> {</span><span>static</span><span>$cache</span> = <span> = </span> 🎜>''<span>; </span>// 倉庫倉庫倉庫又是倉庫<span></span>//第一步:初始化<span></span>if<span>(is_array(</span>$options <span>)){ </span>// 如果快取參數其實有點亂type 可以放到任何一個位置<span></span>// 快取操作的同時初始化其實就是個初始化的過程<span></span> $type<span> = </span>isset<span>(</span>$options<span>[</span>'type'<span>])?</span>$options<span>[</span>])?<span>$options</span>[<span>'type' </span>]:<span>''</span>;
<span>$cache</span> = ThinkCache::getInstance(<span>$type</span>,<span>$options</span>);
}<span>elseif</span>(is_array(<span>$name</span>)) { <span>// 快取初始化// 如果快取參數其實有點亂type 可以放到任何一個位置</span><span> $type</span> = <span>isset</span>(<span>$name</span>[<span>'type'</span>])?<span>$name</span>[<span>'type' </span>]:<span>''</span>;
<span>$cache</span> = ThinkCache::getInstance(<span>$type</span>,<span>$name</span>);
<span>return</span><span>$cache</span>;
}<span>elseif</span>(<span>empty</span>(<span>$cache</span>)) { <span>// 自動初始化還沒有的話</span><span>$cache</span> = =🎜> = ThinkCache::getInstance(); <span>//初始化</span>
}
<span>// 根據對資料設計</span><span>if</span>(<span>''</span>=== <span>$value</span>){ <span>// 取得快取</span><span>return</span><span>$cache</span>->get(<span>$name</span>); <span>// 取得資料</span>
}<span>elseif</span>(is_null(<span>$value</span>)) { <span>// 刪除快取</span><span>return</span><span>$cache</span>-> (<span>$name</span>); <span>// 刪除資料</span>
}<span>else</span> { <span>// 快取資料</span><span>if</span>(is_array(<span>$options</span>)) {
<span>$expire</span> = <span>isset</span>(<span>$options</span>[<span>'expire'</span>])?<span>$options</span>[<span>])?</span>$options<span>[</span>[<span>$options</span>[<span>[</span>$options<span>[</span> 'expire'<span>]:</span>NULL<span>;
}</span>else<span>{
</span>$expire<span> = is_numeric(</span>$options<span>)?</span>$options<span>:</span>NULL<span>;
}
</span>return<span><span>$cache</span>->set(<span>$name</span>, <span>$value</span>, </span>$expire<span>) <span>) </span> // 儲存資料<span>
}
}
</span>// 總結,其實這個就是做什麼的呢,關鍵點是那個class 類函數<span><span>// 其實那個函數也沒什麼了</span><span>// 今天學一個新的東西,就是寫模版引擎</span><span>/*** 取得模版檔案 格式 資源://模組@主題/控制器/操作
*</span> @param<span> string $template 模版資源位址
*</span> @param</span> string $layer 視圖層(目錄)名稱
*</span> @return<span> string*/</span><span></span>function<span></span>T<span></span>(<span>$🎜>T</span><span>(</span>$ =<span>''</span>,<span>$layer</span>=<span>''</span>)<span>{</span><span>// 解析模版資源位址第一步:</span><span>if</span>(<span>false</span> === strpos(<span>$template</span>,<span>'://'</span>)){
<span>$template</span> = <span>'http://'</span>.str_replace(<span>':'</span>, <span>'/'</span>,<span>$template</span>);
}
<span>$info</span> = parse_url(<span>$template</span>); <span>// 第二步:解析到自己的陣列裡面</span><span>$file</span> = <span>$info</span>[<span>'host'</span>].(<span>isset</span>(<span>$info</span>[<span>'path'</span>])?<span>[</span>'path'<span>])?</span>[<span>'path'</span>])?<span>[</span>'path'<span>])?</span>[<span>'path'</span>])?<span>$info</span>[<span>'path'</span>]:<span>''</span>);
<span>$module</span> = <span>isset</span>(<span>$info</span>[<span>'user'</span>])?<span>$info</span>[<span>[</span> 'user'<span>].</span>'/'<span>:MODULE_NAME.</span>'/'<span>; </span>// 擴充使用者名稱<span></span>$extend<span> = = </span>$info<span>[</span>'scheme'<span>]; </span>// 擴充檔案副檔名<span></span>$layer<span> = </span>$layer<span>$layer</span> = <span>$layer</span> <span>$layer</span>:C(<span>'DEFAULT_V_LAYER'</span>); <span>// 層次</span><span>// 取得目前主題的模版路徑</span><span>$auau </span> = C('AUTOLOAD_NAMESPACE');
if($auto && isset($auto[$extend])){ [$extend])){ / / 擴充資源$baseUrl = $auto[$extend].$module.$layer.'/';
}elseif(C('VIEW_PATH')){
// 改變模組視圖目錄$baseUrl = C('VIEW_PATH');
}<span>elseif</span>(defined(<span>'TMPL_PATH'</span>)){
<span>// 指定全域視圖目錄</span><span>$baseUrl</span> = TMPL_PATH.<span>$module</span>;
}<span>else</span>{
<span>$baseUrl</span> = APP_PATH.<span>$module</span>.<span>$layer</span>.<span>'/'</span>;
}
<span>// 取得主題</span><span>$theme</span> = substr_count(<span>$file</span>,<span>'/'</span>)2 ? (<span>'DEFAULT_THEME'</span>) : <span>''</span>;
<span>// 分析範本檔案規則</span><span>$depr</span> = C(<span>'TMPL_FILE_DEPR'</span>);
<span>if</span>(<span>''</span> == <span>$file</span>) {
<span>// 若範本檔案名稱為空白 依照預設規則定位</span><span>$file</span> = CONTROLLER_NAME . <span>$depr</span> . ACTION_NAME;
}<span>elseif</span>(<span>false</span> === strpos(<span>$file</span>, <span>'/'</span>)){
<span>$file</span> = CONTROLLER_NAME . <span>$depr</span> . <span>$file</span>;
}<span>elseif</span>(<span>'/'</span> != <span>$depr</span>){
<span>$file</span> = substr_count(<span>$file</span>,<span>'/'</span>)><span>1</span> ? substr_replace(<span>$file</span>$file<span>$file</span>$file<span>$file</span>$file<span>$file</span>$file<span>$file</span>$file<span>$file</span>$file<span>$file</span>$file<span>$file$depr<span>,strrpos(</span>$file<span>,</span>'/'<span>),</span>1<span>) : str_replace(</span>'/'<span>, </span>$depr<span>, </span>$file<span>);
}
</span>return<span></span>$baseUrl<span>.(</span>$theme<span>?</span>$theme<span>.<span>'/'</span>:<span>''</span>''<span>''</span>''<span>''</span>''<span>''</span>'''''''''''''' ).$file.C('TMPL_TEMPLATE_SUFFIX');
}
// 總結,其實,這貨 就是返回了一個 真實的網址路徑而已啦// 今天是這個新東西,組裝產品/**
* URL組裝 支援不同URL模式
* @param string $url URL表達式,格式:'[模組/控制器/操作#錨點@域名]?參數1=值1&參數2=值2...'
* @param string|array $vars 傳入的參數,支援陣列和字串
* @param string|boolean $suffix 偽靜態後綴,預設為true表示取得設定值
* @param boolean $domain 是否顯示域名
* @return string
* 本函數不是用來驗證給定 URL 的合法性的,只是將其分解為下面列出的部分。不完整的 URL 也被接受,parse_url() 會嘗試盡量正確地將其解析。* Array
(
[scheme] => http
[host] => hostname
[user] => username
[pass] => password
[path] => /path
[query] => arg=value 在問號 ? 之後
[fragment] => anchor 在散列符號 # 之後
)
* $url = 'http://username:password@hostname/path?arg=value#anchor';
*/</span><span><span>function</span><span>U</span><span>(<span>$url</span>=<span>''</span>,<span>$vars</span>=<span>''</span>,<span>$suffix</span>=true,<span>$domain</span>=false)</span> {</span><span>// 解析URL 其實傳入的url 不是正常地址上人的url 他重新做了組合,個人覺得不是很科學</span><span>$info</span> = parse_url(<span>$url</span>); <span>/ / 解析參數這裡的解析方式跟正常的還不太一樣</span><span>// 情況1</span><span>// $url = 'Home/Index/index#zhangsan@www.maizi.net? name=lisi&age=32';</span><span>// var_dump(parse_url($url));</span><span>//array (size=2)</span><span>//'path' = > string 'Home/Index/index' (length=16)</span><span>// 'fragment' => string 'zhangsan@www.maizi.net?name=lisi&age=32' (length=39)</span><span>// 情況2</span><span>// $url = 'Home/Index/index@www.maizi.net?name=lisi&age=32';</span><span>// var_dump(parse_url ($url));</span><span>// array (size=2)</span><span>// 'path' => string 'Home/Index/index@www.maizi.net' (length= 30)</span><span>// 'query' => string 'name=lisi&age=32' (length=16)</span><span>$url</span> = !<span>empty</span>(<span>$info</span>[<span>'path'</span>])?<span>$info</span>[<span>'path'</span>]:ACTION_NAME; <span>// 如果解析到了路徑,就用解析的路徑,否則就用action_name</span><span>if</span>(<span>isset</span>(<span>$info</span>[<span>'fragment'</span>] )) { <span>// 解析錨點就是網頁中跳到網站固定位置的標記</span><span>$anchor</span> = <span>$info</span>[<span>'fragment'</span>]; <span>// 其實這種是全的'[模組/控制器/操作#錨點@域名]?參數1=值1&參數2=值2...'</span><span> if</span>(<span>false</span> !== strpos(<span>$anchor</span>,<span>'?'</span>)) { <span>// 解析參數如果錨點後面還有跟隨的參數</span><span>list</span>(<span>$anchor</span>,<span>$info</span>[<span>'query'</span>]) = explode(<span> '?'</span>,<span>$anchor</span>,<span>2</span>);
}
<span>if</span>(<span>false</span> !== strpos(<span>$anchor</span>,<span>'@'</span>)) { <span>// 解析網域如果錨點後,還有@ 網域</span><span>list</span>(<span>$anchor</span>,<span>$host</span>) = explode(<span>'@'</span>,<span>$anchor</span>, <span>2</span>);
}
}<span>elseif</span>(<span>false</span> !== strpos(<span>$url</span>,<span>'@'</span>)) { <span>// 解析網域把網域名稱把使用者名稱密碼跟網域分割</span><span>list</span>(<span>$url</span>,<span>$host</span>) = explode(<span>'@'</span>,<span>$info</span>[<span>'path'</span>], <span>2</span>);
<span>// '[模組/控制器/操作@網域名稱]?參數1=值1&參數2=值2...' 這種是不全的</span>
}
<span>// 解析子網域host 就是網域名稱了</span><span>if</span>(<span>isset</span>(<span>$host</span>)) { <span>// 不是二級網域嗎其實一般情況下是沒有這個東西的</span><span>// 其實這個用法很奇怪一般情況下,就是$domain = $host 這裡可以能是跟隨參數的</span><span>$domain</span> = <span>$host</span>.(strpos(<span>$host</span>,<span>'.'</span>)?<span>''</span>:strstr(<span>$ _SERVER</span>[<span>'HTTP_HOST'</span>],<span>'.'</span>));
}<span>elseif</span>(<span>$domain</span>===<span>true</span>){ <span>//如果顯示網域如果有加,這裡就不是true boolen類型才可以哈</span><span>$domain</span> = <span>$_SERVER</span>[<span>'HTTP_HOST'</span>]; <span>// 顯示主機名域名</span><span>if</span> (C(<span>'APP_SUB_DOMAIN_DEPLOY'</span>) ) { <span>// 開啟子網域部署預設為沒有開啟</span><span>$domain</span> = <span>$domain</span>$domain<span> = </span>$domain<span>== </span>'localhost'<span>?</span>'localhost'<span>:</span>'www'<span>.strstr(</span>$_SERVER<span>[</span>'HTTP_HOST'<span> ],</span>'.'<span>); </span>// 默認給他緩存了www.你的網域啦本地的就不管了<span></span>// '子網域'=>array( '模組[/控制器]'); 找到子網域的符合規則實際上,可能用不到哈<span></span>foreach<span> (C(</span>'APP_SUB_DOMAIN_RULES'<span>) </span> as<span></span>$key<span> => </span>$rule<span>) {</span>// 處理子網域規則<span></span>$rule<span> = is_array(</span><span>$rule</span> = is_array(<span> $rule</span>)?<span>$rule</span>[<span>0</span>]:<span>$rule</span>;
<span>if</span>(<span>false</span> === strpos(<span>$key</span>,<span>'*'</span>) && <span>0</span>===== strpos(<span>$url</span>,<span>$rule</span>)) {
<span>$domain</span> = <span>$key</span>.strstr(<span>$domain</span>,<span>'.'</span>); <span>// 產生對應網域名稱</span><span>$url</span> = substr_replace(<span>$url</span>,<span>''</span>,<span>0</span>,strlen(<span>$rule</span>0<span>,strlen(</span>$rule<span> );
</span>break<span>;
}
}
}
}
</span>// 解析參數解析參數,這是後面傳入的參數<span></span>if<span>(is_string(</span>$vars<span>)) { </span>// aaa=1&bbb= 2 轉換成陣列<span>
parse_str(</span>$vars<span>,</span>$vars<span>);
}</span>elseif<span>(!is_array(</span>$vars<span>)){
</span>$vars<span> = </span>array<span>();
}
</span>// 合併參數<span></span>if<span>(</span>isset<span>(</span>$info<span>[</span>'query'<span>])) { </span>// 解析位址裡面參數合併到vars<span>
parse_str(</span>$info<span>[</span>'query'<span>],</span>$params<span>);
</span>$vars<span> = array_merge(</span>$params<span>,</span>$vars<span>);
}
</span>// 這裡總結一下,其實就量大步驟,第一步拆分<span></span>// 第二步:組裝<span></span>// URL組裝<span></span>$ depr<span> = C(</span>'URL_PATHINFO_DEPR'<span>); </span>//'/', // PATHINFO模式下,各參數之間的分割符號<span></span>$urlCase<span> = C(</span>'URL_CASE_INSENSITIVE'<span>); </span>//// 預設false 表示URL區分大小寫true則表示不區分大小寫<span></span>// 如果有url 位址<span></span>if<span>(</span>$url<span>) {
</span>if<span>(</span>0<span>=== strpos(</span>$url<span>,</span>'/'<span>)) {</span>// 定義路由如果是跟目錄<span></span>$route<span> = </span>true<span>;
</span>$url<span> = substr(</span>$url<span>,</span>1<span>); </span>// 去掉第一個斜線<span></span>if<span> (</span>'/'<span> != </span>$depr<span>) { </span>// 換成系統的指定的間隔符號<span></span>$url<span> = str_replace(</span>'/'<span>,</span>$depr<span>,</span>$url<span>);
}
}</span>else<span>{ </span>// 也就是, 不是根目錄的情況下<span></span>if<span>(</span>'/'<span> != </span>$depr <span>) { </span>// 安全替換$url = str_replace('/',$depr$$url );
}<span>// 解析模組、控制器與操作</span><span>$url</span> = trim(<span>$url</span>,<span>$depr</span>); <span>//刪除兩端的間隔符號</span><span>$path</span> = explode(<span>$depr</span>,<span>$url</span>); <span>// 解析路徑</span>$url<span>); </span>// 解析路徑<span></span><span>$var</span> = <span>array</span>();
<span>$varModule</span> = C(<span>'VAR_MODULE'</span>); <span>// 'VAR_MODULE' => 'm', // 預設模組取得變數</span><span>$varController </span> = C(<span>'VAR_CONTROLLER'</span>); <span>//'VAR_CONTROLLER' => 'c', // 預設控制器取得變數</span><span>$varAction</span> = C(<span>'VAR_ACTION'</span>); <span>// 'VAR_ACTION' => 'a', // 預設操作取得變數</span><span>$var</span>[<span>$varAction </span>] = !<span>empty</span>(<span>$path</span>)?array_pop(<span>$path</span>):ACTION_NAME; <span>// 以這種方式解析出action </span><span>$var</span>[<span>$varController</span>] = !<span>empty</span>(<span>$path</span>)?array_path(path):CONTROLLER_NAME;<span>// 同上解析出</span><span>if</span>(<span>$maps</span> = C(<span>'URL_ACTION_MAP'</span>) { </span>if<span>(</span>isset<span>(</span>$maps<span>[strtolower(</span>$var<span>[</span>$varController<span>])])) {
</span>$maps<span> = </span>$maps<span>[strtolower(</span>$var<span>[</span>$varController<span>])];
</span>if<span>(</span>$action<span> = array_search(strtolower(</span>$var<span>[</span>$varAction<span>]),</span>$maps<span>$varAction</span>]),<span>$maps</span>) ){
<span>$var</span>[<span>$varAction</span>] = <span>$action</span>;
}
}
}
<span>if</span>(<span>$maps</span> = C(<span>'URL_CONTROLLER_MAP'</span>)) { <span>// 同上</span><span>// $a=array( "a"=>"red","b"=>"green","c"=>"blue");</span><span>// echo array_search("red",$a);</span> <span>if</span>(<span>$controller</span> = array_search(strtolower(<span>$var</span>[<span>$varController</span>]),<span>$maps</span>$map) ){
<span>$var</span>[<span>$varController</span>] = <span>$controller</span>;
}
}
<span>if</span>(<span>$urlCase</span>) { <span>// 是否區分大小寫預設是true 代表不區分</span><span>$var</span>[<span>$varControllerler </span>] = parse_name(<span>$var</span>[<span>$varController</span>]); <span>// 都轉換成統一的格式</span>
}
<span>$module</span> = <span>''</span>; <span>// 初始化為空</span><span>if</span>(!<span>empty</span>$<span>$ path</span>)) { <span>// 若路徑不為空</span><span>$var</span>[<span>$varModule</span>] = implode(<span>$depr</span>, <span>$path</span>);
}<span>else</span>{
<span>if</span>(C(<span>'MULTI_MODULE'</span>)) { <span>// 如果開啟多模組// 是否允許多模組如果為false 則必須設定DEFAULT_MODULE</span><span></span> if<span>(MODULE_NAME != C(</span>'DEFAULT_MODULE'<span>) || !C(</span>'MODULE_ALLOW_LIST'<span>)){
</span>$var<span>[</span>$varModule<span>]= MODULE_NAME;
}
}
}
</span>if<span>(</span>$maps<span> = C(</span>'URL_MODULE_MAP'<span>)) { </span>// 如果這裡也設定路由同上<span></span>if<span>(</span>$_module<span> = array_search(strtolower(</span>$var<span>[</span>$varModule<span>]),</span>$maps<span>)){🎜>]),</span>$maps<span>)){
</span>$var<span>[</span>$varModule<span>] = </span>$_module<span>;
}
}
</span>if<span>(</span>isset<span>(</span>$var<span>[</span>$varModule<span>])){ </span>// 同上<span></span>$ module<span> = </span>$var<span>[</span>$varModule<span>];
</span>unset<span>(</span>$var<span>[</span>$varModule<span>]);
}
}
}
</span>// 其實這裡才開始真正的組合分兩種方式<span></span>// 網域<span></span>//<span></span>if<span>(C(</span>' URL_MODEL'<span>) == </span>0<span>) { </span>// 普通模式URL轉換<span></span>$url<span> = __APP__.</span>'?'<span>. C(</span>'VAR_MODULE'<span>).</span>"={$module}&"<span>.http_build_query(array_reverse(</span>$var<span>));
</span>if<span>(</span>$urlCase<span>){ </span>// 全部轉換小寫<span></span>$url<span> = strtolower(</span>$url<span>);
}
</span>if<span>(!</span>empty<span>(</span>$vars<span>)) { </span>// 若參數不為空加入參數<span></span>$vars<span> = http_build_query(</span>$vars);
$url .= '&'.$vars;
}
}<span>else</span>{ <span>// PATHINFO模式或相容URL模式</span><span>if</span>(<span>isset</span>(<span>$route) {</span>// 如果開啟了路由<span></span>$url<span> = __APP__.</span>'/'<span>.rtrim(</span>$url<span>,</span>$depr<span>);
}</span>else<span>{
</span>$module<span> = (defined(</span>'BIND_MODULE'<span>) && BIND_MODULE==</span>$module<span> )? </span>''<span> :$module </span>;
<span>$url</span> = __APP__.<span>'/'</span>.(<span>$module</span>?<span>$module</span>.MODULE_PATHINFO_DEPR:<span>''</span> ).implode(<span>$depr</span>,array_reverse(<span>$var</span>));
}
<span>if</span>(<span>$urlCase</span>){ <span>// 轉換</span><span>$url</span> = strtolower(<span>$url</span>);
}
<span>if</span>(!<span>empty</span>(<span>$vars</span>)) { <span>// 增加參數另外的一種解析方式而已</span><span>foreach</span> (<span>$vars</span><span>as</span><span>$var</span> => <span>$val</span>){
<span>if</span>(<span>''</span> !== trim(<span>$val</span>)) <span>$url</span> .= <span>$depr</span> . <span>$var</span> . <span>$depr</span> . urlencode(<span>$val</span>);
}
}
<span>if</span>(<span>$suffix</span>) {<span>// 如果定義了檔案字尾</span><span>$suffix</span> = <span>$suffix</span>$suffix<span> = </span>$suffix<span>== =</span>true<span>?C(</span>'URL_HTML_SUFFIX'<span>):</span>$suffix<span>;
</span>if<span>(</span>$pos<span> = strpos(</span>$suffix<span>, </span>'|'<span>)){
</span>$suffix<span> = substr(</span>$suffix<span>, </span>0<span>, </span>$pos<span>);
}
</span>if<span>(</span>$suffix<span> && </span>'/'<span> != substr(</span>$url<span>,-</span>1<span>)){
</span>$url<span> .= </span>'.'<span>.ltrim(</span>$suffix<span>,</span>'.'<span>);
}
}
}
</span>if<span>(</span>isset<span>(</span>$anchor<span>)){ </span>// 若有錨點組合上<span></span>$url<span> . = </span>'#'<span>.</span>$anchor<span>;
}
</span>if<span>(</span>$domain<span>) { </span>// 組合上網域名稱<span></span>$url<span> = (is_ssl()?</span>'https:/ /'<span>:</span>'http://'<span>).</span>$domain<span>.</span>$url<span>;
}
</span>return<span></span>$url<span>;
}
</span>// 無V函數<span></span>// 總結:<span></span>// 指導parse_url 是對url 位址解析的函數<span></span>// 其實我覺得這個函數他複雜了,就是對不同輸入的url 方式解析成為自己的方式<span></span>// 常用的是U('Home/Index/index',array('name'=>'lijingshan','age' =>'12'));<span></span>// 預設的情況下不會用網域跟錨點的,不過這兩個還是不錯的,哈哈,就是解析起來,不復雜,但是,組合的時候,那個路由規則有點費勁。 <span></span>// 好的,今天我們繼續<span></span>// 這個函數,其實就是個封裝<span><span>/*** 渲染輸出Widget
*</span> @param<span> string $name Widget名稱
*</span> @param<span> array $data 傳入的參數
*</span> @return</span> void*/<span><span></span>function<span></span>W<span><span>(</span>$name<span>, </span>$data<span>=array</span>()</span>)</span>)<span> 🎜></span>return<span> R(</span>$name<span>,</span>$data<span>,</span>'Widget'<span>);
}
</span>// 無X函數<span></span>// 無Y函數<span></span>// 無Z函數<span></span>// 26 字母函數寫完了,<span></span> // A 函數中呼叫的函數<span><span>/**
* 解析資源位址並匯入類別庫文件
* 例如 module/controller addon://module/behavior
*</span></span></su></code>
登入後複製