2012年12月23日 星期日

[PHP] Highlight search result


一般我們在做搜尋時,輸出的結果都會對 keyword 做 highlight 來凸顯比對結果
像字串 How to highlight search result 如果以 highlight, result 為 keyword 來搜尋
我們一般期待輸出的結果為 How to <span class=highlight>highlight</span> search <span class=highlight>result</span>
如果單純以 str_replace 用迴圈來對每個 keyword 比對時,在跑第二次也會發生問題
或是用 array 來建立 keys 和 replace 也會有點麻煩

一個簡單的寫法是使用 preg_replace 來處理

以下是範例
<style>
    .highlight {color:red}
</style>
<?php
$keys[] = 'highlight';
$keys[] = 'result';
$text = 'How to highlight search result.';

echo findKeywords_org($text, $keys) . '<br>';
echo findKeywords($text, $keys) . '<br>';

function findKeywords_org($text, $keys)
{
$replace = array();
foreach($keys as $k)
{
$replace[] = "<span class=highlight>$k</span>";
}
return str_ireplace($keys, $replace, $text);
//這是 str_replace 不分大小寫的版本,但限定 php5 以上才有,故在 php4 要不分大寫法也須要自行處理,會很麻煩
}

function findKeywords($text, $keys)
{
    $text = htmlspecialchars($text);
    $patterns = '/('. implode('|', $keys) .')/i'; //i 是不分大小寫
    $replacements = '<span class=highlight>${0}</span>'; //${0}所以比對 patterns 到的字串 value
    return preg_replace($patterns, $replacements, $text);
}



Ref: http://php.net/manual/en/function.preg-replace.php

2012年12月22日 星期六

[JavaScript] Variable dump

一個簡單的方法是
console.log(object);

另一個是寫個 dump 函數
function dump(obj) {
         var out = '';
         for (var i in obj) {
                 if (typeof obj[i] === "object")
                         out += i + ": {\n" + dump(obj[i]) + "}\n";
                 else
                         out += i + ": " + obj[i] + "\n";
         }
         return out;
}


Example:
<script>
        var book = {
                name: 'Javascript tutorial',
                price: 50,
                index: {
                        1: 'introduction',
                        2: 'hello world'
                },
                toString: function () { return "name: " + this.name + ",price: " + this.price; }
        }
        function dump(obj) {
                var out = '';
                for (var i in obj) {
                        if (typeof obj[i] === "object")
                                out += i + ": {\n" + dump(obj[i]) + "}\n";
                        else
                                out += i + ": " + obj[i] + "\n";
                }
                return out;
        }
        console.log(book);
        console.log(dump(book));
</script>



[PHP] PHP array to Javascript json object


<?php

        $books = array();
        $books[] = array('name'   => 'php tutorial',
                         'author' => 'php',
                         'price'  => 100
                        );
        $books[] = array('name' => 'javascript tutorial',
                         'author' => 'javascript',
                         'price'=> 50
                        );

?>
<script>
        var books = <? echo json_encode($books) ?>;
        for(var i=0; i<books.length; i++)
        {
                console.log('name: '   + books[i].name);
                console.log('author: ' + books[i].author);
                console.log('price: '  + books[i].price);
        }
</script>

2012年12月4日 星期二

[CSS] CSS 選擇器

筆記起來...
ref: http://www.w3.org/TR/CSS2/selector.html




PatternMeaningDescribed in section
*Matches any element.Universal selector
EMatches any E element (i.e., an element of type E).Type selectors
E FMatches any F element that is a descendant of an E element.Descendant selectors
E > FMatches any F element that is a child of an element E.Child selectors
E:first-childMatches element E when E is the first child of its parent. The :first-child pseudo-class
E:link
E:visited
Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited). The link pseudo-classes
E:active
E:hover
E:focus
Matches E during certain user actions. The dynamic pseudo-classes
E:lang(c) Matches element of type E if it is in (human) language c (the document language specifies how language is determined). The :lang() pseudo-class
E + FMatches any F element immediately preceded by a sibling element E.Adjacent selectors
E[foo]Matches any E element with the "foo" attribute set (whatever the value). Attribute selectors
E[foo="warning"]Matches any E element whose "foo" attribute value is exactly equal to "warning". Attribute selectors
E[foo~="warning"]Matches any E element whose "foo" attribute value is a list of space-separated values, one of which is exactly equal to "warning". Attribute selectors
E[lang|="en"]Matches any E element whose "lang" attribute has a hyphen-separated list of values beginning (from the left) with "en". Attribute selectors
DIV.warningLanguage specific. (In HTML, the same as DIV[class~="warning"].) Class selectors
E#myidMatches any E element with ID equal to "myid".ID selectors

