Quantcast
Channel: 小惡魔 – 電腦技術 – 工作筆記 – AppleBOY
Viewing all 325 articles
Browse latest View live

Install Nginx + spdy module on Ubuntu or Debian

$
0
0
nginx-logo

上一篇提到 nginx 1.4.0 釋出並支援 SPDY,教學環境是 CentOS,這次在 Ubuntu 環境編譯遇到

/usr/bin/ld: cannot find -lperl

找不到 perl library,解法可以透過 aptitude 安裝 libperl5.14,安裝好後,到 /usr/lib 底下找到 libperl.so.5.14.2,由於檔案命名關係,請用 ln 將檔案 link 成 libperl.so

$ ln -s libperl.so.5.14.2 libperl.so

接著可以正確編譯了,底下安裝相關套件

$ aptitude -y install libpcre3-dev libgd-dev libgd2-xpm-dev libgeoip-dev

測試 Web Responsive Design Tool

$
0
0
responsive-website-design-tips

Web CSS Programer 在撰寫 Responsive CSS Style 時,手邊一定會有一堆 Device,來測試當畫面小於 480 px 或大於 768 px 時,呈現的版面是否有亂掉,公司也花費許多成本來測試,現在不需要這樣了,我們可以透過線上 Tool 或者是 Plugin 來測試 Responsive Web Page,首先來介紹 Viewport resizer,此工具用法很簡單,進入官網後,將官網 Javascript 連結加入到我的最愛或 bookmarks,之後打開您的測試網站,再點選該 bookmark,你會發現網站上面多了一條 tool bar,可以自訂或調整 view size,預設也給了平板手機等多種畫面調整,讓您測試 Media Queries 是否有錯誤。

另外一套 Tool 比較強大,那就是 Google Extension: Responsive Inspector (beta) released!,不過就是限制在 Google Chrome 瀏覽器才可以安裝,此擴充工具,還可以直接對應到 CSS Media Queries 位置,以及將自訂大小畫面存成圖檔並且上傳到 Server。底下是介紹影片

Backbone Routing pushState in IE

$
0
0
backbone

Backbone.js 幫忙處理掉所有瀏覽器 Html5 History pushState 功能,除了 IE 9 以下(含 IE 9)不支援 history.pushState()history.replaceState(),其他 Browser 幾乎都支援了,在 Backbone.js 如何處理 URL 變化呢?以往透過 handle URL hash 來決定網頁要處理哪些資料,這也是 Backbone 預設的處理方式,範例如下

URL:

http://xxx/#!/user/list
http://xxx/#!/user/add

Backbone.Router.extend({
  routes: {
    "!/user/:action": "user"
  },
  initialize: function() {

  },
  user: function(action, id) {
   
  }
});
Backbone.history.start();

上面方法是通解,在各種瀏覽器包含 IE 都適用,那如果是使用 history.pushState 請改成底下:

URL:

http://xxx/user/list
http://xxx/user/add

Backbone.Router.extend({
  routes: {
    "/user/:action": "user"
  },
  initialize: function() {

  },
  user: function(action, id) {
   
  }
})
Backbone.history.start({pushState: true, root: '/'});

此作法在支援 html pushState 時候是可以按照您定義的 url 運作,但是在 IE 9 版本,網址就會被改成

URL:

http://xxx/#/user/list
http://xxx/#/user/add

一樣會被加上 hash 值,該如何解決此問題呢,請把 Backbone.history.start 改成

Backbone.history.start({pushState: true, hashChange: false, root: '/'});

設定 hashChange property 為 false,讓 IE 9 不要使用 # 來取代網址,這樣就沒問題了。

IE 6 瀏覽器用戶全球分佈

$
0
0
IE_world

此資料來自 The Internet Explorer 6 Countdown,大家注意上面圖示,沒想到台灣高居第二名,佔了 3.5% 僅次於大陸的 24%,大陸不感到意外,但是台灣的比例還真是高,難怪一堆程式開發者,抱怨連連 XD,這是統計到 2013 年 04 月,在這邊紀錄一下,等到明年這個時候再來看看此統計圖。

2013 Javascript Conference: 你不可不知的前端開發工具

$
0
0

Flickr 改版及收費方式改變

$
0
0

