Month: January 2015

[Ubuntu] VIM E319:Sorry, the command not available in this version: syntax on

之前重新安裝ubuntu也有碰到這個問題,但都是直接上網google抓指令來試

沒有去理解為啥會出現這個問題

或著,也許有點印象但事過境遷就忘了…

剛好這次藉著,幫筆電安裝新的ubuntu又碰到這個問題,所以來紀錄一下

今天剛裝完ubuntu之後,想說來設定自己帳號的 (~/.vimrc)

大概像這樣子


set nu
syntax on

但設定完之後,我下這個指令測試就出現錯誤了


vi test.txt

E319:Sorry, the command not available in this version: syntax on

這個錯誤訊息很明白的提示,我目前用的vim version沒有支援syntax on command

但奇怪的是,我記得ubuntu應該預設就有裝vim了

幸好這個小問題,已經有不少人遇過所以google一下就會有點頭緒了

因為ubuntu預設的vim不是完整的vim,是vim-tiny(微型的vim)和精簡版差不多意思

而這個微型的vim沒有支援syntax on command

解決的辦法就是安裝完整版的vim,指令如下:

sudo apt-get install vim

Done! enjoy vim.

.vimrc

 

Advertisements

[Codeingter]config.php的cookie_secure

前言

前陣子的在開發的時候,有一項是要在登入頁做remeber me的功能

這其實還滿簡單的,畢竟只要有買過php的書幾乎都會有範例

不同的是之前是純粹用PHP寫,現在用的是CI

以前沒有用過CI提供的cookie存取功能,但有看過config檔裡面有相關的設定


/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path' = Typically will be a forward slash
| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix'] = "c_";
$config['cookie_domain'] = $_SERVER['HTTP_HOST'];
$config['cookie_path'] = "/";
$config['cookie_secure'] = TRUE;

所以就先設定了一下,但我當下沒有發現自己犯了一個錯…(官方的說明文件也沒有寫得很清楚,還是看code最準XD)

把remeber me功能的做完的時候,當下測試的時候發現登入功能GG了(…WTF)

一開始是馬上去看我剛剛寫的程式是不是有BUG,但還真的沒有啊…

神奇的是我把剛剛寫的code刪光光,登入功能依然GG…

所以我就開始想想我寫code之前做了什麼事?

config~我改了config,但我只是設定cookie相關的config而已

也沒有更動到session的東西啊….

秉持著爬source code的精神,終於讓我釐清事情的來龍去脈…容我慢慢道來

文件vs註解

我在改config相關的cookie設定前有先去看官方的說明文件

其中有一項是設定$config[‘cookie_secure’]

文件是這樣寫的:

The secure boolean is only needed if you want to make it a secure cookie by setting it to TRUE.

所以我就把cookie_secure設為TRUE <—(這就是我犯的錯誤)

但後來在檢查config.php的時候我發現它的註解的解釋是:

/*
| 'cookie_secure' = Cookies will only be set if a secure HTTPS connection exists.
*/

所以,如果將CI config.php的cookie_secure的參數設為TRUE

代表利用$this->input->set_cookie()設定的cookie只能透過https的方式傳輸!

但我做的那個網站並沒有用https…這就是最根本的問題 (如果官方的文件和助解一樣的話我應該就不會把cookie_secure設成TRUE了)

還有還有

debug到這邊應該就可以告一個段落了~~

但是!!我還是沒搞懂為何cookie_secure設為TRUE之後,我TMD的就不能登入

基於爬爬source code的精神,發現..在/system/libraries/Session.php有一段程式碼解決了我最後一個疑惑:


 // Fetch the cookie
 $session = $this->CI->input->cookie($this->sess_cookie_name);

 // No cookie? Goodbye cruel world!...
 if ($session === FALSE)
 {
   log_message('debug', 'A session cookie was not found.');
   return FALSE;
 }

 // Decrypt the cookie data
 if ($this->sess_encrypt_cookie == TRUE)
 {
   $session = $this->CI->encrypt->decode($session);
 }
 else
 {
   // encryption was not used, so we need to check the md5 hash
   $hash = substr($session, strlen($session)-32); // get last 32 chars
   $session = substr($session, 0, strlen($session)-32);

   // Does the md5 hash match? This is to prevent manipulation of session data in userspace
   if ($hash !== md5($session.$this->encryption_key))
   {
     log_message('error', 'The session cookie data did not    match what was expected. This could be a possible hacking attempt.');
     $this->sess_destroy();
     return FALSE;
   }
 }

CI在讀取seesion的時候會有一個檢查機制

1.先檢查Server上的session和client端cookie裡面加密後的session是否存在

2.檢查是否為加密的值

3.比對seesion和cookie是否match

總結因果

1.目前開發的網站不是走HTTPS

2.把config.php的cookie_secure的參數設為TRUE

3.帳密都輸入正確時,程式存一個seesion在Server上,CI則自動在cookie端存一個加密後的session值

4.轉跳到登入後的頁面時,會檢查是否有登入,但這個機制觸發了..

5.CI在讀取seesion時會去比對seesion和cookie是否match

6.但無法取得這個cookie的值…所以return FALSE…死在

log_message('debug', 'A session cookie was not found.');

 

 

 

[Codeingter] 回傳insert、update、delete的執行結果

話說我自己在做MVC開發的時後,有個習慣就是一定要回傳SQL的執行結果

因為這關係到在controller的寫法

但,前幾天在開發的時候遇到一個問題,明明table的資料沒有更新到,但卻回傳true

花了一點時間看了ci的source code和Google

證明是我的理解錯誤…

例如:這邊return的用意是讓我可以在controller判斷在Model的執行結果


public function updateData($id, $data){

  $this->db->where('id', $id);
  return $this->db->update('mytable', $data);

}

但是!!這裡需要理解的地方是$this->db->update() return的結果是「執行update sql是否成功」,不代表資料是否有被更新

所以,比較好的寫法是:


public function updateData($id, $data){

  $this->db->where('id', $id);
           ->update('mytable', $data);

  return ($this->db->affected_rows() > 0) ? TRUE : FALSE; 

}

更簡潔的寫法


public function updateData($id, $data){

  $this->db->where('id', $id);
           ->update('mytable', $data);

  return $this->db->affected_rows() > 0;

}

這樣做的好處是,在controller可以明確的知道table的資料到底有沒有被異動