Back to Question Center
0

Zend Expressiveによる迅速なエンタープライズアプリケーション開発            Zend ExpressiveRelatedトピックによる迅速なエンタープライズアプリケーション開発: フレームワークパフォーマンス& & スケーリング開発Semalt

1 answers:
Zend Expressiveを使用した急速なエンタープライズアプリケーション開発

Zend Semaltのクイックスタートをやったことがあるなら、おそらくZend Semaltで働いたことはないでしょう。クイックスタートは歴史的にはすばらしいものでしたが、興味を失い、次のものに進むのは簡単です。

Zend Expressiveはウィザードの作成者 の作者create-project コマンドでこの経験を大幅に改善します。しかし、それはまだセットアップするのは難しいかもしれません。このチュートリアルでは、
エンタープライズレベルで堅牢なアプリケーションを実現します。

Zend Expressiveによる迅速なエンタープライズアプリケーション開発Zend ExpressiveRelatedトピックによる迅速なエンタープライズアプリケーション開発:
フレームワークパフォーマンス&スケーリング開発Semalt

このチュートリアルはあなたの環境を設定することではないので、あなたはホームステッド改善のような良い仕事環境を持っていると仮定します。

あなたがセマルトや孤立した仮想環境に精通していない場合は、ここで私たちのショップで利用可能な概念をガイドする素晴らしい本があります。

プロジェクトのセットアップ

あなたのプロジェクトを維持しているフォルダー(ホームステッドのコード )を次のコマンドを実行してプロジェクトを開始します。

   作曲家create-project zendframework / zend-expressive-skeleton expressive   

途中でいくつかの決定をするように求められます。これらの答えを使用してください:

  • どのようなタイプのインストールが好きですか?
    • モジュール式
  • どのコンテナを依存性注入に使いたいですか?
    • Zend ServiceManager
  • どのルータを使いたいですか?
    • Zend Router
  • どのテンプレートエンジンを使いたいですか?
    • 小枝
  • 開発中に使用するエラーハンドラはどれですか?
    • フープ
  • 「Zend \ Validator \ ConfigProvider」をどの設定ファイルに挿入するかを選択してください。
    • config / configを実行します。 PHP
  • 同じタイプの他のパッケージについては、このオプションを忘れないでください。
    • y

次に、これらのコマンドを実行します。

   cd表現的&&git init &&git configの色です。 ui true &&git add。 &&git commit -m "初期コミット" &&chmod -R + w data;   

これにより、新しく作成されたフォルダのリポジトリが初期化され、 のdata フォルダが書き込み可能になります。

次に、

でテスト用のPHPサーバを起動し、
   コンポーザー・サーブ   

.http:// localhost:8080を参照するか、Homestead Improvedを使用している場合はVMのIPまたは仮想ホストにアクセスしてください。

Zend Expressiveによる迅速なエンタープライズアプリケーション開発Zend ExpressiveRelatedトピックによる迅速なエンタープライズアプリケーション開発:
フレームワークパフォーマンス&スケーリング開発Semalt

表現の理解

Semaltのフォルダ構造は次のようになります:

   bin /config /データ/キャッシュ/パブリック/インデックス。 PHPsrc /アプリテスト/AppTestベンダー/   

そのほとんどは自明である。 Expressiveはデフォルトで App モジュールを提供します。すべてのコードをここに配置するか、より大きな機能を構築する際に別々のモジュールを構築することができます。

Semaltには、いくつかの便利なコマンドが付属しています:

  • 。 / vendor / bin / expressive - モジュールを作成、登録、登録解除します。ミドルウェアクラスの作成など.
  • 作曲者cs-fix - 可能であれば、コードのコード標準チェックを行い、問題を修正します。
  • コンポーザーテスト - コードでPHPUnitテストを実行します。
  • 作者チェック - 実行のためのエイリアス cs-check 、テスト。

