Phalcon-コンパイルされたPHP MVCフレームワーク



PHP向けにコンパイルされたMVCフレームワークを何度も作成することは、プログラマーの頭に浮かびました。



このアプローチの利点:



そして、それだけで明らかな欠点はありません:







この記事では、コンパイル済みのPHP MVCフレームワークを作成する別の試みを紹介します。



知人



私自身は、高速で信頼性が高く、有能なフレームワークを探しています。 外国のフォーラムやブログを歩き回って、「Hello World!」のフレームワークが何回もおなじみの有名人になった興味深いベンチマークに出会いました。







私はそのようなことを通り抜けることができず、それがどのように機能し、発展するかを見つけ始めました。

プロジェクトは1年未満です。 githubでの最初のコミットは2012年1月10日です。もちろん、これはオープンソースプロジェクトです。 私が理解しているように、今では3人が多かれ少なかれそれに従事しています。



著者は、パフォーマンスを考慮せずにコードを書く機会を人々に与えようとし、標準を遵守し、サーバーの最初からメモリにロードされる使用されるメソッドのほとんどにアクセスできるようにします。





フレームワークを学習する最良の方法は、ドキュメントを並行して学習しながら、フレームワークで何かをすることです。

phalconの機能のいくつかを示す3ページのアプリケーションを作成しました。



さらに、開発者はさらに多くのことを言っています。





プロジェクト階層:


 xmpl /
    アプリ/
         app / config /
        アプリ/コントローラー/
        アプリ/モデル/
        アプリ/ビュー/
        アプリ/私/
    公開/
         public / img /
        公開/ css /
        公開/ js /




すべてのコードはパス/ apps /に沿って配置され、アプリケーション/public/index.phpを初期化します。 最後のファイルは、 apache (/および/ public /フォルダーの.htaccess)またはnginxを介して存在しないページをリダイレクトするように実際に設定する必要があります。



初期化:


スポイラーの下での簡単な初期化について。
<?php //    ini  $config = new Phalcon\Config\Adapter\Ini( '../apps/config/config.ini' ); // ,  ,      $loader = new \Phalcon\Loader(); $loader->registerDirs(array( $config->application->controllersDir, $config->application->modelsDir, $config->application->myDir, )); $loader->register(); // DI $di = new \Phalcon\DI(); //,    url. $di->set('url', function() use ($config){ $url = new \Phalcon\Mvc\Url(); return $url; }); //    ,  ( Mysql, PostgreSQL, SQLite) $di->set('db', function() use ($config) { $connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array( "host" => $config->database->host, "username" => $config->database->username, "password" => $config->database->password, "dbname" => $config->database->name )); return $connection; }); //2       $di->set('modelsManager', function(){ return new Phalcon\Mvc\Model\Manager(); }); //,   -  ,  (Apc, Files, Memory, Session) $di->set('modelsMetadata', function(){ return new \Phalcon\Mvc\Model\Metadata\Memory(); }); //  $di->set('router', 'Phalcon\Mvc\Router'); // ,      view  .    . $di->set('dispatcher', function() use ($di) { $dispatcher = new Phalcon\Mvc\Dispatcher(); return $dispatcher; }); //    $di->set('response', 'Phalcon\Http\Response'); $di->set('request', 'Phalcon\Http\Request'); //   $di->set('filter', function(){ return new \Phalcon\Filter(); }); //    Volt   $di->set('voltService', function($view, $di) use ($config) { $volt = new Phalcon\Mvc\View\Engine\Volt($view, $di); $volt->setOptions(array( "compiledPath" => $config->application->templCompDir, "compiledExtension" => ".compiled" )); return $volt; }); // ,   .    eventManager, //,     view.    //      $di->set('view', function() use ($config) { $eventsManager = new \Phalcon\Events\Manager(); $viewManager = new ViewManager(); $eventsManager->attach('view', $viewManager); $view = new \Phalcon\Mvc\View(); $view->setViewsDir( $config->application->viewsDir ); $view->registerEngines(array( ".phtml" => 'voltService' )); $view->setEventsManager($eventsManager); return $view; }); //    ,  front (Base64, Data, None, Output)  backend (Apc, File, Memcache, Mongo),  ,     $di->set('cache', function(){ $frontCache = new Phalcon\Cache\Frontend\Data(array( "lifetime" => 60 )); $cache = new Phalcon\Cache\Backend\Apc($frontCache); return $cache; }); //         try { $application = new \Phalcon\Mvc\Application(); $application->setDI($di); echo $application->handle()->getContent(); } catch(Phalcon\Exception $e){ echo $e->getMessage(); }
      
      









ほとんどの場合、次のように自動的に接続できます。

 $di = new Phalcon\DI\FactoryDefault();
      
      







コントローラーとそのクラス:


これで、アプリケーションの標準ルーティング/ baseUri / ControllerName / ActionName /が利用可能になり 、コントローラーを継承するメソッドが接続されます $ this-> cache、$ this-> dispatcher、$ this-> db ...



/ apps / My /フォルダーにあるクラスを呼び出すこともできます

ViewManagerクラスは、 Viewによって生成されたすべてのイベントを受け取りますbeforeRenderの興味について。 その中で、クラスとアクションの名前を含むビュー変数に渡します。



