tp剩餘未驗證內容-7

bash腳本中 的 set -e表示 exit immediately if a simple command returns a non-zero value.主要是爲了防止錯誤被忽略.會被當即退出, 可是最好在開發結束後, 刪除這個指令, 以避免留下隱患.javascript

有四種命令提示符, 有PS1, 天然就有 PS2 PS3 PS4, 分別表示 PS2即 在後續的命令下一行的提示符(continu'ation interactive prompt), PS3是在select選項時 的提示符, PS4是調試時的提示符.php

shell中要進行算術運算, 有5種方法: (由於默認的算術運算符號+-*/ 都不會被直接當作運算符, 而只是當作普通字符來看待, 因此須要特殊處理)html

  • 使用算術擴展: $(( ... )); $[...]
  • 使用外部命令expr expr 1 + 2 注意有空格(特殊符號要用* 轉義)
  • 使用內部命令: let 1+2 或 declare -i c=1+2
    外部命令,就是外部存在的 能夠執行的文件, 能夠用 which命令看獲得的, 根shell無關的; 所謂內部命令,就是 shell自己提供的命令(函數), 用which是查看不到沒有的.

shell的調試?java

  • 直接用 sh -x ./foo.sh 命令, 其中 -x就是調試的意思 還有其餘一些選項 : sh -n只是檢查文件是否有語法錯誤; sh -c "..." 表示文件從字符串中讀取.
  • 或者直接將調試選項寫在sh文件中的 #!bin/bash -xv???
  • 或者在文件中, 在要開始調試的 位置 寫上 set -x 可是要注意, 只有set -x以後的命令纔會調試, 這個以前的命令不會被調試.
  • 所謂調試就是 會將每一次/ 每一步 step by step 執行的語句 先顯示出來, 而且會將執行語句中的變量用當前值 替換; 而後輸出命令執行的結果. 並且執行語句前加上+號

$_SERVER['HTTP_REFERER']爲何爲空?mysql

  • referer的正確拼寫是 referrer, 因此前者實際上是一種歷史的錯誤遺留
  • http_referer是header請求頭的一部分, 一般會帶在向web服務器發生的信息中, 告訴服務器我是從 哪一個頁面連接而來的. 能夠給服務器一些額外的信息, 便於其餘一些處理.
  • http_refer徹底依賴於瀏覽器自身, 有的瀏覽器是沒有設置這個變量的. 你就得不到它.web

  • 可是, 在不少狀況下http_referer會無效, null. 好比你 直接訪問一個頁面的時候, 或從收藏夾中訪問頁面的時候,
    因此通常來講,只有經過 <a> 超連接 </a> 或者: location.href=...跳轉, 以及 POST 或 GET 表單 提交訪問的頁面, $_SERVER['HTTP_REFERER']纔有效。
    sql

  • 因爲 $_SERVER['HTTP_REFERER'] 對 POST 表單訪問也是有效的,所以在表單數據處理頁面 必定程度上 能夠經過校驗 $_SERVER['HTTP_REFERER'] 來防止表單數據的惡意提交。但該方法並不能保證表單數據的絕對正確,即對錶單數據的真實性檢測並不能徹底依賴於 $_SERVER['HTTP_REFERER'] 。thinkphp

========================shell

因此, 在tp中, 操做成功或失敗的提示 跳轉是用 success和error. $this->success/errror('跳轉提示信息', 跳轉的地址_默認是http_referer, 跳轉等待時間)數據庫

使用js 使html中的數字遞減?

  • 一個頁面中, 包含多個head, body, html等標籤雖然不規範, 可是仍然能夠解析顯示的.
  • js獲取一個元素的屬性?
  • setInterval和clearInterval?
  • 快速調用一個函數的方法.
<script type="text/javascript">
(function(){
var wait = document.getElementById('wait'),href = document.getElementById('href').href;
var interval = setInterval(function(){
    var time = --wait.innerHTML;
    if(time <= 0) {
        location.href = href;
        clearInterval(interval);
    };
}, 1000);
})();
</script>

關於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')
);

3.把框架中的 Extend/Behavior/CheckLangBehavior.class.php 文件複製到 Home/lib/Behavior/中(完整版的thinkphp包纔有,沒有的話請自行建立)
4.而後就是 建立對應的語言項文件了, 在 /App/Home/下建立對應的三個語言文件夾: zh-cn, en-us, zh-tw. 而後再在這些語言目錄中建立對應的語言文件, 文件名必須設置爲common.php??
5.最後就是 引用/使用 語言配置了, 在模板文件中, 使用 `{$Think.lang.語言項}` 在後臺控制器中, 用L()方法來引用.

==================================================================

若是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> <記錄個數 return_num> 由於是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 ...
MariaDB [test]> select * from user where score in (select max(score) from user group by gender);
+------------+-----------+--------+-------+
| id         | name      | gender | score |
+------------+-----------+--------+-------+
| 0000000002 | 孫徐連    | w      |    98 |
| 0000000010 | 王的徐    | m      |    97 |
+------------+-----------+--------+-------+
2 rows in set (0.00 sec)

MariaDB [test]>

對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子句後執行的??
MariaDB [test]> select id, name as '姓名',  score-60 as chazi from user where chazi>30;
ERROR 1054 (42S22): Unknown column 'chazi' in 'where clause'
// 很明顯, where只是針對 字段來判斷的, 若是是select中的 運算表達式, 則會報錯, "未知的字段"

MariaDB [test]> select id, name as '姓名',  score-60 as chazi from user having chazi>30;
+------------+-----------+-------+
| id         | 姓名      | chazi |
+------------+-----------+-------+
| 0000000001 | 孫以的    |    34 |
| 0000000002 | 孫徐連    |    38 |
| 0000000010 | 王的徐    |    37 |
+------------+-----------+-------+
3 rows in set (0.00 sec)

MariaDB [test]>

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個:

'TMPL_LAYOUT_ITEM'      =>  '{__CONTENT__}', // 佈局模板的內容替換標識
    'LAYOUT_ON'             =>  false, // 是否啓用佈局
    'LAYOUT_NAME'           =>  'layout', 
    // 當前佈局名稱 默認爲layout
  • 這個是總體/全局配置, 對整個項目中的全部模板文件 都有效的.
    可是, 是能夠來調節的,並非說, 只要開啓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" 了.

相關文章
相關標籤/搜索