星期四, 7月 26, 2012

Coding Security Issues

  • 設計篇
    寫程式前先記好「電腦安全的七項設七項設計原則」
    1. 最小權限原則 ( least privilege )
    2. 經濟者是原則 ( econmy of mechanism )
    3. 安全檢測原則 ( complete mediation )
      每一筆資料存取之前,都必須先檢驗是否為合法授權行為
    4. 開放性設計原則  ( open design )
      嚴禁走系統後門的行徑
    5. 分權原則 ( separation of privilege )
    6. 最少共用性原則 ( least common mechanism )
    7. 可接受程度 ( psychological acceptability )
  • 實做篇
    理論太多沒感覺嗎?不然實做黃金三劍客記好就好...
    1. always validate your inputs
    2. always filter your outputs
    3. nerver trust users

    實做細節注意overflow
    避免使用建議使用
    gets()fget()
    strcpy()strncpy()
    stract()strncat()

星期四, 7月 12, 2012

ssl 在ie下網址錯誤

crt1: aa.com
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>
在firefox, chrome都正常
而在...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申請憑證後,會拿到
  • YOUR_WEBSITE.crt
  • YOUR_WEBSITE.YOUR_WEBSITE.csr
  • YOUR_WEBSITE.bundle..ca-bundle
apache的話到/etc/httpd/conf.d/ssl.conf
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咧
<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

  1. 當天的資料
    select * from table where to_days(column_time) = to_days(now());
    select * from table where date(column_time) = curdate(); 
  2. Between日期
    WHERE (created BETWEEN '2012-06-19' and '2012-06-30 23:59:59' ); 
    注意結尾是最後一天一秒,否則只會出現到前一天的資料
  3. 最近7天,1個月
    WHERE DATE_SUB( CURDATE( ) , INTERVAL 7 DAY ) <= `created_date`;
    WHERE DATE_SUB(CURDATE(), INTERVAL INTERVAL 1 MONTH) <= `created_date`;
  4. 本周
    從當週的Sunday開始到星期六的七天資料
    select * from wap_content where week(created_at) = week(now);
    
Reference

星期四, 6月 28, 2012

常用sed與awk


  1. 統計行數
    單一檔案
    awk 'END{print FNR}' xxx.log

    多個檔案
    awk 'END{print FNR}' *.log
    用linux本身的wc指令也可達到效果
    wc -l *.log
  2. 取出重覆及不重覆次數
    [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如何同时统计 总数与不重复个数?
  3. 列出符合的資料
    • 單筆
      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視窗常用指令

兩個切換視窗切到指令都亂了
  1. 合併兩個即有視窗
    • vim: vert sb#
    • tmux
  2. 將目前的pane抽成獨立視窗
    • vim:
    • tmux: CTRL-b !
  3. 分割頁切換
    • vim: CTRL-W 方向鍵
      或是CTRL-W j(往右) or w(往下),大寫則相反
    • tmux: CTRL-o

星期二, 6月 19, 2012

php與awk

  1.  在php中執行shell
    可利用shell_exec
    shell_exec('ls -l');
  2. 使用awk
    $data = shell_exec("awk '{print $1}' " . $filepath );
  3. 取得單行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

  1. 取出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
    )
  2. 轉成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
    1. 建立連線
      $conn = oci_connect('YOUR_ACCOUNT', 'YOUR_PASSWORD','//IP_ADDRESS:PORT/SERVICE_NAME');
    2. 下sql
      $sql = "SELECT ID, NAME as \"name\"
      FROM CATEGORY
      WHERE PARENT_ID = 0 AND STATUS = 1
      ORDER BY CATEGORY_ID ASC";
    3. 取資料
      $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
    1. 建立連線
      $conn = oci_connect('YOUR_ACCOUNT', 'YOUR_PASSWORD','//IP_ADDRESS:PORT/SERVICE_NAME');
    2. 連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);
    3. 給參數

星期日, 6月 03, 2012

linux個人環境設定

每次重灌或換個新環境就得憑記憶重設定
乾脆直接記下來省時間...
感謝Dockerfile等工具... 以後這些都可以不用理了...

  1. bashrc
    vim ~/.bashrc
    
    export TERM=screen-256color #註1
    

    註1: lose vim colorscheme in tmux mode

  2. vim 環境設定
    • 環境
    • 縮排
  3. 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
  4. 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

將scroller移到最上面

兩個方法
//1.html本身的方法
top  //嗯 就這樣

//2.就把scrollTop設定為0就可以了
 $('html, body').scrollTop(0);

厲害點...加點滑動的感覺


