2012年3月25日 星期日

春思

2012-03-25


春天看起來好像來了,卻又快過了?記得老家常說清明過後氣溫會越來越熱,端午過後,焰日更盛。


最近周邊親朋好友紛紛轉換跑道,對於自己的未來似乎越來越明確,只是與人閒聊交談,除了活在不確定性的規劃中,還得應付著別人的觀感,想起來也滿累的。例如跑到新創公司,不被看好的甚多。這種現象早在兩年前我也就感受過,當時周邊有個 team (被迫?!)以 spinoff 的方向進行中,可是單位內幾乎沒人認同,永遠的數落。


最近職場上又被 Push 了一把,說的很不錯:「人生總有犧牲,但要記得自己的犧牲是為了獲取什麼。」不然工作或生活上總只剩得抱怨兩字,只記得自己苦了什麼。有人存錢存了一整年,只為那幾天的出國旅遊;有人打拼二三十年,為了買個房讓妻兒溫暖。想想,這些都是挺有意義的事,何必說別人省吃儉用過的很苦呢?


今年花了不少時間在思考,看到周邊有人追求 CP 值、追求名聲、追求金錢,我想,我漸漸地知道自己要的是什麼。規劃一塊自己認為有意義的嘗試,不用為了滿足別人的眼光而回話、做事,別忘了真正為你負責的還是自己啊,單純為自己的生活之道努力吧!


2012年3月21日 星期三

[PHP] CodeIgniter (PHP Framework) 筆記


圖片來源:http://codeigniter.com/


最近因工作上的關係,重溫 PHP & MySQL 的懷抱。說真的,我上一次寫 PHP & MySQL 已經是 2005 年的事情,但我離 PHP 還沒那麼遠,至少 2009 年還有寫過。最近工作上採用 CodeIgniter Framework,算是第一個我接觸的 PHP Framework 了。我記得在 2009 年時,我還很討厭 framework 這類的東西,但工作幾年後,我發現 framework 在某個角度來說是很有用的,例如工作交接、維護與傳承。


老實說用 framework 開發速度不見得快,但好處之一就是可以讓一群人依循某種共同的開發架構(MVC)撰寫程式,如此一來要接手的人比較不會太痛苦,至少痛苦的機率小了那麼一丁點。這邊就先簡短記錄一些筆記。


效能:


參考 Google Search 的第一筆資料 - PHP Framework 的效能比較。簡單的說,在一些常見的 framework 中,CodeIgniter 效能不算差的,但與原生 PHP 來比,效能還是差了一大截。


架構:


稱得上很標準的 MVC 吧?目錄結構有 application/controllers、application/models 和 application/views ,如其名的架構,其中寫 controller 時,大部分都是用一個  class 的架構,依照該 class 來實作:


class Welcome extends CI_Controller {
        public function index()
        {
                echo "Page at /welcome";
        }
        public function test()
        {
                echo "Page at /welcome/test";
        }
        public function update($x = NULL)
        {
                echo "Page at /welcome/update";
        }


所以,你的網頁上就有 http://domain/index.php/welcome、http://domain/index.php/welcome/test、http://domain/index.php/welcome/update 和 http://domain/index.php/welcome/update/x 四種網址位置(其中最後的 x 是變數)。


接著 Models 的部分,也是繼承某個 class 的寫法:


class MyModel extends CI_Model {
        function get_all_entries()
       {
                $query = $this->db->get('mytable');
                return $query->result();
       }
}


如此一來,在 controller 裡頭就可以用:


class Welcome extends CI_Controller {
        public function index()
        {
                $this->load->model('MyModel');
                $this->MyModel->get_all_entries();
        }
}


而 views 比較像傳統 PHP 用法,不用是個 class 而是像以前寫 PHP 那樣夾雜 HTML、PHP、CSS 和 Javascript 等,而這個 view 能接收的參數需要從 controller 傳進來:


class Welcome extends CI_Controller {
        public function index()
        {
                $x = array('123','456');
                $this->load->view( 'myview' , array( 'data' => $x ) );
        }


接著在 application/views/myview.php 中,就可以透過 global 變數 $data 取得資料。


 缺點:


錯誤訊息不見得會顯示


有道是越難除錯的錯誤,通常是最蠢的問題,對於 CodeIgniter 來說,像 controller 和 models 這種 class 架構來說,不小心漏寫{}時,系統不見得會顯示錯誤,此時只會看到 500 internal server error 這種訊息,這跟直接用 PHP 會顯示錯誤訊息來說,實在很不方便。除此之外,如果使用 MySQL 時,未安裝 php5-mysql 相關套件時,也一樣空白一片。


這些真的還滿糟糕的。


Session 預設為 client side session 架構


對 PHP 來說,原先有 $_SESSION 使用,但在 CodeIgniter 必須改用 $this->session->all_userdata() 這類的存取方式,但真正棘手的是它的實作方式,預設是把 session 資料進行加密儲存在 cookie 裡頭,除了安全問題外,本身 cookie 就跟瀏覽器的實作有關,所以不見得所有資料都可以正常透過 setcookie 方式儲存起來,例如 $session['中文字'] = true 在 2.1.0 版就會發生問題!更別說 cookie 資料被破解、使用限制等等的。


另一個作法是把 session 資訊儲存在 Databases 裡頭,如此也可能導致 DB 連線頻繁而產生效能危機。


更多資訊可以參考:Session 的瓶頸與解決方法,在此就是文中第三種方式。