[PHP] PHP 型態比較表

筆記起來...
ref: http://php.net/manual/en/function.empty.php


Comparisons of $x with PHP functions
Expression gettype() empty() is_null() isset() boolean : if($x)
$x = ""; string TRUE FALSE TRUE FALSE
$x = null NULL TRUE TRUE FALSE FALSE
var $x; NULL TRUE TRUE FALSE FALSE
$x is undefined NULL TRUE TRUE FALSE FALSE
$x = array(); array TRUE FALSE TRUE FALSE
$x = false; boolean TRUE FALSE TRUE FALSE
$x = true; boolean FALSE FALSE TRUE TRUE
$x = 1; integer FALSE FALSE TRUE TRUE
$x = 42; integer FALSE FALSE TRUE TRUE
$x = 0; integer TRUE FALSE TRUE FALSE
$x = -1; integer FALSE FALSE TRUE TRUE
$x = "1"; string FALSE FALSE TRUE TRUE
$x = "0"; string TRUE FALSE TRUE FALSE
$x = "-1"; string FALSE FALSE TRUE TRUE
$x = "php"; string FALSE FALSE TRUE TRUE
$x = "true"; string FALSE FALSE TRUE TRUE
$x = "false"; string FALSE FALSE TRUE TRUE


Loose comparisons with ==
TRUE FALSE 1 0 -1 "1" "0" "-1" NULL array() "php" ""
TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE TRUE FALSE FALSE TRUE FALSE
FALSE FALSE TRUE FALSE TRUE FALSE FALSE TRUE FALSE TRUE TRUE FALSE TRUE
1 TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
0 FALSE TRUE FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE TRUE TRUE
-1 TRUE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
"1" TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
"0" FALSE TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
"-1" TRUE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
NULL FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE
array() FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE
"php" TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
"" FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE


Strict comparisons with ===
TRUE FALSE 1 0 -1 "1" "0" "-1" NULL array() "php" ""
TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
1 FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
0 FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
-1 FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
"1" FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
"0" FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
"-1" FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
NULL FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
array() FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
"php" FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
"" FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE

2012年11月27日 星期二

[伺服器管理] inotify + rsync 完成即時同步資料

inotify 是個強大的檔案監控系統
可以監控所指定目錄下所有檔案變化,包含新增,刪除,修改...等事件

Linux kernel 需要 2.6.13 以才能有支援

故可以利用其機制 + rsync 在發現檔案系統有變化時即執行 rsync 來做同步

rsync 是個好用且強大的同步備份軟體,但可惜的是他在同步時通常是全目錄一起比較後 Diff 把 Diff 部份傳輸,如果檔案很多時,將會消耗許多系統資源。

所以利用 inotily + rsync 來降低其消耗資源,也可以達到即時同步

以下範例將實現將一台 Master 的網頁資料同步至另一台 Slave Server


rsync 遠端同步

將 master 資料(/var/www/myweb) 同步至 slave (/var/www/myweb)
ssh 192.168.1.2
rsync -avz  root@192.168.1.1:/var/www/myweb  /var/www/
(會要求輸入密碼,如不想輸入密碼請建立 ssh-key 並在指令加上 -e "ssh -i [key-path]")

ps一般情況不需即時同步,即可以使用 crontab job 來做定時同止
1 3 * * * /usr/bin/rsync -avz  -e "ssh -i /root/.ssh/priv-key" root@192.168.1.1:/var/www/myweb  /var/www/

上述的 rsync 已經是使用 ssh 登入再做 rsync 可以不用架 server,如果需求上有需要 rsync server 可以參考最後一段。


再來安裝 inotify來做即時監控並同步資料

