星期四, 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

時區設定

星期一, 8月 22, 2011

PHP轉影音檔

[轉]使用PHP進行影片轉檔及擷取縮圖

要在 Linux 主機上使用 PHP 進行影片轉檔,須安裝 LAME、ffmpeg、Ruby、FLVTool2。

  1. 安裝 LAME
    LAME 是用來將聲音壓成 MP3 格式,並加入 --enable-shared 以供 ffmpeg 使用
    網址:http://lame.sourceforge.net/

    下載完成後,輸入下列命令:
    [root@localhost ~]# tar -zxvf lame-3.98.4.tar.gz
    [root@localhost ~]# cd lame-3.98.4
    [root@localhost ~]# ./configure --enable-shared -prefix=/usr
    [root@localhost ~]# make
    [root@localhost ~]# make install
  2. ffmpeg Install With Libx264
    1. Download libx264
      Get the libx264 package from here: http://www.videolan.org/developers/x264.html
    2. Install libx264
      cd /path/to/x264-dir
      ./configure --enable-shared
      make
      make install
      ldconfig
      如果遇到yasm not found,就用無敵的yum install yasm
      如果遇到yum找不到yasm,就先裝epel
      //32bit 
      sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
      
      //CentOS 5 64bit
      sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
      
      //CentOS 6
      rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
  3. 安裝 ffmpeg
    ffmpeg 影片轉檔系統,其 libavcodec 涵蓋大部分影片格式,不過仍有轉換 FLV 上的問題,須另外安裝 FLVTools 來修正。
    網址:http://www.ffmpeg.org/

    下載完成後,輸入下列命令:
    [root@localhost ~]# tar -zxvf ffmpeg-0.5.1.tar.gz
    [root@localhost ~]# cd ffmpeg-0.5.1
    [root@localhost ~]# ./configure --enable-gpl --enable-libmp3lame --enable-shared --enable-libx264 --prefix=/usr

    [root@localhost ~]# make clean && make
    [root@localhost ~]# make install
  4. 安裝 Ruby
    FLVTool2 可以修正 ffmpeg 不正確儲存 FLV metadata 的問題,不過它是用 Ruby 寫的,須先安裝 Ruby。
    網址:http://www.ruby-lang.org/en/

    下載完成後,輸入下列命令:
    [root@localhost ~]# tar -zxvf ruby-1.9.1-p376.tar.gz
    [root@localhost ~]# cd ruby-1.9.1-p376
    [root@localhost ~]# ./configure
    [root@localhost ~]# make
    [root@localhost ~]# make install
  5. 安裝 FLVTool2
    FLVTool2 是一個用來編輯FLV檔的套件,透過它來儲存FLV檔,確保 FLV 檔裡有正確的 metadata。
    網址:http://rubyforge.org/projects/flvtool2/

    下載完成後,輸入下列命令:
    [root@localhost ~]# tar -xvf flvtool2-1.0.6.tar
    [root@localhost ~]# cd flvtool2-1.0.6
    [root@localhost ~]# ruby setup.rb config
    [root@localhost ~]# ruby setup.rb setup
    [root@localhost ~]# ruby setup.rb install
  6. 安裝 ffmpeg-php
    為了讓 PHP 取得影片的資料,要安裝 ffmpeg-php 插件。
    網址:http://ffmpeg-php.sourceforge.net/
    下載:http://sourceforge.net/projects/ffmpeg-php/files/ffmpeg-php/0.6.0/ffmpeg-php-0.6.0.tbz2/download

    下載完成後,輸入下列命令:
    [root@localhost ~]# tar -xvf ffmpeg-php-0.6.0.tbz2
    [root@localhost ~]# cd ffmpeg-php-0.6.0
    [root@localhost ~]# phpize
    [root@localhost ~]# ./configure && make
    [root@localhost ~]# make install

    在configure && make階段遇到CODEC_TYPE_VIDEO undeclared問題
    新增yum的Repository後
    重裝yum install ffmpeg ffmpeg-devel ffmpeg-libpostproc 解決一些問
    Install FFmpeg and ffmpeg-php on CentOS Easily
    之後又遇到‘PIX_FMT_RGBA32′undeclared 看下篇解決
    ffmpeg-php error PIX_FMT_RGBA32

    如果 Apache 是使用 XAMPP 請參考這篇:
    [Linux] 在 XAMPP 上安裝 PHP extension (以 ffmpeg-php 為例)

    make後 可以看到產生ffmpeg.so的資料
    再搬到/usr/lib64/php/modules/ffmpeg.so
    即可設定 PHP 載入這個plugin。
  7. 設定 php.ini
    1. #vi /etc/php.ini
      加入以下內容:
      [ffmpeg]
      extension=ffmpeg.so
    2. 重開apache
      #service httpd restart

    最後重啟 Apache
  8. 開始轉檔
    以下是一個簡單的範例:
    PHP程式碼
    //ffmpeg 的執行路徑
    $ffmpegPath = "/usr/bin/ffmpeg";
    //來源影片路徑
    $srcFile = '/var/www/html/ffmpeg/upload/test_in.wmv';
    //輸出影片路徑
    $outFile = '/var/www/html/ffmpeg/upload/test_out.flv';
    //輸出縮圖路徑
    $outImg = '/var/www/html/ffmpeg/upload/test.jpg';

    //取得影片資訊
    $ffmpegObj = new ffmpeg_movie($srcFile);
    //取得音頻比特率
    $srcAB = intval($ffmpegObj->getAudioBitRate()/1000);

    //將影片轉換為FLV檔
    exec("$ffmpegPath -i $srcFile -f flv -s 436x324 -acodec libmp3lame -ar 22050 -ac 2 -ab $srcAB -y $outFile");

    //從影片產生縮圖
    exec("$ffmpegPath -itsoffset -1 -i $srcFile -vcodec mjpeg -vframes 1 -an -f rawvideo -s 436x324 $outImg");
