自從NodeJS,和Golang出來后,很多人都投奔過去了。不為什么,沖着那牛X的性能。那PHP的性能什么時候能提升一下呢?要不然就會被人鄙視了。其實大牛們也深刻體會到了這些威脅,於是都在秘密開發各種秘密武器。
HHVM和Hack
Facebook自己弄了一套HHVM虛擬機,和一個新語言Hack。HHVM的性能不錯,像Wordpress,PHPMyAdmin這樣的項目,運行在上面很流暢,但是有個問題很致命,如果你引入了第三方擴展,現有的代碼移植過去,沒辦法運行。如果你希望你的代碼運行於HHVM,那么你需要編寫基於HHVM的擴展,這時候你要學習C++了。很抓狂有木有?又或者,用Hack重寫你的代碼,這事誰會干呢?新項目可能可以拿來玩玩,但是舊的項目,如果代碼量大,且代碼混亂的項目,那就只能呵呵了。
PHPNG(next generation)
前些日子PHP核心開發組宣布了個利好消息,將在PHP 5.7版本會有很大的性能提升。這一次又打擊到HHVM了。但是要等到5.7的版本才會發布。現在很多都只是停留在5.4的版本,鞭長莫及啊。
除了這些,就沒有辦法提升性能了嗎?有!------ PHP擴展。
Phalcon沒聽過,Yaf總聽過了吧。什么?都沒聽過?趕緊去Google下,聽說面試會加分。
PHP擴展
PHP的流行,得益於它的擴展系統。開發者通過為PHP開發擴展,通過這個中間件,跟其他系統連接通信。例如我們常用的cURL,Memcache和Redis等擴展。這些擴展不包含在PHP核心,需要額外編譯。這里有一份官方列出的PHP擴展列表:
http://www.php.net/manual/en/extensions.alphabetical.php
如果你想自己編寫PHP擴展,意味着你需要掌握C語言,因為PHP的擴展是通過C編寫的,而且你還需要掌握PHP的Zend API,了解它的核心原理。如果你有興趣,可以參考:《深入理解PHP內核》。如果你懂C,那么你看完上面這本書,那么你大概也能寫了。但是,對於C語言水平比較菜,或者不怎么懂C的人來說,就只能望而卻步了。
為什么我要寫PHP擴展呢?
-
訪問現有的庫。假設現在有一個庫很好用(例如MongoDB),你希望在PHP也能用上它。如果這個庫很熱門,那么你就走運了,應該有大牛幫你實現了。要是運氣不好,這個庫比較冷門,但你業務需求又剛好需要用到的話,那只能干着急了(當然這種情況是極少出現的)。
-
性能。PHP是動態語言,代碼性能比C語言相差一個級別。正是由於此原因,產生了Yaf,Phalcon這樣的PHP的擴展框架。
對於那些不想學C,但又想要得到編寫自己的擴展,怎么辦?
Zephir
分析了以上的種種不靠譜,終於進入了正題。現在隆重向你介紹一個叫Zephir的項目。它可以幫助你使用類PHP的語法,來生成C語言代碼,並幫助你編譯成PHP擴展。是不是很酷?很酷,有沒有?
Show Me The Code
如果你用C寫一個Hello World的擴展,那么你需要這樣寫:
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_test.h" #include "test.h" #include "kernel/main.h" /** * This is a sample class */ ZEPHIR_INIT_CLASS(Test_Hello) { ZEPHIR_REGISTER_CLASS(Test, Hello, hello, test_hello_method_entry, 0); return SUCCESS; } /** * This is a sample method */ PHP_METHOD(Test_Hello, say) { php_printf("%s", "Hello World!"); }
而Zephir則只需要這樣:
01.
namespace Test;
02.
03.
/**
04.
* This is a sample class
05.
*/
06.
class
Hello
07.
{
08.
/**
09.
* This is a sample method
10.
*/
11.
public
function
say()
12.
{
13.
echo
"Hello World!"
;
14.
}
15.
}
是不是跟寫PHP代碼沒什么區別?
安裝 Zephir
1.
$ git clone https://github.com/json-c/json-c.git
2.
$
cd
json-c
3.
$ sh autogen.sh
4.
$ ./configure
5.
$
make
&&
sudo
make
install
1.
$ git clone https://github.com/phalcon/zephir
2.
$
cd
zephir
3.
$ ./
install
-c
安裝完成后,運行
1.
$ zephir help
如果沒有報錯,說明你已經安裝成功了。
Zephir語法
Zephir跟PHP有幾點區別:
- Zephir是強類型語言。變量有自己的類型。
01.
namespace Test;
02.
03.
class
Arithmetic
04.
{
05.
public
function
intSum()
06.
{
07.
int a, b, c;
08.
09.
let a = 1,
10.
b = 2,
11.
c = a + b;
12.
13.
return
c;
14.
}
15.
}
這里需要特別注意的是Zephir有個let關鍵字,用於變量賦值。
編譯擴展
- 初始化一個Zephir擴展
1.
zephir init myframework
- 新建一個叫 calculator.zep的文件
1.
namespace Myframework;
2.
class Calculator {
3.
public
function
add(int a, int b) {
4.
return
a + b;
5.
}
6.
}
Zephir必須指定一個命名空間,上面的例子Myframework為這次Demo的命名空間。Zephir遵循PSR-1的標准進行命名。
- 把Zephir代碼編譯成PHP的C擴展
1.
zephir build
- 開啟擴展
在你的php.ini文件加上
1.
extension=myframework.so
- 測試
1.
$ php -a
2.
php > $calc = new Myframework\Calculator;
3.
php > var_dump($calc->add(2, 1));
4.
int(3)
是不是很簡單?你也來嘗試一下吧。