ぷぎがぽぎ このページをアンテナに追加 RSSフィード

2012-06-18

[][] OrePHPはこれでさらに高速になった(OrePhalcon)

前回、OrePHPはシンプルで速いクールなフレームワーク - ぷぎがぽぎという内容の記事を書きましたが、これぐらいの速度で満足してはいけないということで更に高速化を考えました。

Cのエクステンションで書かれた超高速PHPフレームワーク Phalcon

Phalconというフレームワークをご存知でしょうか?フレームワークをCのエクステンションで書いちゃった超高速PHPフレームワークです。

最速フレームワークと宣言してあるだけのことがあるベンチマーク結果が以下のグラフです。

f:id:brtRiver:20120619020407p:image

前回のベンチマークをも超越しそうな結果です。というわけで、早速HelloWorldでOrePHPと比べてみます。

まずはPhalconをインストール

エクステンションなのでgitからcloneしてきたものをいつもどおりphpnizeしてmake。

あとはphp.iniに

extension=phalcon.so

を追加。

環境はPHP5.4 + nginx なので

nginxの設定に以下を追加

        location / {
          if (!-e $request_filename) {
            rewrite ^/(.+)$ /index.php?_url=$1 last;
            break;
          }
        }

_urlというパラメータで渡すのを忘れずに。

準備はできたのでさっそくベンチ。

nametrans/secrelative(%)
OrePHP484.76100%
Phalcon738.94152%

はい。簡単に負けましたw

最速と自負するだけのことはあります。

じゃあ、Phalconをベースにすればいいじゃまいか

OrePHPではSymfony ComponentsのRoutingコンポーネントを使っていましたが、たぶんこれがCで書かれていないから負けるんだということで、Phalconのルーティングを使うようにしてOrePhalconを作ってみました。

<?php
ini_set('display_errors', 1);
error_reporting(-1);

$router = new Phalcon_Router_Regex();
$router->setBaseUri('/phalcon');
$router->add("hello/(\w+)", array(
    "controller" => "hello",
    "action" => "say",
    "name" => 1,
));

$router->handle();
$controller = $router->getControllerName();
$action =  $router->getActionName();
$params = $router->getParams();

try{
  $controllerFilePath = __DIR__ . '/../app/controllers/' . $controller . ".php";
  if (!file_exists($controllerFilePath)) {
    throw new Exception("controller file is not found");
  }
  require $controllerFilePath;
} catch (Exception $e) {
  echo $e->getMessage();
  exit;
}

$class = ucfirst($controller);
echo $class::$action($params);

今回は最速を目指すのでフレームワークとしてコアファイルはこのファイル1つです。

フレームワークのコアクラスはエクステンションで書かれているのでrequireすら不要です。

あとは、実際に呼び出されるコントローラーファイルをHello.phpとして用意します。

<?php
class Hello
{
  public static function say($params)
  {
    return "Hello " . $params['name'];
  }
}

OrePhalconは最速になれたのか?

nametrans/secrelative(%)
OrePHP484.76100%
Phalcon738.94152%
OrePhalcon923.60191%

はい。最速でした。

Phalconほんと速いですね。

2012-06-10

[][]composerでPHPのプロジェクトを簡単に始める

composerとはなんぞや?

composerはPHPのパッケージの依存関係やバージョン管理を行う仕組みで多くのライブラリPackagistを通して利用可能です。

詳しいcomposerの記事は以下を参照していただくとして...

composerのautoloadを利用する

composerはパッケージ管理なので、別に公開することが前提ではありません。プライベートなプロジェクトでも普通に使うことができます。

composerを使えば、PSR-0に準拠した名前空間のautoloadも用意されていて便利です。準備に必要なのは以下の作業だけ

プロジェクトのディレクトリを作成

これから開発するプロジェクトのディレクトリを作りそこに移動

$ mkdir project
$ cd !$
composerをインストール

composer.pharをダウンロードしてきます。グローバルではなく個々のプロジェクト毎にインストールできます

$ curl -s http://getcomposer.org/installer | php
さくっとプロジェクトのひな形作成

composer.jsonを作成する必要がありますが、通常はコマンドラインからひな形が作成できますが、欲しいのはpackagistに登録するためではなく自分用の名前空間の登録だけです。

というわけで以下をcomposer.jsonとしてコピペ

