2017/07/19

vim 快速使用 sudo 存檔的語法

平常改設定檔通常都是「sudo vim xxx.conf」,不過直接切換成 root 修改檔案其實風險還蠻大的,特別是邊喝酒邊改系統的時候 (?)。

倘若不想使用 sudo vim 來修改系統設定檔時,就 vim xxx.conf 即可。雖然沒有寫入權限,但至少讀取檔案內容是沒問題的。

以一般使用者開啟系統擋時,每次做變更都會收到警告訊息「Warning: Changing a readonly file」,表示 vim 偵測到沒有權限變更檔案內容,避開非預期的異動正是避開誤寫的好方法。那當修改完成後需要寫入時,則可以使用以下指令臨時切換成 root 並寫入檔案:
:w !sudo tee %



說明一下上面那一段到底是什麼意思。

「:w」和大家所知道的寫入檔案是一模一樣的,但若後面加上其他指令,例如「:w ! tee」其實就是把預備寫入的檔案內容 pipe 給後面的指令處理,前面這個寫法就是把檔案內容丟給 console 的 tee 處理,所以可以看到 tee 檔案內容輸出到螢幕上 (stdout)。

vim 中的「%」符號代表的是正在編輯的檔案名稱,可以使用「:!echo %」指令看看會輸出什麼資料。若是「vim xxx.conf」則會印出「xxx.conf」;「vim path/to/xxx.conf」則會印出「path/to/xxx.conf」,應該不難理解。

綜合以上幾個撇步,「:w !sudo tee %」的意思,其實就是讓 vim 不要自己更新檔案,而是將檔案內容拋給以 root 身份執行的 tee,並讓 tee 寫入 vim 目前正在編輯的檔案。tee 寫完檔案以後,vim 會偵測到檔案異動並詢問是否要重新載入 (load) 更新過的檔案內容,重新載入以後就可以繼續下一個批次的修改。

2017/07/14

Nginx URL rewrite for REST API in subfolder

一般來說,要讓 Nginx 遇到 PHP 程式時,只要按照以下寫法就可以將 request 轉接給 php-fpm 處理:
server {
    location / {
        try_files $uri $uri/index.html =404;
    }

    location ~ \.php* {
        root /home/www/data;

        include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }
}

假設 project 在 document root (如上面的就是 /home/www/data),設定方式其實不難,網路到處都可以找的到。像是 Laravel 可以參考 pretty URL 的設定方式,把 index.php 隱藏起來:
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

上面這個設定,可以讓 request 從「http://my.site/user/1」,被改寫為「http://my.site/index.php/user/1」,這個時候 index.php 就可以從 $_SERVER 的參數來判斷到底要走哪個 route。

但假設寫的專案沒有一個 domain name、沒辦法做 virtual host,可以讓專案根目錄當作 document root,且新的 PHP framework 都會把 index.php 放在 /public 目錄下來避免安全問題,這樣的 URL rewrite 就會出問題。

例如今天的 request 是「http://my.site/project/user/1」,在經過上面的 route 以後會被轉成「http://my.site/index.php/project/user/1」,而實際上我們需要的是「http://my.site/project/index.php/user/1」才能讓專案正確運作。

這時需要另外建立 route 規則。先把 http://my.site/project 對應到的正確檔案路徑設定好:
location ^~ /project {
    # define script real path
    alias /home/www/data/project/public;

    try_files $uri $uri/ /project/public/index.php$uri;
}

到這邊算是設定完成一半,暫停來看一下目前 routing 的情況。請求「http://my.site/project/user/1」會被轉換為「http://my.site/project/public/index.php/project/user/1」。index.php 後半部的參數差了一點點,把「project/」片段拿掉就完成了。

這時我們再新增一條規則,使用 REGEX 來處理後面這段參數:
location @project-rule {
    # 若 URI 起始為 /project/
    # 把後面的參數抓出來,放在 /project/public/index.php/ 後方 
    rewrite ^/project/(.*)$ /project/public/index.php/$1 last;
}

調整後,完整的 Nginx URL rewrite 規則會長這樣:
location ^~ /project {
    alias /home/www/data/project/public;

    # 一般規則無法正確找到路徑
    # 就使用 @project-rule 規則來做查詢
    try_files $uri $uri/ @project-rule;
}

location @project-rule {
    rewrite ^/project/(.*)$ /project/public/index.php/$1 last;
}