如果沒有錯誤,又沒有轉出的檔案 檢查一下資料夾權限是否限制寫入

Reference

星期五, 8月 19, 2011

書: Clean Code

  1. What is clean code
    • "elegant and efficient" Bjarne Stroustrup, C++之父
      寫的真好...
    • "simple and direct" Grady Booch, OO大師
      幾個字就說出精要,大師就是大師

    為什麼會有bad code
    程式不斷修改,保持clean,混亂的程式碼才不會越滾越大
    導致沒辦法維護,記住童子軍的規則
    The Boy Scout Rule
    Leave the campground cleaner than you found it.

    5S
    • Sort 命名易辯識
    • Systematize 歸類(知道到哪找)
    • Cleaning 潔簡
    • Standardization 一致的coding style
    • Self-discipline 遵守規定
    總而言之就是Keep it clean
    Each function, each class, each module
    exposes a single-minded attitude

  2. Meaningful Names
    • Use Intention-Revealing Names
      透過命名就能知其意圖,如果還需要註解來解釋它,就代表不夠清楚
    • Use Pronounceable Names
      使用可發音的Name幫助溝通
    • Use Searchable Names
      方便search及取代
    • Use Problem Domain Names
      沒有適合使用的term,就使用domain的term,讓接手維護的人至少還可以問domain專家,這代表什麼
  3. Functions
    • Do One Thing(Small)
      只做命名的事細節,包給其他function
    • Function Arguments The Ideal number of arguments is 0 有參數,增加理解困難

  4. Comments
    Don’t comment bad code
    rewrite it 註解沒太多幫助,不如重寫重新整理

程式持續修改演化
不可能一次把程式寫好
First, Make It Work
Then Make It Right


References

星期五, 8月 12, 2011

git push 二三事

  • push origin
    git push可夾很多參數
    還看不太懂,好好研究一下吧
    • git push
          即git push <remote>, 如果<remote>沒設定,便push到origin
    • git push origin
         即git push origin :.
         The default behavior of this command when no is given can be configured by setting the push option of the remote.
         For example, to default to pushing only the current branch to origin use git config remote.origin.push HEAD. Any valid (like the ones in the examples below) can be configured as the default for git push origin.
    • git push origin :
           自動推到相同名稱的分支     
    • git push origin master
          將目前的master推到origin的master
      (most likely, it would find refs/heads/master), and update the same ref (e.g. refs/heads/master) in origin repository with it.      
    • git push origin HEAD
      將目前所在的branch推回origin下,同名稱的branch(
      未建立,會自動建立)
    • git push origin master:satellite/master dev:satellite/dev
           Use the source ref that matches master (e.g. refs/heads/master) to update the ref that matches satellite/master (most probably
          refs/remotes/satellite/master) in the origin repository, then do the same for dev and satellite/dev.   
    • git push origin HEAD:master
          
      HEAD為目前所在branch,也可以直接下名稱;而後面master是push到origin下的branch
    • git push origin master:refs/heads/experimental
             Create the branch experimental in the origin repository by copying the current master branch. This form is only needed to create a new branch or
                    tag in the remote repository when the local name and the remote name are different; otherwise, the ref name on its own will work.      
    • git push origin :experimental
                    Find a ref that matches experimental in the origin repository (e.g. refs/heads/experimental), and delete it.        
    • git push origin +dev:master
                    Update the origin repository’s master branch with the dev branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling
                    in the origin repository. Consider the following situation, where a fast-forward is not possible:
  • push remote
    • 送給某個repo
      $ git push ssh://yourserver.com/~you/proj.git master