test
top

References

星期六, 5月 26, 2012

php 時間轉換函式

  1. 轉換unix timestamp為可讀日期時間
    date("Y-m-d H:i:s", $timestamp);
    線上轉換
  2. 可讀日期轉換unix timestamp
    strtotime("2009-11-03 11:24:00PM");

星期三, 5月 23, 2012

php array轉xml, json

轉json就沒什麼好說的了,想說轉xml應該也是很簡單的東西,不過還真遇到一些問題
  1. 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;
    }
    
  2. 下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測試事項
  • 是否支援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...

星期五, 3月 09, 2012

linux prompt

  1. 設置檔
    • 全users
      /etc/profile or /etc/bashrc
    • 個別user
      ~/.bash_profile , ~/.bash_login , ~/.profile , ~/.bashrc or ~/.bash_logout
  2. 客製化prompt
    PS1='[\u@\h \w] \$ # ' #即為user@host ~

    PS1="\e[\u@\h \w]$ \e]" #即為[user@host ~]
    加框'[', ']',由於是key words所以要加\e
    而0;32m 是指顏色,其他以此類推應該就看的出來了
  3. 加上顏色
    PS1="\e[0;32m[\u@\h \w]\e]$ \e[m]" #即為[user@host ~]
  4. 啟使
    source .bashrc
    or
    . .bashrc
  5. 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 characterBash special character explanationBash special characterBash 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才能動....

星期四, 2月 23, 2012

What is my IP? (Public IP address)

Using wget
wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'
Using curl
curl -s checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'

curl -s http://whatismyip.org/
Using Lynx
lynx -dump checkip.dyndns.org

lynx -dump www.whatismyip.com | grep 'Your IP'
Reference Linux command: What is my IP? (Public IP address)

星期二, 2月 21, 2012

mysql grant

最近一個案子要連到廠商的db讀資料
不過不知卡在什麼地方,一直沒辦法連到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';

References

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點...更~~~~~~~~~~~~

網上有人整理好了
  • 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本身達成此效果
    trigger_error("Notice Message",E_USER_NOTICE);
    trigger_error("Warning Message",E_USER_WARNING);
    trigger_error("Error Message",E_USER_ERROR);
    如此就不用再掛log4php,就能方便帶訊息
也就是說error_report 是設定php觸發回報錯誤的等級
如果想利用此機制寫自定的訊息就可透過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_NOTICERun-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_STRICTEnable 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_ALLAll 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後,覺得還是用加密比較簡單

  • two way encryption
    先下載加密法encryption_class.php
    在encryption_class.php裡,有以下兩行
    $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';
    此加密法是簡單的利用代換字母做加密,記得叫Caesar Cipher什麼的,主要利用自己的key,去對應scramble相同字母的位置
    當然這樣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的長度
        
      結果如下
      OriginalEncryptedDecrypted
      151
      70
      115011
      991999
      100583100
      101585101
      110505110
      111507111
      這就可以看出來,當key、scramble、偏移量相同,位於前面的字母相同時,代碼都會相同,變化不夠大,忘了那資安的名詞叫什麼,意思是當原文變化不大時,密文的變化仍要夠大,如md5等
      因為可變化的太少了,不過應該算堪用了
      另外還有兩個問題
      • original為7時,沒辦法反解
        原作者在decrypt用empty,所以遇到0會當false,改!isset即可
        相同的,當encrypt 0時,也會當成false,也需要改成!isset
      • decrypt result為0xx
        雖是正常,不過ordre id用integer,這個0就會不見,到時會解不回去
      min length問題
      由於是全數字,又密文長度不能超過明文長度,實在容易被猜出來
      那如何超過明文長度咧...
      解法:不補空格,補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); //新的作法
          ...
      


References
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我恨你...

星期日, 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
  1. 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
  2. 設定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
  3. 解壓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
  4. 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.

      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

  5. 設定php.ini
    vi /etc/php.ini , add the line extension=oci8.so
    再重開apache即可
    # service httpd restart

    這時下php -m 就會看到oci8了~ 開心
  6. 測試
    <?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';
        }
有看到某些文章指出要安裝pdo,自己裝了也一直失敗
後來發現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多歲以上
且教授等級的老師在業界或學術界都頗具名氣
聽課時,就真的覺得有差,除了講義上的東西,還可以講的更深入
一些理論的東西,也能講的比較活,感覺比較實用

有位教授說了句玩笑話:「教授就是專門把簡單的東西教的很難。」
原本只是會心一笑,後來才體會到,教授已經多年研究這領域,且每年都重複教這東西,已經成精了,而我們這些小毛頭,一時要聽懂,真的不是件容易的事。

