メモリ操作を気にせずにPHPエクステンションを作れる言語”Zephir”

  • 51
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

zephirとは?

zephirはphpエクステンションを生成することに特化した開発言語です。
http://zephir-lang.com/

特徴として、

  • メモリ操作を気にすることなくコードが書ける
  • 静的型付け+動的型付け
  • PHPの組み込み関数を利用する事が出来る
  • PHPライクなシンタックス

といった特徴が挙げられます。

PHPを書けるエンジニアなら習得するのは容易で、簡単にエクステンションを作成することが可能です。

インストール

centos6.5で検証しました。
Gitがインストールされていること、remiリポジトリを参照出来る事を前提としています。

yum install -y --enablerepo=remi gcc automake autoconf pecr re2c php-devel

# 適当なディレクトリに移動
cd /usr/local/src

git clone https://github.com/json-c/json-c.git
cd json-c
sh autogen.sh
./configure && make && make install
cd ../

git clone https://github.com/phalcon/zephir
cd zephir
./install -c

上記手順でインストールした場合、
/usr/local/src/zephir/bin/zephir-parserが生成されていればインストールは成功です。

スケルトン生成

コマンドラインからzephir init [name]と実行すればスケルトンが生成されます。

[name]
  Lext
  L[name]
  Lconfig.json

コードは[name]/[name]以下に作成していきます。

エディタ

Sublime Text2 にはzephirのシンタックスハイライトパッケージが提供されていました。
その他エディタについては存じません。

Hello World

定番のHello Worldです。

zephirでエクステンション作成

zephir init sampleでスケルトンを生成します
sample/sample/helloworld.zepでファイルを作成します。(拡張子は.zepです)

sample/sample/helloworld.zep
// namespaceは必須です、スケルトン生成時に指定した名前と同じ値を指定します。
namespace Sample;

// クラス名はファイル名と同一である必要があります
class HelloWorld
{
    public static function say()
    {
        echo 'Hello World!!';
    }
}

zephir buildでコンパイルを実行し、.soファイルを生成します、.soファイルは適当なディレクトリ(phpのエクステンションがデフォルトで置かれているディレクトリ)に生成されます。

今回はパッケージからPHPをインストールすることを想定して、
/etc/php.d/以下にsample.iniを作成しエクステンションを追加します。
echo "extension=sample.so" > /etc/php.d/sample.ini

PHPから作成したエクステンションを実行

Sample\HelloWorld::say(); // Hello World!!

変数はイミュータブル?

zephirで定義した変数はPHPのように直接変更することが出来ません。

var a;
a = 0; // コンパイルエラー

変数に値を設定する場合はletを使います

var a;
let a = 0; // OK

型付けを試してみる

zephirでは静的片付けと動的型付けの両方をサポートしています。

int型を例にどの程度静的型付け出来るのか確認してみた

// 数値以外も代入可能なint型...
int a = 0;     // OK
int b = false; // これはコンパイルエラー
int c = 100.5; // これもコンパイルエラー

int d;
let d = false, // 0   コンパイルエラーにならない
    d = 100.5, // 100 コンパイルエラーにならない
    d = 'foo'  // これは流石にコンパイルエラー

あまりカッチリしてないですね…

メソッドで型定義

public function foo(string str) -> <Foo\Bar>
{
}

引数、戻り値に対して型指定することが出来ます。
型がscalarではない場合<namespace\class>といった形で表現します。

else ifがない

何か代替となる手段があるかというとそうでもない。
else ifを使わないようなコーディングが求められるかも。

// else if と書けないので、同じことをしたいならifをネストさせる
if (1) {
  // 何か
} else {
  if (1) {
    // 何か
  } else {
    // 何か
  }
}

まとめ

軽くzephirについて書いてみましたが、この子、言語的には全く洗練されていません。
とはいっても、処理を高速化したいというケースは何処かしらで出てくるのではないでしょうか?
そういったケースを解決する時にCは難しいけど...というエンジニアでも解決策としてzephirを利用するという答えを持っておくのはいいかなと思います。
(現状大したベンチマークとってないので、どれだけ早いかには言及出来ませんが;;)

まだ新しい言語でもありますので、今後の発展に期待したいです。