git運用流程

目前做法
一台共用的測試機 + n台開發機

雖然每個人可各自pull其他人的東西
不過共同開發還是用1台做merge,其他人pull比較簡單點

  • push時機
    每次commit完
    便push到測試機,而push是push到測試機上自己的branch,這樣方便分辯誰push的
    再到測試機做merge,其他人做pull
  • pull時機
    每次commit完,就做pull

星期三, 8月 10, 2011

MySQL Proxy & Amoeba

做MySQL的效能多會用load balance
目前MySQL的load balance多採用官方的MySQL Proxy及大陸的Amoeba
以下整理網路上收集到的資訊,挺多簡體翻的 要習慣一下
  • MySQL Proxy
    安裝:mysql proxy讀寫分流(一)-mysql proxy的安裝方式
    說明:MySQL Proxy位於 client及MySQL server(s)中間
    MySQL Proxy可以monitor, analyze or transform their communication. 可達到:
    • load balancing
    • failover
    • query analysis
    • query filtering and modification
    • ... and many more. 
  • Amoeba
    安裝:Amoeba For MySQL 實現資料庫負載平衡(讀寫分離)
    說明:Amoeba 也位於Client、Database Server(s)之間
     Amoeba 具有負載均衡、高可用性、 sql過濾
    可承受達到讀寫分離、Query Route(解析sql query語句,並且根據條件與預先設定的規則,請求到指定的目標數據庫。可並發請求多台數據庫合併結果)
    對客戶端透明。主要降低數據切分帶來的複雜多數據庫結構、數據切分規則給應用
    帶來的影響。
  • 比較 in action

    • Load Blance及讀寫分離
      Master:Server1(可讀寫)
      Slaves:Server2, Server3, Server4(3個平等的數據庫。只讀/負載均衡)

      • MySQL Proxy
        #設定db server變數
        Server1=10.1.1.1  #master
        Server2=10.2.1.1  #slave1
        Server3=10.3.1.1  #slave2
        Server4=10.4.1.1  #slave3
        ROOT_DIR=/usr/local

        #指定讀寫server
        LUA_PATH="$ROOT_DIR/mysql-proxy/share/mysql-proxy/?.lua" $ROOT_DIR/mysql-proxy/sbin/mysql-proxy \
        --daemon \
        --proxy-backend-addresses=$Server1:3306 \
        --proxy-read-only-backend-addresses=$Server2:3306 \
        --proxy-read-only-backend-addresses=$Server3:3306 \
        --proxy-read-only-backend-addresses=$Server4:3306 \
        --proxy-lua-script=$ROOT_DIR/mysql-proxy/share/mysql-proxy/rw-splitting.lua

        這個例子中10.1.1.1為可寫
        限制10.2.1.1,10.3.1.1,10.4.1.1只能讀
      • Amoeba
        amoeba提供讀寫分離pool相關配置。並且提供負載均衡配置。
        可配置server2、server3、server4形成一個虛擬的 virtualSlave,該配置提供負載均衡、failOver、故障恢復功能
        <dbServer name=“virtualSlave” virtual=“true”>
        <poolConfig>
        <className>com.meidusa.amoeba.server.MultipleServerPool</className>
        <!-- 負載均衡參數 1=ROUNDROBIN , 2=WEIGHTBASED -->
        <property name="loadbalance">1</property>

        <!-- 參與該pool負載均衡的poolName列表以逗號分割 -->
        <property name="poolNames"> Server2,Server3,Server4</property>
        </poolConfig>
        </dbServer>

        指派讀寫機
        <queryRouter>
        <className>com.meidusa.amoeba.mysql.parser.MysqlQueryRouter</className>
        <property name="LRUMapSize">1500</property>
        <property name="defaultPool">server1</property>

        <property name="writePool">server1</property>
        <property name="readPool">virtualSlave</property>

        <property name="needParse">true</property>
        </queryRouter>
        那麼遇到update/insert/delete將 query語句發送到 wirtePool,將 select發送到 readPool機器中執行。
    • 資料分割
      • MySQL Proxy
      • Amoeba
        SELECT * from user_event where user_id='test' and gmt_create between Sysdate() -1 and Sysdate()

        如果根據gmt_create 時間進行數據切分,比如 6個月進行切分一次
        amoeba提供利用類似sql表達式進行數據切分:
        • 規則1(對應服務器1):
          GMT_CREATE > to_date('2008-01-01','yyyy-mm-dd')
          AND GMT_CREATE < to_date('2008-05-31','yyyy-mm-dd')
        • 規則2(對應服務器2)
          GMT_CREATE > to_date('2008-06-01','yyyy-mm-dd')
          AND GMT_CREATE < to_date('2008-12-31','yyyy-mm-dd')
        上面的sql的條件 gmt_create 與規則裡面的的gmt_create 進行交集判斷,如果存在交集則表示符合規則。 則會將sql轉移到 規則1 的相應的服務器上面執行。
        利用amoeba寫出這種類似規則很容易,但是要想做到數據切分以後可線性擴容,那麼這樣的規則需要自己根據業務實際情況進行設置。
        amoeba可同時將sql 並發分發到多台服務器、然後將結果合併再反饋給客戶端,而且amoeba內部現成採用無阻塞模式,工作線程是不會等待的,並發請求多台 database server情況下,客戶端等待的時間基本上面是性能最差的那台 database server+amoeba內部解析協議的時間

    注意事項

    沒實作過,也不知要注意什麼 還是看別人寫的吧
    • MySQL Proxy
      • 同步延遲問題
        寫入後,其他slaves的同步問題,MySQL Proxy如何解決同步延遲問題
      • 資料是亂碼
        有看到2種解決方法,還沒試過
        • 設定mysql server
          set names "utf8"也沒有效果。
          [mysqld]
          skip-character-set-client-handshake
          init-connect='SET NAMES utf8'
          default-character-set=utf8
        • 修改/etc/my.cnf 設定檔
          加入底下設定,即可解決亂碼問題(當然您要依據您的環境做修改)
          default-character-set = utf8
          skip-character-set-client-handshake
          character-set-server = utf8
          collation-server = utf8_general_ci
          init-connect = SET NAMES utf8
    • Amoeba
        MySQL使用Amoeba作为Proxy时的注意事项 以下是截錄的
      • Amoeba不支持事务
        p.s. 還不知道"事務"是什麼 不過官網似乎提到有支援了
      • Amoeba不支持跨库join和排序
        跨庫的join和排序非常消耗資源,會導致性能嚴重下降,Amoeba沒有進行支持,只能做到分數據庫實例。
      • Amoeba不支持大數據量的查詢。
        不適合返回大量(超過10萬)數據的查詢,大數據量的查詢非常消耗內存,Amoeba在進行大數據量查詢時性能會非常差。當然,實際業務中需要進行大數據量查詢的情況會非常少或者根本沒必要實現這種情況。這裡所謂的大數據量查詢指的是一次查詢結果超過十萬行。
      • Amoeba需要更嚴格的SQL語句規範
        From 關鍵字後面如果不是子查詢,一律不能帶括號」()」;
        如果的表中字段名與關鍵字或者函數名一樣需要帶上字符` (比如:mytable.`order`)
      • 與直接操作mysql數據庫相比,amoeba性能的損失大概在怎麼一個範圍?
        amoeba是屬於代理層,起碼要消耗2次網絡IO,加上amoeba自身的計算時候的消耗,
        如果數據庫的性能非常高,或者sql的執行並不消耗數據庫的磁盤IO,那麼這時候完全不能體現amoeba的好處,反而會降低整體的性能。具體數據目前沒有算過。

    結論

    • 學習曲線
      由於MySQL Proxy需透過Lua Script
      看起來不難,不過要初學者在linux去碰這東西,還真是有難度

      而Amoeba設定就簡單的多
      只需要進行相關的XML配置就可以滿足需求
      SQLJEP語法寫規則
      雖然lua也不難,但比起設定檔的學習曲線還是有差
    • 效能方面
      比官方的mysql proxy性能大致低10%~20%左右
      在一次請求數據量比較大的情況下比如好幾千條數據,性能有所下降,這個原因是由於解析了mysql與客戶端之間交互的所有數據包,而mysql proxy在沒有使用lua特定腳本的時候是不會解析mysql數據包
      並發能力來說比mysql proxy會更強勁,還有穩定性方面都比mysql proxy強。從使用的連接數來看,在相同的客戶端並發連接情況下,與mysql數據庫的連接數將比mysql proxy少一半。
      在0.27版本以後,amoeba的性能逐漸超過了MySQL Proxy
    • 文件支援
      維護amoebad的人似乎不多
      在官網查相關文件都有些不清楚
      問題回覆也沒有歸類,有問題不好解決
    • 穩定性
      覺得Amoeba太新了
      官網上也有不少人回應bug的事
      穩定性也是需要考量的地方
    References

星期五, 8月 05, 2011

php比較相似字串

  1. 比對相似的字串 similar_text($str1, $str2)
    //測試性名陣列
    $names = array('Robert Smith','Bobby Smythe','Roberto Thithe', 'Robin Smith');

    //檢查相似程度
    foreach($names as $name){
    similar_text($name, 'Roberto Smythi', $percent);
    echo "{$name} = {$percent}%\n";
    }
    //result
    //Robert Smith = 88%
    //Bobby Smythe = 64%
    //Roberto Thithe = 74.074074074074%
    //Robin Smith' = 66.66666666667%
  2. levenshtei()


See Also

  • soundex() - Calculate the soundex key of a string

星期一, 8月 01, 2011

$_SERVER

url為www.example.com/controllerA/actionB/argC/C
利用$_SERVER的各參數,可得以下

  • Server相關
    參數說明value
    SERVER_NAMEServer位置www.example.com
    SERVER_ADDRserver IP位置192.168.11.1
    SERVER_PORTPort80
    DOCUMENT_ROOTweb的根目錄/var/www/html(看/etc/httpd/conf/httpd.conf的設定)
    SCRIPT_FILENAMEscript位置
    SCRIPT_NAMEscript名稱
  • Client相關
    參數說明value
    REMOTE_ADDRclient的ip192.168.11.1
  • request相關
    參數說明value
    REQUEST_URIrequest的uri/controllerA/actionB/argC/C






星期三, 7月 27, 2011

git

  • 安裝git
    • install git
      $ yum install git-core
      如果發生No package git-core available.
      $rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
    • 環境設定
      git config、git script自動完成
  • git操作
    1. 建立Repository
      兩種方法
      • 以該資料夾當成新的Repository
        $ cd (project-directory)
        $ git init
        $ (add some files)
        $ git add .
        $ git commit -m 'Initial commit'
      • 從遠端複製一份Repository
        git clone http://xxxx
    2. 查看版本
      git log
    3. 暫存
      git stash
    4. 重置及還原
      reset, revert
FAQ

  • commit原則 (from ihover's slide)
    • 適當的粒度/相關性/獨立性
      • 以一個小功能、小改進或一個bug fixed為單位
      • 無相關的修改不在同一個commit
      • 語法錯誤的半成品程式不能commit
  • git push error
    git v1.7後 就不允許覆蓋origin的master
    如果當初始化資料夾下git --bare init時
    沒加上參數--bare 就會發生這個錯誤
    refusing to update checked out branch: refs/heads/master
    如果硬要幹的話....
    git config --bool core.bare true
    這樣就可以push了

    另外較好的解決方法是在local開branch開發,再push到origin的branch後,做merge動作 在要push的branch下 $git push origin HEAD:branch2 #branchX未建會自動建 回到origin,用git branch會看到branch2 $git checkout master #假設是master要merge branch2 $git merge branch2

References

星期五, 7月 22, 2011

提升查詢效率與避免LOCK發生

Sql查詢時 會因之前的操作而做lock
因此會有些delay的等待
加了WITH (nolock)就不會理會transaction lock
而直接回覆查詢資料,因而提升回覆速度

  • MSSQL
    SELECT * FROM TABLE WITH (nolock)
    但會有dirty read,所以較不重要資料才可以這麼用
先在DB打開Snapshot功能,再用command or connection string 控制isolation level。
PHP的mssql server driver 不支援 connection string控制isolation level,因此只能用sql command 或者在DB打開RCSI (READ COMMITTED SNAPSHOT isolation),全部查詢就會在此isolation level
  • MySQL
    1. 利set session
      SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
      SELECT * FROM TABLE_NAME ;
      SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;
    2. inside a transaction
      SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
      GO

    3. 設定global variable
      SELECT @@global.tx_isolation; (global isolation level)
      SELECT @@tx_isolation; (session isolation level)

MySQL uses table-level locking for ISAM, MyISAM, and MEMORY (HEAP) tables, page-level locking for BDB tables, and row-level locking for InnoDB tables.

http://dev.mysql.com/doc/refman/4.1/en/internal-locking.html

References

星期四, 7月 21, 2011

vim 環境設定

  • 環境
    • 將vi以vim啟動
      就是下vi等於下vim
      # vi ~/.bashrc
      ---------/root/.bashrc----------
      alias vi='vim'  #加入這一行
    • 支援編碼
      vim /etc/vim/vimrc
      
      -----------/etc/vim/vimrc-------------------
      
      set fileencoding=utf-8,big5,gb18030  //支援中文utf-8,繁體big5及簡體gb
    • Turn on or off color syntax highlighting in vi or vim
      • 從環境變數設定
        # echo 'syntax on' >> /root/.vimrc
      • 使用中設定
        //command mode
        
        :syntax on //or off
    • 取消自動產生的*.ext~, .*.swp檔
      這是vi自動產生的備份檔 在/etc/vimrc下加入
      set nobackup #不產生*.ext~
      set noswapfile #不產生.*swp
      set nowritebackup #不管不產生哪一項,這個都要給
      
    • 關掉吵人的beep聲
      set vb
      vb = visual bell
    • 設定tab長度及自動縮排長度
      為了follow PSR規範... 不用tab,要用4個whitespace
      vi ~/.vimrc
      set tabstop=4
      set shiftwidth=4
  • 縮排 indent

    1. 取得indent檔
      先取得相關的indent檔,例如html縮排,會得到html.vim
      其他相關縮排檔
      • javascript
      • jQuery
      • php
      • php(html enhanced)
        由於php裡,常會夾html,而在原php的縮排對html的支援不是很好,所以有人做了加強版
        p.s. 作者預設縮3個空格,如果要改成縮8個,在第27行,set sw=3 //改成8即可
    2. 放到~/.vim/indent 
      如果沒有就自行建資料夾
    3. 啟動縮排
      在~/.vimrc中(如果沒有就自行建),加入 filetype indent on
  • 編輯
    • 取代斷行符號
      用vi編輯時,有時會遇到^M的斷行符號
      雖然不影響,不過還挺礙眼的
      幾百行下來還挺難改的,又打不出取代的符號,總算在找到取代的方法了
      :%s/^V^M//g

      ^v為CONTROL-V,而^m是CONTROL-M當打完這兩個時,就會出現
      :%s/^M//g
  • 縮排
    1. Html, JavaScript
      JavaScript Indent : Javascript indenter (HTML indent is included) , Preston Koprivica  
      直接下載 
      安裝:
      # tar xvf web-indent.tar  //解壓
      # cd web-indent/indent/     //進到html.vim及javascript.vim的資料夾
      # cp *.vim ~/.vim/indent/  //將*.vim全放到runtime目錄下的vim環境

參考網路的範例,調成自己用的
" encoding
 set encoding=utf-8
 set fileencodings=utf-8,cp950,latin1

"syntax
 syntax on " 語法上色顯示
 set nocompatible " VIM 不使用和 VI 相容的模式
 au BufReadPost *.volt set syntax=php
 au BufReadPost *.zep set syntax=php

"indent
 set shiftwidth=4 " 設定縮排寬度 = 4
 set tabstop=4 " tab 的字元數
 set softtabstop=4
 set expandtab

" setting
 set ruler " 顯示右下角設定值
 set backspace=2 " 在 insert 也可用 backspace
 set ic " 設定搜尋忽略大小寫
 set ru " 第幾行第幾個字
 set hlsearch " 設定高亮度顯示搜尋結果
 set incsearch " 在關鍵字還沒完全輸入完畢前就顯示結果
 set smartindent " 設定 smartindent
 set confirm " 操作過程有衝突時,以明確的文字來詢問
 set history=100 " 保留 100 個使用過的指令
 set cursorline " 顯示目前的游標位置
 set laststatus=2
 set statusline=%4*%<\%m%<[%f\%r%h%w][%{&ff},%{&fileencoding},%Y]%=\[Position=%l,%v,%p%%]
 set nu
 set cursorline

 " Color configuration
 set bg="solarized dark"
 color evening " Same as :colorscheme evening
 hi LineNr cterm=bold ctermfg=DarkGrey ctermbg=NONE
 hi CursorLineNr cterm=bold ctermfg=Green ctermbg=NONE

效果見下圖



References

星期一, 7月 18, 2011

window, document, dom的寬與高

  • document
    整份文件的高 $(document).height()
  • window
    視窗(browser)的高 $(window).height()
  • dom物件
    絕對高 $(xxx).position().top; //不是method哦


$(window).scroll(function(){
    console.log('document:%d, window:%d scroll:%d',
        $(document).height(),  //整份文件的高
        $(window).height(),      //視窗(browser)的高
        $(window).scrollTop()); //目前捲的位置
});

星期日, 7月 17, 2011

MySQL - select最佳化分析

利用EXPLAIN幫助索引和查出最佳化的查詢語法
EXPLAIN SELECT * FROM website WHERE url='http://homeserver.com.tw';

欄位資訊,完整版看官網EXPLAIN的欄位說明
Column Meaning
id The SELECT identifier
select_type The SELECT type
沒有union為simple, 其他看官網
table The table for the output row
type The join type
最優至最差的類型為system,const, eq_reg, ref, range, ..., ALL 
possible_keys The possible indexes to choose
key The index actually chosen
如果為NULL,則是沒有使用索引。
key_len The length of the chosen key
長度越短 準確性越高。
ref The columns compared to the index
顯示那一列的索引被使用。一般是一個常數(const)。
rows Estimate of rows to be examined
Extra Additional information
MySQL用來解析額外的查詢訊息。如果此欄位的值為:Using temporary和Using filesort,表示MySQL無法使用索引。

  • Extra
    Extra為MySQL用來解析額外的查詢訊息,其中欄位值所代表的意義如下:
    • Distinct:當MySQL找到相關連的資料時,就不再搜尋。
    • Not exists:MySQL優化 LEFT JOIN,一旦找到符合的LEFT JOIN資料後,就不再搜尋。
    • Range checked for each Record(index map:#):無法找到理想的索引。此為最慢的使用索引。
    • Using filesort:當出現這個值時,表示此SELECT語法需要優化。因為MySQL必須進行額外的步驟來進行查詢。
    • Using index:返回的資料是從索引中資料,而不是從實際的資料中返回,當返回的資料都出現在索引中的資料時就會發生此情況。
    • Using temporary:同Using filesort,表示此SELECT語法需要進行優化。此為MySQL必須建立一個暫時的資料表(Table)來儲存結果,此情況會發生在針對不同的資料進行ORDER BY,而不是GROUP BY。
    • Using where:使用WHERE語法中的欄位來返回結果。
    • System:system資料表,此為const連接類型的特殊情況。
    • Const:資料表中的一個記錄的最大值能夠符合這個查詢。因為只有一行,這個值就是常數,因為MySQL會先讀這個值然後把它當做常數。
    • eq_ref:MySQL在連接查詢時,會從最前面的資料表,對每一個記錄的聯合,從資料表中讀取一個記錄,在查詢時會使用索引為主鍵或唯一鍵的全部。
    • ref:只有在查詢使用了非唯一鍵或主鍵時才會發生。
    • range:使用索引返回一個範圍的結果。例如:使用大於>或小於<查詢時發生。 index:此為針對索引中的資料進行查詢。 ALL:針對每一筆記錄進行完全掃瞄,此為最壞的情況,應該儘量避免。

Reference

星期六, 7月 16, 2011

PHP 效能 - 快取篇

  1. APC
  2. Memcache

何時用APC (獨立在一台server)
  • Application Settings
  • Configuration
  • Data is the same for each user
  • request都由同一台server responses(i.e sticky session)
  • file upload process & sessions (if using sticky session)
何時用Memcache (分散在不同的servers)
  • 當request不保證指向同server時
  • Data is specific or targeted to a user
  • User sessions

References

Apach效能

  1. 確保足夠的RAM
    在無法購買更快的硬體情形下,硬體方面已經沒有方法讓伺服器更快,因此重點要確定有足夠的RAM
    • 利用top或ps檢視apache的process佔用的記憶體
    • 或限制最大的process數,利用MaxClients指令限制
  2. 以ab評校Apache的效能
    解答:apache/bin/ab -n 1000 -c 10 htp://www.example.com/test.html
    ab: 請求url的資源
    -n: request 1000次
    -c: 一次送出10個請求(同步的意思)
    適合用於輕微組態改變,並測試改變前後伺服器的效能
    note:,不要在欲測試的server試ab,因為ab會耗資源,所以效能會低於別台機器發出的ab,且同一台不會有網路delay
  3. 調校保持連線的設定
    解答:啟用KeepAlive指令,並將相關指令設定成合理值
    KeepAlive On
    MaxKeepAliveRequests 0
    KeepAliveTimeout 15

    KeepAlive可讓單一連線上多個請求,減少建立socket連線所需的時間
    MaxKeepAliveRequest即每個連線上允許多少請求
    KeepAliveTimeout 超過閒置時間即斷線,大多數15即可順利運作


Reference
Apache Cookbook, O'Reilly

星期六, 7月 02, 2011

vm指向host為gateway

最近把vm用在自己的nb上跑
利用bridge mode向dhcp取ip

有次到了沒網路的地方 才發覺沒辦法連到vm
才想說用自己的nb當gateway來連,這樣不用怕沒網路,也不用改ip了

想法是把vm的gateway設為自己的nb
不過試了好久,一直沒成功
請教仰哥後,果然成功了
再次感謝仰哥


  1. 選擇Nat模式
    在vm的Network Mode選擇Nat模式
  2. 抄下nat網卡的ip
    vm安裝好後,會建立2張網卡,抄下ip(右鍵/內容... 應該不用教吧)
  3. 設定gateway
    將vm裡的os的gateway設成步驟2的ip即可
  4. 就這麼簡單


星期四, 6月 30, 2011

json parse error with double quotes

搞了半天
原來要用3個斜線
var tmp = {'name' : "kev///'s blog"};


Reference
json parse error with double quotes

星期二, 6月 28, 2011

建立index的準則

  • 具有特定鍵值足以識別特定資料
    如Primary key, Alternative key或user視為key拿來查詢的欄位
  • table資料少
    不到50筆或不到一個Data block,則建立的價值不大
  • join過程在where中會出現的欄位
    join過程大都以Primary key及Foreign key為條件,因此最好針對 Foreign key建立Index
  • 如果update或Delete程度超過20%,index價值不大
    因為系統必需同時I/O索引與實體資料
  • 不要太多索引
    太多的索引會造成資料異動過程要花很多時間調整索引
  • 查尋條件不明確
    考慮建立複合索引

Reference
Oracle 10g 資料庫管理實務, 林存德

星期六, 6月 18, 2011

JavaScript debug工具、技巧

寫入快顯視窗
  • 測試視窗
    var debug = window.open('','newWin',[arguments]);
    function addDebugginMessage(msg){
    debug.document.write(msg + '<br>');
    }

無侵入腳本程式設計 unobtrusive scripting

意思即將html中的view(css),結構(html),行為(js)分開
不要把3者都摻在html裡
css就很明確的利用class name從html分離了
js見下例
//html夾了javascript
<a href="#" onclick="showPopuup('niceimage.jpg')">Nice image!</a>


將html與js分開
<a href="niceimage.jpg" id="nice">Nice image!</a>
document.getElementById('nice').onclick = function(){
showPopup(this.href)
};

利用JavaScript跳過中間轉頁處理

html中,利用href的效果,如同click連結,會開啟新頁面
如果js中,判斷條件後轉頁
利用href轉頁,將會在history多一個歷史記錄
將造成使用者click上一頁會回到判斷頁,
而判斷頁又馬上轉到下一頁

解決方法,利用replace
//javascript
var isSupported = [check JavaScript support];
if (isSupported){
  locaiton.href = 'scriptpage.html';       //如果使用者按上一頁,就會再回到此判斷頁
  locaiton.replace('scriptpage.html');  //將回到真的上一頁
}




Reference:
pp]{ on JavaScript

星期一, 6月 13, 2011

CentOS 5.5升級PHP至最新版


PHP 5.3 on CentOS 5.5


#To install, first you must tell rpm to accept rpm’s signed by me, then add the yum repository information to yum:
rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm

#Now you can install php by doing:
yum --enablerepo=webtatic install php

#update an existing installation of php
yum --enablerepo=webtatic update php

後記
好像失敗,原因還沒查出來
似乎是升級php後,部份套件沒升到相同版本
例如php 5.3,但php-common停在5.1
先remove重灌試試
而yum install php-common 會停在5.1
所以要用上面的方法 改變安裝的來源
yum --enablerepo=webtatic install php-common 安裝php-pear 因為centos的pear版本為1.4.9 需與php-devel 5.1搭
所以如果更新php後,就會裝不了
簡單點的方法就 ...
  1. 先降回5.1
    yum remove php php-*
  2. 再安裝pear
    yum install php-pear
  3. 最後升級php最新版

星期五, 6月 03, 2011

軟體開發書單

初階
  1. 態度
    心態最重要... 一切從心開始...
    • 自慢 1
    • 自慢 4
    • 打不破的人生 30 個定律
    • 學徒模式 優秀軟體開發者的養成之路
  1. Programming 
    • 編程創藝:編寫出卓越的程式碼 Code Craft: The Practive of Writing Excellent Code
    • 重構:改善現有程式碼的設計 Refactoring: Improving the Design of Existing Code, Martin Fowler
    • 程式碼大全 Code Complete
    • 程式開發心理學 The Psychology of Computer Programming 
    • 程式師修煉之道 The Pragmatic Programmer
    • 程式設計實踐 The Practice of Programming
    • Woking Efficiency with Legacy Code
  2. Design Pattern
    • 設計模式:可重複用的物導向軟體的基礎 Design Patters: Elements of Reusable Object-Oriented Software 
    • Design Pattern於java語言上的實習應用, 結城浩
  3. Coding Sytle
進階
  1. 物件觀念
    • Streamlined Object Modeling
    • Object Modes: Strategies, Patterns, and Applications (2/e) - by Peter Coad
    • Java Modeling in Color with UML: Enterprise Components and Process - by Peter Coad, Eric Lefebvre, Jeff De Luca
  2. Software Architecture
    1. Expert One-on-One J2EE Design and Development
      Spring Framework的創始人Rod Johnson對於J2EE 2.x的反思
    2. Expert One-on-One J2EE Development without EJB
  3. Software Development
  4. 專案管理
    • 人月神話 (The Mythical Ma0Month)
    • 溫伯格的軟體管理學, 溫伯格
    • 與熊共舞:軟體專案的風險管理
    • UML Distilled, Martin Fowler
    • 讓事情發生--專案管理之美學
    • 人件 (Peopleware:Productive Projects and Teams)
    • 深入淺出軟體開發 
    • Ship it
References