所以...
碩士畢業的講師不敢說弱
只能說教授真的滿強的...

星期六, 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出錯時,會自行印出錯誤訊息,如果要關掉有兩種方法
  • config/database.php設定
    $db['default']['db_debug'] = TRUE;
  • 程式裡設定
    $this->db->db_debug = false;  
關掉錯誤訊息,那如何取得錯誤訊息咧
$this->db->_error_message(); 
因為不管關不關錯誤訊息try-catch都抓不到
所以如要判斷中斷程式得利用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);
      }
  }
Reference

星期四, 12月 22, 2011

轉:Setting up an SSL secured Webserver with CentOS

在apache裡建https就這麼簡單...
  1. Getting the required software
    yum install mod_ssl openssl
  2. 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
  3. 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>
  4. Configuring the firewall
    yum install mod_ssl openssl

Reference

星期五, 12月 16, 2011

mysql存日期該用什麼data type

mysql存日期的data type有好幾種type,用int存秒數也是一種
一直很猶疑要用哪一種,想法是byte越少越好
所以整理了一下
TypeStorage(Bytes)Minimum Value(Signed/Unsigned)Maximum Value(Signed/Unsigned)
DATE3 bytes
TIME3 bytes
DATETIME8 bytes
TIMESTAMP4 bytes
YEAR1 bytes
INT4-21474836482147483647

所以我想... 利用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
 $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);
}
不過每個有用db的程式這樣寫太麻煩了
原本想改寫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;
}
References Getting CodeIgniter Active Record's current SQL code

星期一, 12月 12, 2011

檢查遠端的檔案是否存在

這方法還不錯,只回傳header,不看body
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';   
}
Reference

星期二, 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,尚未實際執行
  • 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
這篇教學很完整,不再複製貼上了
  • 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
    1. Identify change points 
    2. Find an inflection point 
    3. Cover the inflection point a.
      1. Break external dependencies
        作者舉在testing時,重視測試結果,而常綁死gui的實作,造成testing不易
        作者寫了CustomerView的interface,當測試時,就可在不改變結構下,丟空的實作做測試,有mock的感覺
      2. Break internal dependencies
        在測試時是不必要的地方(如產生暫存等),就繼承該class,直接orverriding掉,不要做任何事即可,有stub的感覺
      3. Write tests 
    4. Make changes 
    5. Refactor the covered code.

待續...

星期五, 11月 18, 2011