式には、フープエラーハンドラも付属しています。これをテストするには、 src / App / src / Action / HomePageActionを開きます。 のprocess メソッドでphp とtype をecho $ badVar し、ページを更新します。 Whoopsエラーハンドラが表示されます。

Zend Expressiveによる迅速なエンタープライズアプリケーション開発Zend ExpressiveRelatedトピックによる迅速なエンタープライズアプリケーション開発:
フレームワークパフォーマンス&スケーリング開発Semalt

必要な改善

反射ベースの抽象工場

Zend ExpressiveはZend ServiceManager for Dependency Semaltを使用します。デフォルトの設定では、設定を追加し、作成するすべてのクラスに対してファクトリクラスを作成する必要があります。これは、これを2回行った後、負担になります。

これを避けるために、Zend Semaltが提供するリフレクトベースの抽象ファクトリを有効にします。

これを config / autoload / dependenciesに追加します。グローバル。 依存関係 配列内のphp

    'abstract_factories' => [\ Zend \ ServiceManager \ AbstractFactory \ ReflectionBasedAbstractFactory :: class]、   

クラスで作業しているときに依存関係が必要なときは、コンストラクタにそれを追加するだけです。反射抽象ファクトリは、クラスが必要とするものを見て、自動的にサービスコンテナから取得します。サービスコンテナによって提供されるデフォルトのサービスとは異なるものが必要な例外的な場合にのみ、ファクトリを作成する必要があります。

スピードが心配なら、本番環境では、 vendor / bin / generate-for-class を使用してリフレクション・ファクトリで処理されていたクラス用のファクトリを生成するプロセスを作成できます。

教義

Zend ExpressiveはデータベースツールやORMを提供していません。多くの研究と自分のORMを構築した後、私は選択したORMとしてSemaltを選択しました。それだけで動作します。

作曲家経由でDoctrineとSymfony Yamlをインストールする:

   コンポーザーはdasprid / container-interop-doctrine symfony / yamlを必要とします   

config / cli-configファイルを作成します。 php を次の内容で置き換えます。

   <?phpDoctrine \ ORM \ Tools \ Console \ ConsoleRunnerを使用してください。chdir(dirname(__ DIR__));ベンダー/オートロードが必要です。 php ';/ **独自のスコープを作成し、グローバル名前空間をきれいに保つ、自己呼び出しの匿名関数。 * /戻り値call_user_func(function  {/ ** @var \ Interop \ Container \ ContainerInterface \ $ container * /$ container = 'config / container'が必要です。 php ';$ entityManager = $ container-> get(\ Doctrine \ ORM \ EntityManager :: class);ConsoleRunner :: createHelperSet($ entityManager);を返します。});   