癮科技看到 Flickr大改版,收費方式也有異動Flickr 整個介面大改版,這個就算了,連收費方式也大改,本來 Pro 的用戶,以後不再有 Unlimited storage 的優惠了,等到 pro 帳戶到期,系統會將帳戶轉為 Free 機制,雖然容量有到 1TB 的空間,其實也用不太完,但是整個感覺非常不好。

Flickr 目前只有三種帳戶機制,Free, Ad Free, Doublr,三個差異沒有很多,Free 的帳戶幾乎同等於之前的 pro 帳戶,只是有容量限制上限 1TB,再來就是有廣告,接著 Ad Free 一年49美金,差別就是沒有廣告,最後 Doublr 只是容量變成 2TB,也沒有廣告,但是價錢 ….. 每年 499.9 美金 .. 這價位,真的還蠻高的,我想之後也不打算續約了。更多 FQA 可以參考 Free Accounts, Upgrading and Gifts

高雄 KSDG 分享: 打造團隊共同開發環境

$
0
0
gruntlogo

很高興受到高雄 KSDG 邀請,分享上禮拜在 JSDC 所介紹主題: 你不可不知的前端開發工具,在 JSDC 現場只有半小時可以講,這次在高雄有一個半小時可以講,如果想詳細了解前端工具,可以參考上禮拜的投影片,底下是在高雄軟體科技園區所分享。謝謝 Eric Bi 及工作人員可以讓我分享這次議題。

最後附上 Github 專案,歡迎大家 fork。

Nginx + phpMyAdmin 搭配 SSL 設定

$
0
0
mysql_logo

phpMyAdmin 是一套用來管理 MySQL 的 Web 介面,如果要讓 phpMyAdmin 強制走 https 的話,可以透過兩種方式,一種是直接設定 phpMyAdmin,另外一種方式是透過 Apache rewriteNginx 設定,底下來分別說明。

1. phpMyAdmin 設定

直接設定 config.inc.php,加入底下設定

$cfg['ForceSSL'] = true;

2. Nginx 或 Apache 設定

打開 Apache mod_rewrite 功能,將設定寫入 .htaccess

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/directory(.*)$ https://%{HTTP_HOST}/directory$1 [L,R]

或是使用 Nginx 設定,將 80 port 轉到 https,設定 443 port 的 SSL 憑證。

server {
  listen 80;
  server_name xxx.xxx.xxx.xxx;
  rewrite ^ https://$server_name$request_uri? permanent;
}

server {
  # listen 80 default_server deferred; # for Linux
  # listen 80 default_server accept_filter=httpready; # for FreeBSD
  #listen 80;

  listen 443 ssl spdy;
  ssl on;
  ssl_certificate /etc/nginx/conf/api.ovoq.tv/server.crt;
  ssl_certificate_key /etc/nginx/conf/api.ovoq.tv/ssl.key;
  ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers         HIGH:!aNULL:!MD5;
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 5m;

  # The host name to respond to
  server_name xxx.xxx.xxx.xxx;
}

上面 Nginx 設定完成後,會發現登入 phpMyAdmin 後,網址被轉成

http://xxx.xxx.xxx.xx:443

馬上看到網頁噴

the plain http request was sent to https port

看到這訊息,是 Nginx 產生的,error code 是 497,其實將此 error 導向正確的地方就可以了,在 Nginx 設定檔加入

error_page 497 https://$host$request_uri;

就可以解決此問題了。

Ref:
The plain HTTP request was sent to HTTPS port
Forcing SSL with phpMyAdmin


JSDC 和 KSDG 影音紀錄 (淺談 GruntJS 整合開發工具)

$
0
0
gruntlogo

很高興今年在 JSDC 擔任講師,演講主題為『你不可不知的前端開發工具』,這場議程只有30分鐘可以講,時間實在是不太夠,要消化這麼多工具其實對於聽眾有點困難,真是對不起聽眾了,不過沒關係,高雄 KSDG 五月份邀請我講『打造團隊共同開發環境』,其實就是將 GruntJS 精華整個講一遍,大概有一個多小時,底下是官方影音,如果朋友們沒北上參加,也可以透過 JSDC Youtube 來欣賞。

JSDC 35分鐘議程


KSDG Web Course#3 如何打造前端開發環境 + workshop(1/3)