Master:
1. 安裝 inotify
    a. 請至 https://github.com/rvoicilas/inotify-tools/wiki/ 下載 inotify-tools
    b. 將 inotify-tools-3.14.tar.gz 上傳至 master
    c. tar -zxvf inotify-tools-3.14.tar.gz
    d. cd inotify-tools-3.14
    e. ./configure
    f. make
   g. make install
2. 使用以下指令測試監控目錄 (/var/www/myweb)
inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format  '%T %w%f %e' --event modify,create,move,delete /var/www/myweb
(可以使用另個 ssh 登入並在該目錄下新增刪除檔案)

完整 event 可參考

http://linux.die.net/man/7/inotify
http://en.wikipedia.org/wiki/Inotify

3. 建立 script 用於啟動監控並即時同止
    a. vi  inotify-tools.sh

    加入以下內容

#!/bin/sh
src='/var/www/myweb'
dest='/var/www'
host='192.168.1.2'

/usr/local/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format  '%T %w%f %e' \
 --event modify,create,move,delete $src | while read date time file event
    do
        # echo $date $time $file $event
        # cmd="rsync -arq --delete $src $host::backup$dest" old command
        cmd="rsync -avz $src root@$host:$dest"
        # echo $cmd
        $cmd
    done




4. 開機時自動啟動
vi /etc/rc.d/rc.local
在後面加入
/root/inotify-tools.sh &
#請依據您放 inotify-tools.sh 的目錄修改

ps.如果不使用 rsync 亦可以使用 nfs + mount 的方式來處理
僅需將  cmd="rsync -avz $src root@$host:$dest"此行的指令
最後 root@$host:$dest 修改為 mount Slave上來目錄路徑即可




(option) 利用 rsync server 來同步資源 

Slave: (登入 Slave)
1. yum install rsync xinetd

2. vi /etc/xinetd.d/rsync
內容
service rsync
{
disable = no #改為 no
socket_type    = stream
wait                = no
user                = root
server              = /usr/bin/rsync
server_args      = --daemon
log_on_failure  += USERID
}
#並加入以下內容
[backup]   #表示在使用rsync指令時目錄代號 (與 samba 設定相似)
path = /var/www   #表示實際指向的目錄
uid = root
gid = root
hosts allow = 192.168.1.0/24  #充許的存取的 host,請依 ip 需求修改
read only = no

3. service xinetd restart

Master:
此時即可將 master 資料(/var/www/myweb) 同步至 slave (/var/www/myweb)
  rsync -arq --delete /var/www/myweb 192.168.1.2::backup/

ps一般情況不需即時同步,即可以使用 crontab job 來做定時同止

1 3 * * * /usr/bin/rsync -arq --delete /var/www/myweb 192.168.1.2::backup/

2012年11月9日 星期五

[IE10] 快速解決 Windows 8 IE 10 相容性問題



在網頁的 header 加入以下 meta 即可
<meta http-equiv='X-UA-Compatible' content='IE=9' >
or
<meta http-equiv='X-UA-Compatible' content='IE=9; requiresActiveX=true' >

IE=Value 表示 ie 預設使用的文件模式

value=5 表示使用 quick模式
value=7,8,9,10 表示使用對應的標準模式,ex: IE=9 即表示使用 IE 9 標準模式
value=Edge 表示使用該瀏覽器支援的最新版本的文式模式,故 IE 9  會使用 IE 9 模式、IE 10會使用 IE 10 模式

此方僅只是令 IE 10 可以快速的相容您目前系統
但無法完全解決問題,最好方法還是針對 IE 10 做最佳化


Reference : http://www.iefans.net/ie10-ie9-jianrongxing-faq/


另外由於 Windows 8 的 Desktop IE 10 與 Metro IE 10 是不同的兩個 ie
Metro IE 10 本身不支援 Flash 和 ActiveX
所以如果有使用 Flash 和 Active X 在 Metro IE 10 是無法正常瀏覽的
故加上 requiresActiveX=true 來提示使用都需要使用 Desktop IE 10

Reference : http://www.windows7hacker.com/index.php/2012/02/how-to-tell-ie-10-to-switch-from-metro-style-to-desktop-version/


Metro IE 10 Agent
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)

Desktop IE 10 Agent
32bit : Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
64bit : Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)

