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 1 + 2
注意有空格(特殊符號要用* 轉義)shell的調試?java
#!bin/bash -xv
???$_SERVER['HTTP_REFERER']爲何爲空?mysql
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, 跳轉等待時間)
數據庫
<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數組, 是應用得最普遍的. 能夠說凡是能用 "字符串"的地方, 幾乎均可以用數組來 表示, 用數組來操做, 並且都推薦用數組, (由於數組更安全??)
其中, add和save方法, 須要先建立 插入和更新的 數據對象$data
(實際上就是要插入/更新到表中的 記錄)
這種建立數據對象的方法, 有兩種, 一是 create()方法, 一是data()方法. 兩個方法的相同點是: 均可以/都支持多種數據來源, 包括從 數組, 其餘數據對象甚至 普通對象來建立; 不一樣點是: create的功能更強大, 不但支持建立的數據對象的自動驗證和自動完成($_validate和$_auto), 並且還能夠 自動地從 $_POST數組建立數據對象.
$User = M('user')
的時候, 就須要數據庫配置, 若是沒有配置/沒有正確配置, 就會報錯.static public function getInstance($config=array())
參數就是$config數據庫鏈接配置!E(L('_NO_DB_DRIVER_') . ':'. $class), E函數的原型是 E($msg, $code); 因此全部的錯誤提示內容, 都要放在整個 E() 函數的括號內
錯誤函數是 拋出了一個 異常 throw new Exception($msg, $code);
因此: E函數後的全部內容 都將 中止執行, 直接從 E()函數處退出了, 並且是調用 統一的 異常輸出模板.一是使用 field函數,( 要注意, field方法沒有複數, 因此其參數也是 一個 字符串. 另外field是指定 接收的/生效的字段, 不是 將被過濾被丟棄的字段 ) 而後用create()建立,
二是配置 insertFields, updateFields兩個的值,
**即便設置了表單 的字段映射, 可是在 後面的全部 連貫操做的 field方法中, 表示 參數的 字段都 應該是實際的數據表字段, 而不是 字段映射, 不是表單中的 字段域, 不然 當定義了字段映射時, 又使用 filed('表單字段'), 那麼就會出現 create的數據對象 爲空 empty的 錯誤!
要注意, 若是要設置 $insertFields 和 $updateFields的值, 以及要實現自動驗證和自動完成, 都要 創
建 自定義的 模型類, 不能直接使用標準 的模型類的基類.
'load_ext_config' => 'mylang'
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()方法來引用.
==================================================================
echo $User->name
;$var_data = $User->create()
, 這樣你就能夠很直觀地dump出 $var_data 查看數據了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 9, 11
從第10條開始的共10條記錄: limit 9, 10
male和female不僅是指人, 還能夠用來指 雄性動物或 雄性植物(雄株) . man和woman一般用來指成年男人和女人. 也就是說 male包括 man和boy. female的fe.
字段映射的方式是: 在自定義模型類 中添加protected $_map=array('表單字段名' => '數據表字段名');
注意是把 表單字段 映射爲 數據表字段, 不多是反過來吧,自己你就要隱藏數據表字段呢, 你難道還想 主動暴露到表單中來嗎?
使用字段映射: 即便使用了字段映射, 並不會 自動 影響 查詢結果, 查詢結果中的 記錄中的 字段名稱仍然是 原來的數據表中的字段名稱, 不會是 "表單"字段名. 除非你在配置中設置了 read_data_map' => true,
或者使用 D('user') -> parseFieldsMap($data_result)方法手動 轉換.
在$User->create()
後, 裏面的數據對象就已經被 映射了, 即原來表單中的字段就已經自動轉換爲數據表中的字段了,(這個是create所做的工做之一),因此接下來就能夠用 連貫操做 add了 .
$_POST是: array (size=2) 'username' => string '' (length=0) //這裏明確給出了是: string , 並且是 '', 不是 null! 'gender' => string 'm' (length=1)
===============================================================
bufdo bd
其中 bufdo是指 針對全部的 緩衝區執行的命令.主要是這個: http://www.cnblogs.com/Qian123/p/5669259.html 和http://www.cnblogs.com/Qian123/p/5669259.html
明確了sql語句的執行過程, 你對數據庫的執行過程和原理就會更深刻, 也會避免一些使用上的錯誤, 好比:distinct子句 的原理 是 在內存中, 利用一個 臨時表來 獲得一個 vt的
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中的說明?
select Max(id) ...
而是用索引來作, 好比: 建立id的索引(show index from table_name
), 而後用 select... order by id desc limit 1
來代替, 這樣效率更高https://blog.csdn.net/john_hongming/article/details/42742965
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]>
show index from user;
select id, name as '姓名', score-60 as chazhi from score having chazi>30;
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]>
===================================
====================================
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
{_ _NOLAYOUT_ _ }
; 二是 在 控制器的操做中 使用 全局函數layout(是框架中的functions.php文件中的函數), 好比 layout(true), layout(false)禁用佈局功能, layout('layout/new_layout')
並且使用全局函數layout時是不須要開啓layout_on=>true
這個配置的.