 以上算是目前粗淺使用的經驗。


2012年3月15日 星期四

[Linux] 使用 Tarball 更新 OpenSSL @ Ubuntu 10.04

又到了一年一度機器被掃的時刻了,這次碰到的問題是 OpenSSL 版本太舊,有資安疑慮。


然而在 Ubuntu 上安裝時,直接用 ./config 後,安裝完的路徑卻不太對。網路上有看到別人用 ln -s 的方式強制切換位置,但安裝其他軟體時,一樣容易碰到 openssl header 跟 openssl library 版本不合的問題,摸索一下才找到正確的解法。


$ sudo apt-get remove openssl libssl-dev


$ tar -xvf openssl-w.x.yz.tar.gz
$ cd openssl-w.x.yz
$ ./config --prefix=/usr
$ sudo make install


如此一來才安全地搞定了。確認 OpenSSL 版本:


$ openssl version -a


只是更新完還有一堆東西要重編 Orz


2012年3月13日 星期二

[Python] 使用 PyPNG (Python PNG encoder/decoder) 產生 PNG 圖檔

sequential color random color


因研究關係,需要產生一些圖片像素有特殊規則的圖檔,找了一下剛好有 PyPNG 可以使用。


Python PNG encoder/decoder


$ tar -xvf pypng-0.0.12.tar.gz
$ cd pypng-0.0.12
$ sudo python setup.py install


程式碼:


import png
import random


rawRow = []
rawColumn = ()
width = 1024
height = 1024
for i in range(256):
        if len(rawRow) >= height:
                break
        if i == 0:
                continue
        for j in range(256):
                if len(rawRow) >= height:
                        break
                if j == 0 :
                        continue
                for k in range(256):
                        if len(rawRow) >= height:
                                break
                        if k == 0:
                                continue
                        if len(rawColumn) < width*3:
                                rawColumn = rawColumn + (i,j,k,)
                                #rawColumn = rawColumn + (random.randint(1,255),random.randint(1,255),random.randint(1,255),)
                        else:
                                rawRow.append( rawColumn )
                                rawColumn = (i,j,k,)


f = open("test"+str(width)+"x"+str(height)+".png","wb")
w = png.Writer(width,height)
w.write( f, rawRow )
f.close()


程式碼有點醜,但堪用 XD 所以還是好好珍惜光陰吧!


2012年3月12日 星期一

Android 開發教學筆記 - 研究 Renderscript 以 Gravity 為例


From: http://code.google.com/p/renderscript-examples/wiki/Gravity


這是一個重力特效的範例。看過 Renderscript HelloWorld 的架構後,很快就能了解 Gravity,他們倆是一樣的架構,只是畫圖的部份不一樣。


這邊有四個檔案 Gravity.java、GravityRS.java、GravityView.java 和 gravity.rs,以 GravityRS.java 和 gravity.rs 最為重要,因此挑這兩個檔案研究一下:


gravity.rs:


(gTouchX, gTouchY) 座標資訊


用來決定重力中心位置,這會從螢幕上的 TouchEvent 後,慢慢傳遞到這兩個變數,所以在畫面上任一點點一下,則改變重力中心位置


Point 資料結構(delta、座標和顏色)


用來紀錄每一個畫在螢幕上的點資訊,包括座標、顏色,而 delta 則是用來計算與重力中心距離相關的數值,在畫面上則是用來決定靠近重力中心的速率,也就是座標變化量


void initParticles()


用來初始化 Point 位置,首先先得知有多少 Point,接著得知 Width 跟 Height 後,把所有 Point 座標用亂數建立出來,並設定顏色,而靠近重力中心的座標變化量就先定為 0


int root()


計算各 Point 與重力中心點 (gTouchX, gTouchY) 的位置,並決定該 Point 移動到重力中心點的座標變化量(越接近移動越快)。最後,則是透過 rsgDrawMesh(partMesh); 畫出各個 Point,並且 return 1 代表 1ms 更新畫面一次,也代表座標會重算一次


GravityRS.java:


void init(RenderScriptGL rs, Resources res, int width, int height) 裡頭包括決定 Point 個數、用 Mesh 結構把 Point 集中起來(方便畫圖),剩下的則是相關的初始化動作。