Reference:http://www.codeproject.com/Articles/269356/Internet-Explorer-10-User-Agent-Strings-On-Windows?display=Print



2012年8月18日 星期六

[MAC OS] 快速在 MAC 安裝 notepad++

Wine:
Unix 上執行 windows 程式軟體

Mac 環境需要
Intel x86 的 cpu
x11 (Snow Leopard 以上內建)


1. 安裝 Wine Bottler (已經 wine 包裝在內)
下載 Wine Bottler : http://winebottler.kronenberg.org/

直接點取,將 wine 和 wine bottler 拖至 appliaction



2. 下載 notepad++ zip package
請至官網 http://notepad-plus-plus.org/

unzip notepad++


直接點取 notepad++.exe 會彈出 Wine 視窗
選取 Run directly in .... (我是直接使用 /User/account/Wine Files)



go 即可執行 notepad++


3. 安裝 notepad++ plugin
直接下載將 dll 放進 notepad++ plugin 目錄內
目前安裝了 function list、hex editor 均可使用



ref:
http://www.youtube.com/watch?v=ZeYA3goZwY4
http://wiki.ubuntu-tw.org/index.php?title=Wine
http://www.winehq.org/

2012年8月16日 星期四

[MySQL] MySQL Replication (master slave)

以下實作一個範例為將 Master's Mysql 內的 test 資料庫同步至 Slave's Mysql 內的 test 資料庫


Master:
1. vi /etc/my.cnf
    加入
    server-id=1
    log-bin=/var/lib/mysql/mysql-bin #mysql 會根據這麼 log 檔去同步資料
    binlog-do-db=test  #設定那個 database 做同步, 在這裡以 test 為例
2.重新啟動 MySQL
   service mysqld restart
3.匯出 test 資料庫的資料(加 -l 是要把目前 table lock 起來再輸出)
   mysqldump -l -u root -p test > test.sql
4.將sql傳送到 slave 的機器上
   scp test.sql root@192.168.1.2:~/test.sql
5.進入MySQL command mode
    mysql -u root -p
6.建立一個做為 replication 的帳號密碼
   在此是建立一個帳號為 replication 密碼為 abc123 為例
    mysql> CREATE USER 'replication'@'%' IDENTIFIED BY 'abc123';
    給予 replication 帳號擁有 replicaiton 的權限
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';

Slave:
1. 建立一個 test 資料庫
    mysql -u root -p
    mysql> CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
2. 匯入資料
    mysql -u root -p test < test.sql
3. vi /etc/my.cnf
    加入
    server-id=2 #不能重複
    log-slave-updates                 #告訴 slave 去 master 抓資料
    log-bin=mysql-bin
    binlog_format=mixed
    relay-log=hostname-relay-bin
    replicate-do-db=test             #需要同步的 database name
    master-connect-retry=60      #取得資料發生錯誤多久重試嘗試(以秒單位)
    read-only=1                      
#很重要, 將 slave 的資料庫設為唯讀, 因為如果資料表格發生衝突時, 該資料表將不會再同步。另外要注意的是此選項對於 root 和擁有 replication 的帳號沒用, 這些帳號還是有寫入權限
4. service mysqld restart
5. mysql -u root -p
    修改 slave 的設定值
    mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.1',
                MASTER_USER='replication', MASTER_PASSWORD='abc123';
    這裡帳號密碼請填入 master 所建立的
    清空原設定 以下指令是如果原本有建立過replication可用此指令清除資料
    mysql> CHANGE MASTER TO MASTER_LOG_FILE='', MASTER_LOG_POS=0;
6. 啟動 slave
     mysql> SLAVE START;
7. 確認是否有啟動
     mysql> SHOW SLAVE STATUS;
    必須看到以下 2 個狀能為 Yes
    Slave_IO_Running Yes
    Slave_SQL_Running Yes
    如不是 Yes 請查看 /var/log/mysqld.log


    為你的系統建一個普通的帳密(上述如果開放寫入, 發生衝突即無法同步)
     mysql> CREATE USER 'test'@'%' IDENTIFIED BY 'eabc123';
    給予 test 帳號存取 test 資料庫權限
     mysql> GRANT ALL ON test.* TO 'test'@'%';