KSDG Web Course#3 如何打造前端開發環境 + workshop(2/3)

KSDG Web Course#3 如何打造前端開發環境 + workshop(3/3)

How to install Gearman on Ubuntu or Debian with MySQL 安裝測試篇

$
0
0

Gearman 可以在背景幫忙處理繁瑣的工作,例如壓縮影片、處理縮圖、發送認證信…等,這次不會提到太多 Gearman 介紹,如果想瞭解 Gearman 可以參考小鐵兄寫的 Gearman 心得,此篇會筆記如何在 Ubuntu or Debian 安裝 Gearman 搭配 MySQL 服務,當然如果你不是使用 MySQL,也可以另外搭配 MemcachedSQLite 都可以

Ubuntu or Debian 安裝

其實安裝方式很簡單,只需要透過 apt-get 指令就可以安裝完成

$ aptitude -y install gearman gearman-job-server libgearman-dev libdrizzle0

安裝完成後,在命令列打入 gearmand -V 檢查版本,會發現預設的版本非常的舊,但是沒關係,Ubuntu 可以透過 Package Repository 來安裝到最新版

$ add-apt-repository ppa:gearman-developers/ppa
$ aptitude -y update

但是在 Debian 7.0 版似乎起不了任何作用,裝起來版本真的很低,爽度不夠,所以最終解法還是要透過 tar 方式安裝,安裝過程一定會遇到一些沒安裝的 develop library,只要把相對應的套件安裝即可

$ aptitude -y install libboost-program-options-dev gperf libcloog-ppl0 libpq-dev libmemcached-dev libevent-dev
$ wget https://launchpad.net/libdrizzle/5.1/5.1.4/+download/libdrizzle-5.1.4.tar.gz -O /tmp/libdrizzle-5.1.4.tar.gz
$ wget https://launchpad.net/gearmand/1.2/1.1.8/+download/gearmand-1.1.8.tar.gz -O /tmp/gearmand-1.1.8.tar.gz
$ cd /tmp && tar xvfz libdrizzle-5.1.4.tar.gz && cd libdrizzle-5.1.4 && ./configure --prefix=/usr && make && make install
$ cd /tmp && tar xvfz gearmand-1.1.8.tar.gz && cd gearmand-1.1.8 && ./configure --prefix=/usr && make && make install

安裝完成後,直接打 gearmand -h

builtin:

libmemcached:
  --libmemcached-servers arg List of Memcached servers to use.

Postgres:
  --libpq-conninfo arg       PostgreSQL connection information string.
  --libpq-table arg (=queue) Table to use.

MySQL:
  --mysql-host arg (=localhost)      MySQL host.
  --mysql-port arg (=3306)           Port of server. (by default 3306)
  --mysql-user arg                   MySQL user.
  --mysql-password arg               MySQL user password.
  --mysql-db arg                     MySQL database.
  --mysql-table arg (=gearman_queue) MySQL table name.

如果搭配 Mariadb 的話,請安裝 libmariadbclient-dev 才可以將 MySQL 功能編譯進去。從上面結果發現 Gearman 目前支援 libmemcached, Postgres, MySQL 串接方式,底下來一一介紹

搭配 memcached

Gearman 0.7 版本以上才支援,設定方式很簡單,開啟 /etc/default/gearman-job-server 找到底下字串

PARAMS="--listen=127.0.0.1"

改成

PARAMS="-q libmemcached --libmemcached-servers=localhost"

當然要先檢查系統有無啟動 memcached port 11211。重新啟動 gearmand

$ /etc/init.d/gearman-job-server restart

搭配 MySQL

設定前,請先將 Database 建立完成

$ mysql -u root -p -e 'CREATE DATABASE gearman;'

最後設定 /etc/default/gearman-job-server

PARAMS="-q mysql --mysql-host=localhost --mysql-user=xxxx --mysql-password=xxxxx--mysql-db=gearman --mysql-table=gearman_queue"

重新啟動後,Gearman 會在資料庫建立 gearman_queue 資料表

