tp剩余未验证内容-7
bash腳本中 的 set -e表示 exit immediately if a simple command returns a non-zero value.主要是為了防止錯誤被忽略.會被立即退出, 但是最好在開發結束后, 刪除這個指令, 以免留下隱患.
有四種命令提示符, 有PS1, 自然就有 PS2 PS3 PS4, 分別表示 PS2即 在后續的命令下一行的提示符(continu'ation interactive prompt), PS3是在select選項時 的提示符, PS4是調試時的提示符.
shell中要進行算術運算, 有5種方法: (因為默認的算術運算符號+-*/ 都不會被直接當做運算符, 而只是當做普通字符來看待, 所以需要特殊處理)
- 使用算術擴展: $(( ... )); $[...]
- 使用外部命令expr expr 1 + 2 注意有空格(特殊符號要用* 轉義)
- 使用內部命令: let 1+2 或 declare -i c=1+2
外部命令,就是外部存在的 可以執行的文件, 可以用 which命令看得到的, 根shell無關的; 所謂內部命令,就是 shell本身提供的命令(函數), 用which是查看不到沒有的.
shell的調試?
- 直接用 sh -x ./foo.sh 命令, 其中 -x就是調試的意思 還有其他一些選項 : sh -n只是檢查文件是否有語法錯誤; sh -c "..." 表示文件從字符串中讀取.
- 或者直接將調試選項寫在sh文件中的 #!bin/bash -xv???
- 或者在文件中, 在要開始調試的 位置 寫上 set -x 但是要注意, 只有set -x之后的命令才會調試, 這個之前的命令不會被調試.
- 所謂調試就是 會將每一次/ 每一步 step by step 執行的語句 先顯示出來, 并且會將執行語句中的變量用當前值 替換; 然后輸出命令執行的結果. 而且執行語句前加上+號
$_SERVER['HTTP_REFERER']為什么為空?
- referer的正確拼寫是 referrer, 所以前者其實是一種歷史的錯誤遺留
- http_referer是header請求頭的一部分, 通常會帶在向web服務器發生的信息中, 告訴服務器我是從 哪個頁面鏈接而來的. 可以給服務器一些額外的信息, 便于其他一些處理.
http_refer完全依賴于瀏覽器自身, 有的瀏覽器是沒有設置這個變量的. 你就得不到它.
但是, 在很多情況下http_referer會無效, null. 比如你 直接訪問一個頁面的時候, 或從收藏夾中訪問頁面的時候,
所以一般來說,只有通過 <a> 超鏈接 </a> 或者: location.href=...跳轉, 以及 POST 或 GET 表單 提交訪問的頁面, $_SERVER['HTTP_REFERER']才有效。由于 $_SERVER['HTTP_REFERER'] 對 POST 表單訪問也是有效的,因此在表單數據處理頁面 一定程度上 可以通過校驗 $_SERVER['HTTP_REFERER'] 來防止表單數據的惡意提交。但該方法并不能保證表單數據的絕對正確,即對表單數據的真實性檢測并不能完全依賴于 $_SERVER['HTTP_REFERER'] 。
========================
所以, 在tp中, 操作成功或失敗的提示 跳轉是用 success和error. $this->success/errror('跳轉提示信息', 跳轉的地址_默認是http_referer, 跳轉等待時間)
使用js 使html中的數字遞減?
- 一個頁面中, 包含多個head, body, html等標簽雖然不規范, 但是仍然可以解析顯示的.
- js獲取一個元素的屬性?
- setInterval和clearInterval?
- 快速調用一個函數的方法.
關于tp?
tp的文件上傳 在"專題"中.
tp使用 "類" 的思想: 先new一個 類對象, 然后讓 類對象與實際要操作(上傳)的文件相關聯, 然后通過操作這個 已經關聯了的類對象實現對該文件的各種操作.
- 實際上,這也是 "類"的一個基本思想. 一個類對象(泛泛的), 必須跟具體的實物(生活中的個體) 相關聯. (類的對象, 跟具體的實物/事物相關聯的 過程, 正是所謂的 類對象的實例化/初始化). 實例化后, 這個類對象 就代表該具體的 人/事物了, 對該對象的操作, 就是對該人/事物的操作!
- 如果類對象, 沒有跟具體的實物相關聯, 那么它實際上是沒有意義的, 也是沒有用處的. 比如一張 銀行卡"對象", 在沒有跟某個具體的人(儲戶)相關聯的時候, 即沒有"開卡"的時候, 這張卡其實是沒有用的,你隨便怎樣處置都是可以的. 但是如果你有一張十萬元的卡, 跟你的儲存信息/存儲資金 相關聯了, 如果你丟失了, 又是怎樣的一種情景呢?
- 而上面所說的, 類(對象)沒有跟具體的 事物相關聯, 只是規定了這個類 可以具有的功能和特征, 這種類, 其實也是有用的, 它就是只是作為一種協議, 一種規定, 就是一種 "接口", "接口"都是抽象的, 即泛泛而論的東西, 不能跟具體的某個 實物相關聯, 因此, 它是接口, 不能被 "實例化""初始化"
tp中的array數組, 是應用得最廣泛的. 可以說凡是能用 "字符串"的地方, 幾乎都可以用數組來 表示, 用數組來操作, 而且都推薦用數組, (因為數組更安全??)
tp的orm就是, 對數據庫的操作, 不再用原始的/原生的 mysql/mysqli函數(面向過程)來處理, 而是用 模型(跟數據庫的表相對應)的類/對象來操作, 用對象的方法比如find,select add save等進行增刪改查的操作.
其中, add和save方法, 需要先創建 插入和更新的 數據對象$data(實際上就是要插入/更新到表中的 記錄)
這種創建數據對象的方法, 有兩種, 一是 create()方法, 一是data()方法. 兩個方法的相同點是: 都可以/都支持多種數據來源, 包括從 數組, 其他數據對象甚至 普通對象來創建; 不同點是: create的功能更強大, 不但支持創建的數據對象的自動驗證和自動完成($_validate和$_auto), 而且還可以 自動地從 $_POST數組創建數據對象.
- 創建的數據對象是保持在 內存中, 并沒有馬上寫入到數據庫中, 要直到使用 add()方法和save()方法才會寫入數據庫.
- 所以, create的數據對象, 你是可以直接顯示dump出它的內容的; 而且還可以繼續修改.
在進行數據庫相關的操作時, 一定要首先設置 數據庫配置.
- 因為你在創建 模型對象 $User = M('user') 的時候, 就需要數據庫配置, 如果沒有配置/沒有正確配置, 就會報錯.
- 首先去加載 Frame\Library\Think\Db.class.php, 執行第一個靜態方法去獲取數據庫類的實例static public function getInstance($config=array()) 參數就是$config數據庫連接配置!
- tp錯誤的統一輸出形式用 : E(L('_NO_DB_DRIVER_') . ':'. $class), E函數的原型是 E($msg, $code); 所以所有的錯誤提示內容, 都要放在整個 E() 函數的括號內 錯誤函數是 拋出了一個 異常 throw new Exception($msg, $code); 所以: E函數后的所有內容 都將 停止執行, 直接從 E()函數處退出了, 而且是調用 統一的 異常輸出模板.
- 注意配置的下標名稱是: 由于DB本身就有 '數據庫' 的意思, 數據庫的名稱 配置項 是 'DB_NAME' 不是DB_DATABASE, 數據庫密碼是DB_PWD, 不是 DB_PASSWD.
- 數據庫類型要明確寫成, 因為在 convention.php中, 沒有默認的數據庫類型配置
tp表單在提交的時候, 有兩種方式過濾字段,
一是使用 field函數,( 要注意, field方法沒有復數, 所以其參數也是 一個 字符串. 另外field是指定 接收的/生效的字段, 不是 將被過濾被丟棄的字段 ) 然后用create()創建,
二是配置 insertFields, updateFields兩個的值,
**即使設置了表單 的字段映射, 但是在 后面的所有 連貫操作的 field方法中, 表示 參數的 字段都 應該是實際的數據表字段, 而不是 字段映射, 不是表單中的 字段域, 否則 當定義了字段映射時, 又使用 filed('表單字段'), 那么就會出現 create的數據對象 為空 empty的 錯誤!
要注意, 如果要設置 $insertFields 和 $updateFields的值, 以及要實現自動驗證和自動完成, 都要 創
建 自定義的 模型類, 不能直接使用標準 的模型類的基類.
甚至于, 即使一個大型的很多文件 需要同時編輯的場合下, 用一個 vim窗口界面都是可以勝任的, 首先它的打開速度很快, 其次可以分成多個(比如4~5)個子窗口來同時編輯多個文件, 最重要的是, 每一個子窗口都可以 保存多個 曾經打開的 文件的緩沖, 在每一個子窗口都可以使用 ctrl+^ 來切換緩沖的文件.
tp多個配置文件?
- 你可以將所有的配置雜七雜八地放到同一個配置文件中, 比如/Application/Home/Conf/config.php中, 但是如果配置比較多, 比較繁雜的話,就會 顯得比較凌亂. 所以將配置分門別類的放在各自的/ 單獨的 配置文件, 然后 "包含它們" 是一個比較好的.
- 你也不能單單的把 某個方面的 配置文件 "放到" '扔到' conf目錄下就行, 那樣的話, tp也不會知道 你的文件就是配置文件啊, 所以需要給 tp "說 一聲, 告知一下 注冊一下", 就是要在 "主"配置文件中 說一下: 比如 'load_ext_config' => 'mylang'
- 自己擴展的配置文件,比如mylang.php是放在跟你包含 說明的配置文件相同目錄下, 比如 在 Home/Conf/config.php中配置load_ext_config, 那么擴展配置也就放在Home/Conf中, 而且擴展配置 說明中 不要帶.php擴展名
tp的配置盡量用 小寫字母, 因為不管大寫還是小寫, 最后都要轉變為小寫. 雖然為了好看,"推薦"用小寫. 但是在實際開發中, 一切都是 以 "效率" 為最高原則的.
tp如何配置自己的 語言文件?? 參考https://www.jb51.net/article/47624.htm http://www.cnblogs.com/yuwensong/p/4156383.html
這個還是比較復雜的, 通常是不需要的.如果確實要這樣做, 步驟是:(但是好像有錯誤???)
1.在/App/Home/Conf/config.php配置中, 追加 'LANG_SWITCH_ON' => true, //開啟語言包功能 'LANG_AUTO_DETECT' => true, // 自動偵測語言'DEFAULT_LANG' => 'zh-cn', // 默認語言 'LANG_LIST' => 'en-us,zh-cn,zh-tw', //必須寫可允許的語言列表'VAR_LANGUAGE' => 'l', // 默認語言切換變量 2.在Home/Conf目錄中創建一個php文件, 比如: tag.php 內容如下<?php
return array(
// 添加下面一行定義即可
'app_begin' => array('CheckLang')
);
==================================================================
如果dump一個對象的話, 將輸出這個對象的所有內容, 包括對象的 所有成員變量和所有的成員方法.
關于數據對象data和模型對象$User的區別?
- $User是 通過M, D等方法創建的模型對象. 有兩個方面的作用, 一個是 關于模型的所有方法操作, 如add, select, save, delete等都必須通過這個對象完成; 另一個作用是, 其本身也可以 保持/保存 一些"數據", (這些數據不是指 模型類本身定義時所包含的成員等, 而是指 包含 將要寫入到數據庫表中 "記錄"內容).
- 數據對象, 是指 模型類$User 所包含的 表記錄 數據. $User獲得 表記錄數據有兩種途徑, 使用 data()方法, 或者使用 create()方法.
一方面, 你可以直接 echo出 對象$User所包含的表記錄字段, 比如: echo $User->name;
另一方面, 你還可以接收 create方法的返回對象 $var_data = $User->create() , 這樣你就可以很直觀地dump出 $var_data 查看數據了
數據表的select操作, 不只是可以選擇記錄, 而且可以完成復雜的 字段運算等
where子句,不但能根據條件選擇篩選記錄, 而且 在 id自增的時候 可以用來選擇最前/最后/中間 N條記錄: ... where id > Max(id)....
通常來說, where, limit等的操作耗時 比order的耗時 要小, 應該盡量避免 order操作??
在非mysql的選擇子句中,最前面N條記錄 可以用 top子句 , 但是 mysql沒有top子句! 只能使用limit子句. 參考 http://www.cnblogs.com/freeliver54/archive/2008/07/23/1249232.html
- limit子句的格式是: limit 因為是offset偏移, 所以總是比起始記錄位置小1. 比如: 選擇從第10條到20條的記錄, 應該是: limit 9, 11 從第10條開始的共10條記錄: limit 9, 10
- mysql沒有直接選取 最后N條 的子句.**
male和female不只是指人, 還可以用來指 雄性動物或 雄性植物(雄株) . man和woman通常用來指成年男人和女人. 也就是說 male包括 man和boy. female的fe.
create在 創建數據對象時, 會 驗證數據源的合法性(會自動過濾 數據表中沒有的字段!). 所以即使表單中有 多余的/不是數據表中的字段信息, 也不用管, 因為 非數據表字段會自動過濾/丟棄,不會出現在 創建的數據對象中.
- 模型類對表單中的 字段映射: 目的, 因為默認的在創建數據對象時, 是要求 表單中的 字段name要和 數據表中的字段名稱 相同, 否則會報錯. 但是那樣會在表單中暴露數據表的字段,引起安全問題. 所以 通過字段映射, 讓在表單中的字段名稱 => 映射到 數據表中的字段名. (這樣即實現了 從表單到 數據表的數據對象創建, 又隱藏了數據表自動名, 多了一點安全保護).
字段映射的方式是: 在自定義模型類 中添加protected $_map=array('表單字段名' => '數據表字段名'); 注意是把 表單字段 映射為 數據表字段, 不可能是反過來吧,本身你就要隱藏數據表字段呢, 你難道還想 主動暴露到表單中來嗎?
使用字段映射: 即使使用了字段映射, 并不會 自動 影響 查詢結果, 查詢結果中的 記錄中的 字段名稱仍然是 原來的數據表中的字段名稱, 不會是 "表單"字段名. 除非你在配置中設置了 read_data_map' => true, 或者使用 D('user') -> parseFieldsMap($data_result)方法手動 轉換.
在$User->create() 后, 里面的數據對象就已經被 映射了, 即原來表單中的字段就已經自動轉換為數據表中的字段了,(這個是create所作的工作之一),所以接下來就可以用 連貫操作 add了 .
字符為空 和 not null 是不同的! 當表單中的input域(比如姓名) 沒有填入內容的時候, 傳遞到$_post的是 ""空字符串, 不是not null. 所以 它是合法的, 會被add添加到數據表中.
$_POST是: array (size=2)'username' => string '' (length=0) //這里明確給出了是: string , 而且是 '', 不是 null!'gender' => string 'm' (length=1)在數據表中, 字段field也叫做 column列. 在定義表/修改表結構的時候, 格式是: col_name colomn_specification/col_definition 即 列名 然后是對列的定義/說明/描述 (多個定義單詞直接用空格分隔).
===============================================================
要想一次性的關閉多個 已經打開的緩沖區, (而不用一個一個地去關閉), 使用 冒號命令: bufdo bd其中 bufdo是指 針對所有的 緩沖區執行的命令.
關于sql語句中 各子句的執行順序? 參考 主要是這個: http://www.cnblogs.com/Qian123/p/5669259.html 和http://www.cnblogs.com/Qian123/p/5669259.html 明確了sql語句的執行過程, 你對數據庫的執行過程和原理就會更深入, 也會避免一些使用上的錯誤, 比如:
- sql語句中, 任何一個 "關鍵字(單詞/詞組)"都是一個子句, 包括: from -> on -> join -> where -> group by -> having -> select -> disctinct -> order by-> limit
- select子句雖然在最前面, 但并不是第一個執行, 它是在第8步才執行的. 而只有在select 子句中 才能定義 字段(列)的alias,(from子句中可以定義表的別名) 所以在第8步select子句之前都是不能使用 列的別名的, 只有在這之后, 即第9步distinct 第10步order by子句中使用列的別名
- 最先執行的總是 from子句, 最后執行的總是 limit子句. 所以 在from子句中定義 的表的 alias別名, 可以在 其后的(從第2步后)所有子句中都可以使用, 包括隨后的where子句中就可以使用表的別名.
- mysql中 的所有別名, 包括 表的別名, 和 字段的別名 都可以加上 as, 也可以省略 as.
- 通常每一步子句 得到的是一個 虛擬表virtual table(即虛表VT), 從 VT1~ VT9, 但是在第10步, 即order by子句, 返回的并不是一個 虛表vt, 而是 一個游標 即VC(virtual cursor). 所以凡是包含 order by子句的 查詢句都不能作為 "表的表達式)(即在 凡是需要一個 表的表達式的地方, 都不能包含order by子句) 表的表達式其實就是 一個虛表vt.
distinct子句 的原理 是 在內存中, 利用一個 臨時表來 得到一個 vt的
- 要理解select子句的過程: 查詢/選擇 結果字段, 其實并不是直接拿著 這些要顯示的字段到數據表里面去"挑選"記錄.實際上, 在select之前, 已經做了大量的工作, 已經經過/得到了多個 步驟的 VT虛表的迭代過程了. 已經準備好了 查詢結果的(包含所有字段)的 多個記錄了. select子句的作用 僅僅是 挑選要顯示/要返回的 部分字段(但是其他字段其實還是存在的, 因為即使在 其后的 distinct/order by 等步驟中, 虛表VT10/11 其實還是一直存在的, 在內存中), 所以在 select子句后, 還可以使用 order by子句按 非select字段進行排序的.
- 在order by子句前, 整個過程的vt都是 無序的. 只有當你確實需要有序的, 需要排序的結果集時, 才用order by. order by很耗資源和時間, 要慎用.
mysql中的統計函數, 比如max, min, sum, avg, 也叫 分組函數(group functions). 也就是說, 只有在 執行了group by子句后, 其他子句才能使用: 即在第5步后 才能使用 分組(統計)函數. 而where子句是在 group by子句之前執行的, 所以 在 where 子句中, 就不能使用 group子句中才能使用的 統計函數. 比如 where score>=average(score)?? 就會報錯: "invalid use of group functins"
分組后, 在分組記錄中, 我們可以 select出關于分組的統計信息, 也可以select 原數據表中的非統計信息(即普通字段信息), 雖然分組操作的目的通常是要 select出統計信息. 如果分組后 select的是 非統計字段信息,則 在第9 步(select步驟)總是顯示的/保留的是 相同分組中 排在最前面的那個記錄的 字段信息. (但是 在分組后所得的虛擬表VT(第5步時)分組中的 其他記錄/信息仍然是保留的. 是按分組字段的不同 挨著挨著排列的(類似于excel中的分組), 所以, 一直到第8步select的時候 還可以用 count, max等統計函數對所有 記錄 和 相關字段進行統計 )
關于分組后的顯示結果?
+------+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+ | 1 | SIMPLE | user | range | PRIMARY | PRIMARY | 4 | NULL | 7 | Using where; Using temporary; Using filesort | +------+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+ 1 row in set (0.00 sec)關于explain中的說明?
- type是指查詢的范圍, 是整個記錄ALL, 還是有條件/范圍的, 通常where子句屬于 type=range的. 如果查詢條件中包含了主鍵 那么在explain中會顯示primary key. extra是說會用到哪些 "額外" 操作. group by分組, 會使用到臨時表temporary和其結果會自動 按分組字段 升序排序??(隱含一個 order by group_column asc)?? 所以explain中, 會有 using filesort. 凡是有 (或者是 隱含有) order by 排序的操作, 都會有 using filesort的 執行計劃. 比如 group by的分組操作, 就暗含了 分組后的記錄 按 分組字段 asc 升序排列的 操作.
在要實現一些比較 復雜的 查詢功能時, 都會使用 "子查詢". 子查詢主要有兩個作用: 得到的 可以是一個 表的表達式, 用來作為中間表/臨時表, 也可以得到的是一個 數值, 用在where等子句中. 所以, "子查詢"的使用還是 很多的!
當要求id最大值時, 慎用select Max(id) ... 而是用索引來做, 比如: 創建id的索引(show index from table_name), 然后用 select... order by id desc limit 1 來代替, 這樣效率更高
- 在用group by分組后, 可以使用 分組函數(統計函數)比如max, min, sum等 確實能夠 對每一組的數據 進行 最大值等的統計, 而不會只針對所有記錄進行統計. 因為select子句在 group by子句后執行.
- 但是 group by和max等統計函數一起使用時要注意: 如果包含了非統計數據(比如普通字段的值), 由于分組后, 總是取第一條記錄的普通字段的值,這樣 當第一條記錄的普通字段值和該分組的最大值等統計值一起 并列組成一條記錄時, 就可能發生誤解,跟實際情況不符. 比如統計分組中的最大值, 但是這個最大值并不一定就是 第一條記錄的用戶 正好具有該最大值.
此時有兩種解決方案, 參考: https://blog.csdn.net/john_hongming/article/details/42742965
一是, 先將原來的表 按照要求Max/min的字段 進行排序, 升序或降序, 反正要保證 出現/保留在 分組里面的" 包含普通字段的那條記錄" 要在 第一個記錄位置就好. 得到一個 (中間表/表的表達式) 然后對這個中間表進行 分組.
二是: 使用where in ...
對mysql而言, 當創建了主鍵后, (最常用的是id), 會自動地給 主鍵創建 索引 (所以, 不必重復地 去創建索引). show index from user;
- 給數據表創建主鍵時, 要注意對主鍵的設置加以程序安全性的保護, 因為一方面 增刪改查主要就是根據主鍵來進行的; 另一方面,主鍵也 比較容易暴露泄露 數據庫的信息.
數據表的 索引的創建很方便, 很簡單, 不會給數據表帶來負擔. 但是, 索引在查詢方面 可以帶來很大的速度提升. 所以, 在實際項目中, 通常應該 給 要查詢的 字段 (不只是主鍵字段) 比如'name'字段創建索引. 另外, 在 可能出錯, 根據某個字段進行 排錯時的字段 也可以給它創建索引.
"every derived(派生的/繼承的/衍生的/導出的...) table must have its own alias" 就是說, 在 mysql中, 任何 中間表(表的表達式)/臨時表都必須有一個 別名,而不管你會不會用到這個別名.
- 但并不是所有的 中間查詢/臨時查詢/放在括號中的查詢, 都要用 表的別名. 這個只是針對 需要 "表"的時候, 只是在 derived table, 是table , 只是在 from子句 后面的中間表, 才需要用 別名. 而在 where子句 是不需要表 的別名的! 因為 where子句中 只是需要一個 數據/數值/集合,用來滿足where的 >, in, between等表達式而已.
having 和where的區別?
- 兩者在語法上的寫法是一樣的, 都是條件篩選, 只不過where是對 表的 "列"進行篩選, 因此where表達式中只能 出現表的列字段, 而having是對 查詢結果進行篩選.
- having可以單獨使用, 不一定總是 必須 跟 group by一起使用!
- having 是對 (可以分組 也可能不分組 group by ->) select之后的結果 進行條件篩選. 所以 , 可以使用 select子句中的 所有別名, 包括字段運算后的別名.
- 在select語句中, 字段被 看成是 "變量" , 所以 可以對字段進行 算術運算的. 比如 查找成績在90分以上的記錄: select id, name as '姓名', score-60 as chazhi from score having chazi>30;
??? 難道having子句 是在 select子句后執行的??
group by和order by的一起使用?
- 要求, order by中的字段, 必須是 出現在group by子句clause中.
- order by子句必須放在 group by子句的后面
- group by默認也要進行排序, 多個字段進行分組或排序時, 字段順序必須固定, 不是隨便寫的.
===================================
終端terminal shell是一個集成環境, 在里面運行的任何程序包括 vim, mysql, 等都是子程序, 都可以使用 shell統一的 菜單/快捷鍵設置操作, 比如 復制/粘貼等. 消除其他行, 到最頂端, 使用 ctrl_L
====================================
tp的功能也不是盡善盡美(實際上世上也沒有盡善盡美的東西吧), 還有一些bug的.
在 項目App/Runtime/Home/目錄下的 那些php文件, 實際上就是 View目錄下的 "模板" 的編譯結果文件(所謂編譯, 就是將模板中的php代碼 解析成普通的html后)
關于布局模板
(模板)布局layout是tp的功能, 實現布局的方式是用 模板, 這個模板叫" 布局模板" . 不管哪一個框架的模板布局, 還是很有用的. 它是生成 基本框架都相同的多個頁面的一種快速方法: 把多個頁面中, 相同的要素(結構)比如頁面的頭部, 菜單欄, 頁腳等內容是基本相同的, 提取出來, 然后多個頁面中只有 主體內容 不同的部分進行組裝. 沒有必要每一個頁面都完整的寫一遍, 這個正是 符合軟件 "結構化/模塊化+重用" 的思想.
布局模板的實現有三種方式, 其中第二種方式, 是使用 layout標簽, 這個標簽的使用方法 ,跟其他html標簽一樣, 也是指定相應的屬性就好了
layout標簽不需要任何配置;
layout標簽的屬性有 name(使用哪個布局模板), 和 replace(布局模板中的替換字符串)
在 頭部增加(好像不一定是要在 head中, 在body中定義也是可以的! 而且 layout標簽甚至可以在body內容的最下面/最后面書寫都是可以的. 但是一定要在配置中, 關閉 LAYOUT_ON設置,否則 布局不會成功, 不會應用 布局模板!!! ):<layout name="Layout/newlayout" replace="{__REPLACE__}" />
使用了layout標簽后, 同樣的, 是把 當前模板文件的內容 替換到 布局模板中的 {REPLACE}使用include標簽 中的 layout標簽, 可以實現模板標簽的嵌套.
在convention.php配置中, 關于布局(模板) 的配置 有3個:
- 這個是整體/全局配置, 對整個項目中的所有模板文件 都有效的.
但是, 是可以來調節的,并不是說, 只要開啟layout_on=>true后, 就必須/不得不 使用布局功能了. 實際上, 即使開啟了layout功能后, 仍然有兩者方法來關閉: 一是 在 需要 關閉的模板頁面中, 加上 {_ _NOLAYOUT_ _ } ; 二是 在 控制器的操作中 使用 全局函數layout(是框架中的functions.php文件中的函數), 比如 layout(true), layout(false)禁用布局功能, layout('layout/new_layout') 而且使用全局函數layout時是不需要開啟layout_on=>true 這個配置的.
要注意, 布局模板的位置默認的 跟普通模板文件的位置一樣, 即布局模板 文件是: /AppName/Home/View/layout.html, 注意默認的是View目錄下的 layout.html, 而如果有的配置設置了 模板的子目錄位置時, 就要重新指定 "layout_name" 了.
轉載于:https://www.cnblogs.com/bkylee/p/9303769.html
總結
以上是生活随笔為你收集整理的tp剩余未验证内容-7的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bash的特性
- 下一篇: 1.3(java学习笔记)构造方法及重载