ref:
http://homeserver.com.tw/%E7%86%B1%E9%96%80%E6%9B%B8%E7%B1%A4/mysql-master-slave/
http://blog.wu-boy.com/2008/12/mysql-%E5%AF%A6%E5%81%9A-mysql-master-master-replication-%E5%90%8C%E6%AD%A5/

2012年7月31日 星期二

[Python] Windows 下快速安裝 Apache+Mysql+python

1. 快速安裝 apache + mysql + php + phpMyAdmin
首先到 http://www.appservnetwork.com/
下載 AppServ 執行安裝

 2. 安裝 python 到 http://www.python.org/download/
下載 python 2.x (or python 3.x)

 3. 安裝 mysql-pyhone 模組 到 http://www.lfd.uci.edu/~gohlke/pythonlibs/
下載 MySQL-python-1.2.3.win32-py2.7.‌exe or (MySQL-python-1.2.3.win32-py3.2.‌exe)
(這是 32 位元版本, 如是 64 位元是 MySQL-python-1.2.3.win-amd64-py2.7.‌exe )
執行安裝
再到 python shell
執行 import MySQLdb
如沒錯誤訊息就表示完成

4. 使用 cgi 模式
修改 httpd.conf
拿掉 LoadModule cgi_module modules/mod_cgi.so 註解
在 addHandle 加入 .py
AddHandler cgi-script .cgi .py
重開 apache

建立 C:\AppServ\www\test.py
輸入以下內容 (注意第一行請指向安裝 python 的目錄內的 python.exe)


#!C:\Python27\python.exe -u
# -*- coding: utf-8 -*-

print "Content-Type: text/html\n"
import MySQLdb

db = MySQLdb.connect(host="db_host", user="db_user", passwd="db_password", db="db_name")
cursor = db.cursor()

cursor.execute("SELECT * FROM table_name")
result = cursor.fetchall()

for record in result:
    print record[0],"<br>"


打開瀏覽器 http://localhost/test.py




ref
http://blog.xuite.net/autosun/study/42871538-%5BUbuntu%5D+%E5%AE%89%E8%A3%9D+Apache2+%2B+Python+%2B+MySQL
http://wiki.python.org/moin/CgiScripts



2012年6月4日 星期一

[Android] Bitmap out of memory 一些解決法

使用 Bitmap 在讀取較大的原始圖片時,常會發生 Out of memory 的錯誤
即可以利用 Bitmap.Options 的參數設定來降低讀取圖片時所需要的記憶體
其中 Android Developer 官方所教導的方法是使用 isSampleSize 的方式來降低讀取圖檔時所需要的 memory

該參數大於 1 時
如 2 即表示回傳的解析度為 width /2 * height / 2 的圖檔
4 即表示回傳的解析度為 width /4 * height /4 的圖檔
依此類堆
因解析度少很多,故可以減少讀圖檔的 memory

這部份的 code 可以依自己需求修改,跟官方不太一樣
以下所計算的方式是將圖片縮到比想要的解析度大一點的最小縮圖,求在顯示時有較佳的解析度
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) 
{
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
  
    inSampleSize = (int) Math.min(Math.ceil((float)width/(float)reqWidth),  Math.ceil((float)height/(float)reqHeight));

    return inSampleSize;
}

