- 設計篇
寫程式前先記好「電腦安全的七項設七項設計原則」
- 最小權限原則 ( least privilege )
- 經濟者是原則 ( econmy of mechanism )
- 安全檢測原則 ( complete mediation )
每一筆資料存取之前,都必須先檢驗是否為合法授權行為 - 開放性設計原則 ( open design )
嚴禁走系統後門的行徑 - 分權原則 ( separation of privilege )
- 最少共用性原則 ( least common mechanism )
- 可接受程度 ( psychological acceptability )
- 實做篇
理論太多沒感覺嗎?不然實做黃金三劍客記好就好...
- always validate your inputs
- always filter your outputs
- nerver trust users
實做細節注意overflow
避免使用 建議使用 gets() fget() strcpy() strncpy() stract() strncat()
星期四, 7月 26, 2012
Coding Security Issues
星期四, 7月 12, 2012
ssl 在ie下網址錯誤
crt1: aa.com
crt2: host2.aa.com
appache裡設定ssl.conf
在firefox, chrome都正常
而在...ie時,host2.aa.com的憑證是失效的
研究了很久,發現網址不正確,這下有趣了,明明就是來驗證網址的
居然說網址不正確
這才發現原本應抓host2.aa.com的憑證,居然是抓aa.com,而判斷目前網址錯誤
後來將ssl.conf順序倒了一下就解決了
我想是virtualhost *:443的關係吧
不過寫成;VirtualHost aa.com:443 順序一樣要細的在上
而且還會有warnning指出前者overlap後者
最後發現是萬惡ie沒辦法分辨...
最後只能... 再架個server各自獨立
crt2: host2.aa.com
appache裡設定ssl.conf
<VirtualHost *:443> SSLCertificateFile /etc/pki/tls/certs/aa_com.crt SSLCertificateKeyFile /etc/pki/tls/private/aa_com.key SSLCertificateChainFile /etc/pki/tls/certs/aa_com.ca-bundle </VirtualHost> <VirtualHost *:443> SSLCertificateFile /etc/pki/tls/certs/host_aa_com.crt SSLCertificateKeyFile /etc/pki/tls/private/host_aa_com.key SSLCertificateChainFile /etc/pki/tls/certs/host_aa_com.ca-bundle </VirtualHost>
而在...ie時,host2.aa.com的憑證是失效的
研究了很久,發現網址不正確,這下有趣了,明明就是來驗證網址的
居然說網址不正確
這才發現原本應抓host2.aa.com的憑證,居然是抓aa.com,而判斷目前網址錯誤
後來將ssl.conf順序倒了一下就解決了
我想是virtualhost *:443的關係吧
不過寫成;VirtualHost aa.com:443 順序一樣要細的在上
而且還會有warnning指出前者overlap後者
最後發現是萬惡ie沒辦法分辨...
最後只能... 再架個server各自獨立
星期二, 7月 10, 2012
firefox 的 sec_error_unknown_issuer 問題
最近用了Comodo發的ssl憑證建了https
結果在firefox遇到了sec_error_unknown_issuer問題

查了一下得加個ca-bundle設定
在跟comodo申請憑證後,會拿到
#後記
後來遇到https都連不到,才發現原來在load balance的server上也要給
References
結果在firefox遇到了sec_error_unknown_issuer問題