{
   "repositories": [
     {
       "packagist": false
     }
   ],
   "autoload": {
     "psr-0": {"Oreore": "src"}
   }
}

Oreoreの部分はあなたのベンダー名をつけてくださいね。

あとは

$ php composer.phar install

するだけで、自前のライブラリは./src/Oreore/Hoge.phpのように書けばautoloadに対応できます。

composerは"packagist": falseを書かないと標準でリポジトリとしてPackagistを見に行こうとするようです。ただ自前のディレクトリ構造を用意したいだけなのにこのPackagistへのアクセスのためにインストールに時間がかかってしまいます。1分以上掛かることもあります。というわけでこの対策のためにfalseを書いています。これを書いておけば1秒も掛かりません。

composerのautoload.phpを利用する

これで準備完了です。あとはコードでautoload.phpをrequireするだけ

<?php
require __DIR__ . "/vendor/autoload.php";

use Oreore\Hoge;
$hoge = new Hoge();
...

名前空間を使うのもこれだと簡単だと思います。

Let's enjoy PHP with Composer.


あ、Composerって突然仕様が変わったりしてちょっとまだ安定してないので注意してね。(はーと)

2012-06-09

[][]OrePHPはシンプルで速いクールなフレームワーク

[追記1] 2012-06-10: ベンチマークを追加

[追記2] ブクマのコメントに回答

[追記3] ベンチマークをちょっと充実させた。Pinocoはえー

[追記4] コントローラーの仕組みを変更 & debugモード追加

[追記5] PHP5.4.4で再ベンチ

"ぼくがかんがえたさいきょうのふれーむわーく"ではないですが、OrePHPというPHP Webアプリケーション フレームワークを1つ書いてみた。

no title

こんせぷと

フレームワークが提供するのはルーティングだけ。シンプルに。速く。

ぼくがほしいのは、るーてぃんぐ

素のPHPでWebアプリケーションを書きたくない理由の1つがルーティングを用意するのが面倒というのがあります。Symfonyだとyaml、php、xmlなどで定義できて結構便利です。つまり、自分が欲しいのはルーティングだけなんだというのは結構多いような気がします。というわけで、Symfony Component Routingを利用できるようにしただけのフレームワークです。なので、コアコードは70行ちょっと。

るーてぃんぐ・ふれーむわーく

仕組みは簡単。ルーティングの定義をconfig/routing.yaml に書きます。

書き方はSymfonyとほぼ同じ。どのコントローラーを呼ぶかを定義すればOK。

hello:
    pattern: /hello/{name}
    defaults: { controller: 'hello' }

これだと/hello/hogeでアクセスされると app/controller/hello.phpがincludeされるというだけ。

あとは、hello.phpでやりたいことを書いて、returnでブラウザに返したい文字列を書くだけ。

ここで、hello.phpで無名関数をreturnするようにします。そして無名関数内のreturnでブラウザに返したい文字列を書くだけ。

<?php
return function($request, $params, $container) {
    $now = date('Y-m-d H:i:s');
    return "Hello world " . $params['name'];
};

見ての通りクラスじゃないです。普通のPHPファイルです。よくMVCフレームワークだとアクションという概念がありますが、これには無いです。コントローラーだけです。

無名関数に渡される引数は、リクエストオブジェクト(Symfony2と同じ)、ルーティングで取得したパラメータDIコンテナ(Pimple)です。

ただ、returnで文字列返すのは面倒だ。やっぱりTwigぐらい使いたいってのはありますよね。その場合は次のように書けばOK

<?php
return function($request, $params, $container) {
    $now = date('Y-m-d H:i:s');
    return $container['tpl']->render('hello.html', array('now' => $now, 'name' => $params['name']));
};

$container['tpl']というのがTwigのインスタンスになってるので、この場合はだとapp/views/hello.htmlがtwigのテンプレートとして処理されます。簡単ですね。また、Twigのインスタンスは遅延読込になっているので呼ばない限り読込すらしません。このあたりはPimpleというDIコンテナを使ってよしなにやってます。つまり、Pimpleのインスタンスが$containerですね。

ふつうにはやい

一番重い処理はrouting.yamlの解析だと思いますが、一度解析するとcache/ProjectUrlMatcher.php にキャッシュし、2度目以降は解析しません。普通にPHPのクラスファイルを読み込むだけになるので速いです。ということで、routing.yamlを書き換えたらキャッシュされているファイルを手動で削除しなくちゃいけません。