BaseControllerクラスも作成します
 class BaseController extends \Phalcon\Mvc\Controller { public function initialize() { Phalcon\Tag::prependTitle('Example | '); } }
      
      





 class IndexController extends BaseController { public function initialize() { //    title,     (   Poll) Phalcon\Tag::setTitle('Index'); parent::initialize(); } public function indexAction(){ } }
      
      







標準クラスを継承します。 コントローラーは既にBaseControllerを継承し、htmlタイトルタグのプレフィックスを取得します。





表示する


Phalconは、階層が存在する場合に非常に便利なテンプレートメソッドを提供します。

テンプレートは/ apps / views /に保存されます

ルートテンプレート/apps/views/index.phtmは、異なるパスが明示的に設定されているコントローラーを除き、すべてのコントローラーによってレンダリングされます。

このファイルには、さらに階層パスが含まれる場合があります。

 {{ content() }}
      
      







組み込みのテンプレートエンジンの構文を使用しました。 他のエンジンにも独自のアナログがあります。

この関数は、パスに沿って配置された次のパターンを呼び出します。

/apps/view/layer/ControllerName.phtml



実際、アプリケーションで行ったように、特定のコントローラーに特別な設計を設定します。 また、その中のcontent()を呼び出して、/apps/views/ControllerName/ActionName.phtmlテンプレートをロードすることもできます



テンプレートでは、他のテンプレートをロードし、事前定義されたブロックを置き換え、ユーザー定義およびエンジン事前定義された関数を呼び出し、Modelsメソッドにアクセスできます。

若いプロジェクトはVoltだけであるため、多くの機能は含まれていませんが、今後のリリースで計画されています。

箱から出して、 スリムスマーティー口ひげをサポート...



すぐに使用可能なコンパイル済みテンプレートをキャッシュする機能があります。最大0.6.0までのバージョンでのみ、キャッシュを無効にして空白ページを生成するバグがあります。



モデル


データベースへの接続は、PDOを使用して実行されます。 データベースの操作には、オブジェクト指向パスと、独自の疑似SQL文字列ハンドラーであるPHQLの2つの実装があります。

残念ながら、最初のクエリはかなり単純なクエリにのみ適しており、2番目のクエリは最初のクエリに慣れている人には難しいでしょう。



応用モデル
 class Poll extends Phalcon\Mvc\Model { //    ,  ,    public public $id; public $gender; public $age; public $read_modern; public $authors; public $genre; public $method; public $timestamp; //    ,      public function getSource() { return 'answers'; } //     public function initialize() { $this->setConnectionService('db'); } }
      
      









モデルでは、私にとっては、メタデータをさまざまな場所に保存することを除いて、新しくて面白いものは見つかりませんでした。 それらは完全に事前に決定することもできます。



短所


私はこのフレームワークでできることをすべて理解していませんでしたが、まだ欠陥に気づいていました。



それを欠陥と呼ぶのは難しいです。 githubの問題リストを除き、開発者と直接連絡がない限り。



アプリケーション機能



メインページ、投票ページ、結果の出力を備えたアプリケーションがあります。 したがって、データベースを操作し、フィルタリングを使用してデータを送信し、Apcで詳細なキャッシュを使用して受信します。



Iron:VPSホスティング。 プロセッサーx1 500 MHz、OP 256 MB。 馬は弱いです。

接続されたAPC。 設定はすべてデフォルトです。 サーバー:nginx-php-fpm-php-mysql



模擬テスト:

1. -c50 -d5 -r10

2. -c100 -d2 -r10

3. -c300 -d2 -r20(LA-0.7)

4. -c400 -d1 -r20(LA-0.47)

5. -c800 -d1 -r30(LA-1.1)

6. -c1000 -b -r20(LA-2)

(-c:競合他社、-d:再呼び出しまでの遅延、-r:再試行回数、-b:遅延なく呼び出し、LA:負荷平均)





Siegeは、すべて動的に3つのリクエストをランダムに行います。 そのうち2つはデータベースクエリを使用し、1分間のキャッシュを使用します。

競争が激しいため、エラーが発生しました(リクエストの最大2%)。

1秒あたり最大516リクエストを処理しました。 かなりいいね。 要求されたjsonをファイルに保存し、それらをcronで更新すると、負荷を減らすことができます。



包囲でさらに2、3のテストを実施しました。 -c500 -r10 -d1 -i

1. APCは無効です

2. APCは小さなバッファーで有効であり、stat = 0

画像



参照資料



ファルコンのウェブサイト

Phalconリポジトリ



実施例

GitHubサンプルソース



PS


アプリケーションの調査は単に選ばれたものではなく、正直に答えてください;)

混乱をおかけして申し訳ありません。すべてを1つの記事にまとめることは不可能です。



11/19/2012 11:00 p.m.

誰かが、データベースから結果を返すクエリを止めることにしました。 ログは飛躍的に成長します。 LAの範囲は1〜4です。サイトは読み込み中です。 私はとても幸せです:)

wrkを使用してください 。 ログから判断すると、1秒あたり60リクエストになります。 ip 188.254.105.18

11/19/2012 11:43 PM

0.5GBのログをスパムしましたが、それで十分です。 さようなら



All Articles