查了一下得加個ca-bundle設定
在跟comodo申請憑證後,會拿到
- YOUR_WEBSITE.crt
- YOUR_WEBSITE.YOUR_WEBSITE.csr
- YOUR_WEBSITE.bundle..ca-bundle
SSLCertificateFile /etc/pki/tls/certs/YOUR_WEBSITE.crt SSLCertificateKeyFile /etc/pki/tls/private/YOUR_WEBSITE.key SSLCertificateChainFile /etc/pki/tls/certs/YOUR_WEBSITE.ca-bundle
#後記
後來遇到https都連不到,才發現原來在load balance的server上也要給
References
星期四, 7月 05, 2012
偵測新視窗的close event
如何偵測新視窗的close event咧
不過這方法不能跨網域
也就是如果child開到不同網域,close不會觸發unload事件
解決方法先轉個空白的網頁,裡面夾iframe去連該網頁
後記-跨網頁問題
被同事嗆「閃開! 讓專業的來」 見下面程式碼
也不去bind event,只是持續monitor關了沒...真是好招...
References
<script type="text/javascript">
var win = window.open("secondwindow.html", "_blank");
win.onunload =onun;
function onun() {
if(win.location != "about:blank") // This is so that the function
// doesn't do anything when the
// window is first opened.
{
alert("closed");
}
}
</script>
也就是如果child開到不同網域,close不會觸發unload事件
解決方法先轉個空白的網頁,裡面夾iframe去連該網頁
後記-跨網頁問題
被同事嗆「閃開! 讓專業的來」 見下面程式碼
也不去bind event,只是持續monitor關了沒...真是好招...
var child = window.open('http://google.com','','toolbar=0,status=0,width=626,height=436');
var timer = setInterval(checkChild, 500);
function checkChild() {
if (child.closed) {
alert("Child window closed");
clearInterval(timer);
}
}
References
星期一, 7月 02, 2012
mysql常用日期query
- 當天的資料
select * from table where to_days(column_time) = to_days(now()); select * from table where date(column_time) = curdate();
- Between日期
注意結尾是最後一天一秒,否則只會出現到前一天的資料WHERE (created BETWEEN '2012-06-19' and '2012-06-30 23:59:59' );
- 最近7天,1個月
WHERE DATE_SUB( CURDATE( ) , INTERVAL 7 DAY ) <= `created_date`; WHERE DATE_SUB(CURDATE(), INTERVAL INTERVAL 1 MONTH) <= `created_date`;
- 本周
從當週的Sunday開始到星期六的七天資料
select * from wap_content where week(created_at) = week(now);
星期四, 6月 28, 2012
常用sed與awk
- 統計行數
單一檔案
awk 'END{print FNR}' xxx.log
多個檔案
awk 'END{print FNR}' *.log
用linux本身的wc指令也可達到效果
wc -l *.log - 取出重覆及不重覆次數
[root@test]# cat a.txt
12 1209185885333940
12 1209185089989307
12 1209185891525318
13 1209186004855839
13 1209185995006463
13 1209185995006463
awk '{a[$1]++}flag[$1,$2]!=1{b[$1]++}{flag[$1,$2]=1}END{for (i in a)print i,a[i],b[i]}' a.txt
--
12 3 3
13 3 2
reference: 请教awk如何同时统计 总数与不重复个数?
- 列出符合的資料
- 單筆
sed '0,/PARSE_FROM_HERE/' a.txt
awk '/regex/ {getline;print}' a.txt - 之後(含符合項)
awk '/regex/,0' a.txt
awk '/regex/,G' a.txt - 之後(不含符合項)
sed '0,/regex/d' a.txt
awk '/regex/ {getline;print}' a.txt - 之前
試半天用不出來,乾脆先倒過來讀,就可用上面的方法做出來了
sed '1!G;h;$!d' test | awk '/regex/,0'
- 單筆
星期二, 6月 26, 2012
vim及tmux視窗常用指令
兩個切換視窗切到指令都亂了
- 合併兩個即有視窗
- vim: vert sb#
- tmux
- 將目前的pane抽成獨立視窗
- vim:
- tmux: CTRL-b !
- 分割頁切換
- vim: CTRL-W 方向鍵
或是CTRL-W j(往右) or w(往下),大寫則相反 - tmux: CTRL-o
- vim: CTRL-W 方向鍵
星期二, 6月 19, 2012
php與awk
- 在php中執行shell
可利用shell_exec
shell_exec('ls -l');
- 使用awk
$data = shell_exec("awk '{print $1}' " . $filepath ); - 取得單行awk內容
由於shell_exec是一次將每行內容回傳,如果要一行行取得awk的資料就要搭配exec
$feeds = array(); exec("awk '{print $1}' " . $filepath, $feeds ); foreach($feeds as $feed) echo $feed . '< br/>';
星期二, 6月 12, 2012
將url字串的參數轉為array
- 取出query部份
$url = 'http://username:password@hostname/path?arg=value#anchor'; $urlinfo = parse_url($url); ------------------------ Array ( [scheme] => http [host] => hostname [user] => username [pass] => password [path] => /path [query] => arg=value [fragment] => anchor ) - 轉成array
$str = "first=value&arr[]=foo+bar&arr[]=baz"; parse_str($str); echo $first; // value echo $arr[0]; // foo bar echo $arr[1]; // baz parse_str($str, $output); echo $output['first']; // value echo $output['arr'][0]; // foo bar echo $output['arr'][1]; // baz
References
星期一, 6月 11, 2012
php連oracle stored procedure
- sql
- 建立連線
$conn = oci_connect('YOUR_ACCOUNT', 'YOUR_PASSWORD','//IP_ADDRESS:PORT/SERVICE_NAME'); - 下sql
$sql = "SELECT ID, NAME as \"name\"
FROM CATEGORY
WHERE PARENT_ID = 0 AND STATUS = 1
ORDER BY CATEGORY_ID ASC"; - 取資料
$stid = oci_parse($conn, $sql);
oci_execute($stid);
$nrows = oci_fetch_all($stid, $res,0, -1, OCI_FETCHSTATEMENT_BY_ROW);
//echo "$nrows rows fetched
print_r( $res);*/
- 建立連線
- stored procedure
- 建立連線
$conn = oci_connect('YOUR_ACCOUNT', 'YOUR_PASSWORD','//IP_ADDRESS:PORT/SERVICE_NAME'); - 連stored procedure
假設sp名為myStoredProcedured,目的是將取到的時間轉為unit timestamp
$sql ="begin
:result := myStoredProcedured(:result => to_date(:myDate,'yyyy-mm-dd'));
end; ";
$stmt = oci_parse($conn,$sql) or die('could not parse statement.');
//bind參數
oci_bind_by_name($stmt,':result',$result,10); //回傳值需靠參數回傳
oci_bind_by_name($stmt,':myDate',$myDate,10);
//給值
$myDate = '2012-06-12';
//取值
oci_execute($stmt) or die('execute');
print_r($result);
- 給參數
- 建立連線
星期日, 6月 03, 2012
linux個人環境設定
每次重灌或換個新環境就得憑記憶重設定
乾脆直接記下來省時間...
乾脆直接記下來省時間...
感謝Dockerfile等工具... 以後這些都可以不用理了...
- bashrc
vim ~/.bashrc
export TERM=screen-256color #註1
註1: lose vim colorscheme in tmux mode
- vim 環境設定
- 環境
- 縮排
- tmux
# General configuration. # $ tmux show-options -g set -g base-index 1 set -g display-time 5000 set -g repeat-time 1000 set -g status-keys vi set -g status-utf8 on set -g status-bg black set -g status-fg white set -g status-justify left set -g status-interval 1 set -g status-left-length 15 set -g status-right-length 55 set -g status-left "#[fg=white,bright] #[fg=yellow,bright]#S #[default] |" # session-name set -g status-right "#[fg=red,bright][ #[fg=cyan]#(git branch --no-color | sed -e '/^[^*]/d' -e 's/* //') #[fg=red]]#[default] #[fg=yellow,bright] %Y-%m-%d #[fg=green]%H:%M:%S #[default]#[fg=magenta,bright]#[default]" # window setting setw -g utf8 on setw -g window-status-format " [#I] #W " setw -g window-status-current-format " [#I] #W " setw -g window-status-current-fg black setw -g window-status-current-bg green setw -g window-status-current-attr default # using function keyCtrl+A unbind C-b set -g prefix ^A bind a send-prefix # split window unbind % unbind '"' bind v split-window -h bind | split-window -h bind h split-window -v bind - split-window -v
設好後,重啟config
tmux source-file ~/.tmux.conf - git
星期三, 5月 30, 2012
linux監控磁碟空間
- df 監控可用磁碟空間與inode數舉
- 語法
df [options] [dir] - 說明
顯示dir所的檔案系統磁碟空間用量。df會依據/etc/fastab 組態檔找出dir掛載點,然後顯示檔案系統資訊。若沒指定dir,則df會顯示所有已掛載的檔案系統資訊 - 常用選項
-h 以較容易辨識的單位(M、G)顯示數值
-i 顯示inode用量資訊。若不指定,則顯示磁碟空間用量
- 範例一
檢視所有檔案系統的磁碟空間用量:
# df -h - 範例二
檢視所有檔案系統的inode用量:
# df -i - 範例三
查看目前工作目錄位於哪個分割區:
# df .
- 範例一
- 語法
- du 監控磁碟用量
- 語法
du [options] [directories] - 說明
顯示directories的磁碟使用資訊。如果省略directories,則顯示現行工作目錄的用量。 - 常用選項
-a 顯示所有檔案,不只是目錄。
-c 累計所顯示的項目總用量
-h 以較容易辨識的單位(M、G)顯示數值
-s 僅印出指定目錄本身摘要資訊,而不是遞迴顯示每個子目錄
-S 子目錄的用量不列入計算
- 範例一
檢祖/etc/rc.d 的disk用量
# du /etc/rc.d - 範例二
顯示 /etc 的disk用量:
# du -sh /etc - 範例三
顯示 /etc 的disk用量,但不包括其下的子目錄:
# du -Ssh /etc - 範例四
誰耗用最多空間(/home/*):
# du -csh /home/*
排序
# du -cs /home/* | sort -nr #用h會當成文字 ex, 1k,11k,2k
- 範例一
- 語法
iframe autoresize
先前一直從iframe內部出發,向parent呼叫調整高度
後來發現... parent自己取iframe的內容高去調整就可以了
References
Iframe Auto Resize Height
後來發現... parent自己取iframe的內容高去調整就可以了
References
Iframe Auto Resize Height
將scroller移到最上面
星期六, 5月 26, 2012
php 時間轉換函式
- 轉換unix timestamp為可讀日期時間
線上轉換date("Y-m-d H:i:s", $timestamp); - 可讀日期轉換unix timestamp
strtotime("2009-11-03 11:24:00PM");
星期三, 5月 23, 2012
php array轉xml, json
轉json就沒什麼好說的了,想說轉xml應該也是很簡單的東西,不過還真遇到一些問題
結合一下兩者,利用同一個function回覆
- array to xml
原本在google了一段code後,後來發現有中文xml會掛掉因為有不合法字元,
後來找到以下的code有編碼過,才知道原是編碼的問題
function toXml($data = array(), $structure = NULL, $basenode = 'xml'){ // turn off compatibility mode as simple xml throws a wobbly if you don't. if (ini_get('zend.ze1_compatibility_mode') == 1) { ini_set('zend.ze1_compatibility_mode', 0); } if ($structure == NULL) { $structure = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$basenode />"); } // loop through the data passed in. $data = $this->_force_loopable($data); foreach ($data as $key => $value) { // no numeric keys in our xml please! if (is_numeric($key)) { // make string key... //$key = "item_". (string) $key; $key = "item"; } // replace anything not alpha numeric $key = preg_replace('/[^a-z_]/i', '', $key); // if there is another array found recrusively call this function if (is_array($value) OR is_object($value)) { $node = $structure->addChild($key); // recrusive call. $this->_format_xml($value, $node, $basenode); } else { // Actual boolean values need to be converted to numbers is_bool($value) AND $value = (int) $value; // add single node. $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, "UTF-8"); $UsedKeys[] = $key; $structure->addChild($key, $value); } } // pass back as string. or simple xml object if you want! return $structure->asXML(); } function _force_loopable($data){ // Force it to be something useful if ( ! is_array($data) AND ! is_object($data)) { $data = (array) $data; } return $data; } - 下header
browser才會當成xml,而不是html
$array = array(...); header('Content-type: application/xml;charset=utf-8'); exit(toXml($array)) ;
結合一下兩者,利用同一個function回覆
//給header用
$_supported_formats = array(
'xml' => 'application/xml',
'rawxml' => 'application/xml',
'json' => 'application/json',
'jsonp' => 'application/javascript',
'serialize' => 'application/vnd.php.serialized',
'php' => 'text/plain',
'html' => 'text/html',
'csv' => 'application/csv'
);
function response($data, $format = 'json'){
header('Content-type: '.$this->_supported_formats[$format]);
switch (strtolower($format)){
case 'xml':
exit($this->toXml($data));
case 'json':
default:
exit(json_encode($data));
}
}星期三, 4月 18, 2012
網站上線前測試項目
javascript測試事項
unit test測試事項
get reals一書提到...
- 是否支援json
}//檢查json是否存在 if (typeof (JSON) == 'undefined') { //沒有 JSON 時才讓 browser 下載 json2.js $('head').append($("<script src="json2.js" type="text/javascript"> ));
- 兼容性测试
不同browser都要試一下
unit test測試事項
- 邊界值及最大、最小值
get reals一書提到...
對於每一個新功能你需要……
- 1. 對它說不
- 2. 強迫它證明自己的價值
- 3. 如果得到否定的答案,就此打住。如果是yes,繼續往下……
- 4. 為界面繪製草圖
- 5. 設計界面
- 6. 編寫代碼
- 7-15. 測試,改進,測試,改進,測試,改進,測試,改進……
- 16. 檢查幫助文字是否需要修改
- 17. 更新產品預覽流程(如果有必要的話)
- 18. 更新用於銷售的拷貝(如果有必要的話)
- 19. 更新服務條款(如果有必要的話)
- 20. 檢查是否違背之前的任何許諾
- 21. 檢查價格體系是否受影響
- 22. 上線
- 23. 深吸一口氣
星期六, 3月 17, 2012
firefox同步
這實在太強大了...
之前有擴充套件(add-on)可以同步記錄書籤
但現在firefox自己出了"選項/同步",只能記錄書籤已經不夠看了
試用了一下,真的是太棒了
除了書籤外,最重要的是每次換台新電腦就得要重安裝套件
居然連這也能同步,太強了... 我要按個讚
後記...
firefox不知為何在2012.7常當掉
發現是在輸入項(input)時,很容易掛
因為太頻繁了,所以只好先改用chrome
用完Chrome後...
好吧... 我改用Chrome了
因為browser是綁gmail帳號
chrome就自動把書籤、autocompleted都同步了...
firefox強項剩firebug...
之前有擴充套件(add-on)可以同步記錄書籤
但現在firefox自己出了"選項/同步",只能記錄書籤已經不夠看了
試用了一下,真的是太棒了
除了書籤外,最重要的是每次換台新電腦就得要重安裝套件
居然連這也能同步,太強了... 我要按個讚
後記...
firefox不知為何在2012.7常當掉
發現是在輸入項(input)時,很容易掛
因為太頻繁了,所以只好先改用chrome
用完Chrome後...
好吧... 我改用Chrome了
因為browser是綁gmail帳號
chrome就自動把書籤、autocompleted都同步了...
firefox強項剩firebug...
星期五, 3月 09, 2012
linux prompt
- 設置檔
- 全users
/etc/profile or /etc/bashrc
- 個別user
~/.bash_profile , ~/.bash_login , ~/.profile , ~/.bashrc or ~/.bash_logout
- 全users
- 客製化prompt
PS1='[\u@\h \w] \$ # ' #即為user@host ~
PS1="\e[\u@\h \w]$ \e]" #即為[user@host ~]
加框'[', ']',由於是key words所以要加\e
而0;32m 是指顏色,其他以此類推應該就看的出來了
- 加上顏色
PS1="\e[0;32m[\u@\h \w]\e]$ \e[m]" #即為[user@host ~]
- 啟使
source .bashrc
or
. .bashrc - Changing foreground and background bash prompt colors
Syntax for changing colors in the bash is as follows:
\033[ -> Indicates the beginning of color in the text x;yzm - Indicates color code \033[00m - Indicates the end of color in the text
截錄常用的字元代表意思
| Bash special character | Bash special character explanation | Bash special character | Bash special character explanation |
|---|---|---|---|
| \] | end a sequence of non-printing characters | \[ | begin a sequence of non-printing characters, which could be used to embed a terminal control sequence into the prompt |
| \h | the hostname up to the first `.' | \H | the hostname |
| \s | the name of the shell, the basename of $0 (the portion following the final slash) | \l | the basename of the shell's terminal device name |
| \$ | if the effective UID is 0, a #, otherwise a $ | \u | the username of the current user |
| \w | the current working directory | \W | the basename of the current working directory |
| \D{format} | the format is passed to strftime(3) and the result is inserted into the prompt string; an empty format results in a locale-specific time representation. The braces are required | ||
個人配置檔
#prompt
if [ $TERM = 'xterm' ]
then
PS1='\e[0;32m[\[\033[02;32m\]\u@\h\[\033[01;34m\] \w\e[0;32m]\$\e[m '
else
PS1='[\u@\h \w] \$ # '
fi
# colorful man page
export PAGER="`which less` -s"
export BROWSER="$PAGER"
export LESS_TERMCAP_mb=$'\E[01;36m'
export LESS_TERMCAP_md=$'\E[01;36m'
export LESS_TERMCAP_me=$'\E[0m'
export LESS_TERMCAP_se=$'\E[0m'
export LESS_TERMCAP_so=$'\E[01;44;33m'
export LESS_TERMCAP_ue=$'\E[0m'
export LESS_TERMCAP_us=$'\E[01;33m'
References
Bash prompt basics
星期二, 3月 06, 2012
FirePHP no message in FireBug console
忘記更新了什麼東西,結果FirePHP居然沒反應了
goolge了一下,也有人遇到,印象中是更新了FirePHP的套件就解決了
而最近公司更換網域,環境也跟著改變
重新安裝FireBug及FirePHP後,居然又沒反應了
又找不到原本解決的網頁,真是快瘋了
後來注意到firefox有個提醒列
提到要"enable Net Panel ..."
才去開放script及net panel,如下圖
才知道FirePHP需要開啟net panel才能動....
goolge了一下,也有人遇到,印象中是更新了FirePHP的套件就解決了
而最近公司更換網域,環境也跟著改變
重新安裝FireBug及FirePHP後,居然又沒反應了
又找不到原本解決的網頁,真是快瘋了
後來注意到firefox有個提醒列
提到要"enable Net Panel ..."
才去開放script及net panel,如下圖
才知道FirePHP需要開啟net panel才能動....
星期四, 2月 23, 2012
What is my IP? (Public IP address)
Using wget
Using curl
Using Lynx
Reference
Linux command: What is my IP? (Public IP address)
wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'
curl -s checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//' curl -s http://whatismyip.org/
lynx -dump checkip.dyndns.org lynx -dump www.whatismyip.com | grep 'Your IP'
星期二, 2月 21, 2012
mysql grant
最近一個案子要連到廠商的db讀資料
不過不知卡在什麼地方,一直沒辦法連到db
後來想到是mysql沒開遠端連線的權限,想透過phpmyadmin去開
但是限制一堆,只能用ssh進mysql server下指令...
用慣了phpmyadmin.... 要用指令下授權...ㄟ... grant all db.... 什麼.... 放棄
下select就算了,下授權... 不知多久才用一次的東西...google一下吧..
不過不知卡在什麼地方,一直沒辦法連到db
後來想到是mysql沒開遠端連線的權限,想透過phpmyadmin去開
但是限制一堆,只能用ssh進mysql server下指令...
用慣了phpmyadmin.... 要用指令下授權...ㄟ... grant all db.... 什麼.... 放棄
下select就算了,下授權... 不知多久才用一次的東西...google一下吧..
- 先連db囉
$ mysql -u root -p - 查詢 某 User 的權限
這樣就可以知道該User是否有從某ip連db的權限
mysql> select User,Host from mysql.user;
+------+---------------------------+
| User | Host |
+------+---------------------------+
| root | localhost |
+------+---------------------------+
1 rows in set (0.00 sec)
- add SELECT,INSERT privileges to a user using GRANT
上例中,root未開放192.168.0.1的連線
這裡假設開放root(密碼:ok1234)可從192.168.0.1連線db_base下的所有table(利用*來代表所有的table)的權限
GRANT SELECT,INSERT ON db_base.* TO root@192.168.0.1 IDENTIFIED BY 'ok1234';
git增減remote及fetch and pull branch
- 增加一個remote
//增加一個在github的remote git remote add github https://github.com/username/Hello-World.git //origin也視成一個remote,所以一樣的方法,只是叫origin git remote add origin https://github.com/username/Hello-World.git
當origin或remote有local沒有的branhc要如何抓下來
- 自己的
#git branch * master
- Origin或remote的
#git branch check * master
- 利用fetch抓回來
#git fetch origin check:check
星期五, 2月 10, 2012
ie中session遺失問題
先前寫個cross site的程式給廠商呼叫
結果最近在說只有ie會掛,firefox, chrome都通過
一試之下,還真的同事的全掛,最有趣的是我的ie卻能過
且我ie 7,8,9全試了,都可以,為什麼.. 還沒查出來
因為ie不能看iframe裡的內容,而自己的電腦又不會有問題
只能請同事看,查到快起肖了
最後發現是session值會不見
看到有人提到session的useragent不同,而ci裡的config會比對,只要關掉即可
可是還是失敗,總之查了半天,突然看到P3P的字眼...
才想到以前也有遇到ie跨網域取不到相關值的問題,加上後就解決了
friday night加班到9點...更~~~~~~~~~~~~
網上有人整理好了
References
結果最近在說只有ie會掛,firefox, chrome都通過
一試之下,還真的同事的全掛,最有趣的是我的ie卻能過
且我ie 7,8,9全試了,都可以,為什麼.. 還沒查出來
因為ie不能看iframe裡的內容,而自己的電腦又不會有問題
只能請同事看,查到快起肖了
最後發現是session值會不見
看到有人提到session的useragent不同,而ci裡的config會比對,只要關掉即可
可是還是失敗,總之查了半天,突然看到P3P的字眼...
才想到以前也有遇到ie跨網域取不到相關值的問題,加上後就解決了
friday night加班到9點...更~~~~~~~~~~~~
網上有人整理好了
- How to set p3p http header in ASP.Net?
HttpContext.Current.Response.AddHeader("p3p", "CP=\""IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""") - How to set p3p http header in PHP?
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); - How to set p3p http header in JSP?
response.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'") - How to set p3p http header in ColdFusion?
<cfheader name="P3P" value="CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'">
References
星期四, 2月 09, 2012
利用 php 本身寫 error log 及 error/warning/notice message
- error_reporting
設定php回發生錯誤的等級
error_reporting(0); // Turn off all error reporting ini_set('error_reporting', E_ALL); // Same as error_reporting(E_ALL); - error_log
bool error_log ( string $message [, int $message_type = 0 [, string $destination [, string $extra_headers ]]] )
Sends an error message to the web server's error log or to a file.
需寫入file,因此需指定file path
用法
//log to file ini_set('error_log', dirname(__FILE__) . '/error_log.txt'); // Send notification through the server log if we can not // connect to the database. if (!Ora_Logon($username, $password)) { error_log("Oracle database not available!", 0); } // Notify administrator by email if we run out of FOO if (!($foo = allocate_new_foo())) { error_log("Big trouble, we're all out of FOOs!", 1, "operator@example.com"); } // another way to call error_log(): error_log("You messed up!", 3, "/var/tmp/my-errors.log"); - error/warning/notice message
定義log level多配合log4php,不過也可透過trigger_error
即可靠php本身達成此效果
如此就不用再掛log4php,就能方便帶訊息trigger_error("Notice Message",E_USER_NOTICE); trigger_error("Warning Message",E_USER_WARNING); trigger_error("Error Message",E_USER_ERROR);
如果想利用此機制寫自定的訊息就可透過trigger_error
而error_log就自己想log什麼就log什麼
error_report設定篇
開啟是否顯示error及log的等級
- 在php.ini中設定
display_errors = On
- 在.php中設定
每次要到php.ini設定就太累了,這邊有方法可以直接在.php裡,直接設定log,這樣開發起來就方便多了,且不會動到整體環境
ini_set('display_errors', 1); //turn on display error on screen ini_set('log_errors', 1); //turn on log error error_reporting(E_ALL); //log all errors and warnings
常見常數定義
列出常見的幾個,其他看官網Predefined Constants
| Constant | Description | Note |
|---|---|---|
| E_NOTICE | Run-time notices. Indicate that the script encountered something that could indicate an error, but could also happen in the normal course of running a script. | |
| E_STRICT | Enable to have PHP suggest changes to your code which will ensure the best interoperability and forward compatibility of your code. | Since PHP 5 but not included in E_ALL until PHP 5.4.0 |
| E_ALL | All errors and warnings, as supported, except of level E_STRICT prior to PHP 5.4.0. |
References
星期日, 1月 29, 2012
亂數order id
最近在寫銷售系統,由於會把order id給客戶,主管反應這樣會被會看出銷售量,所以要改成亂數,避免競爭對手等看出銷售數量。
研究了半天,自己用padding、加亂數的方法似乎還是會被察覺,google後,覺得還是用加密比較簡單
Four ways to generate unique id by PHP
How to generate Unique Order Id (just to show touser) with actual Order Id?
研究了半天,自己用padding、加亂數的方法似乎還是會被察覺,google後,覺得還是用加密比較簡單
- two way encryption
先下載加密法encryption_class.php
在encryption_class.php裡,有以下兩行
此加密法是簡單的利用代換字母做加密,記得叫Caesar Cipher什麼的,主要利用自己的key,去對應scramble相同字母的位置$this->scramble1 = '! #$%&()*+,-./0123456789:;>=<?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~'; $this->scramble2 = 'f^jAE]okIOzU[2&q1{3`h5w_794p@6s8?BgP<dFV=m D>TcS%Ze|r:lGK/uCy.Jx)HiQ!#$~(;Lt-R}Ma,NvW+Ynb*0X';
當然這樣1對1的對應,很容易就被破,所以裡面的function _applyFudgeFactor(),就是在每次計算代換字母就偏移順序
利用scramble1把key轉換成順序,每次再偏移位置,從scramble2取出該字母當祕文
- 產生加密後的order id
結果如下<?php include 'encryption_class.php'; $crypt = new encryption_class(); $key = "A-COMPLETELY-RANDOM-KEY-THAT-I-HAVE-USED"; // Min length of 8 for encrypted string $min_length = 8; $order_id = 123456789; print "Original: " . $order_id . PHP_EOL; $encrypt_result = $crypt->encrypt($key, $order_id, $min_length); print "Encrypted: " . $encrypt_result . PHP_EOL; // DECRYPT $decrypt_result = $crypt->decrypt($key, $encrypt_result); print "Decrypted: " . $decrypt_result . PHP_EOL; ?>
Original: 123456789
Encrypted: 2UD5UIK9S
Decrypted: 123456789
- 以數字實作
不過問題又來了,因為order id用integer,所以要求全是數字
- 轉ascii code
就直接全轉3位數的ascii code
$numeric_cipher=''; for($i=0;$i<strlen($decrypt_result);$i++){ $numeric_cipher .= str_pad(ord(substr($decrypt_result,$i,1)),3,'0',STR_PAD_LEFT); //不到3碼,左邊補0至3碼 }
不過實在太長了,5位數就要長到15個數字
所以ascii百位數後全不用,即d(100),e(101),...
這樣padding就只要2位,這樣5位數也只要10個數字 - 還嫌太長!?最終極版大絕!!!
由於key是對應scremble的排序...
把key跟scremble都只放數字,這樣............ 應該夠短了吧...
就是有點容易猜...不過一時間內應該也夠用了
order id太長,將來要查也不好查
- 改encryption_class.php
//把scramble改成如下,不要重覆,順序可亂擺,不要一樣就好 $this->scramble1 = '0123456789'; $this->scramble2 = '2135794680';
- 改key值
因為要對應scramble,所以key有什麼值,scramble就要有什麼值,否則對應不到
至於密文min length長度,當超過明文長度時,預設是在字串後方補上空格
但因為得全為數字,所以scramble沒有空格,造成空格對應不到,因此不能超過order id的長度
//key可隨意變化,但key的值一定要出現在scramble裡 $key='1234534567890'; $key='11223344'; $key='68490'; $min_length = strlen($order_id); //因為1對1,所以不能超過order id的長度
這就可以看出來,當key、scramble、偏移量相同,位於前面的字母相同時,代碼都會相同,變化不夠大,忘了那資安的名詞叫什麼,意思是當原文變化不大時,密文的變化仍要夠大,如md5等Original Encrypted Decrypted 1 5 1 7 0 11 50 11 99 19 99 100 583 100 101 585 101 110 505 110 111 507 111
因為可變化的太少了,不過應該算堪用了
另外還有兩個問題
- original為7時,沒辦法反解
原作者在decrypt用empty,所以遇到0會當false,改!isset即可
相同的,當encrypt 0時,也會當成false,也需要改成!isset - decrypt result為0xx
雖是正常,不過ordre id用integer,這個0就會不見,到時會解不回去
由於是全數字,又密文長度不能超過明文長度,實在容易被猜出來
那如何超過明文長度咧...
解法:不補空格,補0,在明文字串前方補足0,由於integer前面有0,也是當成0,所以沒差
ex. $id = 50; $min_length = 4;
$id = '0050'; // 補2個0,足4位
在encryption_class.php裡
function encrypt(){ ... //$source = str_pad($source, $sourcelen); //原作法 $source = str_pad($source, $sourcelen, '0', STR_PAD_LEFT); //新的作法 ...
- 改encryption_class.php
- 轉ascii code
Four ways to generate unique id by PHP
How to generate Unique Order Id (just to show touser) with actual Order Id?
星期四, 1月 19, 2012
該死的ie form
在html包form實在是在平常不過的事了
在firefox, chrome都跑的好好的
沒想到ie跑版,馬上開F12來看一下
天殺的那是在iframe裡... 要到該網頁又要帶參數....好想殺人
查了半天的css實是看不出原因
亂搬了一下form,居然有變化了
最後把margin設為0... 更.. 好了....
同事事後也說,他也遇過,說這form實在很奧妙....
忘了是ie什麼版本影響了... 總之先記下來
ie我恨你...
在firefox, chrome都跑的好好的
沒想到ie跑版,馬上開F12來看一下
天殺的那是在iframe裡... 要到該網頁又要帶參數....好想殺人
查了半天的css實是看不出原因
亂搬了一下form,居然有變化了
最後把margin設為0... 更.. 好了....
同事事後也說,他也遇過,說這form實在很奧妙....
忘了是ie什麼版本影響了... 總之先記下來
ie我恨你...
星期日, 1月 15, 2012
PHP5.3, CentOS,裝Oci8, pdo_oci8
沒連過oracle,一開始要用還真搞不太懂
載了2個檔案,共2G回來,還是不會用
最後看只需載個client的basic,供oci連線即可
看完網路一裝教學,還是裝不起來,在交叉比對下,終於成功了~~~
os: CentOS 6.4
php: 5.3
download Instant Client Downloads
自己的環境是linux 64bit, 所以載了 Instant Client for Linux x86-64
後來發現php5.3已經有了,所以不用裝了
載了2個檔案,共2G回來,還是不會用
最後看只需載個client的basic,供oci連線即可
看完網路一裝教學,還是裝不起來,在交叉比對下,終於成功了~~~
os: CentOS 6.4
php: 5.3
download Instant Client Downloads
自己的環境是linux 64bit, 所以載了 Instant Client for Linux x86-64
- Install oracle instant client
- oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
- oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
- oracle-instantclient11.2-sdk-11.2.0.1.0-1.x86_64.zip
# rpm -ivh oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm # rpm -ivh oracle-instantclient11.2-devel-11.2.0.3.0-1.x86_64.rpm
- 設定ORACLE_HOME
設定ORACLE_HOME的提示真是讓我暈倒,說要指到lib
設好了,但在install oci時,會掛,最後試出只要到"HOME"就好了
看下面設定 vi /etc/profile
export ORACLE_HOME=/usr/lib/oracle/11.2/client64 export ORACLE_OWNER=oracle export ORACLE_SID=ora1 export LD_LIBRARY_PATH=$ORACLE_HOME/lib export PATH=$ORACLE_HOME/bin:$PATH export TNS_ADMIN=$ORACLE_HOME/network/admin export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"
啟動環境變數
source /etc/profile
- 解壓sdk並把裡面的sdk裡的資料複製到/usr/include
# unzip oracle-instantclient11.2-sdk-11.2.0.1.0-1.x86_64.zip # cp -fr instantclient_11_2/sdk/include/* /usr/include
- install oci
Installing OCI8 from PECL
- Use 'pecl install oci8' to install for PHP 8.
- Use 'pecl install oci8-2.2.0' to install for PHP 7.
- Use 'pecl install oci8-2.0.12' to install for PHP 5.2 - PHP 5.6.
- Use 'pecl install oci8-1.4.10' to install for PHP 4.3.9 - PHP 5.1.
- 設定php.ini
vi /etc/php.ini , add the line extension=oci8.so
再重開apache即可
# service httpd restart
這時下php -m 就會看到oci8了~ 開心 - 測試
<?php $option = array( 'ip' => '10.0.3.20', 'port' => '15210', 'account' => 'web', 'password' => 'FEF00CB', 'service_name' => 'WXS4' ); $db = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={$option['ip']})(PORT={$option['port']}))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={$option['service_name']})))"; if(function_exists('ocilogon')){ $c1 = ocilogon($option['account'],$option['password'],$db) or die('OCI Connect error, wrong connection string'); echo 'OCI Connect pass. yes!!!'; }else{ echo 'ocilogon not exists, installment is not correct'; }
p.s. 基本上裝最新版即可,它有向下相融
就這麼簡單,過程會要求輸入ORACLE_HOME的位置,如果第3步有做的話,就按enter即可 如果找不到pecl,就先安裝pear
-
yum install php-pear
#如果找不到的話,就先增加repository
rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm
yum --enablerepo=webtatic install php-pear
後來發現php5.3已經有了,所以不用裝了
全手動安裝
在公司封閉的網路,只能手動安裝可以參考這篇 PHP 5.3 連線 Oracle 的客戶端及 PDO_OCI 模組安裝
issue
- pdo_oci unsupported oracle version
由於oracle instantclient可能出了新版,而pdo_oci未更新,可以直接改pdo_oci/config.m4 ,自己加上要的版本,search 一下unsupported version字眼,就可以找到,詳細可參考這篇
p.s. 改完記得要先phpize --clean,不然configure的內容不會生效哦!!!
星期三, 1月 11, 2012
教授比較強!?
以前唸專科時,學校裡有教授頭術及碩士畢業的講師
曾經有個交大畢業的碩士講師跟我說過
有些學生比較看不起講師,覺得教授等級才夠看
專科時期,算是個人進入資訊領域的起萌期
老師個人當然還是有強弱,不過都覺得可學習的滿多的
也沒有感覺有沒有教授的頭銜有什麼差別
後來進了大學
老師都至少助理教授以上等級,且大多為40多歲以上
且教授等級的老師在業界或學術界都頗具名氣
聽課時,就真的覺得有差,除了講義上的東西,還可以講的更深入
一些理論的東西,也能講的比較活,感覺比較實用
有位教授說了句玩笑話:「教授就是專門把簡單的東西教的很難。」
原本只是會心一笑,後來才體會到,教授已經多年研究這領域,且每年都重複教這東西,已經成精了,而我們這些小毛頭,一時要聽懂,真的不是件容易的事。
所以...
碩士畢業的講師不敢說弱
只能說教授真的滿強的...
曾經有個交大畢業的碩士講師跟我說過
有些學生比較看不起講師,覺得教授等級才夠看
專科時期,算是個人進入資訊領域的起萌期
老師個人當然還是有強弱,不過都覺得可學習的滿多的
也沒有感覺有沒有教授的頭銜有什麼差別
後來進了大學
老師都至少助理教授以上等級,且大多為40多歲以上
且教授等級的老師在業界或學術界都頗具名氣
聽課時,就真的覺得有差,除了講義上的東西,還可以講的更深入
一些理論的東西,也能講的比較活,感覺比較實用
有位教授說了句玩笑話:「教授就是專門把簡單的東西教的很難。」
原本只是會心一笑,後來才體會到,教授已經多年研究這領域,且每年都重複教這東西,已經成精了,而我們這些小毛頭,一時要聽懂,真的不是件容易的事。
所以...
碩士畢業的講師不敢說弱
只能說教授真的滿強的...
星期六, 1月 07, 2012
tmux改 screen 256 color
改了tmux的設定後,發現顏色沒有改
查了一下,知道可用tput color來看
只有8色,不支援256
可在config裡給screen-256color
set -g default-terminal "screen-256color"
不過開vim時,卻發生Terminal entry not found in terminfo 'screen-256color' not known
所以讀預色的ansi
搞的vim都沒顏色了,而且很多vim指令不能下
又看了一下要用
export TERM=screen-256color
不改還好,一改連tmux也進不去
出現 missing or unsuitable terminal: screen-256color
想改回去 已經不知原本的值了
幸好另一台server也有灌,看了原來本的設定是
TERM=screen
改回來就進tmux了
結論...
還是沒顏色... 有改回來就偷笑了
不過應該centos 沒有screen-256color這東西
想辦法搞定,應該就能work了
References
星期四, 1月 05, 2012
ci取db錯誤
codeigniget在db出錯時,會自行印出錯誤訊息,如果要關掉有兩種方法
因為不管關不關錯誤訊息try-catch都抓不到
所以如要判斷中斷程式得利用affected row
ci論談已經有人寫好function,可配合暫時關掉錯誤訊息,中斷和印出錯誤訊息
Reference
- config/database.php設定
$db['default']['db_debug'] = TRUE;
- 程式裡設定
$this->db->db_debug = false;
$this->db->_error_message();
所以如要判斷中斷程式得利用affected row
ci論談已經有人寫好function,可配合暫時關掉錯誤訊息,中斷和印出錯誤訊息
function insert_quiet($table = ‘’, $set = NULL)
{
$oldv =$this->db_debug;
$this->db_debug = false;
$this->insert($table, $set);
$e = $this->_error_message();
$aff = $this->affected_rows();
$this->db_debug = $oldv;
if($aff < 1) {
return($e);
} else {
return(true);
}
}
星期四, 12月 22, 2011
轉:Setting up an SSL secured Webserver with CentOS
在apache裡建https就這麼簡單...
Reference
- Getting the required software
yum install mod_ssl openssl
- Generate a self-signed certificate
# Generate private key openssl genrsa -out ca.key 1024 # Generate CSR openssl req -new -key ca.key -out ca.csr # Generate Self Signed Key openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt # Copy the files to the correct locations cp ca.crt /etc/pki/tls/certs cp ca.key /etc/pki/tls/private/ca.key cp ca.csr /etc/pki/tls/private/ca.csr
- Setting up the virtual hosts
#vim /etc/httpd/conf.d/ssl.conf ----------------------------- #將<virtualhost>裡的內容修改為以下... <virtualhost *:443> SSLEngine on SSLCertificateFile /etc/pki/tls/certs/ca.crt SSLCertificateKeyFile /etc/pki/tls/private/ca.key <Directory /var/www/vhosts/yoursite.com/httpsdocs> AllowOverride All </Directory> DocumentRoot /var/www/vhosts/yoursite.com/httpsdocs ServerName yoursite.com </VirtualHost> - Configuring the firewall
yum install mod_ssl openssl
Reference
星期五, 12月 16, 2011
mysql存日期該用什麼data type
mysql存日期的data type有好幾種type,用int存秒數也是一種
一直很猶疑要用哪一種,想法是byte越少越好
所以整理了一下
所以我想... 利用INT存比較快吧...
created date就用int來存秒數,轉換日期就利用FROM_UNIXTIME(seconds)
last updated date就用timestamp來存,反正一樣大,而且會自動更新
References
一直很猶疑要用哪一種,想法是byte越少越好
所以整理了一下
| Type | Storage(Bytes) | Minimum Value(Signed/Unsigned) | Maximum Value(Signed/Unsigned) |
|---|---|---|---|
| DATE | 3 bytes | ||
| TIME | 3 bytes | ||
| DATETIME | 8 bytes | ||
| TIMESTAMP | 4 bytes | ||
| YEAR | 1 bytes | ||
| INT | 4 | -2147483648 | 2147483647 |
所以我想... 利用INT存比較快吧...
created date就用int來存秒數,轉換日期就利用FROM_UNIXTIME(seconds)
last updated date就用timestamp來存,反正一樣大,而且會自動更新
References
星期四, 12月 15, 2011
active record使用memcached
一直用sql當memcached的key跑的順順的
不過最近在用ci在開發,發現用的active record不知抓什麼來當key
研究了一下,發現有last_query()可取出sql string
不過又看了一下發現是先execute後,才會有的query
而cache當然是要跑之前做,不然就沒有意義了
又serach了一下,發現有_compile_select()
差別當然在有執行跟沒執行,以下是片斷程式碼
有引用tomschlick寫好給ci用的memcached-library
不過每個有用db的程式這樣寫太麻煩了
原本想改寫ci的db driver,看起來有點麻煩,先求有吧
所以先簡單的寫在helper裡,有空再來研究改寫driver
References
Getting CodeIgniter Active Record's current SQL code
不過最近在用ci在開發,發現用的active record不知抓什麼來當key
研究了一下,發現有last_query()可取出sql string
不過又看了一下發現是先execute後,才會有的query
而cache當然是要跑之前做,不然就沒有意義了
又serach了一下,發現有_compile_select()
差別當然在有執行跟沒執行,以下是片斷程式碼
有引用tomschlick寫好給ci用的memcached-library
$key = $this->db->_compile_select();
$this->load->library('Memcached_library','','memcached');
$results = $this->memcached->get($key);
// If the key does not exist it could mean the key was never set or expired
if ($results)
echo 'hit';
else{
echo 'miss';
$results = $this->db->get()->row_array();
$this->memcached->add($key, $results);
}
原本想改寫ci的db driver,看起來有點麻煩,先求有吧
所以先簡單的寫在helper裡,有空再來研究改寫driver
_compile_select());
$ci = & get_instance();
$ci->load->library('Memcached_library','','memcached');
$results = $ci->memcached->get($key);
// If the key does not exist it could mean the key was never set or expired
if ($results) {
$ci->fb->info('[memcache] hit', "info");
}else{
$ci->fb->warn('[memcache] miss', "memcached");
$results = $db->get()->row_array();
$ci->memcached->add($key, $results);
}
$db->_reset_select(); //clear sql query string
return $results;
}
星期一, 12月 12, 2011
檢查遠端的檔案是否存在
這方法還不錯,只回傳header,不看body
Reference
function remoteFileExists($url) {
$curl = curl_init($url);
//don't fetch the actual page, you only want to check the connection is ok
curl_setopt($curl, CURLOPT_NOBODY, true);
//do request
$result = curl_exec($curl);
$ret = false;
//if request did not fail
if ($result !== false) {
//if request was ok, check response code
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($statusCode == 200) {
$ret = true;
}
}
curl_close($curl);
return $ret;
}
$exists = remoteFileExists('http://stackoverflow.com/favicon.ico');
if ($exists) {
echo 'file exists';
} else {
echo 'file does not exist';
}
星期二, 12月 06, 2011
CodeIgniter - db active record常用指令
- basic
- 取得config中,名為group_one的db
$DB1 = $this->load->database('group_one', TRUE); //給true才會產生實體給$DB1 $this->db->select('title')->from('mytable')->where('id', $id)->limit(10, 20);p.s. 給true才會回傳個db object - 取sql string
- last_query()
執行的過程中,最後的一個sql query string - _compile_select()
目前sql條件的sql query string,尚未實際執行
- last_query()
- 取得config中,名為group_one的db
- select
$this->db->select('title, content, date'); //不下的話就是* $query = $this->db->get('mytable'); foreach ($query->result() as $row) { echo $row->title; } - from、join
$this->db->from('mytable');$this->db->select('*'); $this->db->from('blogs'); $this->db->join('comments', 'comments.id = blogs.id'); $query = $this->db->get(); // Produces: // SELECT * FROM blogs // JOIN comments ON comments.id = blogs.id - where
//法1. $query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset); $this->db->or_where('id >', $id); // Produces: WHERE name != 'Joe' OR id > 50 //法2 $this->db->select('title')->from('mytable')->where('id', $id); - insert 新增欄位為now()的方法
$data = array (
'customer_id'=> $customer_id,
'total' => $totalprice
);
$this->db->set('order_date', 'NOW()', FALSE);
$this->db->insert('omc_orders', $data);Reference
星期四, 12月 01, 2011
FirePHP
FireBug用久了,做php時,也很想要有這樣的好物
用過之後,覺得真的是超~~~~~~~~~~~~~~方便.......感動到想哭...
不過其他如ie要查時就... 無言了...
除了直接跟php搭外
還可以跟php的framework搭
[PHP] 好用 Debug PHP 工具 FirePHP for FireFox on CodeIgniter
這篇教學很完整,不再複製貼上了
讓config可以控制要不要輸出log
References
用過之後,覺得真的是超~~~~~~~~~~~~~~方便.......感動到想哭...
不過其他如ie要查時就... 無言了...
除了直接跟php搭外
還可以跟php的framework搭
[PHP] 好用 Debug PHP 工具 FirePHP for FireFox on CodeIgniter
這篇教學很完整,不再複製貼上了
- CodeIgniter
- Zend
require_once('Zend/Log.php'); require_once('Zend/Log/Writer/Firebug.php'); $writer = new Zend_Log_Writer_Firebug(); $logger = new Zend_Log($writer); $logger->info('info message'); $logger->warn('warning message'); $logger->err('error message');
讓config可以控制要不要輸出log
- 配置config文件
在application/config/目录下找到config.php,增加如下一行内容:
$config['enable_firephp'] = true;
- libraries/firephp.php文件
$CI = & get_instance(); if($CI->config->item('enable_firephp')) define('ENABLE_FIREPHP', true); else define('ENABLE_FIREPHP', false); - 每個class裡,使用firephp
$this->fb->setEnabled(ENABLE_FIREPHP); $logger->info('info message');
References
星期五, 11月 25, 2011
書:Working Effectively With Legacy Code
一直對TDD很猶豫... 讀完後,決定好好的寫TDD了...
不想要再為了改個地方,而怕東怕西... 決定用這個可以放輕鬆的開發方法..
待續...
不想要再為了改個地方,而怕東怕西... 決定用這個可以放輕鬆的開發方法..
- What is legacy code
legacy code與non-legacy code的差別 - "test"
接手的人不敢亂改,但如果有test機制,就能夠一步步修改維護 - Test Coverings
將程式佈滿測試,就不會害怕去改變他 - Legacy Management Streategy
- Identify change points
- Find an inflection point
- Cover the inflection point a.
- Break external dependencies
作者舉在testing時,重視測試結果,而常綁死gui的實作,造成testing不易
作者寫了CustomerView的interface,當測試時,就可在不改變結構下,丟空的實作做測試,有mock的感覺 - Break internal dependencies
在測試時是不必要的地方(如產生暫存等),就繼承該class,直接orverriding掉,不要做任何事即可,有stub的感覺 - Write tests
- Make changes
- Refactor the covered code.
待續...
星期五, 11月 18, 2011
星期四, 11月 10, 2011
linux切換多重視窗 - tmux
用pietty開發時,經常需要連到其他servers
懶得再開一個pietty,直接用ssh連線做完後,又得要exit掉,回到原本的環境
如果忘了做件事,又要再重連一次,指令密碼一直下,路徑也要一直切
環境一直切換覺得挺煩的,但再開一個pietty來做,切換視窗也是切到暈,常切到不知自己在哪...
今天同事也遇到以上問題,問我知不知道怎麼切換連線
說他有看過,但他不會...
這才一語驚醒夢中人... 對呀!!! 這東西應該有人有做出什麼神奇的工具
我怎麼都沒想過,即然同事都說有看過了,就jfgi了一下...
結果出現screen及tmux這好東西... 試用了一下,真是太感動了
個人覺得最方便的功能如下:
懶得再開一個pietty,直接用ssh連線做完後,又得要exit掉,回到原本的環境
如果忘了做件事,又要再重連一次,指令密碼一直下,路徑也要一直切
環境一直切換覺得挺煩的,但再開一個pietty來做,切換視窗也是切到暈,常切到不知自己在哪...
今天同事也遇到以上問題,問我知不知道怎麼切換連線
說他有看過,但他不會...
這才一語驚醒夢中人... 對呀!!! 這東西應該有人有做出什麼神奇的工具
我怎麼都沒想過,即然同事都說有看過了,就jfgi了一下...
結果出現screen及tmux這好東西... 試用了一下,真是太感動了
個人覺得最方便的功能如下:
- 同一個pietty連線,可以使用多個windows
有點像是用本機登入linux,用F1,F2... 就可以切換多重視窗
而且可以自定內部視窗的名字,這樣開再多也不怕
- 視窗保留
離開tmux後(tmux detach),再下tmux attach能夠保留上一次所有開啟的視窗連線狀態(session)。例如用vim開發常會開好幾個分頁,離開時要全關,下次再一一打開,有時只是離開一下座位,開著編輯畫面總覺得怪怪的,利用視窗保留就能不離開vim或當時的環境,等要用時再取回,這真是太酷了...
而且能夠開多個session,保留不同的開發環境 - 保留開發環境(多重seesions)
個人是習慣每個專案即建相關的session,而該session下就是該專案相關的開發環境
如此一來,切換專案時,所有的環境(該seesion下的windows)都保留著,在切換專案時,也不用花太多時間回想環境
- install tmux
如果找不到套件,先加入epel的repo# yum install tmux
Reference: Install EPEL Repo CentOS RHELInstall EPEL Repository On 32-bit CentOS Linux 5.5: # rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm Install EPEL Repository On 64-bit CentOS Linux 5.5: # rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
- 啟動tmux
畫面如下圖所示# tmux

重點在1.session 及2.window
把每一個session看成獨立一個連線
而每個session都可如上圖有多個windows
因此seesion 1 為project A,再對project A開啟多個windows
而session 2 即為project B, 再對project B開啟多個windows
- tmux指令(啟動tmux環境)
- 取回視窗
$ tmux attach $ tmux attach -t session-id //指定特定seesion
- 列出所有sessions
$tmux ls
- 更改session名
或者直接下function key + $$ tmux rename-session -t session1 session2 //把session1改成session2
- 取回視窗
- tmux視窗指令 ()
- Ctrl-b c Create new window
- Ctrl-b d Detach current client
- Ctrl-b l Move to previously selected window
- Ctrl-b n Move to the next window
- Ctrl-b p Move to the previous window
- Ctrl-b & Kill the current window
- Ctrl-b $ Rename the current session
- Ctrl-b , Rename the current window
- Ctrl-b % Split the current window into two panes
- Ctrl-b ? List all keybindings
- Ctrl-b s 切換session,如下圖,列出所有sessions,再選擇要切換的
- 分割 / 切割視窗 (切出來的叫pane)
- Ctrl-b q Show pane numbers
- Ctrl-b alt按著,再按上下左右, 可以調整視窗大小
- Ctrl-b % 直切
- Ctrl-b :"split-window" 橫切
- Ctrl-b Ctrl-o 調換 切割視窗 的 位置
- Ctrl-b o Switch to the next pane
- Ctrl-b 上下左右 跳到上下左右的分割視窗
- Ctrl-b ! 將目前的pane抽成window
- Ctrl-b x 移除目前的pane
- 自定key組合
切割視窗還是先設好key,不然還真不好用,以下是個人參考網路上的設定
把預設的Ctrl-b改為Ctrl-a,手比較不會抽筋...
# vi ~/.tmux.conf
設好後,重啟config# General configuration. # $ tmux show-options -g set -g base-index 1 set -g display-time 5000 set -g repeat-time 1000 set -g status-keys vi set -g status-utf8 on set -g status-bg black set -g status-fg white set -g status-justify left set -g status-interval 1 set -g status-left-length 15 set -g status-right-length 55 set -g status-left "#[fg=white,bright] #[fg=yellow,bright]#S #[default] |" # session-name set -g status-right "#[fg=red,bright][ #[fg=cyan]#(git branch --no-color | sed -e '/^[^*]/d' -e 's/* //') #[fg=red]]#[default] #[fg=yellow,bright] %Y-%m-%d #[fg=green]%H:%M:%S #[default]#[fg=magenta,bright]#[default]" # window setting setw -g utf8 on setw -g window-status-format " [#I] #W " setw -g window-status-current-format " [#I] #W " setw -g window-status-current-fg black setw -g window-status-current-bg green setw -g window-status-current-attr default set-option -g allow-rename off #禁止rename,在tmux v1.8 在換路徑時,會一直rename window # using function keyCtrl+A unbind C-b set -g prefix ^A bind a send-prefix # split window unbind % unbind '"' bind v split-window -h bind | split-window -h bind h split-window -v bind - split-window -v
tmux source-file ~/.tmux.conf
git branch資訊不曉得為何,偶爾會有出現,後來發現要在git folder裡開tmux才會有,不曉得為什麼
星期二, 10月 18, 2011
php轉碼問題
利用iconv轉碼會有轉不回來的問題
可用mbstring來轉碼 就不會有問題了
當然apache要先安裝mbstring
可用mbstring來轉碼 就不會有問題了
當然apache要先安裝mbstring
- 安裝
yum install php-mbstring
- big5轉utf8
mb_convert_encoding($msg, "UTF-8", "BIG-5");
- 配合自動偵測,統一轉utf8
要注意要自己加上可能的碼,不然可能會找不到$encoding = mb_detect_encoding($this->content, "UTF-8,BIG-5,GB2312, ASCII, ISO-8859-1"); $msg = mb_convert_encoding($msg, "UTF-8", $encoding);
星期四, 10月 13, 2011
php處理url函式
- 組url字串
利用http_build_query<?php $data = array('foo'=>'bar', 'baz'=>'boom', 'cow'=>'milk', 'php'=>'hypertext processor'); echo http_build_query($data) . "\n"; echo http_build_query($data, '', '&'); //前置詞 $data = array('foo', 'bar', 'baz', 'boom', 'cow' => 'milk', 'php' =>'hypertext processor'); echo http_build_query($data, 'myvar_'); -- foo=bar&baz=boom&cow=milk&php=hypertext+processor foo=bar&baz=boom&cow=milk&php=hypertext+processor myvar_0=foo&myvar_1=bar&myvar_2=baz&myvar_3=boom&cow=milk&php=hypertext+processor - 解url字串
利用parse_str<?php $str = "first=value&arr[]=foo+bar&arr[]=baz"; parse_str($str); echo $first; // value echo $arr[0]; // foo bar echo $arr[1]; // baz parse_str($str, $output); echo $output['first']; // value echo $output['arr'][0]; // foo bar echo $output['arr'][1]; // baz
星期一, 10月 10, 2011
git log
- 一般
- 查看commit歷程 # git diff --name-only // 最近一次的commit有哪些檔案被修改
# git log # git log --stat // 更動檔案和異動的行數 # git log <file> //指定檔案
- 查看commit歷程
- 排版
- 圖形化commit歷程
看了沒fu嗎… 用文字圖形化看吧
git log --graph //文字圖示版本
- 異動的內容
即為git diff的內容,太多不寫了,看reference裡有$ git log -p
- 一列一版本
查看版本一目瞭然...... 前提是commit的message要跟範例一樣清楚的話....git log --pretty=oneline -- a6b444f570558a5f31ab508dc2a24dc34773825f dammit, this is the second time this has reverted 49d77f72783e4e9f12d1bbcacc45e7a15c800240 modified index to create refs/heads if it is not 9764edd90cf9a423c9698a2f1e814f16f0111238 Add diff-lcs dependency e1ba1e3ca83d53a2f16b39c453fad33380f8d1cc Add dependency for Open4 0f87b4d9020fff756c18323106b3fd4e2f422135 merged recent changes: * accepts relative alt pat f0ce7d5979dfb0f415799d086e14a8d2f9653300 updated the Manifest file
- 特定資料夾
$ git log fs/ # commits that modify any file under fs/
- 圖形化commit歷程
- 搜尋及過濾
- 誰異動的,何時,哪個commit
# git blame filename commit author when -------- ---- ------------------------- 394d743f (fish 2013-10-22 17:22:34 +0800 8) public function getSource() 394d743f (fish 2013-10-22 17:22:34 +0800 9) { 394d743f (fish 2013-10-22 17:22:34 +0800 10) return ""; 394d743f (fish 2013-10-22 17:22:34 +0800 11) } - 用文字找版本
$ git log -S'foo()' # commits that add or remove any file data matching the string 'foo()'
- 最近二周
其他還有--after, --until, and --before$ git log --since="2 weeks ago" # commits from the last 2 weeks
- 不要顯示merge的版本
$ git log --no-merges
- 誰異動的,何時,哪個commit
$ git log v2.5.. # commits since (not reachable from) v2.5
$ git log test..master # commits reachable from master but not test
$ git log master..test # commits reachable from test but not master
$ git log master...test # commits reachable from either test or
# master, but not both
星期日, 10月 09, 2011
git stash 暫存
當要checkout b branch時,當下a branch的資料如果未commit
就會連當被帶過去b branch
//假設有a, b branches且都有file1內容為1-1 # echo '1-2' > file1 # git checkout b M file1 Switched to branch 'b' # cat file1 1-2
- 丟入暫存
但如果未完成又不想commit時 可利用git stash# echo '1-2' > file1 # git stash # cat file1 1-1 <-- 被reset, 這時就可以切換
- 取出
git stash可重覆使用,用法如stack 多下個幾次就堆疊起來,取法一樣pop囉# git stash pop # cat file1 1-2 <--再被改為stash的內容
- git stash list (列出stash的清單)
# git stash list stash@{0}: WIP ... //第1個暫存 stash@{1}: WIP ... //第2個暫存 - git stash pop (取出暫存)
# git stash pop // pop out 最後進入的stash # git stash apply // 跟pop一樣. 但不會清掉stash # git stash apply stash@{1} //取出陣列1的stash # git stash drop stash@{1} //刪掉,不套用 # git stash clear // 不用解釋吧...
git還原 - revert, reset, checkout
- 回復至最近一次commit(所有檔案)
$ git reset --hard HEAD - 還原修改過的單一檔案
有以下不同的方法
//以下從staging取出 $ git checkout hello.txt //1 $ git checkout -- hello.txt //2 $ git checkout -f hello.txt //3 //以下從HEAD最新版取出 $ git checkout HEAD hello.txt //4
ex. 假設HEAD的hello.txt 如果為hello
$ echo 'hi' > hello.txt //這時三者皆相同 $ git add . //放到staging,這時1,2,3取到staging(hi),4取到hello感謝Charlie Lee的訂正,本以為-f也會取到hello
話說不知道當初為何要看-f參數,這參數是用在"強制換"branch時,不理會當下修改的檔案,跟"還原"檔案沒什麼關係 XD
可能當初還不太懂,看著人家寫就照抄 - Staging(git add)後,要退回unstage
$ git reset HEAD file - 回復特定版本
雖說是回復,但其實是將指定的版本新增為最新的commit
不過通常回復到舊版本,是要繼續往下開發$ git revert commit_name
所以勢必得再一次commit
所以如果只是要回復且不要commit 可以加 -n or --no-commit
如果要修改的話 得commit或放棄,否則沒辦法回復$ git revert -n commit_name
- fatal: Commit 137ea95 is a merge but no -m option was given.
因為該commit為merge(兩個branches合併,所以得指定要回復的branch (-m or --mainline option) 搭配數字 1 or 2 指定第幾個commit
- fatal: Commit 137ea95 is a merge but no -m option was given.
- 從commit裡,指定checkout檔案
格式:git checkout SHA /file/to/path
$ git checkout 35216 controller/ui.php - 從branch裡,指定checkout檔案
格式:git checkout <branch_name> <paths> #會在相同的資料夾找
格式:git checkout <branch_name> -- <paths>
$ git checkout branch_b test.php //從branch_b取出test.php - 改變最後一次的 Commit的訊息
git commit --amend (改git log的內容)
星期六, 10月 08, 2011
git 常見問題
- 程式改爛了,怎麼還原
- 還原單一檔案
$ git checkout hello.txt
- 整個還原到最後commit版本 只會還原上一版本有加入track的檔,還沒加入的新檔不會變更
$ git reset --hard HEAD
- 還原單一檔案
- 回復特定版本
雖說是回覆,但其實是將指定的版本新增為最新的commit$ git revert commit_name
- checkout某版本或分支的特定檔
git checkout SHA-1 -- FILE_PATH git checkout BRANCH_NAME -- FILE_PATH
- 衝突了!怎麼解
打開confilct的檔案<<<<<<<< HEAD 目前的版本 --------------------- 上一個版本 >>>>>>>>>> 版本碼 只要看哪個正確,改正就可以了
- 要切換branch,還不想commit
- 先丟到暫存區 這時會回到最後commit的結果
$ git stash
不過未經commit的新檔不會改變,也不會被刪除 - 取回暫存
$ git stash pop
- 先丟到暫存區
- 圖示commit版本
-
$ git log --graph
- commit後,想修改message
$ git commit --amend
-
- 新增remote
- 查目前所有的remote點
$ git remote -v
- 新增remote點
$ git remote add remote別名 repository的url位置
- 移除remote點
$ git remote rm remote名
- 查目前所有的remote點
- push回origin權限不足
通常創repository跟clone下來的帳號不同
造成要push回去時,會有權限不足的問題
可利用group的解決這問題
sudo chmod -R g+ws * sudo chgrp -R YOUR_GROUP * git config core.sharedRepository true
星期六, 9月 24, 2011
書:老闆不說卻默默察的45件事
滿不錯的書,很適合工作一陣子,遇到瓶頸的人
讀完也發覺自己採了不少地雷,趁還年輕好好的糾正自己的態度 把45件事都寫下來,隨時自己反省一下
- 好人不升官?誰叫你踩到九大地雷
- 總是把NO留給老闆說
- 熱心?野心?失職分不清
- 成為公司中的岳飛型人物
- 以「很會問問題」自豪
- 喜歡亂猜就出局
- 英文好,沒什麼了不起?
- 分不出應該做的與想做的
- 堅持,堅持,再堅持
- 倚老賣老,危險啊!
- 這些眉角,都很重要
- Happy Problem---有問題就有機會
- 機會一直在
- 你有受害者心態嗎?
- 生氣有什麼用?
- 說別人笨不代表自己聰明
- 情緒與工作要分清楚
- 別人的成就看起都很簡單?
- 你穿什麼進辦公室?
- 改變自己
- 別當垃圾筒
- 當個實心英雄
- 讓老闆打從「心底」欣賞你
- 學習做個職場修羅
- 不必在意他們笑什麼
- 面對迷惘「冷」處理
- 珍惜走過的足跡
- 「理所當然」不如「設身處地」
- 尋找心靈的安定感
- 選對「老闆績優股」
- 都是學歷的問題?
- 絕不能忽略的「時空背景」
- 輸在終點線前的遺憾
- 誰才是競爭的裁判?
- 留心腳邊的小石頭
- 主管要有新想法+新角度
- 學習面對和要求
- 你會說故事嗎?
- 一張紙,一隻嘴
- 絕招!心錨制約術!
- 固執VS堅持
- 傻瓜才愛比聰明
- 吉人詞寡,躁人詞多
- 知易信難的處事黑洞
- 面對現實
- 慎用二分法
- 企業的致勝武-人才
- 減少會議,多點溝通
- 做對的事,把事情做對
星期一, 9月 12, 2011
為blogger的code設定css
一直懶得為網誌上的code用範本
雖然覺得應該是有plugin可以直接套用
不過懶得用,挺多設定一些css而已
一直到最近同事用了Syntax Highlighter 覺得挺不錯的 就看了一下
不過在blogger上要得需要網頁空間 覺得還挺麻煩的
終於看到有人提供用的空間及在blogger上的設定 Color My World – Syntax highlighter
我的blogger總於有ide等級的範本了
雖然覺得應該是有plugin可以直接套用
不過懶得用,挺多設定一些css而已
一直到最近同事用了Syntax Highlighter 覺得挺不錯的 就看了一下
不過在blogger上要得需要網頁空間 覺得還挺麻煩的
終於看到有人提供用的空間及在blogger上的設定 Color My World – Syntax highlighter
我的blogger總於有ide等級的範本了
- 設定
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/> <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeRDark.css' rel='stylesheet' type='text/css'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPowerShell.js' type='text/javascript'/> <script language='javascript'> SyntaxHighlighter.config.bloggerMode=true; SyntaxHighlighter.config.clipboardSwf='http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf'; SyntaxHighlighter.all(); </script>
- 使用
在每一段的code加上div及pre<div class="code"><pre class="brush: js;"> //程式碼放這 </pre></div>
- 使用
星期五, 9月 09, 2011
格式化json,php array
- php array
用print_r或var_dump印php array時
output都不會自動縮排,全擠在一行
很難查看陣列的內容
之前用Zend可以用Zend_Debug::dump($array);
但純php就一直沒找到方法(懶得找 哈)
後來發現原來是自己錯怪print_r
其實本來就有排版,只是空格及斷行不是用php
所以加個pre tag包起來即可
偶然的機會下看到get_object_vars($array) 才發現有早就有這function了echo "<pre>" . print_r($array, true) . "</pre>"; //output array(2) { ["b"]=> int(1) ["c"]=> NULL }
不過這只能印object,所以得先將array轉object
怎麼轉...... 一個個轉...
function arrayToObject($array) { if(!is_array($array)) { return $array; } $object = new stdClass(); if (is_array($array) && count($array) > 0) { foreach ($array as $name=>$value) { $name = strtolower(trim($name)); if (!empty($name)) { $object->$name = arrayToObject($value); } } return $object; }else { return FALSE; } } - json
json也是,只會用JSON.stringify(array)
全又擠在一起,一個個看實在很沒效率
目前只有看到這篇"format json" 自行寫程式去轉
星期六, 9月 03, 2011
正規表達式 Regular Expression
Metacharacters
用來描敘match項目的特殊字元,可組合使用
Quantifiers
指定次數
References
Regular Expression (RegExp) in JavaScript
| 符號 | 說明 |
|---|---|
| . | 任一字元 |
| ˆ | 放在最前面表示後面的符號需在開頭,如果在中間表是否定 |
| $ | 符號需在結尾字串 |
| \s | Match any whitespace character |
| \d | Match any digit |
| \w | Match any “word” character |
Quantifiers
指定次數
| 符號 | 說明 |
|---|---|
| * | The character can appear zero or more times |
| + | The character can appear one or more times |
| ? | The character can appear zero or one times |
| () | 表示一個 sub pattern ,符合 sub pattern 的字串內容會被存放在匹配陣列中,並依序指派數字代表此 sub pattern 。 例如 /The h([0-9]) means Title (\1)/ 即為 'The h1 means Title 1', 'The h2 means Title 2' ... |
| [] | 表示字串含有括號中任一字元的內容。可以 - 表示一組連續字元,例如 /[a-z]/, /[0-9]/ 。注意, [] 僅代表一個字元,例如 /[abc]/ 表示 'a' 或 'b' 或 'c' ,而不是 'abc' /ab[cd]e/ abce, abde皆正確 /ab[c-e\d]/ abc, abd, abe及任何ab後接數字皆正確 |
| {n,m} | The character can appear at least n times, and no more than m. Either parameter can be omitted to indicated a minimum limit with no maximum, or a maximumlimit without a minimum, but not both. |
Example
驗證
`[a-zA-Z0-9]$` 英數字,不含特殊字元
取值
- 取html tag值或attribute
//取tag value function getTextBetweenTags($string, $tagname) { $pattern = "/<$tagname ?.*>(.*)<\/$tagname>/"; preg_match($pattern, $string, $matches); return $matches[1]; } //取tag attribue function getAttribute($attrib, $tag){ //get attribute from html tag $re = '/' . preg_quote($attrib) . '=([\'"])?((?(1).+?|[^\s>]+))(?(1)\1)/is'; if (preg_match($re, $tag, $match)) { return urldecode($match[2]); } return false; } - host相關
// get host name from URL preg_match('@^(?:http://)?([^/]+)@i', "http://www.php.net/index.html", $matches); $host = $matches[1]; // get last two segments of host name preg_match('/[^.]+\.[^.]+$/', $host, $matches); echo "domain name is: {$matches[0]}\n"; - 取代
將轉換tag - php$subjects['body'] = "[b]Make Me Bold![/b]"; $subjects['subject'] = "[i]Make Me Italics![/i]"; $regex[] = "@\[b\](.*?)\[/b\]@i"; $regex[] = "@\[i\](.*?)\[/i\]@i"; $replacements[] = "<b>$1</b>"; $replacements[] = "<i>$1</i>"; $results = preg_replace($regex, $replacements, $subjects); //ouput--- array(2) { ["body"]=> string(20) "<b>Make Me Bold!</b>" ["subject"]=> string(23) "<i>Make Me Italic!</i>" } - 驗證
星期四, 9月 01, 2011
log等級的使用時機
- debug
The DEBUG Level designates fine-grained informational events that are most useful to debug an application. - info
The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. - warn
The WARN level designates potentially harmful situations.
需注意的情況,例如網路連線斷了 非永久性錯誤的情況進行一些修復性的工作,應該還可以把系統恢復到正常狀態中來,系統應該可以繼續運行下去。 - error
The ERROR level designates error events that might still allow the application to continue running.
可以進行一些修復性的工作,但無法確定系統會正常的工作下去,系統在以後的某個階段,很可能會因為當前的這個問題,導致一個無法修復的錯誤(例如宕機),但也可能一直工作到停止也不出現嚴重問題。 - fatal
The FATAL level designates very severe error events that will presumably lead the application to abort.
系統即將Crash或無法再往下執行,只能關閉肯定這種錯誤已經無法修復,並且如果系統繼續運行下去的話,可以肯定必然會越來越亂。這時候採取的最好的措施不是試圖將系統狀態恢復到正常,而是儘可能地保留系統有效數據並停止運行。
記錄應該寫在發生的那一層
再記錄stack可以trace
Reference
log4j
日誌級別的選擇:Debug、Info、Warn、Error還是Fatal
設定git config
常用git config 每次建新repo都要重設一次,直接拉拿copy-paste
- .git/config
[core] filemode = false [core] filemode = false [color] ui = true branch = auto diff = auto status = auto log = auto interactive = auto
- .gitattributes
* text=auto
說明
- 設定git
#git config --global user.name "YOUR_NAME" #git config --global user.email YOUR_EMAIL
- git指令自動完成
- 下載git source code
- 複製.git-completion.bash
$ cp contrib/completion/git-completion.bash. ~/ - 編輯.bashrc $ vim ~/.bashrc 加入 source ~/.git-completion.bash
- UI環境設定
- 啟用色彩
# git config --global color.ui true # git config --global color.branch auto # git config --global color.diff auto //將diff的資料加入色彩 # git config --global color.interactive auto # git config --global color.status auto //
- 自訂色彩
#git config --global color.diff.meta "blue black bold"
- 一次設定
$ vim .git/config 編輯以下內容,顏色可自訂 [color] branch = auto diff = auto status = auto [color "branch"] current = yellow reverse local = yellow remote = green [color "diff"] meta = yellow bold frag = magenta bold old = red bold new = green bold [color "status"] added = green changed = red untracked = cyan
- 啟用色彩
- 檔案環境
- 格式化空白
由於windows(\r\n)及max, linux(\n)的換行符號不同 所以在不同環境下共同編輯時,會一直有換行符號的問題 看到原來git很聰明的可以自動幫我們做轉換 Git可以在你提交時自動地把行結束符CRLF轉換成LF,而在簽出代碼時把LF轉換成CRLF。 用core.autocrlf來打開此項功能, - Windows系統
設置成true,這樣當checkout代碼時,LF會被轉換成CRLF#git config --global core.autocrlf true
- Linux或Mac系統
core.autocrlf設置成input來告訴 Git 在提交時把CRLF轉換成LF,checkout時不轉換#git config --global core.autocrlf input
- 檔案權限
git不會理檔案權限,所以當init後,就不會再改變,即使改過權限(744 -> 777)又commit
當下的working area是會變,不過clone此repository會回到原本的744
改為false後就會一致了
git config core.filemode false
- 格式化空白
星期三, 8月 31, 2011
星期六, 8月 27, 2011
書:學徒模式 Apprenticeship Patterns
列出作者提的模式清單
時時回顧,鞭策自己
- 不同的道路
你發現你想要前進的方向與軟體工藝之路不同 - 成為菜鳥
隨著你超越身邊其他人,你發現自己學習的速度減慢 - 拋棄式玩具
你在一個無法允許失敗的環境工作,然而你需要一個安全的地方學習 - 具體技能
你想要在一個偉大的開發團隊中工作,但你只擁有極少的實務經驗 - 正視你的無知
你發現自己的知識有巨大的差距,但你的工作要求你瞭解這些主題 - 工藝先於藝術
你需要交付解決方案給客戶,可以選擇一個簡潔、驗證過的解決方式或是藉機建立一個新穎、了不起的解決方案 - 建立回饋迴路
你無法分辨自己是否處於「無自覺的無知」 - 量身繪製地圖
僱主所提供的職涯路線都不適合 - 擴展你的頻寬
你對軟體開發的瞭解很狹窄,專注在每天工作上的低階細節 - 顯露你的無知
- 熟悉使用工具
- 尋找個人導師
- 志趣相同的夥伴
- 自失敗中學習
- 培養你的熱情
- 練習練習再練習
- 持續閱讀
- 閱讀清單
- 記錄個人所學
- 邊工作邊反省
- 退回舒適區
- 密切交往
- 分享個人所學
- 堅守初衷
- 研讀經典
- 持續的動力
- 打掃地板
- 深水區
- 漫漫長路
- 繫上白帶
- 釋放你的熱情
- 使用原始碼
- 使用你的頭銜
- 你的第一個語言
星期五, 8月 26, 2011
Object & Data Structure
- 資料隱藏
如setter及getter對I/O的validate及filter
而data structure會曝露資料
如同從db來欄位出來用tb['name']
將來欄位修改為name2時,不同引用的地方就都得改
而物件就只需要在組成的地方修改即可 - 抽像化
透過method操作資料public interface Vehicle { double getPercentFuelRemaining(); }
不用知道實作的細節
上例不會從程式裡知道data的細節
user只知道要呼叫的method,不用考慮細節或有何資料
連setter及getter都不用
而data structure曝露資料且無意義的名稱
.gitignore
不加入版本控管可透過.gitgnore設定
在git的根目錄下建.gitgnore,其內容設定
由於git不會track空資料夾,所以當ignore *, 會造成tmp/log資料夾不會加入repository
這時只要在tmp/log下,加個.gitignore,內容如下
在git的根目錄下建.gitgnore,其內容設定
#.gitignore內容
tmp.txt #不加入tmp.txt
*.log #不加入所有的log檔
tmp/* #不加入tmp下所有檔
log/**/*.log #忽略log目錄下包含子目錄的所有.log檔案
log/**/* #略特定目錄下的所有檔案由於git不會track空資料夾,所以當ignore *, 會造成tmp/log資料夾不會加入repository
這時只要在tmp/log下,加個.gitignore,內容如下
vi tmp/.gitignore # log/.gitignore
#--
*
!.gitignore #這個檔也可以不追蹤其他過濾條件(其實就正規表達式)
- ?:代表任意的一個字元
- *:代表任意數目的字元
- {!ab}:必需不合於此pattern
- {ab,bb,cx}:代表合於ab,bb,cx之一種pattern即可
- [abc]:代表合於a,b,c中任一字元即可
- [^abc]:代表必需不合於a,b,c中任一字元
FAQ
- 加入ignore無效?
明明就已經加入了,但一樣會檢查
因為一開始就把檔案加入tracking,就把檔案放進repository追蹤
所以每次改變都會檢查,這時只要下
然後再commit一次,這樣就ok啦git rm --cached <ignore file>
p.s. 當然這次 gitignore就要先寫好 後記:但別人merge後,不知為何他的<ignore fil>會整個刪掉....
星期四, 8月 25, 2011
PHP時間函數
- 取值
- 取今天日期
$today = date("F j, Y, g:i a"); // March 10, 2001, 5:16 pm $today = date("m.d.y"); // 03.10.01 $today = date("j, n, Y"); // 10, 3, 2001 $today = date("Ymd"); // 20010310 $today = date('h-i-s, j-m-y, it is w Day'); // 05-16-18, 10-03-01, 1631 1618 6 Satpm01 $today = date('\i\t \i\s \t\h\e jS \d\a\y.'); // it is the 10th day. $today = date("D M j G:i:s T Y"); // Sat Mar 10 17:16:18 MST 2001 $today = date('H:m:s \m \i\s\ \m\o\n\t\h'); // 17:03:18 m is month $today = date("H:i:s"); // 17:16:18 - 取今、明、後天的秒數
$tomorrow = mktime(0, 0, 0, date("m") , date("d")+1, date("Y")); $lastmonth = mktime(0, 0, 0, date("m")-1, date("d"), date("Y")); $nextyear = mktime(0, 0, 0, date("m"), date("d"), date("Y")+1); - 取特定日期到目前的秒數
$Date_In = '2007-01-08'; echo time() - strtotime($Date_In); // Output the number of seconds between now and $Date_In
- 取今天日期
- Validation
- 判斷是否日期是否正確
if(strtotime($Date_In))
...
- 判斷是否日期是否正確
Reference
log4php
Quick Start
- Install
- download Apache log4php
- copy
將src/main/php/搬到目的地library/log4php
- logging
This produces the following output:include('library/log4php/Logger.php'); $logger = Logger::getLogger("main"); $logger->info("foo"); $logger->warn("bar");
Sun Jul 26 01:40:23 2009,021 [10093] INFO main - foo Sun Jul 26 01:40:23 2009,030 [10093] WARN main - bar
- 設定配置
config.xml//在getLogger前讀 Logger::configure('config.xml'); $logger = Logger::getLogger("main");
- appender
log的記錄可寫到不同的地方,如console, file, db,這就靠appender裡的設定來區分,而appender可以設定不同的class,以寫到不同的類型,以下列出常用的appender classes
- LoggerAppenderEcho 即php的echo
- LoggerAppenderFile 寫入檔案
- LoggerAppenderDailyFile依日期寫入新的檔案
- LoggerAppenderMail 透過mail將log寄出
- logger
logger即為記錄器,透過logger記錄資訊,logger設定提供過濾等級(debug, warn或error),及配對appender以便寫到不同的媒體(console, file或db)裡
- Logger threshold
設定info以上全記錄
<configuration xmlns="http://logging.apache.org/log4php/"> <appender class="LoggerAppenderConsole" name="default"> </appender> </configuration> - Configuring loggers
範例中每次要換appender,就得改xml設定
可透過取得不同logger,即可得不同的appender
$logger = Logger::getLogger("fileAppender"); //即可取得 myFileAppender
- Logger threshold
- Filters
提供比logger設定裡更精確的過濾條件 - Renderers
要記錄object時,log4php會透過default renderer預設將所有屬性印出,如果要客製化的話
- 先寫render
例如$person
/** All object renderers must implement the LoggerRendererObject interface. */ class PersonRenderer implements LoggerRendererObject { public function render($person) { return "{$person->firstName} {$person->lastName} ({$person->age})"; } } - 設定檔
Person對應PersonRenderer
<configuration xmlns="http://logging.apache.org/log4php/"> <renderer renderedClass="Person" renderingClass="PersonRenderer" /> <appender name="defualt" class="LoggerAppenderEcho" /> <root> <appender_ref ref="defualt" /> </root> </configuration>
- 先寫render
- Configuration
設定檔可用XML, properties(ini) or PHP files來設定,擇一即可
- 利用properties(ini)設定default的appender
log4php.appender.default = LoggerAppenderDailyFile log4php.appender.default.layout = LoggerLayoutPattern log4php.appender.default.layout.ConversionPattern = "%d{ISO8601} [%p] %c: %m (at %F line %L)%n" log4php.appender.default.datePattern = Ymd log4php.appender.default.file = logs/behavior/%s.log - 利用php設定default2的appender
//config.php return array( 'rootLogger' => array( 'appenders' => array('default2'), ), 'appenders' => array( 'default2' => array( 'class' => 'LoggerAppenderEcho', 'layout' => array( 'class' => 'LoggerLayoutSimple' ) ) ) )); //include cofigure file Logger::configure('config.php');
- 利用properties(ini)設定default的appender
- Pattern Layout Parameters
%d 時間
%p log的level( info, error , ...)
$c appender的名稱
%m message
%F filename
%L 行數
%n 斷行
訂閱:
文章 (Atom)