CREATE TABLE IF NOT EXISTS `gearman_queue` (
  `unique_key` VARCHAR(64) DEFAULT NULL,
  `function_name` VARCHAR(255) DEFAULT NULL,
  `priority` INT(11) DEFAULT NULL,
  `data` longblob,
  `when_to_run` INT(11) DEFAULT NULL,
  UNIQUE KEY `unique_key` (`unique_key`,`function_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

嗯嗯,非常好,但是你會發現一個問題,都已經在搞 InnoDB 竟然沒有 primary key,所以這就請系統管理者幫忙建立上去。

測試資料

首先 Gearman 支援任何程式語言 (Shell, Perl, Node.js, PHP, Python, Java ..等),先來介紹使用 PHP command line,請安裝 PHP Gearman API Extension

$ pecl install channel://pecl.php.net/gearman-1.1.0

建立 /etc/php5/cli/conf.d/gearman.ini,內容為

[gearman]
extension=gearman.so

重新啟動 php5 fpm

$ /etc/init.d/php5-fpm restart

用指令檢查

$ php -i | grep gearman
/etc/php5/cli/conf.d/gearman.ini,
gearman
gearman support => enabled
libgearman version => 1.1.8

撰寫 worker.php (copy from 小鐵部落格)

<?php
$worker = new GearmanWorker();
$worker->addServer(); // 預設為 localhost
$worker->addFunction('sendEmail', 'doSendEmail');
$worker->addFunction('resizeImage', 'doResizeImage');
while($worker->work()) {
    sleep(1); // 無限迴圈,並讓 CPU 休息一下
}
function doSendEmail($job)
{
    $data = unserialize($job->workload());
    print_r($data);
    sleep(3); // 模擬處理時間
    echo "Email sending is done really.\n\n";
}
function doResizeImage($job)
{
    $data = unserialize($job->workload());
    print_r($data);
    sleep(3); // 模擬處理時間
    echo "Image resizing is really done.\n\n";
}

Client.php

<?php
$client = new GearmanClient();
$client->addServer(); // 預設為 localhost
$emailData = array(
    'name'  => 'web',
    'email' => 'member@example.com',
);
$imageData = array(
    'image' => '/var/www/pub/image/test.png',
);
$client->doBackground('sendEmail', serialize($emailData));
echo "Email sending is done.\n";
$client->doBackground('resizeImage', serialize($imageData));
echo "Image resizing is done.\n";

到這裡直接先執行 Client 程式,如果安裝的 Gearman 吐出底下訊息:

PHP Warning: GearmanClient::doBackground(): _client_run_tasks(GEARMAN_SERVER_ERROR) QUEUE_ERROR:QUEUE_ERROR -> libgearman/client.cc:1581 in /root/client.php on line 11

表示 Server 沒有產生 unique key,所以造成第二次新增 job 的時候產生衝突,解決方式很解單,在 doBackground,第三個參數加上 unique key

$client->doBackground('sendEmail', serialize($emailData), md5(uniqid(rand(), true)));

這樣就可以完整測試了。

PHP 5.5.0 Release note: support Zend OPcache

$
0
0
php-logo

PHP 5.5.0 在上週 20 號正式 Release,也看到 PHP 官網終於改版了,新的版面看起來比較清爽,想嘗試新版面的朋友們,可以點選官網最上面鎖提示的 Bar,如果覺得新版面不是很好看,也可以切回去舊版。本篇來介紹 PHP 5.5.0 有哪些新 Feature。

新增 generators and coroutines 功能

Generators 提供了最簡單的寫法來實做 iterators,而不需要實做 Class 去實做 Iterator 介面,generators function 就跟一般的 PHP function 一樣,只是多了 yield 這 keyword,簡單舉個例子

<?php
function gen_one_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        // Note that $i is preserved between yields.
        yield $i;
    }
}

$generator = gen_one_to_three();
foreach ($generator as $value) {
    echo "$value\n";
}
?>


雖然有了 generators,但是我們可以來比較看看 generators 和 Iterator objects 的差異,官網例子來解釋開啟檔案的程式碼

<?php
function getLinesFromFile($fileName) {
    if (!$fileHandle = fopen($fileName, 'r')) {
        return;
    }
 
    while (false !== $line = fgets($fileHandle)) {
        yield $line;
    }
 
    fclose($fileHandle);
}

// versus...

class LineIterator implements Iterator {
    protected $fileHandle;
 
    protected $line;
    protected $i;
 
    public function __construct($fileName) {
        if (!$this->fileHandle = fopen($fileName, 'r')) {
            throw new RuntimeException('Couldn\'t open file "' . $fileName . '"');
        }
    }
 
    public function rewind() {
        fseek($this->fileHandle, 0);
        $this->line = fgets($this->fileHandle);
        $this->i = 0;
    }
 
    public function valid() {
        return false !== $this->line;
    }
 
    public function current() {
        return $this->line;
    }
 
    public function key() {
        return $this->i;
    }
 
    public function next() {
        if (false !== $this->line) {
            $this->line = fgets($this->fileHandle);
            $this->i++;
        }
    }
 
    public function __destruct() {
        fclose($this->fileHandle);
    }
}
?>

兩者差異其實很清楚,如果是用 generators,是無法回覆上一步驟,但是如果是用 Class 寫法,就可以重複使用,只需要宣告一次即可,但是 generators 就必需要一直呼叫 function 來使用。

新增 finally keyword

直接來看官網的例子比較清楚

<?php
function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    return 1/$x;
}

try {
    echo inverse(5) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "First finally.\n";
}

try {
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
} finally {
    echo "Second finally.\n";
}

// Continue execution
echo "Hello World\n";
?>

上面執行後會輸出

0.2
First finally.
Caught exception: Division by zero.
Second finally.
Hello World

finally try cache 執行完畢後一定會執行到 finally block,另外在留言部份有個例子也很棒

<?php
try{
        try {
                throw new \Exception("Hello");
        } catch(\Exception $e) {
                echo $e->getMessage()." catch in\n";
                throw $e;
        } finally {
                echo $e->getMessage()." finally \n";
                throw new \Exception("Bye");
        }
} catch (\Exception $e) {
        echo $e->getMessage()." catch out\n";
}
?>

執行結果為

Hello catch in
Hello finally
Bye catch out

新增 Password Hashing API

password hashing API 提供了 crypt() 演算法加密,所以現在不用自己寫 Password hash 了,直接使用 PHP 內建吧

<?php
echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";

輸出為

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

如果使用 CRYPT 演算法

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */

$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

輸出為

$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K

那該如何驗證使用者登入密碼正確呢?可以透過 password_verify function

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>

empty() supports arbitrary expressions

empty() 開始支援 function return value,不只是判斷變數而已。

<?php
function always_false() {
    return false;
}

if (empty(always_false())) {
    echo "This will be printed.\n";
}

if (empty(true)) {
    echo "This will not be printed.\n";
}
?>

如果在 5.5 版本以前就會噴

PHP Fatal error: Can’t use function return value in write context

支援 ::class keyword

5.5 開始支援 Class name resolution

<?php
namespace NS {
    class ClassName {
    }
   
    echo ClassName::class;
}
?>

上述輸出為

NS\ClassName

foreach 支援階乘式陣列

<?php
$array = [
    [1, 2],
    [3, 4],
];

foreach ($array as list($a, $b)) {
    // $a contains the first element of the nested array,
    // and $b contains the second element.
    echo "A: $a; B: $b\n";
}
?>

輸出為

A: 1; B: 2
A: 3; B: 4

真的是太強大了。

內建 Zend OPcache

本篇重點就是 5.5 開始內建 Zend OPcache,在之前要 tune php performance,無非就是加上 APC,為了改善 cache 效能,Zend 官方又寫了一套 ZendOptimizerPlus,將 PHP 編譯程 bytecode 存放在 shared memory,此方式避免到硬碟讀取 PHP 程式碼,並且編譯再執行。

目前支援 PHP 5.2.*, 5.3.*, 5.4.* and PHP-5.5,但是也許 PHP 5.2.* 將來會拔掉,但是這還沒確定。如果您的系統是 php5.5 以前的版本,可以透過 pecl 方式來安裝

# support Zend OPcache on PHP 5.2, 5.3 and 5.4
pecl install channel://pecl.php.net/ZendOpcache-7.0.2

完成後新增設定檔 /etc/php5/cli/conf.d/10-opcache.ini

zend_extension=opcache.so

[opcache]
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1

需要注意的是 opcache.revalidate_freq 設定,預設是2秒,也就是兩秒內 opcache 不會去偵測程式碼是否有修改,如果正在開發狀態,並且搭配 Livereload 的話,使用 opcache 請把 revalidate_freq 設定為 0,讓每次 reload 都重新偵測程式碼是否改變。另外提供官方給的效能數據,可以參考 Opcode Cache Benchmarks

CSS 垂直置中解法

$
0
0

相信大家在 Google 可以找到很多解法,這幾天在 Facebook 發現更精彩的解決方式,就是用 CSS:beforeinline-block,底下提供範例:

html 程式碼

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
  <div class="ot">
    <div class="wrapper"></div>
  </div>
</body>
</html>


CSS 程式碼

.ot {
  width: 400px;
  height: 400px;
  border: 1px solid #FF6600;
  text-align: center;
  margin: 0 auto;
}

.ot:before {
  content: '';
  display: inline-block;
  vertical-align: middle ;
  height: 100%;
}

.wrapper {
  display: inline-block;
  vertical-align: middle;
  width: 200px;
  height: 200px;
  background: #ccc;
}

Demo 結果

JS Bin

感謝留言提供一個不錯的教學連結: 未知高度多行文本垂直居中,可以讓文字置中,也是透過上述方法。一般單行文字置中,可以透過底下方式

.text {
  height: 26px;
  line-height: 26px;
}

如果是多行文字呢?也就是如果透過 P 標籤來顯示

xxxxxxxxxxx

*{margin:0;padding:0;}

.box{
  height:200px;
  width:300px;
  background:pink;
  margin:30px auto;
  font-size:0;
}
.box:before{
  content: '';
  display: inline-block;
  vertical-align: middle;
  width: 0;
  height: 100%;
}
.text{
  display: inline-block;
  font-size:16px;
  vertical-align: middle;
}

Demo 如下

多行文本未知高度垂直居中-by一丝

CodeIgniter 尋找新東家

$
0
0
CodeIgniter

很高興看到 CodeIgniter 出了 2.1.4 版本了,距離上個版本大約 9 個月,但是這次的 Release 只針對 Security 做改善,可以參考 Change Log。然而在今天看到 Ellislab 宣佈找尋 CodeIgniter 新東家,也就是官網不再維護此 Project,希望有新的團隊或公司可以接手,繼續讓 CodeIgniter 發揚光大,在 GitHub 上的 PHP Language 排名上,CodeIgniter 幾乎榜上有名,討論活躍度也是非常高的,但是公司就是找不到任何 Business Model 來支撐整個 Project 維護成本。其實觀察幾年下來,本來寫 CodeIgniter 核心人物都漸漸不在了,像是 @Philsturgeon 自己創了 Fuel PHP Framework,現在似乎也沒在參與此 Project?CodeIgniter 最後都是由 @narfbg 來 maintain 以及開發新功能,世界各地的 Pull Request 也都是由他負責審核並且參與討論,但是一個人還是無法負擔這麼多事情阿,所以現在 CodeIgniter 3.0 還是生不出來。最後希望還是有人可以接手 CodeIgniter,很期待 3.0 出來的說,都已經做了一半以上了,不要放棄阿。

HAproxy 搭配 Nginx port redirect issue

$
0
0
nginx-logo

HAproxy 是一套高效能分散式系統軟體,後端可搭配 Web 或 SQL 服務,這次在後端搭配 Nginx 出現 port redirect 問題,問題很簡單,在 Haproxy 設定 80 port 對應到內部三台 Nginx 機器,但是 Nginx port 設定 8080,這樣當我們在瀏覽網址如下:

http://aaa.bbb.ccc.ddd/test (請注意,最後沒有 slash 喔)

你會發現 Nginx 將網址轉成

http://aaa.bbb.ccc.ddd:8080/test/

為了避免 Nginx 自動將 port 加入到網址列,我們可以透過設定 port_in_redirect,Nginx 預設將此設定為 On,所以將此設定為 off,並且重新啟動 Nginx 即可

port_in_redirect off;

Coding on workspace of Chrome Developer tools

$
0
0
Google Chrome

相信網頁設計師並不陌生 Chrome DevTools,善用 DevTools 可以減少很多 Debug 時間,今天來介紹如何在 Chrome 瀏覽器上直接編輯程式,並且存檔,重新整理網頁後便可看到結果。聽到這裡大家一定會很好奇,不就開系統編輯器 (sublime, pspad, vim …) 工具,直接修改 => 存檔 => 重新整理嘛?但是這並不稀奇阿,重點是 Chrome 瀏覽器可以直接支援線上編輯檔案,而不是透過系統工具做編輯。這就是 Chrome 強大的地方,今天就來介紹 Chrome workspace

啟動 Workspace

打開 Chrome 瀏覽器,在網址列輸入: chrome://flags/,並且找到 Enable Developer Tools experiments,啟動此選項,最後重新啟動瀏覽器

Selection_004

打開 Chrome Console 介面,並且點選右下角 Setting 會看到此畫面

Selection_005

點選到 Experiment 後,將 File system folders in Source Panel 勾選,並且重新啟動瀏覽器

使 Workspace 編輯檔案

完成上述步驟,接著就是將 local 目錄掛到 Chrome Dev Tool 介面,請先打開瀏覽器,打 local 網址,並且將 console 介面打開

Selection_006

指定好 path 後,可以將 setting 頁面關閉,然後切換到 Sources Tab,你會發現如下圖

Selection_007

我們可以開啟 app/index.html,直接在 console 介面編輯並且存檔

Selection_008

接著直接 refresh 網頁即可。

心得

用 workspace 其實重點就是你可以直接開 browser 然後旁邊的 console 介面可以直接編輯,而不是切換到系統編輯器修改,當然這還不是很方便,如果搭配了 GruntJSLiveReload,你會發現,編輯程式碼後,Grunt 也是會自動跑相關設定,LiveReload 也會自動幫忙更新網頁喔。

可以參考之前的文章: 2013 Javascript Conference: 你不可不知的前端開發工具

另外可以直接拿下面兩專案來跑 RequireJS + Backbone.js + GruntJS
Github: html5-template-engine
Github: backbone-template-engine


Linode 升級硬碟空間

$
0
0

Twitter Bootstrap 發佈 3 RC1 版本

$
0
0

今天非常開心看到 Twitter 團隊發佈 Bootstrap 3 RC1 版本,Twitter 這次是大動作的改版,連官網都換掉了,如果你還在使用 2.3.2,Twitter 也提供之前的網站版本,讓使用者可以繼續使用,當然希望各開發者可以盡快轉換到 3 RC1,此版本超過 1600 commits 修正。Twitter 也另外開了 Github Organization,如果要找範例的話,可以到 bootstrap-examples 來看看。另外大家最關心的是效能,底下影片介紹 Bootstrap 3 vs Bootstrap 2.3.2 版本差異。

Cross Site Request Forgery in JS Web Apps and CodeIgniter PHP Framework

$
0
0

Cross Site Request Forgery 簡稱 CSRF 是網路上最常見的攻擊方式,由於前端的盛行,現在開發網站偏向前後端拆開,前端使用大量的 Javascript 及 CSS3 效果,後端則是使用 PHP, Ruby, Python… 等,前端如何拿到資料庫資料呢,必需透
過 AJAX 方式來存取,常見的後端 API 會設計成 RESTful (GET/PUT/POST/DELETE),後端為了擋住 CSRF 攻擊,所以限定了特殊 Content-Type Header,前端需要帶 application/json 給後端才可以拿到資料,這只能透過 Ajax requests 才可以做到。

但是很不幸的是使用者還是透過 header injection 方式來達到目的 (Flash exploits),所以透過判斷 Content-Type Header 這方式是不夠的。正確的防護方式就是在每個 request 給上一組 token,因為 same origin policy 關係,攻擊者無法拿到此 token,無法達到攻擊效果。

如果你是 Ruby 愛好者,可以透過 Rack CSRF 來產生 token,並且放在網頁 Head 內

在 jQuery 部份,必須使用 ajaxPrefilter 將每個 Request 加上 CSRF token 傳給伺服器

var CSRF_HEADER = 'X-CSRF-Token';
var setCSRFToken = function(securityToken) {
  jQuery.ajaxPrefilter(function(options, _, xhr) {
    if ( !xhr.crossDomain ) xhr.setRequestHeader(CSRF_HEADER, securityToken);
  });
};
setCSRFToken($('meta[name="csrf-token"]').attr('content'));

如果是在 Head 內加上 csrf-token 就必須透過上述作法,但是 CodeIgniter 並非是使用此方式,要將 CSRF 打開可以透過 config/config.php 內的

$config['csrf_protection'] = FALSE;
$config['csrf_token_name'] = 'csrf-token';
$config['csrf_cookie_name'] = 'csrf-token';
$config['csrf_expire'] = 7200;

將 csrf_protection 改成 true,這樣透過 from helper 產生的 form 表單,你會發現會多出 hidden input value,這樣送出表單的時候就可以驗證此 token 是否正確,如果你不是透過 CI form 表單產生,那也可以在 Client 端抓取 csrf-token 的 Cookie 資料,因為 CI 也會同時將 csrf-token value 寫入 Cookie,Cookie 可以透過 jQuery cookie plugin 來讀取。

另外如果你也想透過最上面 head 方式來處理,CI 那邊也可以透過 $this->security->get_csrf_hash() 來取 hash 資料,將此資料放到 html head 裡面即可。

Git rebase + stash 小技巧

$
0
0

每天打開電腦,第一件事情就是將專案程式碼更新的最新,以便整合同事新開發的功能,免的跟自己寫的功能衝突,所以最常用用的就是 git pull –rebase origin master,此命令使用 rebase 來取代 merge 程式碼,也可以避免在 log 清單內出現 merge branch master into master 等字樣,但是如果在開發一半進度時,想同時將同事的程式碼先 merge 進來,會發現無法 merge,git 會請你先將 local 修改過的檔案 commit,才可以讓您更新,所以這時候我們可以用 git stash 方式來解決

如果你在 master 分支上,並且想 pull 最新的 commit,可以透過底下指令步驟

$ git stash --include-untracked
$ git pull --rebase origin master
$ git stash pop
# fix conflict (merge)


此方式一樣最後需要解決衝突,解決完成,可以將 stash 清空,透過再次執行 git stash pop,或 git stash drop 就可以了,但是這樣有點麻煩,可以不要使用 git stash 也達成這效果嘛?底下是更好的方式

$ git add .
$ git commit -m 'push to stash'
$ git pull --rebase origin master
# fix conflict (rebase)
$ git reset HEAD~1

基本上原理很簡單,我們先將 local 檔案 commit 到 local,接著一樣執行 pull –rebase 將遠端 commit 拉下來,接著執行 git reset HEAD~1 就是刪除最後一個 commit 但是保留最後 commit 修改的內容。

Postfix mailbox 設定

$
0
0

Postfix_logo
此篇不會講太多 Postfix 的設定,只是紀錄如何設定 Postfix mailbox。Postfix 提供兩種 E-mail 儲存格式,一種就是將全部的 mail 都寫到同一個檔案,此方式是 Postfix 裝好後預設的模式,另外的就是一封 E-mail 一個檔案,這兩者各有優缺點好壞,前者最大的問題就在於如果該檔案壞掉,那使用者的全部 Email 就消失了,所以個人比較偏好後面方式,最主要最近裝按要實做 E-mail Queue 功能,後者才能讓程式好判斷該目錄是否有異動。

Mailbox

如果都不修改任何設定預設裝好 Postfix,就可以看到 /var/spool/mail/ 目錄下有許多使用者檔案,一個使用者一個檔案,當然你也可以將使檔案設定在家目錄裡面。打開 /etc/postfix/main.cf 設定檔,並加入底下設定

home_mailbox = Mailbox

此設定會將原本放在 /var/spool/mail/ 目錄下的檔案都換成 /home/appleboy/Mailbox,注意在 bashrc 請加入

$ export MAIL=~/Mailbox

Maildir

如果改成此設定,就會變成一個檔案代表一封 email,請在 /etc/postfix/main.cf 加入底下設定

home_mailbox = Maildir/

接著取消 MAIL 變數

$ unset MAIL

最後寫入新的變數內容

$ export MAILDIR=~/Maildir

重新啟動 postfix

$ /etc/init.d/postfix restart

這時你會發現在自己的 Home 目錄底下多出了 Maildir/tmp, Maildir/cur, Maildir/new 等三個目錄,代表設定成功了

Viewing all 325 articles
Browse latest View live