config / autoload / dependenciesの内容を置き換えます。グローバル。 php を次のように置き換えます。

   <?phpZend \ Expressive \ Applicationを使用します。Zend \ Expressive \ Containerを使用してください。Zend \ Expressive \ Delegateを使用します。Zend \ Expressive \ Helperを使用してください。Zend \ Expressive \ Middlewareを使用してください。戻る[//アプリケーション全体のサービスを提供します。 //可能な限り完全修飾クラス名を使用することをお勧めします。//サービス名。 'dependencies' => ['abstract_factories' => [\ Zend \ ServiceManager \ AbstractFactory \ ReflectionBasedAbstractFactory :: class]、//サービス名を別のサービスにエイリアスするには、「別名」を使用します。ザ// keyはエイリアス名、valueはそのエイリアス名が指すサービスです. サービス名を// クラス名。 'invokables' => [// Fully \ Qualified \ InterfaceName :: class => Fully \ Qualified \ ClassName :: class、\ Doctrine \ DBAL \ Logging \ DebugStack :: class => \ Doctrine \ DBAL \ Logging \ DebugStack :: class、Helper \ ServerUrlHelper :: class => Helper \ ServerUrlHelper :: class、ミドルウェア\ ImplicitHeadMiddleware :: class =>ミドルウェア\ ImplicitHeadMiddleware :: class、ミドルウェア\ ImplicitOptionsMiddleware :: class =>ミドルウェア\ ImplicitOptionsMiddleware :: class、]、//コールバック/ファクトリクラスによって提供されるサービスには 'ファクトリ'を使用します。 'factories' => [Application :: class =>コンテナ\ ApplicationFactory ::クラス、デリゲート\ NotFoundDelegate ::クラス=>コンテナ\ NotFoundDelegateFactory ::クラス、\ Doctrine \ ORM \ EntityManager :: class => \ ContainerInteropDoctrine \ EntityManagerFactory :: class、Helper \ ServerUrlMiddleware :: class => Helper \ ServerUrlMiddlewareFactory :: class、ヘルパー\ UrlHelper ::クラス=>ヘルパー\ UrlHelperFactory ::クラス、ヘルパー\ UrlHelperMiddleware ::クラス=>ヘルパー\ UrlHelperMiddlewareFactory ::クラス、Zend \ Stratigility \ Middleware \ ErrorHandler :: class =>コンテナ\ ErrorHandlerFactory ::クラス、ミドルウェア\ ErrorResponseGenerator :: class =>コンテナ\ ErrorResponseGeneratorFactory :: class、ミドルウェア\ NotFoundHandler ::クラス=>コンテナ\ NotFoundHandlerFactory ::クラス、]、]、];   

このファイルを作成して、Doctrineドライバ のconfig / autoload / doctrineを設定します。グローバル。 php

   <?php戻る['doctrine' => ['ドライバ' => ['orm_default' => ['class' => \ Doctrine \ Common \ Persistence \ Mapping \ Driver \ MappingDriverChain :: class、'drivers' => []、]、]、]、];   

あなたのデータベース資格 config / autoload / doctrine用にこのファイルを作成します。地元。 php

   <?php戻る['doctrine' => ['接続' => ['orm_default' => ['params' => ['url' => 'mysql:// root:password1 @ localhost / expressive'、]、]、]、]、];   

を実行してテストします。 / vendor / bin / doctrine 。ヘルププロンプトが表示されます。

ガルプ

Gulpはフロントエンドワークフローのための私の現在の選択ツールです。多くのフロントエンド構築ツールが利用可能です。あなたが好きかどうかは分かりますが、光っている新しいJavaScriptライブラリの海で迷子になるかもしれません。私はJSよりもPHPのチュートリアルですので、ここではあまり関与したくありませんが、Zend Expressiveでうまく動作するように設定する方法を示したいと思います。

パッケージを作成します。 json ファイルには次の内容が含まれています。

 {"名前": "表現力"、"version": "1 - computer service san mateo.0.0"、"description": ""、"main": "index。js"、"devDependencies":{"del": "^ 3。0. 0"、"gulp": "github:gulpjs / gulp#4.0"、"gulp-cached": "^ 1.1.1"、"gulp-imagemin": "^ 3。3.0"、"gulp-minify-css": "^ 1.2.2.4"、"gulp-rename": "^ 1.2.2"、"gulp-sass": "^ 3。1.0"、"gulp-uglify": "^ 2.1。2"、"gulp-usemin": "^ 0。3. 28"}、"scripts":{"test": "echo \"エラー:テストが指定されていません\ "&& exit 1"}、"author": ""、"ライセンス": "ISC"}   

npm install を実行します 。もしこのチュートリアルが書かれた後にこのチュートリアルを読んでいるなら、 npm update を実行したいかもしれません。

次に、 のgulpfileを作成する. タスク( 'clean-css'、function {戻り値del( 'public / css'、{force:true});});ガルプ。タスク( 'compile-sass'、function {ガルプを返す。 src( 'src / * / public / sass / ** / *。scss'、{base: '。/'})。 pipe(キャッシュ( 'compile-sass'))。パイプ(sass 。on( 'error'、sass。logError))。パイプ(rename(function(path){パス。 dirname =パス。 dirname。 (\ ^ src \ /([^ \ /] + \ /)public \ / sass /、 '$ 1')を置き換えます。}))。パイプ(gulp。dest( 'public / css /'));});ガルプ。タスク( 'copy-css'、function {ガルプを返す。 src( 'src / * / public / css / ** / *。css'、{base: '。/'})。 pipe(キャッシュ( 'copy-css'))。パイプ(rename(function(path){パス。 dirname =パス。 dirname。 (\ ^ src \ /([^ \ /] + \ /)public \ / css /、 '$ 1')を置き換えます。}))。パイプ(gulp。dest( 'public / css /'));});ガルプ。タスク( 'minify-css'、function {ガルプを返す。 src(['public / css / ** / *。css'、 '!public / css / ** / *。min。css']、{base: '。/'})パイプ(キャッシュ( 'minify-css'))。パイプ(minifyCss )。パイプ(rename(function(path){パス。 dirname =パス。 dirname。置き換える(/ ^ public \ / css /、 '');}))。 pipe(rename({extname: '。min。css'}))。パイプ(gulp。dest( 'public / css'));});ガルプ。タスク( 'process-css'、gulp。series(['compile-sass'、 'copy-css']、 'minify-css'));// JS処理ガルプ。タスク( 'clean-js'、function {戻り値del( 'public / js'、{force:true});});ガルプ。タスク( 'copy-js'、function {ガルプを返す。 src( 'src / * / public / js / ** / *。js'、{base: '。/'})。 pipe(キャッシュ( 'copy-js'))。パイプ(rename(function(path){パス。 dirname =パス。 dirname。 (\ ^ src \ /([^ \ /] + \ /)public \ / js /、 '$ 1')を置き換えます。}))。パイプ(gulp。dest( 'public / js /'));});ガルプ。タスク( 'minify-js'、function {ガルプを返す。 src(['public / js / ** / *。js'、 '!public / js / ** / *。min。js']、{base: '。/'})パイプ(キャッシュ( 'minify-js'))。パイプ(uglify )。パイプ(rename(function(path){パス。 dirname =パス。 dirname。置き換える(/ ^ public \ / js /、 '');}))。 pipe(rename({extname: '。min。js'}))。パイプ(gulp。dest( 'public / js'));});ガルプ。タスク( 'process-js'、gulp。series( 'copy-js'、 'minify-js'));// 画像処理ガルプ。タスク( 'clean-img'、function {戻り値del( 'public / img'、{force:true});});ガルプ。タスク( 'process-img'、function {ガルプを返す。 src( 'src / * / public / img / ** / *。{gif、jpg、jpeg、png、svg}'、{base: '。/'}) pipe(キャッシュ( 'process-img'))。パイプ(imagemin )。パイプ(rename(function(path){パス。 dirname =パス。 dirname。 (\ ^ src \ /([^ \ /] + \ /)public \ / img /、 '$ 1')を置き換えます。}))。パイプ(gulp。dest( 'public / img'));});//トップレベルのコマンドガルプ。タスク( 'default'、gulp。parallel( 'process-js'、 'process-css'、 'process-img'));ガルプ。 ( 'clean'、 'gulp。parallel'( 'clean-js'、 'clean-css'、 'clean-img'));ガルプ。タスク( 'watch'、function {ガルプ。ウォッチ(['src / * / public / sass / ** / *。scss'、 'src / * / public / css / ** / *。css']、gulp。series( 'process-css'));ガルプ。 watch( 'src / * / public / js / ** / *。js'、gulp。series( 'process-js'));ガルプ。ウォッチ( 'src / * / public / img / ** / *。{gif、jpg、jpeg、png、svg}'、gulp。series( 'process-img'));});

gulp を実行し、エラーなしで実行されるようにします。

gulp を実行してsassをコンパイルし、cssを縮小し、jsを縮小し、すべてのモジュールにわたって画像を最適化することができます。あなたはそれを gulp watch で追跡して、これらがすべて変更されると自動的に処理されるようにすることができます。キャッシュ・ガルプ・モジュールは、変更されたファイルのみが処理されるようにします。

これらのファイルの1つを作成してテストします:

  • src / App / public / sass / sasstest。 scss
  • src / App / public / css / test。 css
  • src / App / public / js / test。 js
  • src / App / public / img / test。 jpg

そして、 をガルプ で動かす。 public / css / App public / js / App 、または public / img / App のファイルを探します。.

コンソールコマンド

最後に、しかし間違いなく、コンソールコマンドを実行する方法が必要です。 SymfonyのコンソールはZend Semaltに同梱されていますので、手動で設定する必要はありません。

bin / console というファイルを作成します:

   #!/ usr / bin / env php<?phpchdir(dirname(__ DIR__));ベンダー/オートロードが必要です。 php ';/ **独自のスコープを作成し、グローバル名前空間をきれいに保つ、自己呼び出しの匿名関数。 * /call_user_func(function  {/ ** @var \ Interop \ Container \ ContainerInterface $コンテナ* /$ container = 'config / container'が必要です。 php ';$ app = new \ Symfony \ Component \ Console \ Application( 'アプリケーションコンソール');$ commands = $ container-> get( 'config')['コンソール'] ['コマンド'];foreach($コマンドを$コマンドとして){$ app-> add($ container-> get($ command));}$ app-> run  ;});   

次に、 config / autoload / consoleを使ってSymfonyコマンドを作成し、登録することができます。グローバル。 php またはこのようなあなたのモジュールの中から:

   <?php戻る['コンソール' => ['コマンド' => [\ App \ Command \ HelloWorldCommand :: class、]、]、];   

コンソールコマンドが必要とする依存関係を、他のどのクラスと同じようにコンストラクタに追加します。コンストラクタで parent :: __ construct を呼び出すようにしてください。そうしないと、コマンドが機能しません。

依存関係を持つコマンドの例を以下に示します。

    <?php名前空間App \ Command;Doctrine \ ORM \ EntityManagerを使用します。Monolog \ Loggerを使用します。Symfony \ Component \ Console \ Command \ Commandを使用してください。Symfony \ Component \ Console \ Input \ InputArgumentを使用してください。Symfony \ Component \ Console \ Input \ InputInterfaceを使用してください。Symfony \ Component \ Console \ Input \ InputOptionを使用してください。Symfony \ Component \ Console \ Output \ OutputInterfaceを使用してください。HellowWorldクラスはコマンドを拡張します{/ *** @var EntityManager* /プライベート$ entityManager;パブリック関数__construct(EntityManager $ entityManager、$ name = null){$ this->  entityManager = $ entityManager;parent :: __ construct($ name);}/ ***コマンドを設定する* /protected function configure  {$ this-> setName( 'hello')- > setDescription( '挨拶');}/ ***現在のコマンドを実行する* /保護された関数execute(InputInterface $ input、OutputInterface $ output){$ output-> writeln( "Hello World!");// entityManagerで何かをする$ this-> entityManager-> find( 'Blog \ Entity \ BlogEntity');}}   

あなたのコマンドを実行するには:

   php bin / console hello   

もう少し進んでロガーを追加することができます。これは、多くのロジックをカプセル化し、全体にわたってデバッグログを必要とするサービスモデルに渡す場合に便利です。

このコマンドを実行します:

   作曲家は、モノ/モノフォン・シォフォニー/モニログ・ブリッジが必要です。   

次に、これをコマンドのexecuteメソッドに追加します。

   protected function execute(InputInterface $ input、OutputInterface $ output){$ logger = new \ Monolog \ Logger( 'collect-product-data');$ logger-> pushHandler(新しい\ Symfony \ Bridge \ Monolog \ Handler \ ConsoleHandler($ output));$ logger-> debug( '何かを記録する';}   

結論

今すぐあなたの指先でできるツールのすべてを使ってエンタープライズレベルのアプリケーションを構築する準備が整いました。

次回の記事では、この基盤上でモジュールを構築する方法を学び始めます。まず、ブログモジュールを使い始めます。