SQL 常用查詢

  • 從url字串截取domain
    SELECT substring_index(substring_index(trim(leading "https://" from trim(leading http://" from trim(`URL`))), "/", 1), ":", 1) as domain FROM `uchome_app` WHERE 1 `redirect_uri`
    

星期四, 11月 10, 2011

linux切換多重視窗 - tmux

用pietty開發時,經常需要連到其他servers
懶得再開一個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
  • install tmux
    # yum install tmux
    如果找不到套件,先加入epel的repo
    Install 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
    Reference: Install EPEL Repo CentOS RHEL
  • 啟動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名
      $ tmux rename-session -t session1 session2  //把session1改成session2
      或者直接下function key + $

  • 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
    # 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
    
    
    設好後,重啟config
    tmux source-file ~/.tmux.conf
    git branch資訊不曉得為何,偶爾會有出現,後來發現要在git folder裡開tmux才會有,不曉得為什麼

星期二, 10月 18, 2011

php轉碼問題

利用iconv轉碼會有轉不回來的問題
可用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 log    
      # git log --stat  // 更動檔案和異動的行數
      # git log <file> //指定檔案
      
      # git diff --name-only // 最近一次的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
      # 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()'
      
    • 最近二周
      $ git log --since="2 weeks ago" # commits from the last 2 weeks
      
      其他還有--after, --until, and --before
    • 不要顯示merge的版本
      $ git log --no-merges
      
其他
$ 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
References

星期日, 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 pop
    # cat file1
    1-2     <--再被改為stash的內容
    git stash可重覆使用,用法如stack 多下個幾次就堆疊起來,取法一樣pop囉
更多指令
  • 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
    $ git revert -n commit_name
    如果要修改的話 得commit或放棄,否則沒辦法回復
    • fatal: Commit 137ea95 is a merge but no -m option was given.
      因為該commit為merge(兩個branches合併,所以得指定要回復的branch (-m or --mainline option) 搭配數字 1 or 2 指定第幾個commit
  • 從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的內容)
References

星期六, 10月 08, 2011

git 常見問題

  1. 程式改爛了,怎麼還原
    • 還原單一檔案
      $ git checkout hello.txt
      
    • 整個還原到最後commit版本
      $ git reset --hard HEAD
      
      只會還原上一版本有加入track的檔,還沒加入的新檔不會變更
  2. 回復特定版本
    雖說是回覆,但其實是將指定的版本新增為最新的commit
    $ git revert commit_name
  3. checkout某版本或分支的特定檔
    git checkout SHA-1 --  FILE_PATH
    git checkout BRANCH_NAME -- FILE_PATH
  4. 衝突了!怎麼解
    打開confilct的檔案
    <<<<<<<<     HEAD
    目前的版本
    ---------------------
    上一個版本
    >>>>>>>>>> 版本碼
    只要看哪個正確,改正就可以了
    
  5. 要切換branch,還不想commit
    1. 先丟到暫存區
      $ git stash
      
      這時會回到最後commit的結果
      不過未經commit的新檔不會改變,也不會被刪除
    2. 取回暫存
      $ git stash pop
      
  6. 圖示commit版本
    • $ git log --graph
    • commit後,想修改message
      $ git commit --amend
      
  7. 新增remote
    • 查目前所有的remote點
      $ git remote -v
    • 新增remote點
      $ git remote add remote別名 repository的url位置
    • 移除remote點
      $ git remote rm remote名

  8. 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件事都寫下來,隨時自己反省一下











  • 好人不升官?誰叫你踩到九大地雷
    1. 總是把NO留給老闆說
    2. 熱心?野心?失職分不清 
    3. 成為公司中的岳飛型人物
    4. 以「很會問問題」自豪
    5. 喜歡亂猜就出局
    6. 英文好,沒什麼了不起?
    7. 分不出應該做的與想做的
    8. 堅持,堅持,再堅持
    9. 倚老賣老,危險啊!
  • 這些眉角,都很重要
    1. Happy Problem---有問題就有機會
    2. 機會一直在
    3. 你有受害者心態嗎?
    4. 生氣有什麼用?
    5. 說別人笨不代表自己聰明
    6. 情緒與工作要分清楚
    7. 別人的成就看起都很簡單?
    8. 你穿什麼進辦公室?
    9. 改變自己
    10. 別當垃圾筒
    11. 當個實心英雄
  • 讓老闆打從「心底」欣賞你
    1. 學習做個職場修羅
    2. 不必在意他們笑什麼
    3. 面對迷惘「冷」處理
    4. 珍惜走過的足跡
    5. 「理所當然」不如「設身處地」
    6. 尋找心靈的安定感
    7. 選對「老闆績優股」
    8. 都是學歷的問題?
    9. 絕不能忽略的「時空背景」
    10. 輸在終點線前的遺憾
    11. 誰才是競爭的裁判?
    12. 留心腳邊的小石頭
  • 主管要有新想法+新角度
    1. 學習面對和要求
    2. 你會說故事嗎?
    3. 一張紙,一隻嘴
    4. 絕招!心錨制約術!
    5. 固執VS堅持
    6. 傻瓜才愛比聰明
    7. 吉人詞寡,躁人詞多
    8. 知易信難的處事黑洞
    9. 面對現實
    10. 慎用二分法
    11. 企業的致勝武-人才
    12. 減少會議,多點溝通
    13. 做對的事,把事情做對

星期一, 9月 12, 2011

為blogger的code設定css

一直懶得為網誌上的code用範本
雖然覺得應該是有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包起來即可
    echo "<pre>" . print_r($array, true) . "</pre>";
    //output 
    array(2) {
      ["b"]=>
      int(1)
      ["c"]=>
      NULL
    }
    偶然的機會下看到get_object_vars($array) 才發現有早就有這function了
    不過這只能印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" 自行寫程式去轉
Reference PHP - Convert Array to Object with stdClass

星期六, 9月 03, 2011

正規表達式 Regular Expression

Metacharacters

用來描敘match項目的特殊字元,可組合使用
符號說明
. 任一字元
ˆ 放在最前面表示後面的符號需在開頭,如果在中間表是否定
$ 符號需在結尾字串
\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>"
    }


  • 驗證 


References Regular Expression (RegExp) in JavaScript

星期四, 9月 01, 2011

Windows下看網頁縮圖

原本作業系統是xp,利用 一直用的好好的
結果換個win7就沒效了
就找了一下,發現有AveHTMLPreview

References
[PC]Win7也可預覽html網頁縮圖

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指令自動完成
    1. 下載git source code 
    2. 複製.git-completion.bash
      $ cp contrib/completion/git-completion.bash. ~/
    3. 編輯.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
References Git Configuration

星期六, 8月 27, 2011

書:學徒模式 Apprenticeship Patterns


很棒的一本書
教導軟體人員在不同階段的學習心態

最重要的是認清自己的無知
才能持續學習
且軟體的技術太多 單只會特定一項就自以為是
要跟外界多交流,而不是閉門造車
否則只會是個井底之蛙






列出作者提的模式清單
時時回顧,鞭策自己
  • 不同的道路
    你發現你想要前進的方向與軟體工藝之路不同
  • 成為菜鳥
    隨著你超越身邊其他人,你發現自己學習的速度減慢
  • 拋棄式玩具
    你在一個無法允許失敗的環境工作,然而你需要一個安全的地方學習
  • 具體技能
    你想要在一個偉大的開發團隊中工作,但你只擁有極少的實務經驗
  • 正視你的無知
    你發現自己的知識有巨大的差距,但你的工作要求你瞭解這些主題
  • 工藝先於藝術
    你需要交付解決方案給客戶,可以選擇一個簡潔、驗證過的解決方式或是藉機建立一個新穎、了不起的解決方案
  • 建立回饋迴路
    你無法分辨自己是否處於「無自覺的無知」
  • 量身繪製地圖
    僱主所提供的職涯路線都不適合
  • 擴展你的頻寬
    你對軟體開發的瞭解很狹窄,專注在每天工作上的低階細節
  • 顯露你的無知
  • 熟悉使用工具
  • 尋找個人導師
  • 志趣相同的夥伴
  • 自失敗中學習
  • 培養你的熱情
  • 練習練習再練習
  • 持續閱讀
  • 閱讀清單
  • 記錄個人所學
  • 邊工作邊反省
  • 退回舒適區
  • 密切交往
  • 分享個人所學
  • 堅守初衷
  • 研讀經典
  • 持續的動力
  • 打掃地板
  • 深水區
  • 漫漫長路
  • 繫上白帶
  • 釋放你的熱情
  • 使用原始碼
  • 使用你的頭銜
  • 你的第一個語言

星期五, 8月 26, 2011

Object & Data Structure

  • 資料隱藏
    如setter及getter對I/O的validate及filter
    而data structure會曝露資料
    如同從db來欄位出來用tb['name']
    將來欄位修改為name2時,不同引用的地方就都得改
    而物件就只需要在組成的地方修改即可
  • 抽像化
    public interface Vehicle {
        double getPercentFuelRemaining();
    }
    
    透過method操作資料
    不用知道實作的細節
    上例不會從程式裡知道data的細節
    user只知道要呼叫的method,不用考慮細節或有何資料
    連setter及getter都不用
    而data structure曝露資料且無意義的名稱

.gitignore

不加入版本控管可透過.gitgnore設定
在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追蹤
    所以每次改變都會檢查,這時只要下
    git rm --cached <ignore file>
    然後再commit一次,這樣就ok啦
    p.s. 當然這次 gitignore就要先寫好 後記:但別人merge後,不知為何他的<ignore fil>會整個刪掉....
References git ignore

星期四, 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
    1. download Apache log4php
    2. copy
      將src/main/php/搬到目的地library/log4php
  • logging
    include('library/log4php/Logger.php');
    $logger = Logger::getLogger("main");
    $logger->info("foo");
    $logger->warn("bar");
    
    This produces the following output:
    Sun Jul 26 01:40:23 2009,021 [10093] INFO main - foo
    Sun Jul 26 01:40:23 2009,030 [10093] WARN main - bar
    
  • 設定配置
    //在getLogger前讀
    Logger::configure('config.xml');
    $logger = Logger::getLogger("main");
    
    config.xml
    
            
            
            
    
            
            
                            
            
                    
                     
            
    
    
進階設定
  • appender
    log的記錄可寫到不同的地方,如console, file, db,這就靠appender裡的設定來區分,而appender可以設定不同的class,以寫到不同的類型,以下列出常用的appender classes
  • 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
      
  • Filters
    提供比logger設定裡更精確的過濾條件
  • Renderers
    要記錄object時,log4php會透過default renderer預設將所有屬性印出,如果要客製化的話
    1. 先寫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})";
          }
      }
    2. 設定檔
      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>

  • 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');
      
  • Pattern Layout Parameters
    %d 時間
    %p log的level( info, error , ...)
    $c appender的名稱
    %m message
    %F filename
    %L 行數
    %n 斷行
references

時區設定