public static Bitmap decodeSampledBitmapFromFile(String fileName, int reqWidth, int reqHeight) 
{
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(fileName, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(fileName, options);
}
ps: inJustDecodeBounds 的參數表示會讀取圖片的一些 info 但不會將圖檔本體讀進來
此時可以讀到圖檔的寬高並無法使用該圖檔去處理或顯示(因為沒讀進 memory)

不過竟然有這樣的參數
interface 應該有可能實現,直接讀取想要寬高的圖檔才對!?


Ref:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

這樣的方式雖然可以大量減少 out of  memory 的問題
但還是有可能會發生
所以還是可以配合

bitmap.recycle();
System.gc();

來減少發生

更詳細與其他解法的 Ref:
http://givemepass.blogspot.tw/2011/11/blog-post_16.html
http://bluegray-javalearning.blogspot.tw/2011/07/android-out-of-memoryoom.html

2012年4月12日 星期四

[Apache] 在 windows apache2.2 編譯 mod_encoding

mod_encoding.c

環境
windows 7
visual studio 2010
apache2.2
apxs

1.
官網
http://webdav.todo.gr.jp/
http://gnuwin32.sourceforge.net/packages/regex.htm

下載
a. http://webdav.todo.gr.jp/download/mod_encoding-20021209.tar.gz
b. http://webdav.todo.gr.jp/download/experimental/mod_encoding.c.apache2.20040616a
c. http://gnuwin32.sourceforge.net/downlinks/regex-bin-zip.php (regex-2.7-bin.zip)

2.
a. 解開 mod_encoding-20021209.tar.gz
b. cd mod_encoding-20021209
c. 改名 mod_encoding.c 為 mod_encoding.c.bak
d. 複製 mod_encoding.c.apache2.20040616a 進來改名為 mod_encoding.c
e. 解開 regex-2.7-bin.zip
f. 複製 regex-2.7-bin/include/regex.h 到 mod_encoding-20021209/

3.
a. 建立目錄 mod_encoding-20021209/iconv_hook
b. 複製 mod_encoding-20021209/lib/iconv.h.replace 到 mod_encoding-20021209/iconv_hook/inconv.h
c. 複製 mod_encoding-20021209/lib/iconv_hook.h 到 mod_encoding-20021209/iconv_hook/iconv_hook.h

4. 修改 regex.h
windows 沒有的 sys/types.h 改為 stddef.h
將 #include <sys/types.h> 註解
加入 #include <stddef.h>

5. 修改 mod_encoding.c
a. 在 #include <httpd.h> 上加入 #include "regex.h"
b. 加入
#include <apr_strings.h>
#include "iconv_hook/iconv.h"

c. 修改 548 行
windows 沒有 index 改用 strchr 取代
if ((user = index(r->user, '\\')) == NULL)
改為
if ((user = strchr(r->user, '\\')) == NULL)

6. 修改 iconv_hook_eucjp.c、iconv_hook_mssjis.c、iconv_hook_ucs2_cp932.c、iconv_hook_utf8_cp932.c、iconv_hook_utf8_eucjp.c
(在 mod_encoding-20021209/lib)
windows 沒有 dirent.h 和 unistd.h
註解
//#include <dirent.h>
//#include <unistd.h>
加入
#include <windows.h>

7. 修改 identify_encoding.h
(在 mod_encoding-20021209/lib)
因為 windows 沒有 strcasecmp 和 strncasecmp 所以改用 stricmp 和 strncmp
加入
#define strcasecmp stricmp
#define strncasecmp strncmp

8. 使用 apxs 編譯

cd mod_encoding-20021209/
c:\apache2\bin\apxs -llibhttpd -llibapr-1 -llibaprutil-1 -c mod_encoding.c ./lib/iconv_hook.c ./lib/iconv_hook_default.c ./lib/iconv_hook_eucjp.c ./lib/iconv_hook_ja_auto.c ./lib/iconv_hook_mssjis.c ./lib/iconv_hook_ucs2_cp932.c ./lib/iconv_hook_utf8_cp932.c ./lib/iconv_hook_utf8_eucjp.c ./lib/identify_encoding.c

如果沒有 apxs 可以自行編譯,指令如下

cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fomod_encoding.lo mod_encoding.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook.lo ./lib/iconv_hook.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_default.lo ./lib/iconv_hook_default.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_eucjp.lo ./lib/iconv_hook_eucjp.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_ja_auto.lo ./lib/iconv_hook_ja_auto.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_mssjis.lo ./lib/iconv_hook_mssjis.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_ucs2_cp932.lo ./lib/iconv_hook_ucs2_cp932.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_utf8_cp932.lo ./lib/iconv_hook_utf8_cp932.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/iconv_hook_utf8_eucjp.lo ./lib/iconv_hook_utf8_eucjp.c
cl.exe /nologo /MD /W3 /O2 /D WIN32 /D _WINDOWS /D NDEBUG -I"C:\apache2\include" /c /Fo./lib/identify_encoding.lo ./lib/identify_encoding.c

link kernel32.lib /nologo /subsystem:windows /dll /machine:I386 /libpath:"c:\apache2\lib" /out:mod_encoding.so libhttpd.lib libapr-1.lib libaprutil-1.lib ./lib/identify_encoding.lo ./lib/iconv_hook_utf8_eucjp.lo ./lib/iconv_hook_utf8_cp932.lo ./lib/iconv_hook_ucs2_cp932.lo ./lib/iconv_hook_mssjis.lo ./lib/iconv_hook_ja_auto.lo ./lib/iconv_hook_eucjp.lo ./lib/iconv_hook_default.lo ./lib/iconv_hook.lo mod_encoding.lo

9. 複製 mod_encoding.so 到 apache2/modules/

10.
加入以下的 config 註解掉的為 web-dav 所用,依需求自行開啟

#LoadModule headers_module modules/mod_headers.so
LoadModule encoding_module modules/mod_encoding.so
#<IfModule mod_headers.c>
# Header add MS-Author-Via "DAV"
#</IfModule>
<IfModule mod_encoding.c>
EncodingEngine on
NormalizeUsername on
SetServerEncoding UTF-8
DefaultClientEncoding UTF-8 Big5
# AddClientEncoding "(Microsoft .* DAV $)" UTF-8 Big5
# AddClientEncoding "Microsoft .* DAV" UTF-8 Big5
# AddClientEncoding "Microsoft-WebDAV*" UTF-8 Big5http://www.blogger.com/img/blank.gif
</IfModule>


Ref
http://webdav.todo.gr.jp/
http://blog.makk.idv.hk/post/31/

[PHP] 在 centos6 將 PHP 5.3 降版至 5.2



1. 安裝 atomic  repository
wget -q -O - http://www.atomicorp.com/installers/atomic | sh
安裝完畢會看到 /etc/yum.repos.d/atomic.repo

2. 移除 php5.3 (如無安裝過即跳過此步驟)
yum remove php*

3. 安裝 php 5.2
php-5.2* php-mbstring-5.2* php-xml-5.2* php-ldap-5.2* php-gd-5.2* php-xml-5.2* php-pdo-5.2*

4.避免升級到 php 5.3
vi /etc/yum.repos.d/atomic.repo  或 /etc/yum.conf
加入  exclude=php-5.3*  (加在 [atomic] 內)


Ref: https://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/










下面是舊方法~

rpm -qa | grep php
rpm -e --nodeps phpxxxx

32bit

wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-cli-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-common-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-mbstring-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-devel-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-ldap-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-gd-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-xml-5.2.17-1.el6.art.i686.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/i386/RPMS/php-pdo-5.2.17-1.el6.art.i686.rpm

rpm -ivh php-common-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-cli-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-mbstring-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-xml-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-ldap-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-gd-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-devel-5.2.17-1.el6.art.i686.rpm
rpm -ivh php-pdo-5.2.17-1.el6.art.i686.rpm

yum install libXpm.so.4 libt1.so.5 autoconf automake

64bit

wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-cli-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-common-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-mbstring-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-devel-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-ldap-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-gd-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-xml-5.2.17-1.el6.art.x86_64.rpm
wget http://www6.atomicorp.com/channels/atomic/centos/6/x86_64/RPMS/php-pdo-5.2.17-1.el6.art.x86_64.rpm

rpm -ivh php-common-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-cli-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-mbstring-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-xml-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-ldap-5.2.17-1.el6.art.x86_64.rpm
wget http://mirror.centos.org/centos/6/os/x86_64/Packages/libXpm-3.5.8-2.el6.x86_64.rpm
rpm -ivh libXpm-3.5.8-2.el6.x86_64.rpm
wget http://mirror.centos.org/centos/6/os/x86_64/Packages/t1lib-5.1.2-6.el6.x86_64.rpm
rpm -ivh t1lib-5.1.2-6.el6.x86_64.rp
rpm -ivh php-gd-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-xml-5.2.17-1.el6.art.x86_64.rpm
rpm -ivh php-pdo-5.2.17-1.el6.art.x86_64.rpm


vi /etc/php.ini
把 short_open_tag = Off 改成 On
service httpd restart

避免 yum 更新到 php 做以下設定
vi /etc/yum.conf
加入
exclude=php*

Ref :
http://linux-bloggers.blogspot.com/2011/09/downgrade-php-in-centos-6.html