Nginx 的 rewrite rule 實在很難 debug,這段是自己花了數小時嘗試錯誤並觀察 $_SERVER 參數變化才找到規律的,希望多少對大家有一點幫助。

2017/07/02

天興搬家公司 與 崔媽媽基金會

獲得了一個在新竹工作的機會,六月初從高雄搬家至新竹。在 PTT MoveHouse (搬家) 板上面一直找不到中意的搬家服務,最後在 play.google.com 上面亂找,發現有個 app 叫做「搬家 Easy Go」,列出由崔媽媽基金會評鑑、審核過的搬家公司,於是挑了高雄離家比較近的「天興搬家公司」來協助這次的旅程。

透過網頁上的聯絡方式打電話給高雄經理,經理聽過我的行李數量以後,說大概只需要用最小的卡車 (好像是 3 頓的那型) 半車就可以裝完,且早上八點上車以後,中午過後便可在新竹卸貨,開價是 12000。只要我在早到公司去做確認並簽約即可,費用則是搬家之後才收。

搬家當天遇到鋒面過境下大雨,意料之外的是快遞士大哥居然有準備封膜,把我的電腦椅和幾件重要家具都先包好,上推車以後在蓋一層防水布運送上卡車,全程都不需要我出力,大哥一個人就搞定了。由於雨勢過大,拿行李到高鐵上新竹花掉的時間可能比卡車還要慢,所以就搭了大哥的順風車。

大哥沒啥不良嗜好,也蠻聊的開的,開車也很穩,幾乎不太需要擔心。新竹下車時沒有下雨,一下子就把行李搬進房間,最後付款並填寫問卷。



車上有像大哥詢問了崔媽媽基金會和搬家公司有什麼關連。原來崔媽媽基金會成立主要是用來協助搬家公司建立完整的安全制度,包括各家搬家公司遇到的問題,像是如何固定家具才不會在運送途中損壞,雨天注意事項,或是需要使用吊車來協助家具進出時的安全規範,以及定期為搬家公司建立教育訓練,訓練及驗收。客戶也可以透過崔媽媽基金會找到有保障的搬家公司。

所以可以確定的是,有經過崔媽媽基金會認可的搬家公司,不會遇到家具搬到不見、損毀找不到地方求償、或是搬家後隨意加價等問題的發生,整個交易比較有保障。

以這次的經驗,以後有需求應該也會透過崔媽媽基金會來尋找搬家公司協助搬運。

「全勤獎」真的對公司也對員工都很好嗎?

全勤獎目的是為了讓員工可以盡量員工準時上下班,也盡可能安排假期能考慮到公司的時程。之前和同事討論以後有了不一樣的看法,全勤獎也有可能帶來負面的效果。

以一個工勤的上班族來說,通勤這段時間是完全無法預測的,塞車不說,如果遇到交通事故、或是道路維修等狀況,根本無法預期會花多久的時間到達公司。如果為了預防這樣意外發生而提早出門,自己的生活時間就少了一小時,或是更多,但是公司並沒有補貼這些通勤時間。

另外一個上班族可能的想法,就是在運輸工具上節省通勤時間,也就是「飆車」。但大家也應該都知道飆車的副作用是什麼,遭警察開罰單,或是因此發生交通事故導致無法繼續原來的工作 (住院,或是永久的身體傷害)。

這樣全勤獎的負面效果,似乎比正面效果來的還要大許多,那是否可以用其他方法來取代全勤獎的目的呢?

2017/06/29

Phalcon PHP framework 的 URL rewrite 方法

幾個比較常見的 PHP framework 像是 Silex、Slim、FuelPHP 和 Laravel,都是將 resource path 直接放在 index.php 後方。例如網址為「/my.site/user/10」則會被改寫為「/my.site/index.php/user/10」,所以在測試環境下,如果不想設定 URL rewrite 可以直接把 resource path 手動放在 index.php 後方。

今天研究 Phalcon 的 routing 很久,不管怎麼設定就是沒有 match 到 controller,而且還沒有任何錯誤訊息。把整個文件都翻遍以後,才發現 .htaccess 有個不一樣的地方:
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^((?s).*)$ index.php?_url=/$1 [QSA,L]
</IfModule>

Phalcon 的 rewrite 行為和上述的不一樣,resource path 會轉到「_url」這個參數上面,所以若是沒有動到「_url」這個參數,router 就視為要開啟首頁,不管 index.php 後面接什麼都不會改變行為 ....。



可惡,八小時就這樣飛了 .....