聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

六月 25, 2013

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» PHP 5.5.0 Release note: support Zend OPcache

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

九月 20, 2011

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 安裝 XCache 加速 PHP 執行速度

php-logo

前言

最近 FreeBSD 系統常常會當機,加上 Varnish cache + APC 一直給我出包,所以這次就換了一套加速 PHP 執行的套件 XCache,這是一套由華人所開發的加速器,可以參考篇台灣PHP聯盟論壇所發表 PHP 加速器 – xcache,裡面可以看到這篇裡面就有中文的對話,非常好玩,這次也順便把 PHP 升級到 5.3.8 版本,還有 Varnish 一次升級到 3.0.1 版本。

各家 PHP 加速器

大家都知道目前網路上知名的 PHP 加速器 apc, eaccelerator, phpa, truck-mmcache,這幾套網路上資料很多,大家都可以試著玩看看,尤其是前面兩套 APC 及 eaccelerator,phpa 目前已經不再維護了,truck-mmcache 版本好像也沒啥在更新,距離上次更新是 2009-07-17,Xcache 作者研究 truck-mmcache 跟 APC 已經很長的時間,他發現 APC 的程式碼比起 truck-mmcache 還要簡單更容易瞭解,所以大家也可以研究 APC 相關程式碼。

Xcache 的由來

大家一定很想知道作者為什麼想要開發一套新的 PHP 加速器 Xcache 呢?早期作者還沒開啟此專案以前,都是在使用 APC 跟 eaccelerator,如果碰到任何 bug,作者都會第一時間告訴官方,作者也跟 eaccelerator 其中一位開發者 zoeloelip 有互動,zoeloelip 是第一位看到 XCache 程式碼,也因為他看過了 Xcache,所以他參考 Xcache 作者 Disassembler idea 來改寫 ea_dasm.c 大部分程式碼。這部份作者也是猜測的,最後作者有提到他為什麼寫了這專案,其實很簡單。

  • 作者有太多 idea 無法實做在 ea/apc
  • ea/apc 架構過於龐大,所以無法實際用在裡面
  • 作者用來練功

最後作者也認同 ea/apc 是不錯的加速器,大家可以實際用看看,感受一下加速過後的 PHP。也可以參考 FeatureList 看看 Xcache 有哪些功能。

安裝 Xcache

這邊環境是 FreeBSD 7.1 Release ports 安裝方式:

$ cd /usr/ports/www/xcache/; make install clean

安裝完成之後要進行設定,設定檔放在 /usr/local/share/examples/xcache/,裡面也包含了 admin 管理介面。

$ cp /usr/local/share/examples/xcache/xcache.ini /usr/local/etc/php/

接著附上我機器的設定檔

[xcache-common]
extension = xcache.so

[xcache.admin]
xcache.admin.enable_auth = On
xcache.admin.user = "admin"
xcache.admin.pass = "xxxxxxx"

[xcache]
xcache.shm_scheme =        "mmap"
xcache.size  =               16M
xcache.count =                 1
xcache.slots =                8K
xcache.ttl   =                 0
xcache.gc_interval =           0
xcache.var_size  =            2M
xcache.var_count =             1
xcache.var_slots =            8K
xcache.var_ttl   =             0
xcache.var_maxttl   =          0
xcache.var_gc_interval =     300
xcache.test =                Off
xcache.readonly_protection = On
xcache.mmap_path =    "/tmp/xcache"
xcache.coredump_directory =   ""
xcache.cacher =               On
xcache.stat   =               On
xcache.optimizer =           Off

[xcache.coverager]
xcache.coverager =          Off
xcache.coveragedump_directory = ""

這邊有要注意的地方就是在 Unix 系統設定 xcache.mmap_path 的時候,這是檔案而並非是目錄,這邊設定好之後,請先建立 /tmp/xcache 檔案

$ touch /tmp/cache && chmod 777 /tmp/cache

安裝完成之後請重新啟動 apache 或 lighttpd:

$ /usr/local/etc/rc.d/apache22 restart
$ /usr/local/etc/rc.d/lighttpd restart

最後直接可以看到 phpinfo 的相關訊息: 補個圖
phpinfo
或者是打看看 php -v 也可以看到訊息:

PHP 5.3.8 (cli) (built: Sep 20 2011 14:37:25)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
    with XCache v1.3.2, Copyright (c) 2005-2011, by mOo

安裝 Xcache 管理介面

設定管理者帳號密碼 (/usr/local/etc/php/xcache.ini 裡面) 請注意

xcache.admin.enable_auth = On
xcache.admin.user = "admin"
xcache.admin.pass = "xxxxxxxxxxxx"

密碼該如何產生呢?可以透過 php 指令去產生您要的 md5 密碼

php -r "echo md5('admin');"

或者是透過網頁

<?php
echo md5("password");
?>

最後將 admin 目錄放到您網站根目錄底下即可

$ cp -r /usr/local/share/examples/xcache/admin /usr/local/www/apache22/data/xcache

網址列打入 http://xxxxx/xcache 並且輸入上面所設定好的帳號密碼即可
XCache 1.3.2 管理頁面

參考網站:
http://xcache.lighttpd.net/wiki/InstallAdministration

Related View

support:

biggo.com.tw

biggo.sg

A Django site.