そうしないと、変更後の内容が反映されないので。

また、デバッグモードを追加しました。

index.phpで

$app->c['debug'] = true;

と追記してデバッグモードを有効にすれば毎アクセスごとにrouting.yamlをパースします。開発時には有効にしておくと便利です。

(追記)簡単なHello World的なベンチマーク結果は以下のとおり。PHP5.4.3(php-fpm)+apc+nginxのvmにsiegeで計測。あくまでオレ環境なので参考程度で。

(追記2)FuelPHPを再計測

(追記3)PHP5.4.4で再ベンチ

siege -b -c 10 -t 3S http://xxxx/xxx で検証
nametemplate enginetrans/secresult(relative)
FuelPHP 1.2Twig130.0463%
FuelPHP 1.2-169.0882%
SilexTwig170.6383%
Silex-205.61100%
OrePHPTwig342.89167%
Pinoco(dev-master)PHPTAL352.11171%
CodeIgniter 2.1-373.02181%
Pinoco(dev-master)-429.84209%
OrePHP-484.76236%

SilexのTwig無バージョンを基準としてみると、2倍ぐらいのレスポンスは叩きだせますね。わーい。

でーたべーすとかは?

なにそれ?おいしいの?

せっていふぁいるとかは?

routing.yamlだけあります。ほかは$app->cがDIコンテナなのでよしなにやってね。web/index.phpでTwigをほり込んでるあたりが分かりやすいかと。ちなみにindex.php全体でもたったこれだけ。

<?php
require __DIR__ . '/../vendor/autoload.php';
$app = new Ore\Framework;
$app->c['tpl'] = $app->c->share(function($c){
    $loader = new Twig_Loader_Filesystem($c['base_dir'] . '/app/views');
    return new Twig_Environment($loader,array(
                                  'cache' => $c['cache_dir'],
                                  ));
  });
// $app->c['debug'] = true;
$app->display();

つかいかた

githubからgit cloneなりダウンロードしてきたら

$ php composer.phar install

で外部ライブラリインストールするだけ。

cacheディレクトリは実行者が書き込めるように0777にしておきましょう。

あとは、ブラウザからhttp://example.com/hello/orephpにアクセスすればOK

コメントありがとうございます

以下のコメントをいただきました。ありがとうございますm(__)m

なぜPHPを直書きさせてないのか?について
  • yaml じゃなくて素の PHP の方が速くなりそうなんだけど、どうなんだろう。 by id:heavenshellさん
  • キャッシュを手動削除する手間が必要なら、素直にPHP直書きさせたらいいのに by id:terurouさん

キャッシュを利用しているのは速くなるからなのですが、yamlよりPHPの方がと考えが浮かぶのはわかります。しかし、実際にどのようにキャッシュされているかを見ると納得してもらえるのではないかと...。

routing.ymlで以下のように定義したファイルは

hello:
    pattern: /hello/{name}
    defaults: { controller: 'hello' }
default:
    pattern: /{controller}
    defaults: { controller: controller }

以下のような cache/ProjectUrlMatcher.php に変換されキャッシュされます。

<?php

use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RequestContext;

/**
 * ProjectUrlMatcher
 *
 * This class has been auto-generated
 * by the Symfony Routing Component.
 */
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
{
    /**
     * Constructor.
     */
    public function __construct(RequestContext $context)
    {  
        $this->context = $context;
    }

    public function match($pathinfo)
    {  
        $allow = array();
        $pathinfo = rawurldecode($pathinfo);

        // hello
        if (0 === strpos($pathinfo, '/hello') && preg_match('#^/hello/(?<name>[^/]+)$#s', $pathinfo, $matches)) {
            return array_merge($this->mergeDefaults($matches, array (  'controller' => 'hello',)), array('_route' => 'hello'));
        }

        // default
        if (preg_match('#^/(?<controller>[^/]+)?$#s', $pathinfo, $matches)) {
            return array_merge($this->mergeDefaults($matches, array (  'controller' => 'controller',)), array('_route' => 'default'));
        }

        throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
    }
}

なんとなくyamlファイルがただパースされてPHPの配列になると想像する方もいるかもしれませんが、Symfony Component Routingはこのように、DSLで複雑なPHPコードを抽象化し記述できるようにしてくれています。なので、今回はyamlを選択していますが、xmlでもphpの配列でも定義することができ、最終的には同じPHPコードに変換されます。さすがにこのクラスコードをルーティングを追加、編集するたびに書けというのは辛いですよね。

参考: ドメイン特化言語とモデル駆動エンジニアリング - Johan den Haan - Digital Romanticism

とはいえ、開発用にキャッシュしないオプションがあったほうがいいですよね。

index.phpでデバッグモードを有効にしている場合はキャッシュを利用せずに毎回パースするようにしました。

$cとか突然でてくるのキモいよね
  • $cとか突如出現するの怖いし、$thisにできないですかね。(再代入防げるし)by id:escape_artistさん

はい。キモイですよね。うん。キモイとおもいます。

まだまだ改良の余地はありますよね。せめてクラスメソッドで閉じ込めるようにしたいと思います。

改良し、無名関数に閉じ込めました。

オレオレフレームワーク作るの楽しいですね。

2012-06-03

[]プロとしてWebアプリケーションを開発するということ

f:id:brtRiver:20120603212700j:image:left

クロコスのエンジニアでもあり、日本Symfonyユーザー会のメンバーでもある小川さん([twitter:@fivestr])が執筆した最新作「効率的なWebアプリケーションの作り方 -PHPによるモダン開発入門-」を献本いただいたので紹介したいと思います。

最新の技術を追っているわけではなく、実績ある技術や手法の基礎編

サブタイトルに「モダン」という言葉があってPHPでの最先端な開発かと感じる方がいるかもしれませんが、内容はOOP、DI、そしてドメイン駆動開発などの基礎的なところを実例を通して紹介しています。つまり、これから5年後または10年後と利用することができる実績ある技術と手法について紹介していることが特徴だと感じました。*1

Webアプリケーションをプロとして開発するために必要な知識を理解するための一歩

PHPの書籍というと、PHPの構文などPHPの使い方にフォーカスした本、またはWordpressEC-CubeCakePHPなど特定のアプリケーションやフレームワークに特化した書籍は本屋でよく見かけると思います。しかし、Webアプリケーションを設計、開発するために必要な知識はそういった説明をPHPでしっかりとしてくれている日本語で読むことができる書籍はほとんど知りません。実際、そういった知識を得るためにはTDDDDDデザパタなどの世界へ足を踏み入れる必要がありますが、これらが敷居が高いと感じる方が多いのではないでしょうか?そうでない方は次のような本は既に読んでると思いますが...

洋書だとこんなのあるんですけどね...


「説明が浅すぎるかな?」と感じる部分はありますが、今まで一歩目を踏み出すことができなかった方も、この本でその世界に触れることができ理解を深めるための第一歩が踏み出せると思うととても良いバランス配分だと思います。ただ、決して内容は簡単ではありません。かなりの時間と努力が必要になると思います。

Symfony本であってSymfony本ではない

もう一つ大切な側面として、日本語で読むことができるSymfony2系の解説本という側面もあります。本書ではレンタカーアプリケーションの開発例を通して具体的な開発方法を説明するというかなりガッツリな内容になっています。ただし、本を開かない限りSymfonyだということを意識させない紙面構成になっています。なぜなら、フレームワークに特化した使い方の説明がメインではなく、フレームワークに依存しない知識や技術がメインだからです。もっというと、PHP以外の言語で開発するとなってもきっと役に立つことが多いんじゃないでしょうか?

「何か難しそう。興味はあるけど本を読むだけではよくわからん。」

という方もいらっしゃるでしょう。で、ステマですが、6/30(土)に Symfony勉強会#6 を渋谷で開催します。

zusaar.com -&nbspzusaar リソースおよび情報

この勉強会ではテーマを「フレームワークに縛られない技術とそれを実践している一歩先ゆくエンジニアたちの声」としてSymfony2の基礎から開発に必要な技術を皆で学ぼうという機会で多くのベテランエンジニアの方に参加して頂いたり、スピーカーとして話していただいたりします。もちろん、この中でメインセッションとして著者である小川さんにも40分の講演をしていただく予定です。

募集は6/4(月) 12:00 ~ から先着順で行いますので、小川さんのサインが欲しい方、握手したい方、写真を一緒に撮りたい方、ファンの方是非ご参加を検討いただければと思います。

*1:本書内でもコラムでしっかりとこの点について強調されていました。

2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |