Zend-framework-quick-guide

提供:Dev Guides
移動先:案内検索

Zend Framework-はじめに

PHP Webフレームワークは、Webアプリケーションの開発に役立つクラスのコレクションです。 Zendは、最も人気のあるPHPフレームワークの1つです。 これは、急速に開発されている最新のWebアプリケーション向けの*オープンソースMVCフレームワーク*です。 Zend Frameworkには疎結合コンポーネントがいくつかあるため、「コンポーネントライブラリ」と呼ばれます。 Zend Frameworkは、Zendフレームワークアプリケーションを実行するためのPHPスタックとZendサーバーを提供します。

Zend Studioは、Zend Frameworkと統合する機能を含むIDEです。 MVCビューとコード生成を提供します。 現在のZend framework 3.0には、JSON RPCサーバー、XML to JSONコンバーター、PSR-7機能、PHP 7との互換性などの新しいコンポーネントが含まれています。

Zend Framework 2は、PHP 5.3+を使用してWebアプリケーションおよびサービスを開発するためのオープンソースフレームワークです。 Zend Framework 2は100%オブジェクト指向のコードを使用し、PHP 5.3の新機能のほとんど、つまり Namespaces、Lambda Functions および Closures を利用します。

Zend Framework 2は、1500万ダウンロードを超える成功したPHPフレームワークであるZend Framework 1から進化しました。 Zend Serverには、無料のコミュニティバージョンと商用バージョンがあります。

Zend Frameworkの機能

Zend Frameworkの顕著な特徴のいくつかは次のとおりです-

  • 純粋なオブジェクト指向のWebアプリケーションフレームワーク
  • 高度なMVC実装
  • PostgreSQL、SQLiteなどを含むマルチデータベースをサポートします。
  • シンプルなクラウドAPI
  • セッション管理
  • データ暗号化
  • 柔軟なURIルーティング
  • ZendはRESTful API開発サポートを提供します。
  • コードは再利用可能であり、保守が容易です。

Zend Frameworkを選ぶ理由

Zend FrameworkをPHP開発者が使用する最高のフレームワークの1つにしたのは、知的財産権を備えたクリーンで安定したコードを提供するからです。 また、プログラミングが容易になります。 それは速く、学びやすく、便利なフレームワークです。 Zendは強力な暗号化ツールとパスワードハッシュ技術をサポートしています。

Zendの目標

Zend Frameworkの目標は次のとおりです。

  • 柔軟性
  • シンプルで生産的
  • 互換性
  • 拡張性-プログラマはすべてのフレームワーククラスを簡単に拡張できます。
  • 移植性-複数の環境をサポート

Zendアプリケーション

次の一般的な製品は、Zend Frameworkを使用して開発されています。

  • McAfee Company Webサイト
  • IBM会社のWebサイト
  • Magento-人気のあるショッピングカートWebサイトの1つ。

Zend Frameworkの利点

Zend Frameworkの利点のいくつかを以下にリストします。

  • 疎結合-Zendには、アプリケーションで不要なモジュールまたはコンポーネントを削除するオプションがあります。
  • パフォーマンス-Zend Frameworkはパフォーマンスのために高度に最適化されています。 Zend Framework 3は、以前のバージョンより4倍高速です。
  • セキュリティ-フレームワークは業界標準の暗号化をサポートしています。
  • テスト-PHPUnitはZendと統合されているため、フレームワークを簡単にテストできます。

次の章では、Zend Frameworkのインストール方法を学びます。

Zend Framework-インストール

Zend Frameworkをインストールするには、最初にComposerと最新バージョンのPHPを次の手順に示すようにインストールする必要があります。

  • * Composerのインストール*-ZendはComposerを使用して依存関係を管理するため、Composerがマシンにインストールされていることを確認してください。 Composerがインストールされていない場合は、https://getcomposer.org/download/[Composer]の公式Webサイトにアクセスしてインストールします。
  • * PHPの最新バージョンをインストールします*-Zend Frameworkを最大限に活用するには、PHPの最新バージョンをインストールします。 Zend Framework 3に最低限必要なバージョンは、PHP 5.6以降です。

Zend Frameworkをインストールする

Zend Frameworkは2つの方法でインストールできます。 彼らは次のとおりです-

  • 手動インストール
  • Composerベースのインストール

これらのインストールについて詳しく説明します。

手動インストール

次のリンクにアクセスして、Zend Frameworkの最新バージョンをダウンロードします– https://framework.zend.com/downloads/archives

ダウンロードしたアーカイブファイルの内容を、保存したいフォルダーに抽出します。 ローカルマシンでZend Frameworkのコピーを使用できるようになると、Zend FrameworkベースのWebアプリケーションはフレームワーククラスにアクセスできます。 これを実現する方法はいくつかありますが、PHPの include_path には、ディストリビューションの/libraryディレクトリの下にあるZend Frameworkクラスへのパスを含める必要があります。 この方法は、Zend Frameworkバージョン2.4以前にのみ適用されます。

Composerベースのインストール

Zend Frameworkを簡単にインストールするには、Composerツールを使用してください。 これは、Zend Frameworkの最新バージョンをインストールする推奨方法です。 Zend Frameworkのすべてのコンポーネントをインストールするには、次のComposerコマンドを使用します-

$ composer require zendframework/zendframework

各Zend Frameworkモジュール/コンポーネントも個別にインストールできます。 たとえば、Zend Frameworkの* MVCコンポーネント*をインストールするには、次の composer コマンドを使用します-

$ composer require zendframework/zend-mvc

Zend Framework-スケルトンアプリケーション

Zend Framework MVCレイヤーおよびモジュールシステムを使用してスケルトンアプリケーションを作成しましょう。

Composerを使用したインストール

新しいZend Frameworkプロジェクトを作成する最も簡単な方法は、Composerを使用することです。 以下のように定義されます-

$ cd/path/to/install
$ composer create-project -n -sdev zendframework/skeleton-application myapp

あなたの画面に次の結果が表示されます-

Installing zendframework/skeleton-application (dev-master
   941da45b407e4f09e264f000fb537928badb96ed)
   - Installing zendframework/skeleton-application (dev-master master)
   Cloning master

Created project in myapp
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
   - Installing zendframework/zend-component-installer (0.3.0)
   Loading from cache

   - Installing zendframework/zend-stdlib (3.0.1)
   Loading from cache

   - Installing zendframework/zend-config (2.6.0)
   Loading from cache

   - Installing zendframework/zend-loader (2.5.1)
   Loading from cache

   - Installing zendframework/zend-eventmanager (3.0.1)
   Loading from cache

   - Installing zendframework/zend-view (2.8.0)
   Loading from cache

   - Installing container-interop/container-interop (1.1.0)
   Loading from cache

   - Installing zendframework/zend-servicemanager (3.1.0)
   Loading from cache

   - Installing zendframework/zend-validator (2.8.1)
   Loading from cache

   - Installing zendframework/zend-escaper (2.5.1)
   Loading from cache

   - Installing zendframework/zend-uri (2.5.2)
   Loading from cache

   - Installing zendframework/zend-http (2.5.4)
   Loading from cache

   - Installing zendframework/zend-router (3.0.2)
   Loading from cache

   - Installing zendframework/zend-modulemanager (2.7.2)
   Loading from cache

   - Installing zendframework/zend-mvc (3.0.1)
   Loading from cache

   - Installing zendframework/zend-skeleton-installer (0.1.3)
   Loading from cache

   - Installing zfcampus/zf-development-mode (3.0.0)
   Loading from cache
zendframework/zend-config suggests installing zendframework/zend-filter
   (Zend\Filter component)
zendframework/zend-config suggests installing zendframework/zend-i18n
   (Zend\I18n component)
zendframework/zend-config suggests installing zendframework/zend-json
   (Zend\Json to use the Json reader or writer classes)
zendframework/zend-view suggests installing zendframework/zend-authentication
   (Zend\Authentication component)
zendframework/zend-view suggests installing zendframework/zend-feed
   (Zend\Feed component)
zendframework/zend-view suggests installing zendframework/zend-filter
   (Zend\Filter component)
zendframework/zend-view suggests installing zendframework/zend-i18n
   (Zend\I18n component)
zendframework/zend-view suggests installing zendframework/zend-json
   (Zend\Json component)
zendframework/zend-view suggests installing zendframework/zend-navigation
   (Zend\Navigation component)
zendframework/zend-view suggests installing zendframework/zend-paginator
   (Zend\Paginator component)
zendframework/zend-view suggests installing zendframework/zend-permissions-acl
   (Zend\Permissions\Acl component)
zendframework/zend-servicemanager suggests installing ocramius/proxy-manager
   (ProxyManager 1.* to handle lazy initialization of services)
zendframework/zend-validator suggests installing zendframework/zend-db
   (Zend\Db component)
zendframework/zend-validator suggests installing zendframework/zend-filter
   (Zend\Filter component, required by the Digits validator)
zendframework/zend-validator suggests installing zendframework/zend-i18n
   (Zend\I18n component to allow translation of validation error messages as well as
   to use the various Date validators)
zendframework/zend-validator suggests installing zendframework/zend-i18nresources
   (Translations of validator messages)
zendframework/zend-validator suggests installing zendframework/zend-math
   (Zend\Math component)
zendframework/zend-validator suggests installing zendframework/zend-session
   (Zend\Session component)
zendframework/zend-router suggests installing zendframework/zend-i18n
   (^2.6, if defining translatable HTTP path segments)

zendframework/zend-modulemanager suggests installing zendframework/zend-console
   (Zend\Console component)
zendframework/zend-mvc suggests installing zendframework/zend-json ((^2.6.1 ||
   ^3.0) To auto-deserialize JSON body content in AbstractRestfulController
   extensions, when json_decode is unavailable)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-console
   (zend-mvc-console provides the ability to expose zend-mvc as a console application)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-i18n
   (zendmvc-i18n provides integration with zend-i18n, including a translation bridge
   and translatable route segments)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginfileprg
   (To provide Post/Redirect/Get functionality around forms that container
   file uploads)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginflashmessenger
   (To provide flash messaging capabilities between requests)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-pluginidentity
   (To access the authenticated identity (per zend-authentication) in controllers)
zendframework/zend-mvc suggests installing zendframework/zend-mvc-plugin-prg
   (To provide Post/Redirect/Get functionality within controllers)
zendframework/zend-mvc suggests installing zendframework/zend-psr7bridge
   ((^0.2) To consume PSR-7 middleware within the MVC workflow)
zendframework/zend-mvc suggests installing zendframework/zend-servicemanager-di
   (zend-servicemanager-di provides utilities for integrating zend-di and
   zendservicemanager in your zend-mvc application)

Generating autoload files
   Removing optional packages from composer.json
   Updating composer.json
Removing zendframework/zend-skeleton-installer...
   - Removing zendframework/zend-skeleton-installer (0.1.3)
   Removed plugin zendframework/zend-skeleton-installer.
   Removing from composer.json
   Complete!
> zf-development-mode enable
You are now in development mode.

アプリケーションがインストールされたので、* PHPのビルトインWebサーバー*を使用してすぐにテストできます-

$ cd path/to/install/myapp
$ composer serve

その後、次の応答が表示されます-

> php -S 0.0.0.0:8080 -t public/public/index.php

これにより、ポート8080でPHP組み込みCLIサーバーが起動します。 開発サーバーが起動したら、*(http://localhost:8080/)*のサイトにアクセスできます。 組み込みのCLIサーバーは開発専用です。

CLIサーバー

単体テスト

スケルトンユニットテストを実行するには、ターミナルで次のコマンドを入力します。

$ composer require --dev zendframework/zend-test

それは次の応答を生成します-

Using version ^3.0 for zendframework/zend-test
   ./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
   - Installing zendframework/zend-dom (2.6.0)
   Loading from cache

   - Installing zendframework/zend-console (2.6.0)
   Loading from cache

   - Installing sebastian/version (2.0.1)
   Loading from cache

   - Installing symfony/yaml (v3.2.1)
   Downloading: 100%

   - Installing sebastian/resource-operations (1.0.0)
   Loading from cache

   - Installing sebastian/recursion-context (2.0.0)
   Loading from cache

   - Installing sebastian/object-enumerator (2.0.0)
   Loading from cache

   - Installing sebastian/global-state (1.1.1)
   Loading from cache

   - Installing sebastian/exporter (2.0.0)
   Loading from cache

   - Installing sebastian/environment (2.0.0)
   Loading from cache

   - Installing sebastian/diff (1.4.1)
   Loading from cache

   - Installing sebastian/comparator (1.2.2)
   Loading from cache

   - Installing phpunit/php-text-template (1.2.1)
   Loading from cache

   - Installing doctrine/instantiator (1.0.5)
   Loading from cache

   - Installing phpunit/phpunit-mock-objects (3.4.3)
   Downloading: 100%

   - Installing phpunit/php-timer (1.0.8)
   Loading from cache

   - Installing phpunit/php-file-iterator (1.4.2)
   Loading from cache

   - Installing sebastian/code-unit-reverse-lookup (1.0.0)
   Loading from cache

   - Installing phpunit/php-token-stream (1.4.9)
   Loading from cache

   - Installing phpunit/php-code-coverage (4.0.4)
   Downloading: 100%

   - Installing webmozart/assert (1.2.0)
   Loading from cache

   - Installing phpdocumentor/reflection-common (1.0)
   Loading from cache

   - Installing phpdocumentor/type-resolver (0.2.1)
   Loading from cache

   - Installing phpdocumentor/reflection-docblock (3.1.1)
   Loading from cache

   - Installing phpspec/prophecy (v1.6.2)
   Loading from cache

   - Installing myclabs/deep-copy (1.5.5)
   Loading from cache

   - Installing phpunit/phpunit (5.7.4)
   Downloading: 100%

   - Installing zendframework/zend-test (3.0.2)
   Loading from cache

zendframework/zend-console suggests installing zendframework/zend-filter
   (To support DefaultRouteMatcher usage)
symfony/yaml suggests installing symfony/console (For validating YAML files
   using the lint command)
sebastian/global-state suggests installing ext-uopz (*)
phpunit/phpunit-mock-objects suggests installing ext-soap (*)
phpunit/php-code-coverage suggests installing ext-xdebug (>=2.4.0)
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
phpunit/phpunit suggests installing ext-xdebug (*)
zendframework/zend-test suggests installing zendframework/zend-mvc-console
   (^1.1.8, to test MVC <-> console integration)
Writing lock file
Generating autoload files

これで、テストサポートが有効になり、次のコマンドを使用してテストを実行できます。

$ ./vendor/bin/phpunit

Apache Webサーバー

Zend Frameworkベースのアプリケーションを本番環境でホストするのは非常に簡単で簡単です。 Apache構成ファイルで VirtualHost を作成し、 DocumentRoot をZend Frameworkアプリケーションの Public フォルダーにポイントするだけです。

サンプル構成(myapp)は以下のとおりです-

<VirtualHost *:80>
   ServerName myapp.localhost
   DocumentRoot/path/to/install/myapp/public
   <Directory/path/to/install/myapp/public>
      DirectoryIndex index.php
      AllowOverride All
      Order allow,deny
      Allow from all
      <IfModule mod_authz_core.c>
         Require all granted
      </IfModule>
   </Directory>
</VirtualHost>

Zend Framework-MVCアーキテクチャ

この章に進む前に、MVCについて簡単に説明します。 Model View Controller は、アプリケーションロジックをプレゼンテーションから分離するソフトウェアアプローチです。 実際には、プレゼンテーションはWebページとは別なので、Webページに最小限のPHPスクリプトを含めることができます。

MVCコンポーネントの簡単な説明は次のとおりです。

  • モデル-モデルは、アプリケーションデータの構造を表します。 通常、モデルクラスには、バックエンドデータベース(MySQL、PostgreSQLなど)でビジネスデータを取得、挿入、および更新するのに役立つ関数が含まれています。
  • View -ViewはMVCアプリケーションのプレゼンテーションレイヤーです。 コントローラーを介してモデルデータを取得し、必要に応じて表示します。 Controller および Model に疎結合されているため、ModelとControllerに影響を与えることなく変更できます。
  • Controller -ControllerはMVCアーキテクチャの主要コンポーネントです。 すべての要求が最初にコントローラーにヒットします。 言い換えると、コントローラーはすべてのリクエストを処理し、モデル、ビュー、および* HTTPリクエストを処理し、レスポンスを生成するために必要な他のリソース間の仲介役として機能します。

次の章では、Zend Frameworkのさまざまな概念を理解します。

Zend Framework-コンセプト

Zend Frameworkは、60以上のコンポーネントのコレクションです。 それらは互いに緩やかに接続されています。 これらは、スタンドアロンコンポーネントとしても、単一のユニットとして機能するコンポーネントのグループとしても使用できます。

Zend Frameworkは、次の3つの最も重要なコンポーネントを提供します-

  • zend-servicemanager
  • zend-eventmanagerおよび
  • zend-modulemanager。

これらは、Zendコンポーネントに他のコンポーネントと効率的に統合する機能を提供します。

  • イベントマネージャ-イベントベースのプログラミングを作成する機能を提供します。 これは、新しいイベントの作成、注入、管理に役立ちます。
  • Service Manager -少しの労力でどこからでもサービス(PHPクラス)を使用できるようにします。
  • モジュールマネージャー-同様の機能を持つPHPクラスのコレクションを*モジュール*と呼ばれる単一のユニットに変換する機能。 新しく作成されたモジュールは、単一のユニットとして使用、保守、構成できます。

これらの概念については、後続の章で詳しく説明します。

Zend Framework-サービスマネージャー

Zend Frameworkには、 zend-servicemanager と呼ばれる強力なサービスロケーターパターンの実装が含まれています。 Zendフレームワークは、そのすべての機能にサービスマネージャーを広く使用しています。 Service Managerは、Zend Frameworkの高レベルの抽象化を提供します。 また、Zend Frameworkの他のすべてのコンポーネントとうまく統合されます。

Service Managerをインストールする

Service Managerコンポーネントは、 composer ツールを使用してインストールできます。

composer require zendframework/zend-servicemanager

まず、すべてのサービスをサービスマネージャーに登録する必要があります。 サービスがサーバーマネージャーシステムに登録されると、最小限の労力でいつでもアクセスできます。 サービスマネージャーは、サービスを登録するための多くのオプションを提供します。 簡単な例は次のとおりです-

use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Factory\InvokableFactory;
use stdClass;
$serviceManager = new ServiceManager([
   'factories' => [stdClass::class => InvokableFactory::class,],
]);

上記のコードは、 Factory オプションを使用して stdClass をシステムに登録します。 これで、次に示すように、サービスマネージャーの* get()*メソッドを使用して、いつでもstdClassのインスタンスを取得できます。

use Zend\ServiceManager\ServiceManager;
$object = $serviceManager->get(stdClass::class);

get()メソッドは取得したオブジェクトを共有するため、get()メソッドを複数回呼び出して返されるオブジェクトは、同一のインスタンスです。 毎回異なるインスタンスを取得するために、サービスマネージャーは* build()*メソッドである別のメソッドを提供します。

use Zend\ServiceManager\ServiceManager;
$a = $serviceManager->build(stdClass::class);
$b = $serviceManager->build(stdClass::class);

サービスマネージャーの登録

サービスマネージャは、コンポーネントを登録するための一連のメソッドを提供します。 最も重要な方法のいくつかは以下のとおりです-

  • 工場方式
  • 抽象ファクトリーメソッド
  • 初期化メソッド
  • デリゲートファクトリメソッド

これらの各項目については、今後の章で詳しく説明します。

ファクトリーメソッド

ファクトリは、基本的に、呼び出し可能オブジェクト、または FactoryInterface (Zend \ ServiceManager \ Factory \ FactoryInterface)を実装するクラスです。

FactoryInterfaceには単一のメソッドがあります-

public function __invoke(ContainerInterface $container, $requestedName, array
   $options = null)

FactoryInterfaceの引数の詳細は次のとおりです-

  • * container(ContainerInterface)*-ServiceManagerの基本インターフェイスです。 他のサービスを取得するオプションを提供します。
  • requestedName -それはサービス名です。
  • options -サービスに必要な追加オプションを提供します。

FactoryInterfaceを実装する単純なクラスを作成し、クラスを登録する方法を見てみましょう。

クラステスト-取得するオブジェクト

use stdClass;
class Test {
   public function __construct(stdClass $sc) {
     //use $sc
   }
}
*Test* クラスはstdClassに依存します。

クラスTestFactory-テストオブジェクトを初期化するクラス

class TestFactory implements FactoryInterface {
   public function __invoke(ContainerInterface $container, $requestedName,
      array $options = null) {
      $dep = $container->get(stdClass::class);
      return new Test($dep);
   }
}

TestFactoryはコンテナを使用してstdClassを取得し、Testクラスのインスタンスを作成して返します。

Zend Frameworkの登録と使用

Zend Frameworkの登録方法と使用方法を理解しましょう。

serviceManager $sc = new ServiceManager([
   'factories' => [stdClass::class => InvokableFactory::class,
      Test::class => TestFactory::class]
]);
$test = $sc->get(Test::class);

サービスマネージャは、 InvokableFactory という特別なファクトリを提供して、依存関係のないクラスを取得します。 たとえば、 stdClass はInvokableFactoryを使用して設定できます。これは、stdClassが他のクラスに依存しないためです。

serviceManager $sc = new ServiceManager([
   'factories' => [stdClass::class => InvokableFactory::class]
]);
$stdC = $sc->get(stdClass::class);
*FactoryInterface* を実装せずに、または *InvokableFactory* を使用せずにオブジェクトを取得する別の方法は、以下に示すインラインメソッドを使用することです。
$serviceManager = new ServiceManager([
   'factories' => [
      stdClass::class => InvokableFactory::class,
      Test::class => function(ContainerInterface $container, $requestedName) {
         $dep = $container->get(stdClass::class);
         return new Test($dep);
      },
   ],
]);

抽象ファクトリーメソッド

時には、オブジェクトを作成する必要があるかもしれませんが、それは実行時にしかわからなくなります。 この状況は、FactoryInterfaceから派生した AbstractFactoryInterface を使用して処理できます。

AbstractFactoryInterfaceは、要求されたインスタンスでオブジェクトを作成できるかどうかをチェックするメソッドを定義します。 オブジェクトの作成が可能な場合、FactoryInterfaceの __ invokemethod を使用してオブジェクトを作成し、それを返します。

AbstractFactoryInterfaceの署名は次のとおりです-

public function canCreate(ContainerInterface $container, $requestedName)

初期化メソッド

Initializerメソッドは、作成済みのサービスに追加の依存関係を注入する特別なオプションです。 それは InitializerInterface を実装し、利用可能な唯一のメソッドの署名は次のとおりです-

public function(ContainerInterface $container, $instance)
function(ContainerInterface $container, $instance) {
   if (! $instance instanceof EventManagerAwareInterface) {
      return;
   }
   $instance->setEventManager($container->get(EventManager::class));
}

上記の例では、メソッドはインスタンスがEventManagerAwareInterfaceタイプかどうかを確認します。 タイプが EventManagerAwareInterface の場合、イベントマネージャーオブジェクトを設定します。 メソッドは依存関係を設定する場合としない場合があるため、信頼性が低く、実行時の問題が多く発生します。

デリゲーターファクトリメソッド

Zend Frameworkは、 DelegatorFactoryInterface を介してデリゲートパターンをサポートしています。 サービスを装飾するために使用できます。

この関数の署名は次のとおりです-

public function __invoke(ContainerInterface $container,
   $name, callable $callback, array $options = null
);

ここでは、 $ callback がサービスインスタンスを修飾します。

怠zyなサービス

遅延サービスは、作成時に完全に初期化されないサービスの1つです。 それらは単に参照され、本当に必要なときにのみ初期化されます。 最良の例の1つはデータベース接続であり、これはすべての場所で必要なわけではありません。 高価なリソースであり、作成に時間がかかるプロセスです。 Zendフレームワークは DelegatorFactoryInterface から派生した LazyServiceFactory を提供します。これは Delegator コンセプトと* ocramiusプロキシマネージャー*と呼ばれるサードパーティプロキシマネージャーの助けを借りて遅延サービスを生成できます。

プラグインマネージャー

プラグインマネージャーは、サービスマネージャーを拡張し、インスタンス検証などの追加機能を提供します。 Zend Frameworkはプラグインマネージャーを広く使用しています。

たとえば、すべての検証サービスは ValidationPluginManager の下にあります。

構成オプション

サービスマネージャには、サービスマネージャの機能を拡張するためのオプションがいくつか用意されています。 それらは shared、shared_by_default および aliases です。 前に説明したように、取得したオブジェクトはデフォルトで要求されたオブジェクト間で共有され、* build()メソッドを使用して個別のオブジェクトを取得できます。 *shared オプションを使用して、共有するサービスを指定することもできます。 shared_by_default は、 shared 機能と同じですが、すべてのサービスに適用されます。

$serviceManager = new ServiceManager([
   'factories' => [
      stdClass::class => InvokableFactory::class
   ],
   'shared' => [
      stdClass::class => false//will not be shared
   ],
   'shared_by_default' => false,//will not be shared and applies to all service
]);
*aliases* オプションを使用して、登録済みサービスに代替名を提供できます。 これには長所と短所があります。 良い面として、サービスの代替の短い名前を提供できます。 しかし、同時に、名前が文脈から外れ、バグを引き起こす可能性があります。
aliases' => ['std' => stdClass::class, 'standard' => 'std']

Zend Framework-イベントマネージャー

最新のアプリケーションにはすべて、堅実で柔軟なイベントコンポーネントが必要です。 Zend Frameworkは、 zend-eventmanager というコンポーネントを提供します。 zend-eventmanagerは、高レベルアーキテクチャの設計を支援し、サブジェクト/オブザーバーパターンとアスペクト指向プログラミングをサポートします。

イベントマネージャーをインストールする

イベントマネージャは、以下で指定されている Composer を使用してインストールできます-

composer require zendframework/zend-eventmanager

イベントマネージャーの概念

イベントマネージャのコアコンセプトは次のとおりです-

  • Event -イベントは、 greet など、任意のアクションと呼ばれます。
  • リスナー-PHPコールバック。 イベントに添付され、イベントがトリガーされると呼び出されます。 リスナーのデフォルトの署名は-
function(EventInterface $e)
  • EventInterface Class -イベント自体を指定するために使用されます。 名前(set/getName)、ターゲット(get/setTarget)、パラメーター(get/setParams)などのイベント情報を設定および取得するメソッドがあります。
  • * EventManagerクラス*-EventManagerのインスタンスは、アプリケーションおよびその対応するリスナーで定義されたすべてのイベントを追跡します。 EventManagerは、リスナーにイベントをアタッチする attach メソッドを提供し、事前定義されたイベントをトリガーする trigger メソッドを提供します。 トリガーが呼び出されると、EventManagerはそれに接続されたリスナーを呼び出します。
  • EventManagerAwareInterface -イベントベースのプログラミングをサポートするクラスの場合、EventManagerAwareInterfaceを実装する必要があります。 イベントマネージャを取得および設定するための setEventManager および getEventManager の2つのメソッドを提供します。

イベントマネージャーの概念を理解するために、簡単なPHPコンソールアプリケーションを作成しましょう。 以下の手順に従ってください。

  • フォルダー「eventapp」を作成します。
  • コンポーザーを使用して zend-eventmanager をインストールします。
  • 「eventapp」フォルダー内にPHPファイル Greeter.php を作成します。
  • クラス Greeter を作成し、 EventManagerAwareInterface を実装します。
require __DIR__ . '/vendor/autoload.php';
class Greeter implements EventManagerAwareInterface {
  //code
}

ここでは、 require を使用して、Composerがインストールしたすべてのコンポーネントを自動ロードします。

以下に示すように、クラス GreetersetEventManager メソッドを記述します-

public function setEventManager(EventManagerInterface $events) {
   $events->setIdentifiers([ __CLASS__, get_called_class(),]);
   $this->events = $events;
   return $this;
}

このメソッドは、現在のクラスを特定のイベントマネージャー($ events引数)に設定し、ローカル変数 $ events にイベントマネージャーを設定します。

次のステップは、以下に示すように Greeter クラスに getEventManager メソッドを記述することです-

public function getEventManager() {
   if (null === $this->events) {
      $this->setEventManager(new EventManager());
   }
   return $this->events;
}

このメソッドは、ローカル変数からイベントマネージャーを取得します。 使用できない場合は、イベントマネージャーのインスタンスを作成して返します。

クラス Greeter にメソッド greet を記述します。

public function greet($message) {
   printf("\"%s\" from class\n", $message);
   $this->getEventManager()->trigger(__FUNCTION__, $this, $message ]);
}

このメソッドは、イベントマネージャーを取得し、それに関連付けられたイベントを起動またはトリガーします。

次のステップは、 Greeter クラスのインスタンスを作成し、そのメソッド greet にリスナーをアタッチすることです。

$greeter = new Greeter();
$greeter->getEventManager()->attach('greet', function($e) {
   $event_name = $e->getName();
   $target_name = get_class($e->getTarget());
   $params_json = json_encode($e->getParams());
   printf("\"%s\" event of class \"%s\" is called." .
      " The parameter supplied is %s\n",
      $event_name,
      $target_name,
      $params_json);
});

リスナーコールバックは、イベント、ターゲット、および指定されたパラメーターの名前を出力するだけです。

*Greeter.php* の完全なリストは次のとおりです-
<?php
require __DIR__ . '/vendor/autoload.php';

use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventManager;
use Zend\EventManager\EventManagerAwareInterface;

class Greeter implements EventManagerAwareInterface {
   protected $events;
   public function setEventManager(EventManagerInterface $events) {
      $events->setIdentifiers([__CLASS__, get_called_class(), ]);
      $this->events = $events;
      return $this;
   }
   public function getEventManager() {
      if (null === $this->events) {
         $this->setEventManager(new EventManager());
      }
      return $this->events;
   }
   public function greet($message) {
      printf("\"%s\" from class\n", $message);
      $this->getEventManager()->trigger(__FUNCTION__, $this, [$message ]);
   }
}

$greeter = new Greeter();
$greeter->greet("Hello");
$greeter->getEventManager()->attach('greet', function($e) {
   $event_name = $e->getName();
   $target_name = get_class($e->getTarget());
   $params_json = json_encode($e->getParams());
   printf("\"%s\" event of class \"%s\" is called." . " The parameter supplied is %s\n",
      $event_name,
      $target_name,
      $params_json);
});
$greeter->greet("Hello");

今、コマンドプロンプトphp Greeter.php でアプリケーションを実行すると、結果は次のようになります-

"Hello" from class
"Hello" from class
"greet" event of class "Greeter" is called. The parameter supplied is ["Hello"]

上記のサンプルアプリケーションでは、イベントマネージャの基本のみを説明しています。 イベントマネージャーは、*リスナーの優先度、カスタムコールバックプロトタイプ/署名、短絡など*など、より高度なオプションを提供します。 イベントマネージャーは、Zend MVCフレームワークで広く使用されています。

Zend Framework-モジュールシステム

Zend Frameworkは強力なモジュールシステムを提供します。 モジュールシステムには3つのコンポーネントがあります。 彼らは次のとおりです-

  • モジュールオートローダー-モジュールオートローダーは、さまざまなソースからのモジュールの検索とロードを行います。 * Pharアーカイブ*としてパッケージ化されたモジュールもロードできます。 モジュールオートローダーの実装は、myapp/vendor/zendframework/zend-loader/src/ModuleAutoloader.phpにあります。
  • モジュールマネージャー-モジュールオートローダーがモジュールを見つけると、モジュールマネージャーは各モジュールの一連のイベントを発生させます。 Module Managerの実装は、myapp/vendor/zendframework/zendmodulemanager/src/ModuleManager.phpにあります。
  • モジュールマネージャーリスナー-モジュールマネージャーによって起動されたイベントにアタッチできます。 モジュールマネージャーのイベントにアタッチすることで、モジュールの解決と読み込みから、各モジュールの複雑な作業の実行まで、すべてを実行できます。

MVC Webモジュールシステム

Zend FrameworkのMVC Webアプリケーションは通常、モジュールとして記述されています。 1つのWebサイトに、機能ごとにグループ化された1つ以上のモジュールを含めることができます。 MVC指向モジュールの推奨構造は次のとおりです-

module_root/
   Module.php
   autoload_classmap.php
   autoload_function.php
   autoload_register.php
   config/
      module.config.php
   public/
      images/
      css/
      js/
   src/
      <module_namespace>/
      <code files>
   test/
      phpunit.xml
      bootstrap.php
      <module_namespace>/
         <test code files>
   view/
      <dir-named-after-module-namespace>/
         <dir-named-after-a-controller>/
            <.phtml files>

構造は前の章で説明したものと同じですが、ここでは一般的です。 * autoload_ファイル*は、 zend-modulemanager で使用可能な高度な Module Manager を使用せずに、モジュールで使用可能なクラスを自動ロードするためのデフォルトメカニズムとして使用できます。

  • autoload_classmap.php -クラス名とそれに対応するファイル名の配列を返します。
  • autoload_function.php -PHPコールバックを返します。 これは、autoload_classmap.phpによって返されるクラスを利用できます。
  • autoload_register.php -autoload_function.phpによって返されるPHPコールバックを登録します。

これらの自動ロードファイルは必須ではありませんが、推奨されます。 スケルトンアプリケーションでは、* autoload_ファイル*を使用していません。

モジュールクラス

Moduleクラスの名前は Module で、モジュールクラスの名前空間は Module name である必要があります。 これは、Zend Frameworkがモジュールを簡単に解決してロードするのに役立ちます。 スケルトン(myapp)アプリケーション、myapp/module/Application/src/Module.phpの*アプリケーション*モジュールコードは次のとおりです-

namespace Application;
class Module {
   const VERSION = '3.0.2dev';
   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
}

Zend Frameworkモジュールマネージャーは、* getConfig()*関数を自動的に呼び出し、必要な手順を実行します。

Zend Framework-アプリケーション構造

この章では、Zend Frameworkアプリケーションの構造を理解しましょう。 myapp アプリケーションの構造は次のとおりです-

├── composer.json
├── composer.lock
├── CONDUCT.md
├── config
│   ├── application.config.php
│   ├── autoload
│   │   ├── development.local.php
│   │   ├── development.local.php.dist
│   │   ├── global.php
│   │   ├── local.php.dist
│   │   ├── README.md
│   │   └── zend-developer-tools.local-development.php
│   ├── development.config.php
│   ├── development.config.php.dist
│   └── modules.config.php
├── CONTRIBUTING.md
├── data
│   └── cache
│       └── module-classmap-cache.application.module.cache.php ├── docker-compose.yml
├── Dockerfile
├── LICENSE.md
├── module
│   └── Application
│       ├── config
│       ├── src
│       ├── test
│       └── view
├── phpcs.xml
├── phpunit.xml.dist
├── public
│   ├── css
│   │   ├── bootstrap.css
│   │   ├── bootstrap.css.map
│   │   ├── bootstrap.min.css
│   │   ├── bootstrap.min.css.map
│   │   ├── bootstrap-theme.css
│   │   ├── bootstrap-theme.css.map
│   │   ├── bootstrap-theme.min.css
│   │   ├── bootstrap-theme.min.css.map
│   │   └── style.css
│   ├── fonts
│   │   ├── glyphicons-halflings-regular.eot
│   │   ├── glyphicons-halflings-regular.svg
│   │   ├── glyphicons-halflings-regular.ttf
│   │   ├── glyphicons-halflings-regular.woff
│   │   └── glyphicons-halflings-regular.woff2
│   ├── img
│   │   ├── favicon.ico
│   │   └── zf-logo-mark.svg
│   ├── index.php
│   ├── js
│   │   ├── bootstrap.js
│   │   ├── bootstrap.min.js
│   │   └── jquery-3.1.0.min.js
│   └── web.config
├── README.md
├── TODO.md
├── Vagrantfile
└── vendor
├── autoload.php
├── bin
│   ├── phpunit -> ../phpunit/phpunit/phpunit
│   ├── templatemap_generator.php -> ../zendframework/zend-
view/bin/templatemap_generator.php
│   └── zf-development-mode -> ../zfcampus/zf-development-mode/bin/zf-
development-mode
├── composer
│   ├── autoload_classmap.php
│   ├── autoload_namespaces.php
│   ├── autoload_psr4.php
│   ├── autoload_real.php
│   ├── ClassLoader.php
│   ├── installed.json
│   └── LICENSE
├── container-interop
│   └── container-interop
├── doctrine
│   └── instantiator
├── myclabs
│   └── deep-copy
├── phpdocumentor
│   ├── reflection-common
│   ├── reflection-docblock
│   └── type-resolver
├── phpspec
│   └── prophecy
├── phpunit
│   ├── php-code-coverage
│   ├── php-file-iterator
│   ├── php-text-template
│   ├── php-timer
│   ├── php-token-stream
│   ├── phpunit
│   └── phpunit-mock-objects
├── sebastian
│   ├── code-unit-reverse-lookup
│   ├── comparator
│   ├── diff
│   ├── environment
│   ├── exporter
│   ├── global-state
│   ├── object-enumerator
│   ├── recursion-context
│   ├── resource-operations
│   └── version
├── symfony
│   └── yaml
├── webmozart
│   └── assert
├── zendframework
│   ├── zend-component-installer
│   ├── zend-config
│   ├── zend-console
│   ├── zend-dom
│   ├── zend-escaper
│   ├── zend-eventmanager
│   ├── zend-http
│   ├── zend-loader
│   ├── zend-modulemanager
│   ├── zend-mvc
│   ├── zend-router
│   ├── zend-servicemanager
│   ├── zend-stdlib
│   ├── zend-test
│   ├── zend-uri
│   ├── zend-validator
│   └── zend-view
└── zfcampus
└── zf-development-mode

73 directories, 55 files

Zend Frameworkアプリケーションは、さまざまなフォルダーで構成されています。 彼らは次のとおりです-

  • アプリケーション-このディレクトリにはアプリケーションが含まれています。 MVCシステム、構成、使用されるサービス、およびブートストラップファイルが格納されます。
  • Config -このディレクトリには、アプリケーションの構成ファイルが含まれています。
  • データ-このディレクトリは、揮発性で一時的なアプリケーションデータを保存する場所を提供します。
  • モジュール-開発者はモジュールを使用して、関連するコントローラーのセットを論理的に編成されたグループにグループ化できます。
  • パブリック-これはアプリケーションのドキュメントルートです。 Zendアプリケーションを起動します。 また、JavaScript、CSS、画像などのアプリケーションのアセットも含まれています。
  • ベンダー-このディレクトリには、作曲家の依存関係が含まれています。

アプリケーションモジュールの構造

これは、アプリケーションのメインディレクトリです。 Zend Framework 2は、アプリケーションを効率的に整理するための強力で柔軟なモジュールシステムを導入しています。 スケルトンアプリケーションの Application モジュール_(myapp)_は、アプリケーション全体にブートストラップ、エラー、およびルーティング構成を提供します。 *アプリケーション*モジュールの構造は以下のとおりです-

├── module
│   └── Application
│       ├── config
│       │   └── module.config.php
│       ├── src
│       │   ├── Controller
│       │   │   └── IndexController.php
│       │   └── Module.php
│       ├── test
│       │   └── Controller
│       │       └── IndexControllerTest.php
│       └── view
│           ├── application
│           │   └── index
│           │       └── index.phtml
│           ├── error
│           │   ├── 404.phtml
│           │   └── index.phtml
│           └── layout
│               └── layout.phtml

これらのモジュールディレクトリのそれぞれについて詳しく説明します-

  • アプリケーション-これはモジュールのルートディレクトリです。 フォルダーの名前はモジュールの名前と一致し、その名前はモジュール内で定義されたすべてのクラスのPHP名前空間としても使用されます。 MVCシステム、構成、使用されるサービス、およびブートストラップファイルが格納されます。
  • Config -モジュールの独立した構成。
  • Src -アプリケーションのメインビジネスロジック。
  • 表示-デザイン/プレゼンテーション(HTML)ファイルが含まれています。 たとえば、index.phtml。
  • src/Module.php -モジュールの中心です。 モジュールの「フロントコントローラー」として機能します。 このモジュールのPHPクラスを処理する前に、Zendプロセスの src/Module.php ファイル。
  • Application/config/module.config.php -これは、ルーター設定および自動読み込みファイル用に実装されています。
  • アプリケーション/ビュー/レイアウト-レイアウトは、複数のビューの共通部分を表します。 たとえば、ページのヘッダーとフッター。 デフォルトでは、レイアウトは views/layoutsfolder に保存する必要があります。

すべてのモジュールは、上記の_Application_モジュールと同じまたは類似の構造を共有しています。

Zend Framework-モジュールの作成

この章では、Zend FrameworkでMVCベースのモジュールを作成する方法を学びます。 モジュールの作成プロセスを理解するために、 Tutorial というモジュールを作成してみましょう。

 *–Module* という名前の新しいPHPクラスを–myapp/module/Tutorial/src/ディレクトリ内に作成し、ConfigProviderInterfaceを実装します。
* *Tutorial* を *Module* クラスのネームスペースとして設定します。
* *Module* クラスにパブリック関数 *getConfig* を記述し、 *Tutorial* モジュールの構成ファイルを返します。
  • モジュール*クラスの完全なコードは次のとおりです-
<?php
namespace Tutorial;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
}

次のコードを使用して、 autoload セクションの下の composer.jsonTutorial モジュールを構成します。

"autoload": {
   "psr-4": {
      "Application\\": "module/Application/src/",
      "Tutorial\\": "module/Tutorial/src/"
   }
}

以下に示すようにcomposer update コマンドを使用してアプリケーションを更新します。

composer update
*composer* コマンドは、アプリケーションに必要な変更を行い、以下に示すようにコマンドプロンプトにログを表示します-
Loading composer repositories with package information
Updating dependencies (including require-dev)
   - Removing zendframework/zend-component-installer (0.3.0)
   - Installing zendframework/zend-component-installer (0.3.1)
   Downloading: 100%

   - Removing zendframework/zend-stdlib (3.0.1)
   - Installing zendframework/zend-stdlib (3.1.0)
   Loading from cache

   - Removing zendframework/zend-eventmanager (3.0.1)
   - Installing zendframework/zend-eventmanager (3.1.0)
   Downloading: 100%

   - Removing zendframework/zend-view (2.8.0)
   - Installing zendframework/zend-view (2.8.1)
   Loading from cache

   - Removing zendframework/zend-servicemanager (3.1.0)
   - Installing zendframework/zend-servicemanager (3.2.0)
   Downloading: 100%

   - Removing zendframework/zend-escaper (2.5.1)
   - Installing zendframework/zend-escaper (2.5.2)
   Loading from cache

   - Removing zendframework/zend-http (2.5.4)
   - Installing zendframework/zend-http (2.5.5)
   Loading from cache

   - Removing zendframework/zend-mvc (3.0.1)
   - Installing zendframework/zend-mvc (3.0.4)
   Downloading: 100%

   - Removing phpunit/phpunit (5.7.4)
   - Installing phpunit/phpunit (5.7.5)
   Downloading: 100%

Writing lock file
Generating autoload files

モジュール構成ファイル「module.config.php」を次のコードで /config/ に作成します-

<?php
namespace Tutorial;

use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
   'controllers' => [
      'factories' => [Controller\TutorialController::class => InvokableFactory::class,],
   ],
   'view_manager' => [
      'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
   ],
];

構成ファイルには3つの部分があり、それらは次のとおりです-

  • コントローラー構成-モジュール内で使用可能なコントローラーを指定します。
  • ルーティング構成-モジュール内のコントローラーをURLに解決する方法を指定します。
  • 構成の表示-ビューの場所など、エンジンの表示に関連する構成を指定します。

アプリケーションレベルの構成ファイル(myapp/config/modules.config.php)で Tutorial モジュールを構成します。

return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial'];

アプリケーションフォルダーのルートで composer serve を実行して、アプリケーションを実行します。

新しいモジュールは正常に追加されましたが、 Tutorial モジュールを正常に実行するには、 Controller、Routing および Views を追加する必要があります。

Zend Framework-コントローラー

前に説明したように、*コントローラー*はZend MVCフレームワークで重要な役割を果たします。 アプリケーション内のすべてのWebページは、コントローラーで処理する必要があります。

Zend MVCフレームワークでは、コントローラーは– Zend/Stdlib/DispatchableInterfaceを実装するオブジェクトです。 DispatchableInterface には dispatch という1つのメソッドがあり、これは Request オブジェクトを入力として取得し、何らかのロジックを実行し、 Response オブジェクトを出力として返します。

dispatch(Request $request, Response $response = null)

「Hello World」を返すControllerオブジェクトの簡単な例は次のとおりです-

use Zend\Stdlib\DispatchableInterface;
use Zend\Stdlib\RequestInterface as Request;
use Zend\Stdlib\ResponseInterface as Response;
class HelloWorld implements DispatchableInterface {
   public function dispatch(Request $request, Response $response = null) {
      $response->setContent("Hello World!");
   }
}
*DispatchableInterface* は基本的なものであり、高レベルのコントローラーを作成するには他の多くのインターフェイスが必要です。 このようなインターフェイスのいくつかは次のとおりです-
  • InjectApplicationEventInterface -イベントの注入に使用(Zend EventManager)
  • ServiceLocatorAwareInterface -サービスの検索に使用(Zend ServiceManager)
  • EventManagerAwareInterface -イベントの管理に使用(Zend EventManager)

これらのことを念頭に置いて、Zend Frameworkはこれらのインターフェイスを実装する既製のコントローラーを多数提供します。 最も重要なコントローラーは以下に説明されています。

AbstractActionController

AbstractActionController(Zend/Mvc/Controller/AbstractActionController)は、Zend MVCフレームワークで最も使用されているコントローラーです。 典型的なウェブページを書くために必要なすべての機能を備えています。 ルート(ルーティングはリクエストURLをコントローラーとそのメソッドの1つに一致させます)が*アクション*に一致することを許可します。 一致すると、アクションにちなんで名付けられたメソッドがコントローラーによって呼び出されます。

たとえば、ルート test が一致し、ルート、 test がアクションに対して hello を返す場合、 helloAction メソッドが呼び出されます。

*AbstractActionController* を使用して *TutorialController* を記述しましょう。
  • AbstractActionController を拡張して TutorialController という新しいPHPクラスを作成し、 module/Tutorial/src/Controller/ ディレクトリに配置します。
  • Tutorial \ Controller をネームスペースとして設定します。
  • indexAction メソッドを記述します。
  • indexAction メソッドから ViewModel オブジェクトを返します。 ViewModel オブジェクトは、コントローラからビューエンジンにデータを送信するために使用されます。これについては、以降の章で説明します。

完全なコードリストは次のとおりです-

?php
namespace Tutorial\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class TutorialController extends AbstractActionController {
   public function indexAction() {
      return new ViewModel();
   }
}

新しい TutorialController が正常に追加されました。

AbstractRestfulController

AbstractRestfulController(Zend \ Mvc \ Controller \ AbstractRestfulController)は、着信要求のHTTP method を検査し、HTTPメソッドを考慮してアクション(メソッド)と一致します

たとえば、GET HTTPメソッドを使用したリクエストは、 id パラメータがリクエストで見つかった場合、* getList()メソッドまたは get()*メソッドと一致します。

AbstractConsoleController

AbstractConsoleController(Zend \ Mvc \ Controller \ AbstractConsoleController)はAbstractActionControllerに似ていますが、ブラウザではなくコンソール環境でのみ実行される点が異なります。

Zend Framework-ルーティング

ルーティングは、*リクエストURI *を特定のコントローラーのメソッドにマップします。 この章では、Zend Frameworkでルートを実装する方法を説明します。

一般的に、任意のURIには3つの部分があります-

  • ホスト名セグメント、
  • パスセグメント
  • クエリセグメント。

たとえば、URI/URL-* http://www.example.com/index?q = data、* www.example.com はホスト名セグメント、 index はパスセグメント、 q = dataです。 はクエリセグメントです。 一般に、ルーティングは一連の制約に対して*ページセグメント*をチェックします。 制約が一致する場合、値のセットを返します。 主な価値の1つはコントローラーです。

ルーティングは、特定の状況でホストセグメント、クエリセグメント、HTTPメソッドの要求、HTTPヘッダーの要求などもチェックします。

Route&RouteStack

ルートは、ルーティングの主要なオブジェクトです。 Zend Frameworkには、ルートオブジェクト用の特別なインターフェース RouteInterface があります。 すべてのルートオブジェクトはRouteInterfaceを実装する必要があります。 RouteInterfaceの完全なリストは次のとおりです-

namespace Zend\Mvc\Router;
use Zend\Stdlib\RequestInterface as Request;
interface RouteInterface {
   public static function factory(array $options = []);
   public function match(Request $request);
   public function assemble(array $params = [], array $options = []);
}

主な方法は match です。 この一致メソッドは、指定された要求をその中で定義された制約と照合します。 一致するものが見つかった場合、 RouteMatch オブジェクトを返します。 このRouteMatchオブジェクトは、一致したリクエストの詳細をパラメーターとして提供します。 これらのパラメーターは、 getParams メソッドを使用して RouteObject から抽出できます。

RouteObjectの完全なリストは次のとおりです-

namespace Zend\Mvc\Router;
class RouteMatch {
   public function __construct(array $params);
   public function setMatchedRouteName($name);
   public function getMatchedRouteName();
   public function setParam($name, $value);
   public function getParams();
   public function getParam($name, $default = null);
}

一般に、典型的なMVCアプリケーションには多くのルートがあります。 この各ルートはLIFOの順序で処理され、1つのルートが一致して返されます。 一致する/返されるルートがない場合、アプリケーションは「ページが見つかりません」エラーを返します。 Zend Frameworkは、ルートを処理するためのインターフェース RouteStackInterface を提供します。 このRouteStackInterfaceには、ルートを追加/削除するオプションがあります。

RouteStackInterfaceの完全なリストは次のとおりです-

namespace Zend\Mvc\Router;
interface RouteStackInterface extends RouteInterface {
   public function addRoute($name, $route, $priority = null);
   public function addRoutes(array $routes);
   public function removeRoute($name);
   public function setRoutes(array $routes);
}

Zendフレームワークは、 RouteStack インターフェースの2つの実装を提供し、それらは次のとおりです-

  • SimpleRouteStack
  • TreeRouteStack

ルートの種類

Zendフレームワークは、「Zend \ Mvc \ Router \ Http」名前空間の下で、あらゆる状況に対応する既製のルートオブジェクトを多数提供します。 特定の状況に適したルートオブジェクトを選択して使用すれば十分です。

利用可能なルートは次のとおりです-

  • Hostname -URIのホスト部分と一致するために使用されます。
  • Literal -正確なURIに一致するために使用されます。
  • Method -着信リクエストのHTTPメソッドと一致するために使用されます。
  • Part -カスタムロジックを使用してURIパスセグメントの一部を一致させるために使用されます。
  • Regex -正規表現パターンによるURIパスセグメントの照合に使用されます。
  • Schema -http、httpsなどのURIスキーマと一致するために使用されます。
  • セグメント-URIパスを複数のセグメントに分割して一致させるために使用されます。

最も一般的に使用されるリテラルおよびセグメントルートの作成方法を見てみましょう。 通常、ルートは各モジュールの構成ファイル( module.config.php )で指定されます。

リテラルルート

通常、ルートはLIFOの順序で照会されます。 リテラルルートは、URIパスの完全一致を行うためのものです。

以下に示すように定義されます-

$route = Literal::factory(array(
   'route' => '/path',
   'defaults' => array('controller' => 'Application\Controller\IndexController',
      'action' => 'index',),
));

上記のルートは、リクエストURLの /path と一致し、 indexaction として、 IndexController をコントローラーとして返します。

セグメントルート

セグメント化されたルートは、URLが可変パラメーターを含むことになっている場合に使用されます。

以下のように説明されています-

$route = Segment::factory(array(
   'route' => '/:controller[/:action]',
   'constraints' => array(
      'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
      'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
   ),
   'defaults' => array(
      'controller' => 'Application\Controller\IndexController',
      'action' => 'index',),
));

ここでは、セグメントはコロンで示され、その後に英数字が続きます。 セグメントを保持する場合はオプションで、角括弧で囲まれます。 各セグメントには制約が関連付けられている場合があります。 各制約は正規表現です。

チュートリアルモジュールでのルートの構成

チュートリアルモジュールにセグメントルートを追加しましょう。 チュートリアルモジュール構成ファイルを更新します- myapp/module/Tutorial/config で入手可能な module.config.php

<?php
namespace Tutorial;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
   'controllers' => [
      'factories' => [
         Controller\TutorialController::class => InvokableFactory::class,
      ],
   ],
   'router' => [
      'routes' => [
         'tutorial' => [
            'type'    => Segment::class,
               'options' => [
                  'route' => '/tutorial[/:action[/:id]]',
                  'constraints' => [
                     'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                     'id'     => '[0-9]+',
                  ],
                  'defaults' => [
                     'controller' => Controller\TutorialController::class,
                     'action'     => 'index',
                  ],
               ],
            ],
      ],
   ],
   'view_manager' => [
      'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
   ],
];
*Tutorial* モジュールのルーティングを追加しました。 チュートリアルモジュールを完了するには、一歩遅れています。 モジュールの *View* を追加する必要があります。これについては、次の章で学習します。

Zend Framework-ビューレイヤー

ビューレイヤーは、MVCアプリケーションのプレゼンテーションレイヤーです。 プレゼンテーションロジックからアプリケーションロジックを分離します。 典型的なPHP Webアプリケーションでは、すべてのビジネスロジックとデザインが混在しています。 混合により、小規模プロジェクトでの開発を高速化できます。 しかし、多くの高レベルのアーキテクチャが関係する大規模なプロジェクトでは、惨めな失敗に終わります。 Webアプリケーションのデザインを変更するには、開発者もビジネスロジックで作業する必要があります。 これは壊滅的な結果となり、ビジネスロジックが破壊される可能性があります。

Zend Frameworkは、よく考えられた、クリーンで、柔軟で拡張可能なビューレイヤーを提供します。 Viewレイヤーは別のモジュール Zend/View として利用可能で、 Zend/Mvc モジュールとうまく統合されます。 Zend View Layerは、互いにうまくやり取りする複数のコンポーネントに分離されています。

そのさまざまなコンポーネントは次のとおりです-

  • 変数コンテナ-ビューレイヤーのデータを保持します。
  • モデルの表示-可変コンテナとデザインテンプレートを保持します。
  • レンダラー-ビューモデルのデータとテンプレートを処理し、デザイン表現を出力します。おそらく最終的なHTML出力です。
  • Resolvers -Rendererが使用できるように、View Modelで利用可能なテンプレートを解決します。
  • * View(Zend \ View \ View)*-リクエストをレンダラーにマッピングし、レンダラーをレスポンスにマッピングします。
  • レンダリング戦略-ビューがリクエストをレンダラーにマッピングするために使用します。
  • 応答戦略-Viewがレンダラーを応答にマッピングするために使用します。

ビューレイヤー ViewViewModel を処理し、 Resolver を使用してテンプレートを解決し、 Rendering Strategy を使用してレンダリングし、最後に Response Renderer を使用して出力します。

レイヤー構成の表示

コントローラーと同様に、Viewレイヤーは、- module.config.php と呼ばれるモジュールの構成ファイルで構成できます。 主な構成は、テンプレートを配置する場所を指定することです。 これは、「module.config.php」に次の構成を追加することで実現できます。

'view_manager' => [
   'template_path_stack' => ['tutorial' => __DIR__ . '/../view',],
]

デフォルトでは、ビューレイヤーには、そのすべてのコンポーネントのデフォルトの動作があります。 たとえば、 ViewModel は、「小文字のモジュール名/小文字のコントローラー名/小文字のアクション名」ルールによって、テンプレートルート内のコントローラーのアクションのテンプレート名を解決します。 ただし、これはViewModelの* setTemplate()*メソッドによってオーバーライドできます。

コントローラーとビューレイヤー

デフォルトでは、コントローラーはビューレイヤーにデータを送信する必要はありません。 適切な場所にテンプレートを書くだけで十分です。

たとえば、 TutorialController の例では、テンプレートを myapp/module/Tutorial/view/tutorial/tutorial/index.phtml に配置する必要があります。 index.phtml はPHPベースのテンプレートを参照し、PHPRendererによってレンダリングされます。 json 出力には JsonRendererrss および atom 出力には FeedRenderer など、他のレンダラーがあります。

完全なリストは次のとおりです-

<?php
namespace Tutorial\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class TutorialController extends AbstractActionController {
   public function indexAction() {
   }
}

Zendアプリケーションテンプレート

<div class = "row content">
   <h3>This is my first Zend application</h3>
</div>

最後に、 Tutorial モジュールが正常に完成しました。URLを使用してアクセスできます。

アプリケーションテンプレート

ビューレイヤーへのデータの受け渡し

データをビューレイヤーに送信する最も簡単な方法は、 ViewModel 引数を使用することです。 変更された indexAction メソッドは次のとおりです-

public function indexAction() {
   $view = new ViewModel([
      'message' => 'Hello, Tutorial'
   ]);
   return $view;
}

今、次のように index.phtml ファイルを変更します-

<div class = "row content">
   <h3>This is my first Zend application</h3>
   <h4><?php echo $this->message?></h4>
</div>

ヘルパーを表示

ビューヘルパーは、テンプレートで使用される小さなアトミック関数を作成するために使用されます。 Zendフレームワークは、標準のビューヘルパーを作成するためのインターフェイスZend \ View \ Helper \ HelperInterfaceを提供します。

HelperInterfaceには2つのメソッドしかありません。

  • * setView()*-このメソッドは、Zend \ View \ Renderer \ RendererInterfaceインスタンス/実装を受け入れます。

  • * getView()*-そのインスタンスを取得するために使用されます。

    *HelperInterface* の完全なコードリストは次のとおりです-
namespace Zend\View\Helper;
use Zend\View\Renderer\RendererInterface as Renderer;
interface HelperInterface {
  /* *
     * Set the View object
 *
     * @param  Renderer $view
 *@return HelperInterface
  */
   public function setView(Renderer $view);
  /* *
     * Get the View object
 *
     * @return Renderer
   */
   public function getView();
}

ビュースクリプトでヘルパーを使用するには、* $ this→ helperName()*を使用してアクセスします。

組み込みヘルパー

Zend Frameworkは、さまざまな目的のために多くの組み込みヘルパー関数を提供します。 zend-mvc で利用可能なビューヘルパーの一部は次のとおりです-

URL

URLヘルパーは、アプリケーションで定義されたルートに一致するURLを生成するために使用されます。

URLヘルパーの定義は次のとおりです-

$this->url($name, $params, $options, $reuseMatchedParameters)

たとえば、チュートリアルモジュールでは、ルートの名前は tutorial であり、2つのパラメーター action および id があります。 以下に示すように、URLヘルパーを使用して2つの異なるURLを生成できます-

<a href = "<? = $this->url('tutorial'); ?>">Tutorial Index</a>
<a href = "<? = $this->url('tutorial', ['action' => 'show', 'id' =>10]); ?>">
   Details of Tutorial #10
</a>

結果は次のようになります-

<a href = "/tutorial">Tutorial Index</a>
<a href = "/tutorial/show/10"> Details of Tutorial #10</a>

プレースホルダー

プレースホルダーヘルパーは、ビュースクリプトとビューインスタンス間でコンテンツを保持するために使用されます。 最初にデータを設定し、それを後の段階で使用するオプションを提供します。

たとえば、*会社名*を設定して、他のすべての場所で使用できます。

<?php $this->placeholder('companyname')->set("finddevguides") ?>
<?= $this->placeholder('companyname'); ?>

プレースホルダーは、PHPの配列とオブジェクトから複雑なコンテンツを生成するための高度なオプションを提供します。 テンプレート自体の特定のセクションをキャプチャするオプションもあります。

たとえば、次のコードは、間にあるテンプレートの結果をキャプチャし、 productlist プレースホルダーに保存します。

クラス-製品

class Product {
   public $name;
   public $description;
}

コントローラ

$p1 = new Product();
$p1->name = 'Car';
$p1->description = 'Car';
$p2 = new Product();
$p2->name = 'Cycle';
$p2->description = 'Cycle';
$view = new ViewModel(['products' => $products]);

テンプレート

<!-- start capture -->
<?php $this->placeholder('productlist')->captureStart();
   foreach ($this->products as $product): ?>
<div>
   <h2><?= $product->name ?></h2>
   <p><?= $product->description ?></p>
</div>
<?php endforeach; ?>
<?php $this->placeholder('productlist')->captureEnd() ?>
<!-- end capture -->
<?= $this->placeholder('productlist') ?>
  • 結果 *
<div class = "foo">
   <h2>Car</h2>
   <p>Car</p>
</div>
<div class = "foo">
   <h2>Cycle</h2>
   <p>Cycle</p>
</div>

文書型

Doctypeヘルパーは、さまざまなhtml doctypeを生成するために使用されます。* Placeholder *ヘルパーの具体的な実装です。 Doctypeは、ブートストラップファイルと設定ファイルで設定できます。

基本的な使用法を以下に示します-

アプリケーションブートストラップファイル

use Zend\View\Helper\Doctype;
$doctypeHelper = new Doctype();
$doctypeHelper->doctype('XHTML5');

モジュール構成

//module/Application/config/module.config.php:
return [
  /*...*/
   'view_manager' => [
      'doctype' => 'html5',
     /*...*/
   ],
];
  • テンプレート *
<?php echo $this->doctype() ?>

HeadTitle

HeadTitleヘルパーは、htmlタイトル要素を生成するために使用されます。* Placeholder *ヘルパーの具体的な実装です。 Zendには、モジュール構成ファイルにタイトルを設定するオプションがあり、サイト、モジュール、コントローラー、アクションなどの任意のレベルで設定できます。 HeadTitleの部分的なコードは次のとおりです-

モジュール

headTitleHelper->append($action);
$headTitleHelper->append($controller);
$headTitleHelper->append($module);
$headTitleHelper->append($siteName);

テンプレート

<?= $this->headTitle() ?>

結果

action - controller - module - Zend Framework

HeadMeta

HeadMetaヘルパーは、htmlメタタグを生成するために使用されます。 これは、プレースホルダーヘルパーの具体的な実装です。

テンプレート-

<?php
   $this->headMeta()->appendName('keywords', 'turorialspoint, zend framework, php');
   echo $this->headMeta()
?>

結果

<meta name = "keywords" content = "finddevguides, zend framework, php"/>

HeadLink

HeadLinkヘルパーは、外部リソースを含めるHTMLリンクを生成するために使用されます。 これは、プレースホルダーヘルパーの具体的な実装です。

テンプレート

<?php
  //setting links in a view script:
   $this->headLink(['rel' => 'icon', 'href' => '/img/favicon.ico'], 'PREPEND')
      ->appendStylesheet('/styles/site.css')
      ->prependStylesheet('/styles/mystyle.css', 'screen', true, ['id' => 'mystyle']);

  //rendering the links from the layout:
   echo $this->headLink();
?>

結果

<link href = "/styles/mystyle.css" media = "screen" rel = "stylesheet"
   type = "text/css" id = "mystyle">
<link href = "/img/favicon.ico" rel = "icon">
<link href = "/styles/site.css" media = "screen" rel = "stylesheet" type = "text/css">

HeadStyle

HeadStyleヘルパーは、インラインCSSスタイルを生成するために使用されます。 これは、プレースホルダーヘルパーの具体的な実装です。

テンプレート

<?php $this->headStyle()->appendStyle($styles); ?>
<?php echo $this->headStyle() ?>

HeadScript

HeadScriptは、インラインスクリプトを生成したり、外部スクリプトを含めるために使用されます。 これは、プレースホルダーヘルパーの具体的な実装です。

テンプレート

<? $this->headScript()->appendFile(‘/js/sample.js’);?>
<?php echo $this->headScript() ?>

InlineScript

InlineScriptは、htmlテンプレートのheadセクションとbodyセクションの両方でスクリプトを生成するために使用されます。 HeadScriptから派生しています。

HTMLList

HTMLListは、順序付きリストと順序なしリストを生成するために使用されます。 HTMLListの定義は次のとおりです-

定義

htmlList($items, $ordered, $attribs, $escape)

テンプレート

$items = [
   '2015',
   ['March', 'November'],
   '2016',
];
echo $this->htmlList($items);

結果

<ul>
   <li>2015
      <ul>
         <li>March</li>
         <li>November</li>
      </ul>
   </li>
   <li>2016</li>
</ul>

サイクル

サイクルは、ループ環境で代替を生成するために使用されます。 assign、next、prev機能があります。

コントローラ

$view = new ViewModel(['message' => 'Hello, Tutorial', 'data' => array('One', 'Two')]);

テンプレート

<?php $this->cycle()->assign(['#F0F0F0', '#FFF'], 'colors'); ?>

<table>
   <?php foreach ($this->data as $datum): ?>
   <tr style = "background-color: <?= $this->cycle()->setName('colors')>next() ?>">
      <td><?= $this->escapeHtml($datum) ?></td>
   </tr>
   <?php endforeach ?>
</table>

結果

<table>
   <tr style = "background-color: #F0F0F0">
      <td>One</td>
   </tr>
   <tr style = "background-color: #FFF">
      <td>Two</td>
   </tr>
</table>

他のいくつかの重要な組み込みヘルパーは次のとおりです-

  • BasePath -BasePathは、アプリケーションのルートのパブリックフォルダーのパスを生成するために使用されます。
  • Partial -Partialは、独自の変数スコープで特定のテンプレートをレンダリングするために使用されます。
  • PartialLoop -PartialLoopはPartialに似ていますが、ループ環境で使用されます。
  • Identity -Identityは、認証サービスからログインしているユーザーのIDを取得するために使用されます。
  • JSON -JSONは、出力がJSON形式である落ち着いた環境で使用されます。 適切なHTTPヘッダーを発行し、レイアウトの概念を無効にします。

Zend Frameworkには、* i18nヘルパー、フォームヘルパー、ページネーションヘルパー、ナビゲーションヘルパー*など、まだ多くのヘルパーがあります。

ビューヘルパーの作成

Zend Frameworkは、ビューヘルパーを記述するための HelperInterface を実装する組み込みの AbstractHelper を提供します。

新しいヘルパーの作成に必要な手順は次のとおりです-

  • *ステップ1 *-クラスZend \ View \ Helper \ AbstractHelperを拡張します。

  • ステップ2 *- __ invoke()*関数をオーバーライドします。

  • ステップ3 *- module.config.phpファイルで構成を設定します*。

  • *ステップ4 *-ビュースクリプトでビューヘルパーを使用します。

    *TestHelper* を作成しましょう
  • myapp/module/Tutorial/src/ViewディレクトリにHelperフォルダーを作成します*。 ヘルパーディレクトリ TestHelper.php 内に TestHelper を記述します。

完全なリストは次のとおりです-

<?php
namespace Tutorial\View\Helper;
use Zend\View\Helper\AbstractHelper;
class TestHelper extends AbstractHelper {
   public function __invoke() {
      $output = "I am from test helper";
      return htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
   }
}
*module.config.php* で構成を設定します。
'view_helpers' => [
   'aliases' => [
      'testHelper' => View\Helper\TestHelper::class,
   ],
   'factories' => [
      View\Helper\TestHelper::class => InvokableFactory::class,
   ],
],
*about* ビュースクリプトで新しく作成された *TestHelper* を使用します。
<?= $this->testHelper() ?>

Zend Framework-レイアウト

レイアウトは、複数のビューの共通部分を表します。 たとえば、ページのヘッダーとフッター。 デフォルトでは、レイアウトは view/layout フォルダーに保存する必要があります。

レイアウト構成は、module.config.phpの view_manager セクションで定義されます。

スケルトンアプリケーションのデフォルト設定は次のとおりです-

'view_manager' => array(
   'display_not_found_reason' => true,
   'display_exceptions' => true,
   'doctype' => 'HTML5',
   'not_found_template' => 'error/404',
   'exception_template' => 'error/index',
   'template_map' => array(
      'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
      'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
      'error/404' => __DIR__ . '/../view/error/404.phtml',
      'error/index' => __DIR__ . '/../view/error/index.phtml',
   ),
   'template_path_stack' => array(
   __DIR__ . '/../view',
),

ここでは、 template_map を使用してレイアウトを指定します。 レイアウトが見つからない場合は、エラーが返されます。 スケルトンアプリケーションのメインレイアウトを見てみましょう。

Layout.phtml

<?= $this->doctype() ?>
<html lang = "en">
   <head>
      <meta charset = "utf-8">
      <?= $this->headTitle('ZF Skeleton Application')->setSeparator(' - ')>
         setAutoEscape(false) ?>
      <?= $this->headMeta()
         ->appendName('viewport', 'width = device-width, initial-scale = 1.0')
         ->appendHttpEquiv('X-UA-Compatible', 'IE = edge')
      ?>

      <!-- Le styles -->
      <?= $this->headLink(['rel' => 'shortcut icon', 'type' =>
         'image/vnd.microsoft.icon',
         'href' => $this->basePath() . '/img/favicon.ico'])
         ->prependStylesheet($this->basePath('css/style.css'))
         ->prependStylesheet($this->basePath('css/bootstraptheme.min.css'))
         ->prependStylesheet($this->basePath('css/bootstrap.min.css'))
      ?>

      <!-- Scripts -->
      <?= $this->headScript()
         ->prependFile($this->basePath('js/bootstrap.min.js'))
         ->prependFile($this->basePath('js/jquery-3.1.0.min.js'))
      ?>
   </head>

   <body>
      <nav class = "navbar navbar-inverse navbar-fixed-top" role = "navigation">
         <div class = "container">
            <div class = "navbar-header">
               <button type = "button" class = "navbar-toggle" data-
                  toggle = "collapse" data-target = ".navbar-collapse">
                  <span class = "icon-bar"></span>
                  <span class = "icon-bar"></span>
                  <span class = "icon-bar"></span>
               </button>

               <a class = "navbar-brand" href = "<?= $this->url('home') ?>">
                  <img src = "<?= $this->basePath('img/zf-logo-mark.svg') ?>
                     " height = "28" alt = "Zend Framework <?= \Application\Module::
                     VERSION ?>"/> Skeleton Application
               </a>
            </div>

            <div class = "collapse navbar-collapse">
               <ul class = "nav navbar-nav">
                  <li class = "active"><a href = "<?=
                     $this->url('home') ?>">Home</a></li>
               </ul>
            </div>
         </div>
      </nav>

      <div class = "container">
         <?= $this->content ?>
         <hr>
         <footer>
            <p>© 2005 - <?= date('Y') ?> by Zend Technologies Ltd.
               All rights reserved.</p>
         </footer>
      </div>
      <?= $this->inlineScript() ?>
   </body>
</html>

レイアウトを分析するとき、ほとんどの場合、前の章で説明したビューヘルパーを使用します。 よく見ると、レイアウトは特別な変数 $ this→ content を使用しています。 この変数は、実際に要求されたページのビュースクリプト(テンプレート)に置き換えられるため、重要です。

新しいレイアウトを作成する

チュートリアルモジュールの新しいレイアウトを作成しましょう。

まず、「public/css」ディレクトリの下に* tutorial.cssファイル*を作成しましょう。

 body {
   background-color: lightblue;
}
h1 {
   color: white;
   text-align: center;
}

/myapp/module/Tutorial/view/layout/に新しいレイアウトファイル newlayout.phtml を作成し、既存のレイアウトからコンテンツをコピーします。 次に、レイアウトヘッドセクション内の HeadLink ヘルパークラスを使用して、 tutorial.css スタイルシートを追加します。

<?php echo $this->headLink()->appendStylesheet('/css/tutorial.css');?>
*URL* ヘルパーを使用して、ナビゲーションセクションに新しい *about* リンクを追加します。
<li><a href = "<?= $this->url('tutorial', ['action' => 'about']) ?>">About</a></li>

このレイアウトページは、チュートリアルモジュールアプリケーションに共通です。 チュートリアルモジュール構成ファイルの view_manager セクションを更新します。

'view_manager' => array(
   'template_map' => array(
      'layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'),
   'template_path_stack' => array('tutorial' => __DIR__ . '/../view',),
)
*TutorialController* に *aboutAction* 関数を追加します。
 public function aboutAction() {
}

myapp/module/Tutorial/view/tutorial/tutorial/に次の内容の about.phtml を追加します。

<h2>About page</h2>

これで、最終的にアプリケーションを実行する準備ができました-* http://localhost:8080/tutorial/about。*

ページについて

Zend Framework-モデルとデータベース

この章では、Zend Frameworkのさまざまなモデルとデータベースについて説明します。

Zend Frameworkのモデル

モデルは、アプリケーションの論理データ表現を定義します。 たとえば、ショッピングカートアプリケーションでは、製品、顧客、カート、注文がモデルです。 それらは、保持するエンティティのプロパティを定義します。 モデルの概念のいくつかは次のとおりです-

  • コントローラーはモデルと通信し、モデルに必要な情報を取得するよう依頼します。 この取得された情報は、コントローラーによってビューに渡されます。 最後に、Viewはモデルをユーザーの消費可能なプレゼンテーションデータとしてレンダリングします。
  • モデルがビューと直接相互作用することは非常にまれですが、時々起こる場合があります。
  • モデルは互いに対話でき、自己完結型ではありません。 それらは互いに関係を持っています。 これらの関係により、コントローラーは異なるモデルと対話する必要がないため、情報を簡単かつ迅速に取得できます。モデルはそれを自分で行うことができます。

単純なモデル- MyModel を見てみましょう。

<?php
namespace Tutorial\Model;
class Book {
   public $id;
   public $author;
   public $title;
}

Zend Frameworkのデータベース

Zendフレームワークは、データベーステーブルのデータを検索、挿入、更新、削除するためのシンプルで機能豊富なクラスZend \ Db \ TableGateway \ TableGatewayを提供します。

Zend frameworkでPHPのPDOドライバーを介して MySqlservice を接続する方法を次の手順で見てみましょう。

ステップ1:MySQLでデータベースを作成する

ローカルMySQLサーバーにデータベース tutorials を作成します。 この目的のために、 phpmyadmin またはその他のMySQL GUIツールを使用できます。 コマンドプロンプトで* MySQLクライアント*を使用してみましょう。 mysqlサーバーに接続し、次のコマンドを実行して tutorial データベースを作成します。

create database tutorials

ステップ2:チュートリアルデータベースでテーブルを作成する

次のSQLコマンドを使用して、 tutorials dbにデータベース book を作成します。

use tutorials;
CREATE TABLE book (
   id int(11) NOT NULL auto_increment,
   author varchar(100) NOT NULL,
   title varchar(100) NOT NULL,
   PRIMARY KEY (id)
);

ステップ3:本の表にデータを入力する

*book* テーブルにサンプルデータを入力します。 次のSQLコマンドを使用します。
INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming');
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming');
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');

ステップ4:データベース接続を更新する

グローバル構成ファイル(myapp/config/autoload/global.php)を必要なデータベースドライブ情報で更新します。

<?php
return array(
   'db' => array(
      'driver' => 'Pdo',
      'dsn' => 'mysql:dbname = tutorials;host = localhost',
      'driver_options' => array(
         PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
      ),
   ),
   'service_manager' => array(
      'factories' => array(
         'Zend\Db\Adapter\Adapter' => 'Zend\Db\Adapter\AdapterServiceFactory',
      ),
   ),
);

ステップ5:データベース資格情報を更新する

ローカル構成ファイル(myapp/config/autoload/local.php)のデータベース資格情報を更新します。 このようにして、ローカルとライブのデータベース接続資格情報を分離できます。

<?php
return array(
   'db' => array(
      'username' => '<user_name>',
      'password' => '<password>',
   ),
);

ステップ6:ブックのモデルを作成する

モジュール src ディレクトリに Book というモデルを作成しましょう。 通常、モデルは、Modelフォルダー(/myapp/module/Tutorial/src/Model/Book.php)の下にグループ化されます。

<?php
namespace Tutorial\Model;
class Book {
   public $id;
   public $author;
   public $title;
}

ステップ7:ブックモデルにexchangeArrayを実装する

*TableGateway* は、 *exchangeArray* 関数を介してモデルと対話します。 exchangeArray関数の標準引数は、PHP配列として保存されたデータベース結果セットです。 *exchangeArrayfunction* を使用すると、モデルのプロパティを対応するデータベーステーブルと簡単に同期できます。

以下に示すように、モデル Book を更新します-

<?php
namespace Tutorial\Model;
class Book {
   public $id;
   public $author;
   public $title;
   public function exchangeArray($data) {
      $this->id = (!empty($data['id'])) ? $data['id'] : null;
      $this->Author = (!empty($data['author'])) ? $data['author'] : null;
      $this->Title = (!empty($data['title'])) ? $data['title'] : null;
   }
}

ステップ8:TableGatewayを使用して本を取得する

データベースから書籍情報を取得するクラス BookTable を作成します。 Model フォルダー自体にクラスBookTableを作成します。

<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class BookTable {
   protected $tableGateway;
   public function __construct(TableGatewayInterface $tableGateway) {
      $this->tableGateway = $tableGateway;
   }
   public function fetchAll() {
      $resultSet = $this->tableGateway->select();
      return $resultSet;
   }
}

TableGatewayクラスの* select()メソッドを使用して、データベースから書籍情報を取得しました。 ただし、コードの *book というテーブルへの参照は使用していません。 TableGatewayは本質的に汎用であり、特定の構成を使用して任意のテーブルからデータをフェッチできます。 通常、これらの設定は module.config.php ファイルで行われます。これについては、以降の手順で説明します。

ステップ9:BookTableクラスを構成する

チュートリアルモジュール Module.php を* getServiceConfig()*メソッドで更新します。

<?php
namespace Tutorial;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements ConfigProviderInterface {

   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
   public function getServiceConfig() {
      return [
         'factories' => [
            Model\BookTable::class => function ($container) {
               $tableGateway = $container->get(Model\BookTableGateway::class);
               $table = new Model\BookTable($tableGateway);
               return $table;
            },
            Model\BookTableGateway::class => function ($container) {
               $dbAdapter = $container->get(AdapterInterface::class);
               $resultSetPrototype = new ResultSet();
               $resultSetPrototype->setArrayObjectPrototype(new Model\Book());
               return new TableGateway('book', $dbAdapter, null, $resultSetPrototype);
            },
         ],
      ];
   }
}

ここでは、サービスマネージャーを使用して BookTable クラスを登録しました。 BookTableクラスは、書籍情報を取得するために使用され、登録することで必要な場所にアクセスできます。 登録されたサービスは共有されるため、パフォーマンスが向上し、メモリ消費が削減されます。

別の項目Model \ BookTableGateway
classは、 Book モデルに特化したTableGatewayオブジェクトであり、 BookTable の依存関係です。

ステップ10:TutorialController構成を更新する

ブック情報を取得するには、チュートリアルコントローラーに BookTable サービスが必要です。 BookTableサービスを取得するには、TutorialControllerのコンストラクター依存関係として登録します。

このコンストラクターの依存関係は、コントローラー自体が初期化段階にある間にBookTableサービスを取得するのに役立ちます。 以下に示すように、チュートリアルモジュール構成の module.config.php のコントローラーセクションを更新します。

'controllers' => [
   'factories' => [
      Controller\TutorialController::class => function($container) {
         return new Controller\TutorialController(
            $container->get(Model\BookTable::class)
         );
      },
   ],
],

ステップ11:チュートリアルコントローラーを更新する

これは、次の3つのステップを順守することによって行われます。

  • _BookTable_を引数としてコンストラクターを追加します。
private $table;
public function __construct(BookTable $table) {
   $this->table = $table;
}
  • * BookTableのfetchAll()*メソッドを使用して本の情報を取得し、ビューに登録します。
public function indexAction() {
   $view = new ViewModel([
      'data' => $this->table->fetchAll(),
   ]);
   return $view;
}
  • 表示スクリプトで書籍情報を表示します。
<table class = "table">
   <tr>
      <th>Author</th>
      <th>Title</th>
      <th> </th>
   </tr>
   <?php foreach ($data as $sampledata) : ?>
   <tr>
      <td><?php echo $this->escapeHtml($data->author);?></td>
      <td><?php echo $this->escapeHtml($data->title);?></td>
   </tr>
   <?php endforeach ?>
</table>

ステップ12:アプリケーションを実行する

  • http://localhost:8080/tutorial を実行して、アプリケーションを確認します。

アプリケーションの実行

Zend Framework-異なるデータベース

前の章で説明したように、Zendフレームワークは、*データベースドライバー*コンセプトを使用してデータベースにアクセスする一般的な方法を提供します。 データベースの操作はドライバー情報のみに依存するため、異なるデータベースとの接続にはドライバー情報の変更のみが含まれます。

次の手順で、 book の例を変更して postgresql データベースに接続します。

  • ステップ1 *-次のコマンドを使用して、ローカルのpostgresqlデータベースにデータベース、チュートリアルを作成します-
CREATE DATABASE tutorials

ステップ2 *- *book テーブルを追加します。 新しいデータベースに移動して、テーブル作成スクリプトを実行します。

\c tutorials
CREATE TABLE book (
   id SERIAL NOT NULL,
   author varchar(100) NOT NULL,
   title varchar(100) NOT NULL,
   PRIMARY KEY (id)
);
  • ステップ3 *-次のスクリプトを使用してサンプルの書籍情報を追加します-
INSERT INTO book (author, title) VALUES ('Dennis Ritchie', 'C Programming');
INSERT INTO book (author, title) VALUES ('James gosling', 'Java Programming');
INSERT INTO book (author, title) VALUES ('Rasmus Lerdorf', 'Programming PHP');

ステップ4 *- global.configファイルのドライバー情報を変更します*。

<?php
return array (
   'db' => array (
      'driver' => 'Pdo',
      'dsn' => 'pgsql:dbname = tutorials;host = localhost',
      'driver_options' => array (
      ),
   ),
);

ステップ5 *- *local.config ファイルのデータベース資格情報を変更します。

return array (
   'db' => array(
      'username' => '<username>',
      'password' => '<password>',
   ),
);

ステップ6 *-最後に、アプリケーション *http://localhost:8080/tutorial を実行します。 結果は、MySQLアプリケーションと同じです。

Zend Framework-フォームと検証

Zend Frameworkは、 zend-form という独立したコンポーネントを提供して、フォームの作成と検証プロセスを高速化します。 モデルとビューレイヤーを接続します。 事前定義されたモデルから本格的なhtmlフォームを作成する一連のフォーム要素、フォームに対してモデルを検証する InputFilter クラス、およびフォームからモデルにデータをバインドするオプションを提供します。

フォームコンポーネントのインストール

Zendフォームコンポーネントは、以下に指定されているように Composer コマンドを使用してインストールすることができます-

composer require zendframework/zend-form

Zendフォームフレームワークには、フォームを管理するための3つのサブコンポーネントがあります。 それらは以下で詳細に説明されているとおりです-

  • 要素-モデルのプロパティにマッピングされた単一のHTML入力コントロールを定義するために使用されます。
  • Fieldset -要素および他の fieldset をネストされた方法でグループ化するために使用されます。
  • フォーム-HTMLフォームを作成するために使用され、要素とフィールドセットで構成されています。

Zend Formsは通常、 module//src/Form ディレクトリの下に作成されます。

ここで、データベースに book を追加する簡単なフォームを作成しましょう。 これを行うには、次の手順に従う必要があります-

ステップ1:BookFormを作成する

  • myapp/module/Tutorial/src/Form」ディレクトリの下に「BookForm.php」を作成します。 ファイルに次の変更を追加します-
<?php
namespace Tutorial\Form;
use Zend\Form\Form;

class BookForm extends Form {

   public function __construct($name = null) {
      parent::__construct('book');
      $this->add(array(
         'name' => 'id',
         'type' => 'Hidden',
      ));
      $this->add(array(
         'name' => 'author',
         'type' => 'Text',
         'options' => array(
            'label' => 'Author',
         ),
      ));
      $this->add(array(
         'name' => 'title',
         'type' => 'Text',
         'options' => array(
            'label' => 'Title',
         ),
      ));
      $this->add(array(
         'name' => 'submit',
         'type' => 'Submit',
         'attributes' => array(
            'value' => 'Go',
            'id' => 'submitbutton',
         ),
      ));
   }
}
*Form* クラスは、モデルとそれに対応するフォームの詳細をマッピングする* addメソッド*を提供します。 *Form* クラスを拡張して *BookForm* を作成し、 *Book* モデルのフォームの詳細を追加しました。

ステップ2:ブックモデルBook.phpを更新する

以下に指定されているように、フィルターと検証を使用してモデル「*」を更新します-

<?php
namespace Tutorial\Model;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilter;

class Book implements InputFilterAwareInterface {
   public $id;
   public $author;
   public $title;
   protected $inputFilter;
   public function setInputFilter(InputFilterInterface $inputFilter) {
      throw new \Exception("Not used");
   }
   public function getInputFilter() {
      if (!$this->inputFilter) {
         $inputFilter = new InputFilter();
         $inputFilter->add(array(
            'name' => 'id',
            'required' => true,
            'filters' => array(
               array('name' => 'Int'),
            ),
         ));
         $inputFilter->add(array(
            'name' => 'author',
            'required' => true,
            'filters' => array(
               array('name' => 'StripTags'),
               array('name' => 'StringTrim'),
            ),
            'validators' => array(
               array(
                  'name' => 'StringLength',
                  'options' => array(
                     'encoding' => 'UTF-8',
                     'min' => 1,
                     'max' => 100,
                  ),
               ),
            ),
         ));
         $inputFilter->add(array(
            'name' => 'title',
            'required' => true,
            'filters' => array(
               array('name' => 'StripTags'),
               array('name' => 'StringTrim'),
            ),
            'validators' => array(
               array(
                  'name' => 'StringLength',
                  'options' => array(
                     'encoding' => 'UTF-8',
                     'min' => 1,
                     'max' => 100,
                  ),
               ),
            ),
         ));
         $this->inputFilter = $inputFilter;
      }
      return $this->inputFilter;
   }
   public function exchangeArray($data) {
      $this->id = (!empty($data['id'])) ? $data['id'] : null;
      $this->author = (!empty($data['author'])) ? $data['author'] : null;
      $this->title = (!empty($data['title'])) ? $data['title'] : null;
   }
}

各モデルは InputFilterAwareInterface を実装する必要があります。 InputFilterAwareInterfaceには、* setInputFilter() getInputFilter()*の2つのメソッドがあります。

getInputFilterは、モデルの検証の詳細を取得するために使用されます。 Zendフレームワークは、フォームを検証するための豊富なフィルターとバリデーターのセットを提供します。 ブックモデルで使用されるフィルタとバリデータのいくつかは次のとおりです-

  • StripTags -不要なHTMLを削除します。
  • StringTrim -不要な空白を削除します。
  • * StringLengthバリデータ*-ユーザーが指定された制限を超える文字を入力しないようにします。

ステップ3:BookTableクラスを更新する

*saveBook* メソッドを含めて、データベースに本を追加します。
*BookTable.php*
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;

class BookTable {
   protected $tableGateway;
   public function __construct(TableGatewayInterface $tableGateway) {
      $this->tableGateway = $tableGateway;
   }
   public function fetchAll() {
      $resultSet = $this->tableGateway->select();
      return $resultSet;
   }
   public function getBook($id) {
      $id  = (int) $id;
      $rowset = $this->tableGateway->select(array('id' => $id));
      $row = $rowset->current();
      if (!$row) {
         throw new \Exception("Could not find row $id");
      }
      return $row;
   }
   public function saveBook(Book $book) {
      $data = array (
         'author' => $book->author,
         'title'  => $book->title,
      );
      $id = (int) $book->id;
      if ($id == 0) {
         $this->tableGateway->insert($data);
      } else {
         if ($this->getBook($id)) {
            $this->tableGateway->update($data, array('id' => $id));
         } else {
            throw new \Exception('Book id does not exist');
         }
      }
   }
}

ステップ4:TutorialControllerクラスを更新する

チュートリアルコントローラーに新しいアクションaddActionを追加します– myapp/module/Tutorial/src/Controller/TutorialController.php。

public function addAction() {
   $form = new BookForm();
   $form->get('submit')->setValue('Add');
   $request = $this->getRequest();
   if ($request->isPost()) {
      $book = new Book();
      $form->setInputFilter($book->getInputFilter());
      $form->setData($request->getPost());
      if ($form->isValid()) {
         $book->exchangeArray($form->getData());
         $this->bookTable->saveBook($book);

        //Redirect to list of Tutorial
         return $this->redirect()->toRoute('tutorial');
      }
   }
   return array('form' => $form);
}
*addAction* メソッドは次のプロセスを行います-
  • リクエストオブジェクトを取得します。
  • リクエストのhttpメソッドが post メソッドかどうかを確認します。
  • リクエストのhttpメソッドが post でない場合、テンプレート add.phtml をレンダリングするだけです
  • リクエストのhttpメソッドが post でない場合、 inputfilter を設定し、リクエストデータを取得してinputfilerに設定します。
  • Formクラスの* isValid()*メソッドを使用して、フォームが有効かどうかを確認します。
  • フォームが無効な場合、テンプレート add.phtml を再度レンダリングします
  • フォームが有効な場合、ブックをデータベースに保存し、ホームページにリダイレクトします。

ステップ5:add.phtmlテンプレートを追加する

テンプレートを作成します– myapp/module/Tutorial/view/tutorial/tutorial/add.phtmlの下にあるadd.phtml

*Add.phtml*
<?php
$title = 'Add new Book';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
if(!empty($form)) {
   $form->setAttribute('action', $this->url('tutorial', array('action' => 'add')));
   $form->prepare();
   echo $this->form()->openTag($form);
   echo $this->formHidden($form->get('id'));
   echo $this->formRow($form->get('author'))."<br>";
   echo $this->formRow($form->get('title'))."<br>";
   echo $this->formSubmit($form->get('submit'));
   echo $this->form()->closeTag();
}

ここでは、 Form インスタンス _ $ form_ を使用してブックフォームをレンダリングしています。

ステップ6:アプリケーションを実行する

これで、アプリケーションを実行できます- http://localhost:8080/tutorial/add

フォームページ

フォームページ

エラーページの検証

エラーページ

Zend Framework-ファイルのアップロード

ファイルのアップロードは、フォームプログラミングの主要な概念の1つです。 Zendフレームワークは、 zend-form および zend-inputfilter コンポーネントを介してファイルをアップロードするために必要なすべてのアイテムを提供します。

FileInputクラス

zend-inputfilterコンポーネントは、htmlファイルの入力要素( <input type = 'file'/> )を処理するZend \ InputFilter \ FileInputクラスを提供します。 FileInput は、いくつかの例外を除いて、他の入力フィルターに似ています。 彼らは次のとおりです-

  • PHPはアップロードされたファイルの詳細を $ _ FILES グローバル配列に保存するため、FileInputは$ _FILESのみを介してアップロードされたファイル情報を収集します。
  • FileInputクラスがデータを処理する前に検証を行う必要があります。 これは、他の入力フィルターの反対の動作です。 Zend \ Validator \ File \ UploadFileは、使用されるデフォルトのバリデーターです。 UploadFile *は、ファイル入力の詳細を検証します。

フォームにファイルアップロードタイプを追加するには、入力タイプ File を使用する必要があります。 部分的なコードは次のとおりです-

$form->add(array(
   'name' => 'imagepath',
   'type' => 'File',
   'options' => array('label' => 'Picture',),
));

ファイルのアップロードで使用される別のクラスは、Zend \ Filter \ File \ RenameUploadです。 RenameUpload は、アップロードされたファイルを目的の場所に移動するために使用されます。 ファイルフィルタを使用する部分的なクラスは次のとおりです-

$file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach(
   new RenameUpload([
      'target'    => './public/tmpuploads/file',
      'randomize' => true,
      'use_upload_extension' => true
   ]));
$inputFilter->add($file);

ここで、 RenameUpload のオプションは次のとおりです-

  • target -アップロードされたファイルの宛先パス。
  • randomize -アップロードされたファイルの重複を防ぐために、ランダムな文字列を追加します。
  • use_upload_extension -アップロードされたファイルにファイル拡張子をターゲットに追加します。

ファイルのアップロード-作業例

チュートリアルモジュールを変更して、写真のアップロード機能を追加しましょう。

データベーステーブルを変更する

私たちは、次のSQLコマンドを実行することにより、ブックテーブルに*画像パス*列を追加しましょう-

ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';

BookForm.phpを更新する

ファイル入力要素を追加して、本のフォームに画像をアップロードします– myapp/module/Tutorial/src/Model/BookForm.php。

BookFormクラスの __ constructmethod に次のコードを含めます。

$this->add(array(
   'name' => 'imagepath',
   'type' => 'File',
   'options' => array ('label' => 'Picture',),
));

Book.phpを更新する

Bookクラスで次の変更を行います– myapp/module/Tutorial/src/Model/Book.php。

  • 画像の新しいプロパティ imagepath を追加します。
public $imagepath;
  • 以下に示すように getInputFilter メソッドを更新します-
  • ファイル入力要素に FileInput フィルターを追加します。
  • UploadFile 検証を設定して、ファイル入力要素を検証します。
  • RenameUpload を構成して、アップロードされたファイルを適切な宛先に移動します。

部分的なコードのリストは次のとおりです-

$file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach(
   new RenameUpload([
      'target'    => './public/tmpuploads/file',
      'randomize' => true, 'use_upload_extension' => true
   ]));
$inputFilter->add($file);
  • exchangeArray メソッドを更新して、 imagepath プロパティを含めます。 イメージパスは、フォームまたはデータベースから取得できます。 imagepathがフォームから来ている場合、形式は次の仕様を持つ配列になります-
array(1) {
   ["imagepath"] => array(5) {
      ["name"]     => string "myimage.png"
      ["type"]     => string "image/png"
      ["tmp_name"] => string
         "public/tmpuploads/file_<random_string>.<image_ext>"
      ["error"]    => int <error_number>
      ["size"]     => int <size>
   }
}
  • イメージパスがデータベースから取得される場合、それは単純な文字列になります。 imagepathを解析するための部分的なコードリストは次のとおりです-
if(!empty($data['imagepath'])) {
   if(is_array($data['imagepath'])) {
      $this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']);
   } else {
      $this->imagepath = $data['imagepath'];
   }
} else {
   $data['imagepath'] = null;
}
  • 本*モデルの完全なリストは次のとおりです-
<?php
namespace Tutorial\Model;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\Filter\File\RenameUpload;
use Zend\Validator\File\UploadFile;
use Zend\InputFilter\FileInput;
use Zend\InputFilter\InputFilter;

class Book implements InputFilterAwareInterface {
   public $id;
   public $author;
   public $title;
   public $imagepath;
   protected $inputFilter;
   public function setInputFilter(InputFilterInterface $inputFilter) {
      throw new \Exception("Not used");
   }
   public function getInputFilter() {
      if (!$this->inputFilter) {
         $inputFilter = new InputFilter();
         $inputFilter->add(array(
            'name' => 'id',
            'required' => true,
            'filters' => array(
               array('name' => 'Int'),
            ),
         ));
         $inputFilter->add(array(
            'name' => 'author',
            'required' => true,
            'filters' => array(
               array('name' => 'StripTags'),
               array('name' => 'StringTrim'),
            ),
            'validators' => array(
               array(
                  'name' => 'StringLength',
                  'options' => array(
                     'encoding' => 'UTF-8',
                     'min' => 1,
                     'max' => 100,
                  ),
               ),
            ),
         ));
         $inputFilter->add(array(
            'name' => 'title',
            'required' => true,
            'filters' => array(
               array('name' => 'StripTags'),
               array('name' => 'StringTrim'),
            ),
            'validators' => array(
               array(
                  'name' => 'StringLength',
                  'options' => array(
                     'encoding' => 'UTF-8',
                     'min' => 1,
                     'max' => 100,
                  ),
               ),
            ),
         ));
         $file = new FileInput('imagepath');
         $file->getValidatorChain()->attach(new UploadFile());
         $file->getFilterChain()->attach(
            new RenameUpload([
               'target'    => './public/tmpuploads/file',
               'randomize' => true,
               'use_upload_extension' => true
            ]));
            $inputFilter->add($file);
            $this->inputFilter = $inputFilter;
      }
      return $this->inputFilter;
   }
   public function exchangeArray($data) {
      $this->id = (!empty($data['id'])) ? $data['id'] : null;
      $this->author = (!empty($data['author'])) ? $data['author'] : null;
      $this->title = (!empty($data['title'])) ? $data['title'] : null;

      if(!empty($data['imagepath'])) {
         if(is_array($data['imagepath'])) {
            $this->imagepath = str_replace("./public", "",
               $data['imagepath']['tmp_name']);
         } else {
            $this->imagepath = $data['imagepath'];
         }
      } else {
         $data['imagepath'] = null;
      }
   }
}

BookTable.phpを更新する

*BookForm* と* Bookモデル*を更新しました。 ここで、 *BookTable* を更新し、 *saveBook* メソッドを変更します。 これは、データ配列 *$ data* にイメージパスエントリを含めるのに十分です。

部分的なコードのリストは次のとおりです-

$data = array('author' => $book->author, 'title'  => $book->title,
   'imagepath' => $book->imagepath
);
*BookTable* クラスの完全なコードリストは次のとおりです-
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;

class BookTable {
   protected $tableGateway;
   public function __construct(TableGatewayInterface $tableGateway) {
      $this->tableGateway = $tableGateway;
   }
   public function fetchAll() {
      $resultSet = $this->tableGateway->select();
      return $resultSet;
   }
   public function getBook($id) {
      $id  = (int) $id;
      $rowset = $this->tableGateway->select(array('id' => $id));
      $row = $rowset->current();
      if (!$row) {
         throw new \Exception("Could not find row $id");
      }
      return $row;
   }
   public function saveBook(Book $book) {
      $data = array (
         'author' => $book->author,
         'title'  => $book->title,
         'imagepath' => $book->imagepath
      );
      $id = (int) $book->id;
      if ($id == 0) {
         $this->tableGateway->insert($data);
      } else {
         if ($this->getBook($id)) {
            $this->tableGateway->update($data, array('id' => $id));
         } else {
            throw new \Exception('Book id does not exist');
         }
      }
   }
}
*TutorialController.php* のaddActionを更新します。ファイルアップロード情報は *$ _ FILES* グローバル配列で利用でき、* RequestのgetFiles()*メソッドを使用してアクセスできます。 以下に示すように、投稿されたデータとファイルのアップロード情報の両方をマージします。
$post = array_merge_recursive(
   $request->getPost()->toArray(),
   $request->getFiles()->toArray()
);
  • addAction()*メソッドの完全なリストは次のとおりです-
public function addAction() {
   $form = new BookForm();
   $form->get('submit')->setValue('Add');
   $request = $this->getRequest();
   if ($request->isPost()) {
      $book = new Book();
      $form->setInputFilter($book->getInputFilter());
      $post = array_merge_recursive(
         $request->getPost()->toArray(),
         $request->getFiles()->toArray()
      );
      $form->setData($post);
      if ($form->isValid()) {
         $book->exchangeArray($form->getData());
         $this->bookTable->saveBook($book);

        //Redirect to list of Tutorial
         return $this->redirect()->toRoute('tutorial');
      }
   }
   return array('form' => $form);
}

add.phtmlのビューを更新

最後に、「add.phtml」を変更し、以下に示すようにimagepathファイルの入力要素を含めます-

echo $this->formRow($form->get('imagepath'))."<br>";

完全なリストは次のとおりです-

<?php
$title = 'Add new Book';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
if(!empty($form)) {
   $form->setAttribute('action', $this->url('tutorial', array('action' => 'add')));
   $form->prepare();
   echo $this->form()->openTag($form);
   echo $this->formHidden($form->get('id'));
   echo $this->formRow($form->get('author'))."<br>";
   echo $this->formRow($form->get('title'))."<br>";
   echo $this->formRow($form->get('imagepath'))."<br>";
   echo $this->formSubmit($form->get('submit'));
   echo $this->form()->closeTag();
}

アプリケーションを実行する

最後に、 http://localhost:8080/tutorial/add でアプリケーションを実行し、新しいレコードを追加します。

結果は、次のスクリーンショットに示すようになります-

フォームページ

新しい本の例

インデックスページ

インデックスページ

Zend Framework-Ajax

AJAXは、Webプログラミングの最新技術です。 ページを更新することなく、Webページ内のデータを非同期で送受信するオプションを提供します。 Zendフレームワークには、 zend-view および zend-json コンポーネントを介して json モデルを操作するオプションがあります。 この章では、Zend AJAXプログラミングについて学びましょう。

JSONコンポーネントをインストールする

Zend jsonコンポーネントは、以下に指定されている Composer コマンドを使用してインストールできます-

composer require zendframework/zend-json

概念

Zendフレームワークには、AJAX対応のWebアプリケーションを簡単に作成するための2つの方法があります。 彼らは次のとおりです-

  • Request オブジェクトの* isXmlHttpRequest()*メソッド– AJAXリクエストが行われた場合、リクエストオブジェクトのisXmlHttpRequest()メソッドはtrueを返し、そうでない場合はfalseを返します。 このメソッドは、サーバー側でAJAX要求を適切に処理するために使用されます。
if ($request->isXmlHttpRequest()) {
  //Ajax request
} else {
  //Normal request
}
*Zend/View/Model/JsonModel –* JsonModel *は、AJAXおよびREST APIシナリオ専用に使用される *ViewModel* の代替です。 JsonModelと *JsonStrategy* (モジュールのビューマネージャーブロックで構成されます)は、モデルデータを *Json* にエンコードし、ビュー(phtml)の代わりに応答として返します。

AJAX –作業例

チュートリアルモジュールに新しいajaxページ ajax を追加し、書籍情報を非同期に取得してみましょう。 これを行うには、次の手順に従う必要があります。

ステップ1:モジュール構成にJsonStrategyを追加する

チュートリアルモジュール構成ファイル(myapp/module/Tutorial/config/module.config.php)のビューマネージャーブロックを更新します。 その後、 JsonStrategyJsonModel と連携して、jsonデータをエンコードして送信します。

'view_manager' => [
   'template_map' => array
      ('layout/layout' => __DIR__ . '/../view/layout/newlayout.phtml'),
   'template_path_stack' => [
      'tutorial' => __DIR__ . '/../view',
   ],
   'strategies' => array('ViewJsonStrategy',),
],

ステップ2:TutorialController.phpにajaxActionメソッドを追加する

次のコードでTutorialController.phpにajaxActionメソッドを追加します-

public function ajaxAction() {
   $data = $this->bookTable->fetchAll();
   $request = $this->getRequest();
   $query = $request->getQuery();
   if ($request->isXmlHttpRequest() || $query->get('showJson') == 1) {
      $jsonData = array();
      $idx = 0;
      foreach($data as $sampledata) {
         $temp = array(
            'author' => $sampledata->author,
            'title' => $sampledata->title,
            'imagepath' => $sampledata->imagepath
         );
         $jsonData[$idx++] = $temp;
      }
      $view = new JsonModel($jsonData);
      $view->setTerminal(true);
   } else {
      $view = new ViewModel();
   }
   return $view;
}

ここで、ajaxActionは着信リクエストがAJAXかどうかをチェックします。 着信リクエストがAJAXの場合、 JsonModel が作成されます。 それ以外の場合、通常の ViewModel が作成されます。

どちらの場合も、本の情報はデータベースから取得され、モデルに入力されます。 モデルがJsonModelの場合、 JsonStrategy が呼び出され、データをjsonとしてエンコードし、応答として返します。

*$ query-> get( 'showJson')== 1* はデバッグ目的で使用されます。 URLに *showJson = 1* を追加すると、ページにjsonデータが表示されます。

ステップ3:ajax.phtmlを追加する

次に、ajaxActionメソッドのビュースクリプト ajax.phtml を追加します。 このページには、ラベルが付いたリンクがあります-ブック情報をロード

そのリンクをクリックすると、AJAXリクエストが実行され、書籍情報がJsonデータとして取得され、書籍情報がフォーマットされたテーブルとして表示されます。 AJAX処理は JQuery を使用して行われます。

完全なコードリストは次のとおりです-

<a id = "loadbook" href = "#">Load book information</a>
</br> </br>

<table class = "table">
   <tbody id = "book">
   </tbody>
</table>

<script language = "javascript">
$(document).ready(function(){
   $("#loadbook").on("click", function(event){
      $.ajax({
         url:        '/tutorial/ajax',
         type:       'POST',
         dataType:   'json',
         async:      true,

         success: function(data, status) {
            var e = $('<tr><th>Author</th><th>Title</th><th>Picture</th></tr>');
            $('#book')l('');
            $('#book').append(e);

            for(i = 0; i < data.length; i++) {
               book = data[i];
               var e = $('<tr><td id = "author"></td><td id = "title"></td>
               <td id="imagepath"><img src = ""/></td></tr>');
               $('#author', e)l(book['author']);
               $('#title', e)l(book['title']);
               $('#imagepath img', e).attr('src', book['imagepath']);
               $('#book').append(e);
            }
         },
         error : function(xhr, textStatus, errorThrown) {
            alert('Ajax request failed.');
         }
      });
   });
});
</script>

ステップ4:アプリケーションを実行する

最後に、アプリケーション- http://localhost:8080/tutorial/ajax を実行し、[ブック情報の読み込み]リンクをクリックします。

結果は以下のようになります-

  • Ajaxページ*-

Ajaxページ

ブック情報付きのAjaxページ

書籍情報

デバッグ情報を含むAjaxページ

デバッグ情報

Zend Framework-Cookie管理

Cookieは、Webアプリケーションで非常に重要な概念です。 ユーザーのデータ、通常は限られた期間ブラウザ内の小さな情報を保持するオプションを提供します。

Cookieは、Webアプリケーションの状態を維持するために使用されます。 Zendフレームワークは、 zend-http コンポーネント内にCookieモジュールを提供します。 このzend-httpは、HTTP抽象化とその実装を提供します。

HTTPコンポーネントのインストール

HTTPコンポーネントは、以下のコードで指定されている Composer を使用して簡単にインストールできます。

composer require zendframework/zend-http

概念

zend-httpは、Cookieを管理するための Zend \ Http \ Cookies クラスを提供します。 Webサーバーに要求を送信するために使用される Zend \ Http \ Client クラスと共に使用されます。 クッキーは以下のコードに示すように初期化できます-

use Zend\Http\Cookies
$c = new Cookies();

HTTPクライアント(Zend \ Http \ Client)が最初にURI要求をWebサーバーに送信するとき、Cookieはありません。 Webサーバーがリクエストを受信すると、そのレスポンスオブジェクトにCookieが HTTPヘッダー、Set-Cookie として含まれ、HTTPクライアントに送信されます。 HTTPクライアントは、http応答からcookieを抽出し、後続の要求で同じHTTPヘッダーとして再送信します。 通常、各Cookieはドメインとドメインのパスにマップされます。

*Cookies* クラスで使用できるメソッドは次のとおりです-
  • * addCookie(uri)*-指定されたURIのリクエストオブジェクトにCookieを追加するために使用されます。
  • * getCookie(cookieName、$ cookieForm)-指定されたURI *_ $ uri_ で利用可能なcookie $ cookieNameを取得するために使用されます。 3番目の引数は、Cookieがどのように返されるか(文字列または配列)です。
  • * fromResponse(uri)*-指定されたURIの応答オブジェクトからCookieを抽出するために使用されます。
  • addCookiesFromResponse -fromResponseと同じですが、指定されたURIのリクエストオブジェクトに抽出して再度追加します。
  • * isEmpty()-指定された *Cookie オブジェクトにCookieがあるかどうかを確認するために使用されます。
  • * reset()*-指定されたURIのすべてのCookieをクリアするために使用されます。

次の章では、Zend Frameworkでのセッション管理について説明します。

Zend Framework-セッション管理

セッションは、Webアプリケーションで非常に重要な概念です。 ユーザーのデータを限られた期間ウェブサーバーに保存するオプションを提供します。 Zendフレームワークは、セッション情報を処理するための別個のコンポーネント zend-session を提供します。

セッションコンポーネントをインストールする

セッションコンポーネントは、以下に指定されている Composer を使用してインストールできます-

composer require zendframework/zend-session

セッションコンポーネント

Zendフレームワークは、セッション管理を処理する6つのコンポーネントを提供します。 これらのコンポーネントはすべて以下で説明されています-

  • Zend \ Session \ Container -セッション情報を読み書きするメインAPI。
  • Zend \ Session \ SessionManager -セッションのライフサイクル全体を管理するために使用されます。
  • Zend \ Session \ Storage -これは、セッションデータをメモリに保存する方法を指定するために使用されます。
  • Zend \ Session \ SaveHandler -RDBMS、Redis、MangoDBなどの物理的な場所にセッションデータを保存および取得するために使用されます。
  • Zend \ Session \ Validator -これは、初期および後続のリクエストのリモートアドレスとユーザーエージェントをクロスチェックすることにより、ハイジャックからセッションを保護するために使用されます。
  • Zend \ Session \ Config \ SessionConfig -セッションの動作を設定するために使用されます。

デフォルトの構成は、セッションで動作するのに十分です。 上記のコンポーネントを使用すると、セッションのすべての側面を簡単に処理できます。

セッションコンポーネントの例

Zendフレームワークのセッションを理解するための新しいページを作成するために、次の点を順守しましょう。 デフォルトでは、セッションを管理するには Container クラスのインスタンスを作成するだけで十分です。

  • TutorialControllersessionAction という新しいアクションを作成します。
  • Container オブジェクトを初期化します。
$c = new Container();
  • 任意のキー count が存在するかどうかを確認します。 キーが利用できない場合、値1で count を初期化します。 使用可能な場合は、次のコードに示すように値を増やします。
if (!isset($c->count)) {
   $c->count = 0;
} else {
   $c->count++;
}
  • ViewModelにカウントを登録します。

  • myapp/module/Tutorial/view/tutorial/tutorial/session.phtmlにsessionAction、session.phtmlのテンプレートファイルを作成し、 count 値をレンダリングします。

  • ページを更新すると、セッションの count の値が増加します。 完全なリストは次のとおりです-

    *TutorialController.php*
public function sessionAction() {
   $c = new Container();
   if (!isset($c->count)) {
      $c->count = 0;
   } else {
      $c->count++;
   }
   $view = new ViewModel([
      'count' => $c->count,
   ]);
   return $view;
}
*session.pthml*
Session data, COUNT = <?= $this->count ?>

サンプル結果

Session data, Count = 5

Zend Framework-認証

認証は、すべてのWebアプリケーションで最も重要な必須機能の1つです。 Zend Frameworkは、 zend-authentication と呼ばれる認証を処理する別個のコンポーネントを提供します。

認証コンポーネントをインストールする

認証コンポーネントは、次の Composer コマンドを使用してインストールできます。

composer require zendframework/zend-authentication

概念

通常、開発者はphp関数を作成して、データソースに対してユーザーの詳細を認証します。 認証が完了すると、認証の詳細は後続のリクエストのために保持されます。 Zend Frameworkはこの概念を一般化し、以下で説明する2つのクラスを提供します-

クラス1 Zend \ Authentication \ Adaptor \ AdaptorInterface

このクラスは、認証ロジックを記述する単一のメソッド authenticate を提供します。 authenticateメソッドは、 Zend \ Authentication \ Result クラスのインスタンスを返します。

この Result オブジェクトは認証ステータスを保持します。認証が成功した場合はID、認証が失敗した場合はエラーメッセージ。 認証インターフェイスと結果クラスの署名は次のとおりです-

*AdaptorInterface*
namespace Zend\Authentication\Adaptor;
public function authenticate() {
  //code
}
  • 結果クラス *
namespace Zend\Authentication;
class Result {
   public function __construct($code, $identity, array $messages = []);
}

Zend Frameworkは、データベース、ldap、http Basic、およびダイジェスト認証情報に対して認証するデフォルトの実装を提供します。* Adaptor *は認証を行いますが、今後のリクエストの詳細は保持しません。

クラス2 Zend \ Authentication \ AuthenticationService

AuthenticationServiceは主要コンポーネントであり、認証目的ですでに構成されたアダプターを使用します。 認証が完了すると、認証の詳細が保持され、メソッドが提供されます。* hasIdentity()はIDが利用可能かどうかを確認し、 getIdentity()は認証の詳細を取得し、 clearIdentity()*は認証の詳細をクリアします。

このAuthenticationServiceを使用するための部分的なコードリストは次のとおりです-

$adap = new Adapter($username, $password);
$auth = new AuthenticationService();
$result = $auth->authenticate($adap);
if($result->isValid) {
   $identity = $auth->getIdentity();
} else {
  //process $result->getMessages()
}
//clear
$auth->clearIdentity();

認可に関連するものは、 zend-permissions-acl および zend-permissions-rbac の2つの別個のモジュールとしてパッケージ化されています。 zend-permissions-aclはアクセス制御リストに基づいており、zend-permissions-rbacはロールベースのアクセス制御リストに基づいています。 ACLおよびRBACの概念の高レベルの抽象化を提供し、エンタープライズグレードアプリケーションの作成を支援します。

Zend Framework-メール管理

Zend Frameworkは、電子メールメッセージを送信するために zend-mail と呼ばれる別のコンポーネントを提供します。 zend-mailコンポーネントには、テキスト形式とhtml形式の両方の添付ファイル付きの電子メールメッセージを読み書きするオプションもあります。 Zendでのメールの送信は、設定がはるかに簡単で簡単です。

この章では、電子メールの概念、基本設定、SMTPトランスポートなどの詳細設定について説明します。

メールコンポーネントのインストール

メールコンポーネントは、次のComposerコマンドを使用してインストールできます。

composer require zendframework/zend-mail

基本的なメール設定

基本的な電子メールは、1人以上の受信者、件名、本文、および送信者で構成されます。 Zendには、新しいメールメッセージを作成するための Zend \ Mail \ Message クラスが用意されています。 zend-mail を使用して電子メールを送信するには、少なくとも1人の受信者とメッセージ本文を指定する必要があります。

新しいメールメッセージを作成するための部分的なコードは次のとおりです-

use Zend\Mail;
$mail = new Mail\Message();
$mail->setSubject('Zend email sample');
$mail->setBody('This is content of the mail message');
$mail->setFrom('[email protected]', "sender-name");
$mail->addTo('[email protected]', "recipient-name");

Zendは、メールメッセージを送信するためのZend \ Mail \ Sendmailクラスを提供します。 Sendmail はphpのネイティブメール機能 mail を使用してメールメッセージを送信し、php構成ファイルを使用してトランスポート層を構成できます。

Sendmailを使用した部分的なコーディングは次のとおりです-

$transport = new Mail\Transport\Sendmail();
$transport->send($mail);
*zend-mail* は多くのトランスポート層を提供し、それぞれがユーザー名、パスワードなどの多くの追加パラメーターを必要とする場合があります

メール管理方法

注目すべき電子メール管理方法のいくつかは次のとおりです-

  • isValid -「差出人」アドレスのないメッセージは無効です。
isValid() : bool
  • setEncoding -メッセージのエンコードを設定します。
setEncoding(string $encoding) : void
  • getEncoding -メッセージのエンコードを取得します。
getEncoding() : string
  • setHeaders -ヘッダーを作成します。
setHeaders(Zend\Mail\Headers $headers) : void
  • getHeaders -ヘッダーコレクションにアクセスします。
getHeaders() : Zend\Mail\Headers
  • setFrom -送信元アドレスを設定(上書き)します。 キーは人間が読める名前で、値は電子メールアドレスです。
setFrom(
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList,
      string|null $name
) : void
  • addFrom -「差出人」アドレスを追加します。
addFrom(
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressOrList,
      string|null $name
) : void
  • getFrom -「差出人」送信者のリストを取得します。
getFrom() : AddressList
setTo - Overwrite the address list in the To recipients.
setTo(
   string|AddressInterface|array|AddressList|Traversable $emailOrAddressList,
      null|string $name
) : void
  • setSubject -メッセージの件名ヘッダー値を設定します。
setSubject(string $subject) :void
  • setBody -メッセージ本文を設定します。
setBody(null|string|Zend\Mime\Message|object $body) : void

SMTPトランスポート層

*zend-mail* は、 *Zend \ Mail \ Transport \ Smtpclass* を介してSMTPサーバーを使用して電子メールを送信するオプションを提供します。 SMTPホスト、ポート、ユーザー名、パスワードなどを構成するいくつかの追加オプションがあることを除いて、 *Sendmail* に似ています。

部分的なコードは次のとおりです-

use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;
$transport = new SmtpTransport();
$options = new SmtpOptions([
   'name' => 'localhost',
   'host' =>'smtp.gmail.com',
   'port' => 465,
]);
$transport->setOptions($options);

ここに、

  • name -SMTPホストの名前。
  • host -リモートホスト名またはIPアドレス。
  • port -リモートホストがリッスンしているポート。

メールの概念-例

次の点に従って、メールの概念を理解するための簡単なphpコンソールアプリケーションを作成しましょう。

  • フォルダ「mailapp」を作成します。
  • composerツールを使用して zend-mail をインストールします。
  • 「mailapp」フォルダー内にphpファイル Mail.php を作成します。
  • Zend \ Mail \ Message を使用してメッセージを作成します。
$message = new Message();
$message->addTo('[email protected]');
$message->addFrom('[email protected]');
$message->setSubject('Hello!');
$message->setBody("My first Zend-mail application!");
  • SMTPトランスポート層を作成し、必要な構成を追加します。
//Setup SMTP transport using LOGIN authentication
$transport = new SmtpTransport();
$options = new SmtpOptions([
   'name' => 'localhost',
   'host' => 'smtp.gmail.com',//or any SMTP server
   'port' => 465,//port on which the SMTP server is listening
   'connection_class' => 'login',
   'connection_config' => [
      username' => '<your username>', 'password' => '<your password>',
      'ssl' => 'ssl'],
]);
$transport->setOptions($options);
  • send メソッドを使用してメールを送信します。
$transport->send($message);

完全なリスト、_Mail.php_は次のとおりです-

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

use Zend\Mail\Message;
use Zend\Mail\Transport\Smtp as SmtpTransport;
use Zend\Mail\Transport\SmtpOptions;

$message = new Message();
$message->addTo('[email protected]');
$message->addFrom('[email protected]');
$message->setSubject('Hello!');
$message->setBody("My first Zend-mail application!");

//Setup SMTP transport using LOGIN authentication
$transport = new SmtpTransport();
$options = new SmtpOptions([
   'name' => 'localhost',
   'host' => 'smtp.gmail.com',//or any SMTP server
   'port' => 465,//port on which the SMTP server is listening
   'connection_class' => 'login',
   'connection_config' => [
      'username' => '<your username>', 'password' => '<your password>',
      'ssl' => 'ssl'],
]);
$transport->setOptions($options);
$transport->send($message);

ここで、コマンドプロンプト php Mail.php でアプリケーションを実行します。 これにより、アプリケーションで構成されたとおりにメールが送信されます。

Zend Framework-ユニットテスト

一般に、高度なデバッガツール*を使用するか、 *echodie などの単純なコマンドを使用して、PHPアプリケーションをデバッグできます。 Webシナリオでは、プレゼンテーション層だけでなくビジネスロジックもテストする必要があります。 Webアプリケーションのフォームは、関連するテストデータを入力して、フォームが期待どおりに機能することを確認することでテストできます。

Webサイトのデザインは、ブラウザーを使用して手動でテストできます。 これらのタイプのテストプロセスは、単体テストを使用して自動化できます。 大規模プロジェクトでは、単体テストが不可欠です。 これらの単体テストは、テストプロセスを自動化し、何か問題が発生したときに開発者に警告するのに役立ちます。

PHPUnitのセットアップ

Zendフレームワークは、PHPUnitユニットテストフレームワークと統合されます。 Zendフレームワークの単体テストを作成するには、次のComposerコマンドを使用して簡単に実行できるPHPUnitをセットアップする必要があります。

$ composer require --dev phpunit/phpunit

上記のコマンドを実行すると、次のコードブロックに示すように応答が返されます。

Using version ^5.7 for phpunit/phpunit
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files

さて、「composer.json」ファイルを開くと、次の変更が表示されます-

"require-dev": {
   "phpunit/phpunit": "^5.7"
}

テストケースとアサーション

Zendフレームワークは、コントローラーを単体テストするためのヘルパークラスを提供します。 TestCase は、テストケースを記述する PHPUnit フレームワークの主要コンポーネントであり、Zend Frameworkは AbstractHttpControllerTestCase として呼び出されるTestCaseの抽象的な実装を提供します。

このAbstractHttpControllerTestCaseはさまざまな Assert メソッドを提供し、機能ごとにグループ化できます。 彼らは次のとおりです-

  • リクエストアサーション-HTTPリクエストをアサートするために使用されます。 たとえば、assertControllerName。
  • CSS Select Assertions -HTML DOMモデルを使用して応答HTMLを確認するために使用されます。
  • * XPathアサーション*-CSSの代替は、XPathに基づいてアサーションを選択します。
  • リダイレクトアサーション-ページのリダイレクトを確認するために使用されます。
  • 応答ヘッダーアサーション-ステータスコード(assertResponseStatusCode)などの応答ヘッダーの確認に使用

テストディレクトリを作成する

ユニットテストは、モジュールごとに個別に作成できます。 すべてのテスト関連のコーディングは、モジュールのルートディレクトリの下にある test フォルダー内に作成する必要があります。

たとえば、Tutorialモジュールで使用可能なTutorialControllerのテストを作成するには、テストクラスをmyapp/module/Tutorial/test/Controller/ディレクトリに配置する必要があります。

*TutorialController* を単体テストするためのテストクラスを作成しましょう。

まず、TutorialControllerTestというクラスを作成し、AbstractHttpControllerTestCaseに拡張する必要があります。

次のステップは、テスト環境をセットアップする Setup メソッドを記述することです。 これは、 setApplicationConfig メソッドを呼び出して、メインアプリケーション構成ファイルmyapp/config/application.config.phpを渡すことで実行できます。

public function setUp() {
   $configOverrides = [];
   $this->setApplicationConfig(ArrayUtils::merge(
      include __DIR__ . '/../../../../config/application.config.php',
         $configOverrides
   ));
   parent::setUp();
}

1つ以上のメソッドを記述し、要件に応じてさまざまなアサートメソッドを呼び出します。

 $this->assertMatchedRouteName('tutorial');

私たちはテストクラスを書いており、完全なリストは次のとおりです-

<?php
namespace TutorialTest\Controller;
use Tutorial\Controller\TutorialController;
use Zend\Stdlib\ArrayUtils;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;

class TutorialControllerTest extends AbstractHttpControllerTestCase {
   public function setUp() {
      $configOverrides = [];
      $this->setApplicationConfig(ArrayUtils::merge(
         include __DIR__ . '/../../../../config/application.config.php',
            $configOverrides
      ));
      parent::setUp();
   }
   public function testIndexActionCanBeAccessed() {
      $this->dispatch('/tutorial', 'GET');
      $this->assertResponseStatusCode(200);
      $this->assertModuleName('tutorial');
      $this->assertControllerName(TutorialController::class);
      $this->assertControllerClass('TutorialController');
      $this->assertMatchedRouteName('tutorial');
   }
}

ここで、コマンドプロンプトを開き、アプリケーションのルートディレクトリに移動して、 vendor フォルダー内にある phpunit 実行可能ファイルを実行します。

cd/path/to/app
./vendor/bin/phpunit ./vendor/bin/phpunit module/
   Tutorial/test/Controller/TutorialControllerTest.php

結果は、次のコードブロックに示すようになります-

PHPUnit 5.7.5 by Sebastian Bergmann and contributors.
.1/1 (100%)
Time: 96 ms, Memory: 8.00MB
OK (1 test, 5 assertions)

Zend Framework-エラー処理

システムの円滑な実行のためには、システムの障害を効果的に処理する必要があります。 Zend Frameworkには、発生したエラーを印刷して記録する default error trapping が付属しています。 この同じエラーハンドラを使用して、*例外*をキャッチします。

エラーハンドラーは、デバッグがtrueの場合にエラーを表示し、デバッグがfalseの場合にエラーを記録します。 Zend Frameworkにはいくつかの例外クラスがあり、組み込みの例外処理により、キャッチされなかった例外をキャプチャし、有用なページをレンダリングします。

デフォルトのエラー処理

アプリケーション構成ファイルmyapp/module/Application/config/module.config.phpでデフォルトのエラー設定を構成できます。

部分的なコードのサンプルは次のとおりです-

'view_manager' => [
   'display_not_found_reason' => true,
   'display_exceptions'       => true,
   'doctype'                  => 'HTML5',
   'not_found_template'       => 'error/404',
   'exception_template'       => 'error/index',
   'template_map' => [
      'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
      'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
      'error/404'               => __DIR__ . '/../view/error/404.phtml',
      'error/index'             => __DIR__ . '/../view/error/index.phtml',
   ],
   'template_path_stack' => [
      __DIR__ . '/../view',
   ],
],

ここで、display_exception、not_found_template、exception_template、error/404およびerror/indexは、エラーに関連する構成アイテムであり、一目瞭然です。

これらの中で最も重要な項目は*エラー/インデックス*です。 これは、システムで例外が発生したときに表示されるテンプレートです。 このテンプレートmyapp/module/Application/view/error/index.phtmlを変更して、表示するエラーの量を制御できます。

Zend Framework-動作例

この章では、Zend FrameworkでMVCベースの完全な従業員アプリケーションを作成する方法を学びます。 以下の手順に従ってください。

ステップ1:Module.php

まず、myapp/module/Employee/src/ディレクトリ内にEmployeeモジュールを作成してから、ConfigProviderInterfaceインターフェイスを実装する必要があります。

Moduleクラスの完全なコードは次のとおりです-

<?php
namespace Employee;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module implements ConfigProviderInterface {
   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
}

ステップ2:composer.json

次のコードを使用して、autoloadセクションの composer.jsonTutorial モジュールを構成します。

"autoload": {
   "psr-4": {
      "Application\\": "module/Application/src/",
      "Tutorial\\": "module/Tutorial/src/",
      "Employee\\": "module/Employee/src/"
   }
}

次に、composer updateコマンドを使用してアプリケーションを更新します。

composer update

Composerコマンドは、アプリケーションに必要な変更を行い、以下のコマンドプロンプトに表示されるようにログを表示します。

Loading composer repositories with package information
Updating dependencies (including require-dev)
   - Removing zendframework/zend-component-installer (0.3.0)
   - Installing zendframework/zend-component-installer (0.3.1)
   Downloading: 100%

   - Removing zendframework/zend-stdlib (3.0.1)
   - Installing zendframework/zend-stdlib (3.1.0)
   Loading from cache

   - Removing zendframework/zend-eventmanager (3.0.1)
   - Installing zendframework/zend-eventmanager (3.1.0)
   Downloading: 100%

   - Removing zendframework/zend-view (2.8.0)
   - Installing zendframework/zend-view (2.8.1)
   Loading from cache

   - Removing zendframework/zend-servicemanager (3.1.0)
   - Installing zendframework/zend-servicemanager (3.2.0)
   Downloading: 100%

   - Removing zendframework/zend-escaper (2.5.1)
   - Installing zendframework/zend-escaper (2.5.2)
   Loading from cache

   - Removing zendframework/zend-http (2.5.4)
   - Installing zendframework/zend-http (2.5.5)
   Loading from cache

   - Removing zendframework/zend-mvc (3.0.1)
   - Installing zendframework/zend-mvc (3.0.4)
   Downloading: 100%

   - Removing phpunit/phpunit (5.7.4)
   - Installing phpunit/phpunit (5.7.5)
   Downloading: 100%

Writing lock file
Generating autoload files

ステップ3:従業員モジュールのmodule.config.php

次のコードを使用して、myapp/module/Employee/configの下にモジュール構成ファイル「module.config.php」を作成します。

<?php
namespace Employee;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
   'controllers' => [
      'factories' => [
         Controller\EmployeeController::class => InvokableFactory::class,
      ],
   ],
   'view_manager' => [
      'template_path_stack' => ['employee' => __DIR__ . '/../view',],
   ],
];

次に、アプリケーションレベルの構成ファイルmyapp/config/modules.config.phpでEmployeeモジュールを構成します。

return ['Zend\Router', 'Zend\Validator', 'Application', 'Tutorial', 'Employee'];

ステップ4:EmployeeController

AbstractActionControllerを拡張して新しいPHPクラスEmployeeControllerを作成し、myapp/module/Employee/src/Controllerディレクトリに配置します。

完全なコードリストは次のとおりです-

<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class EmployeeController extends AbstractActionController {
   public function indexAction() {
      return new ViewModel();
   }
}

ステップ5:ルーターの構成

Employeeモジュールにセグメントルートを追加しましょう。 myapp/module/Employee/configにある従業員モジュール構成ファイルmodule.config.phpを更新します。

<?php
namespace Employee;
use Zend\ServiceManager\Factory\InvokableFactory;
use Zend\Router\Http\Segment;
return [
   'controllers' => [
      'factories' => [
         Controller\EmployeeController::class => InvokableFactory::class,
      ],
   ],
   'router' => [
      'routes' => [
         'employee' => [
            'type' => Segment::class,
            'options' => [
               'route' => '/employee[/:action[/:id]]',
               'constraints' => [
                  'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                  'id' => '[0-9]+',
               ],
               'defaults' => [
                  'controller' => Controller\EmployeeController::class,
                  'action' => 'index',
               ],
            ],
         ],
      ],
   ],
   'view_manager' => [
      'template_path_stack' => [
         'employee' => __DIR__ . '/../view',
      ],
   ],
];

Employeeモジュールのルーティングを追加しました。 次のステップは、Employeeアプリケーションのビュースクリプトを作成することです。

ステップ6:ViewModelを作成する

myapp/module/Employee/view/employee/employeeディレクトリの下に「index.phtml」というファイルを作成します。

ファイルに次の変更を追加します-

<div class = "row content">
   <h3>This is my first Zend application</h3>
</div>
Move to “EmployeeController.php” file and edit the following changes,

<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class EmployeeController extends AbstractActionController {
   public function indexAction() {
      return new ViewModel();
   }
}

最後に、Employeeモジュールが正常に完了しました。 次のURLを使用してアクセスできます- http://localhost:8080/employee

結果

アプリケーションテンプレート

次のステップでは、従業員アプリケーションで*追加、編集*および*削除*データ操作を実行します。 これらの操作を実行するには、最初にデータベースモデルを作成する必要があります。 次のステップで説明します。

ステップ7:モデルを作成する

モジュール* srcディレクトリ*にモデルEmployeeを作成しましょう。 通常、モデルはModelフォルダー(myapp/module/Employee/src/Model/Employee.php)の下にグループ化されます

<?php
namespace Employee\Model;
class Employee {
   public $id;
   public $emp_name;
   public $emp_job;
}

ステップ8:MySQLテーブル

次のコマンドを使用して、ローカルMYSQLサーバーに tutorials という名前のデータベースを作成します-

create database tutorials;

次のSQLコマンドを使用して、データベースに employee という名前のテーブルを作成しましょう-

use tutorials;
CREATE TABLE employee (
   id int(11) NOT NULL auto_increment,
   emp_name varchar(100) NOT NULL,
   emp_job varchar(100) NOT NULL,
   PRIMARY KEY (id)
);

次のクエリを使用して employee テーブルにデータを挿入します-

INSERT INTO employee (emp_name, emp_job) VALUES ('Adam',  'Tutor');
INSERT INTO employee (emp_name, emp_job) VALUES ('Bruce',  'Programmer');
INSERT INTO employee (emp_name, emp_job) VALUES ('David',  'Designer');

ステップ9:データベース構成の更新

グローバル構成ファイルmyapp/config/autoload/global.phpを必要なデータベースドライブ情報で更新します。

return [
   'db' => [
      'driver' => 'Pdo',
      'dsn' => 'mysql:dbname = tutorials;host=localhost',
      'driver_options' => [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''],
   ],
];

次に、ローカル構成ファイル(myapp/config/autoload/local.php)のデータベース資格情報を更新します。 このようにして、ローカルとライブのデータベース接続資格情報を分離できます。

<?php
return array(
   'db' => array('username' => '<user_name>', 'password' => '<password>',),
);

ステップ10:exchangeArrayを実装する

EmployeeモデルにexchangeArray関数を実装します。

<?php
namespace Employee\Model;
class Employee {
   public $id;
   public $emp_name;
   public $emp_job;
   public function exchangeArray($data) {
      $this->id = (!empty($data['id'])) ? $data['id'] : null;
      $this->emp_name = (!empty($data['emp_name'])) ? $data['emp_name'] : null;
      $this->emp_job = (!empty($data['emp_job'])) ? $data['emp_job'] : null;
   }
}

ステップ11:TableGatewayを使用して従業員データを取得する

Modelフォルダー自体にEmployeeTableクラスを作成します。 次のコードブロックで定義されています。

<?php
namespace Employee\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class EmployeeTable {
   protected $tableGateway;
   public function __construct(TableGatewayInterface $tableGateway) {
      $this->tableGateway = $tableGateway;
   }
   public function fetchAll() {
      $resultSet = $this->tableGateway->select();
      return $resultSet;
   }
}

ステップ12:EmployeeTableクラスを構成する

_getServiceConfig()_メソッドを使用して_Module.php_の従業員サービスを更新する

<?php
namespace Employee;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ConfigProviderInterface;

class Module implements ConfigProviderInterface {
   public function getConfig() {
      return include __DIR__ . '/../config/module.config.php';
   }
   public function getServiceConfig() {
      return [
         'factories' => [
            Model\EmployeeTable::class => function (    $container) {
               $tableGateway = $container>get( Model\EmployeeTableGateway::class);
               $table = new Model\EmployeeTable($tableGateway);
               return $table;
            },
            Model\EmployeeTableGateway::class => function ($container) {
               $dbAdapter = $container->get(AdapterInterface::class);
               $resultSetPrototype = new ResultSet();
               $resultSetPrototype->setArrayObjectPrototype(new Model\Employee());
               return new TableGateway('employee', $dbAdapter, null, $resultSetPrototype);
            },
         ],
      ];
   }
}

ステップ13:コントローラーに従業員サービスを追加する

以下に示すように、myapp/module/config/module.config.phpのEmployee Module Configurationのコントローラーセクションを更新します。

'controllers' => [
   'factories' => [
      Controller\EmployeeController::class => function($container) {
         return new Controller\EmployeeController(
            $container->get(Model\EmployeeTable::class)
         );
      },
   ],
]

ステップ14:EmployeeControllerのコンストラクターを追加する

引数として EmployeeTable を使用してコンストラクターを追加し、次の変更を編集します。

<?php
namespace Employee\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Employee\Model\Employee;
use Employee\Model\EmployeeTable;

class EmployeeController extends AbstractActionController {
   private $table;
   public function __construct(EmployeeTable $table) {
      $this->table = $table;
   }
   public function indexAction() {
      $view = new ViewModel([
         'data' => $this->table->fetchAll(),
      ]);
      return $view;
   }
}

ステップ15:ビュースクリプト「index.phtml」で従業員情報を表示する

ファイルに移動します- index.phtml および次の変更を行います-

<?php
$title = 'Employee application';
$this->headTitle($title);
?>

<table class="table">
   <tr>
      <th>Employee Name</th>
      <th>Employee Job</th>
      <th>Edit/Delete operations</th>
   </tr>
   <?php foreach ($data as $empdata) : ?>
   <tr>
      <td><?php echo $this->escapeHtml($empdata->emp_name);?></td>
      <td><?php echo $this->escapeHtml($empdata->emp_job);?></td>
      <td>
         <a href="<?php echo $this->url('employee',
            array('action'=>'edit', 'id' =>$empdata->id));?>">Edit</a>
         <a href="<?php echo $this->url('employee',
            array('action'=>'delete', 'id' => $empdata->id));?>">Delete</a>
      </td>
   </tr>
   <?php endforeach; ?>
</table>

これでデータベースモデルが正常に作成され、アプリケーション内のレコードを取得できます。

url- http://localhost:8080/employee を使用してアプリケーションを要求します。

結果

成功したデータベース

次のステップでは、従業員モジュールでの*挿入、編集*および*削除*データ操作について説明します。

ステップ16:従業員フォームを作成する

myapp/module/Employee/src/Formディレクトリに EmployeeForm.php というファイルを作成します。 以下のコードブロックで説明します。

<?php
namespace Employee\Form;
use Zend\Form\Form;

class EmployeeForm extends Form {
   public function __construct($name = null) {
     /
     /we want to ignore the name passed
      parent::__construct('employee');
      $this->add(array(
         'name' => 'id',
         'type' => 'Hidden',
      ));
      $this->add(array(
         'name' => 'emp_name',
         'type' => 'Text',
         'options' => array(
            'label' => 'Name',
         ),
      ));
      $this->add(array(
         'name' => 'emp_job',
         'type' => 'Text',
         'options' => array(
            'label' => 'Job',
         ),
      ));
      $this->add(array(
         'name' => 'submit',
         'type' => 'Submit',
         'attributes' => array(
            'value' => 'Go',
            'id' => 'submitbutton',
         ),
      ));
   }
}

ステップ17:従業員モデルを更新する

従業員モデルを更新し、InputFilterAwareInterfaceを実装します。 ディレクトリmyapp/module/Employee/src/Employee/Modelに移動し、 Employee.phpfile に次の変更を追加します。

<?php
namespace Employee\Model;

//Add these import statements
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;

class Employee implements InputFilterAwareInterface {
   public $id;
   public $emp_name;
   public $emp_job;
   protected $inputFilter;
   public function exchangeArray($data) {
      $this->id = (isset($data['id'])) ? $data['id'] : null;
      $this->emp_name = (isset($data['emp_name'])) ? $data['emp_name'] : null;
      $this->emp_job = (isset($data['emp_job']))  ? $data['emp_job'] : null;
   }

  //Add content to these methods:
   public function setInputFilter(InputFilterInterface $inputFilter) {
      throw new \Exception("Not used");
   }
   public function getInputFilter() {
      if (!$this->inputFilter) {
         $inputFilter = new InputFilter();
         $inputFilter->add(array(
            'name' => 'id',
            'required' => true,
            'filters' => array(
               array('name' => 'Int'),
            ),
         ));
         $inputFilter->add(array(
            'name' => 'emp_name',
            'required' => true,
            'filters' => array(
               array('name' => 'StripTags'),
               array('name' => 'StringTrim'),
            ),
            'validators' => array(
               array('name' => 'StringLength',
                        'options' => array(
                           'encoding' => 'UTF-8',
                           'min' => 1,
                           'max' => 50,
                        ),
                    ),
                ),
            ));
         $inputFilter->add(array(
            'name' => 'emp_job',
            'required' => true,
            'filters' => array(
               array('name' => 'StripTags'),
               array('name' => 'StringTrim'),
            ),
            'validators' => array(
               array('name' => 'StringLength',
                  'options' => array(
                     'encoding' => 'UTF-8',
                     'min' => 1,
                     'max' => 50,
                  ),
                  ),
               ),
         ));
         $this->inputFilter = $inputFilter;
      }
      return $this->inputFilter;
   }
}

ステップ18:Employee ControllerにaddActionを追加します

*EmployeeController* クラスに次の変更を追加します。
<?php
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Employee\Model\Employee;
use Employee\Model\EmployeeTable;
use Employee\Form\EmployeeForm;

public function addAction() {
   $form = new EmployeeForm();
   $form->get('submit')->setValue('Add');
   $request = $this->getRequest();

   if ($request->isPost()) {
      $employee = new Employee();
      $form->setInputFilter($employee->getInputFilter());
      $form->setData($request->getPost());

      if ($form->isValid()) {
         $employee->exchangeArray($form->getData());
         $this->table->saveEmployee($employee);

        //Redirect to list of employees
         return $this->redirect()->toRoute('employee');
      }
   }
   return array('form' => $form);
}

ステップ19:EmployeeTableクラスに保存機能を追加する

次の2つの関数をEmployeeTableクラスに追加します– myapp/module/Employee/src/Model/EmployeeTable.php

public function getEmployee($id) {
   $id  = (int) $id;
   $rowset = $this->tableGateway->select(array('id' => $id));
   $row = $rowset->current();
   if (!$row) {
      throw new \Exception("Could not find row $id");
   }
   return $row;
}
public function saveEmployee(Employee $employee) {
   $data = array (
      'emp_name' => $employee->emp_name,
      'emp_job'  => $employee->emp_job,
   );
   $id = (int) $employee->id;
   if ($id == 0) {
      $this->tableGateway->insert($data);
   } else {
      if ($this->getEmployee($id)) {
         $this->tableGateway->update($data, array('id' => $id));
      } else {
         throw new \Exception('Employee id does not exist');
      }
   }
}

ステップ20:AddActionメソッドのビュースクリプトAdd.phtmlを作成します

-myapp/module/view/employee/employeeの「Add.phtml」ファイルに次の変更を追加します。

<?php
   $title = 'Add new employee';
   $this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>

<?php
   $form->setAttribute('action', $this->url('employee', array('action' => 'add')));
   $form->prepare();
   echo $this->form()->openTag($form);
   echo $this->formHidden($form->get('id'));
   echo $this->formRow($form->get('emp_name'))."<br>";
   echo $this->formRow($form->get('emp_job'))."<br>";
   echo $this->formSubmit($form->get('submit'));
   echo $this->form()->closeTag();
Request the application using the url, http://localhost:8080/employee/add

結果

新入社員

データが追加されると、ホームページにリダイレクトされます。

リダイレクトホームページ

ステップ21:従業員レコードの編集

Employeeモジュールでデータ編集操作を実行しましょう。 Employeecontroller.php の以下の変更を更新します。

public function editAction() {
   $id = (int) $this->params()->fromRoute('id', 0);
   if (!$id) {
      return $this->redirect()->toRoute('employee', array(
         'action' => 'add'
      ));
   }
   try {
      $employee = $this->table->getEmployee($id);
   } catch (\Exception $ex) {
      return $this->redirect()->toRoute('employee', array(
         'action' => 'index'
      ));
   }
   $form = new EmployeeForm();
   $form->bind($employee);
   $form->get('submit')->setAttribute('value', 'Edit');
   $request = $this->getRequest();

   if ($request->isPost()) {
      $form->setInputFilter($employee->getInputFilter());
      $form->setData($request->getPost());
      if ($form->isValid()) {
         $this->table->saveEmployee($employee);

        //Redirect to list of employees
         return $this->redirect()->toRoute('employee');
      }
   }
   return array('id' => $id, 'form' => $form,);
}

ここでは、一致したルートにある id を探し、編集操作のために従業員の詳細をロードします。

ステップ22:Employee.php

ここで、「myapp/module/Employee/src/Employee/Model/」ディレクトリにある「Employee.php」ファイルに次の変更を追加します。

public function getArrayCopy() {
   return get_object_vars($this);
}

ここで、Zend \ Stdlib \ Hydrator \ ArraySerializableは、モデル内の2つのメソッド* getArrayCopy()および exchangeArray()*を見つけることを想定しています。

この場合、exchangeArray()が反復に使用されます。 この関数は、従業員テーブルのデータをバインドするために使用されます。

次に、* editAction()*のビュースクリプトを作成する必要があります。

ステップ23:Edit.phtmlを作成する

module/Employee/view/employee/employee/edit.phtmlにビュースクリプトファイルを作成します。

<?php
   $title = 'Edit employee records';
   $this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>

<?php
$form = $this->form;
$form->setAttribute('action', $this->url(
   'employee',
   array('action' => 'edit', 'id' => $this->id,)
));
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('emp_name'))."<br>";
echo $this->formRow($form->get('emp_job'))."<br>";
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();

次のスクリーンショットに、従業員の詳細の編集を示します。

レコードの編集

データが編集されると、ホームページにリダイレクトされます。

編集済みデータ

ステップ24:deleteEmployeeメソッドを追加する

deleteEmployeeメソッドをEmployeeTableクラスに追加します– myapp/module/Employee/src/Model/EmployeeTable.php

public function deleteEmployee($id) {
   $this->tableGateway->delete(['id' => (int) $id]);
}

ステップ25:従業員レコードを削除する

Employeeモジュールでデータの削除操作を実行してみましょう。 次のメソッド deleteAction をEmployeeControllerクラスに追加します。

public function deleteAction() {
   $id = (int) $this->params()->fromRoute('id', 0);
   if (!$id) {
      return $this->redirect()->toRoute('employee');
   }
   $request = $this->getRequest();
   if ($request->isPost()) {
      $del = $request->getPost('del', 'No');
      if ($del == 'Yes') {
         $id = (int) $request->getPost('id');
         $this->table->deleteEmployee($id);
      }
      return $this->redirect()->toRoute('employee');
   }
   return array(
      'id' => $id,
      'employee' => $this->table->getEmployee($id)
   );
}

ここで、deleteEmployee()メソッドは id で従業員を削除し、従業員リストページ(ホームページ)にリダイレクトします。

deleteAction()メソッドに対応するビュースクリプトを作成しましょう。

ステップ26:ビュースクリプトを作成する

-_myapp/module/Employee/view/employee/employee/delete.phtml_にdelete.phtmlという名前のファイルを作成し、次のコードを追加します。

<?php
   $title = 'Delete an employee record';
   $this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>

'<?php echo $this->escapeHtml($employee->emp_name); ?>' by
'<?php echo $this->escapeHtml($employee->emp_job); ?&'?
<?php
   $url = $this->url('employee', array('action' => 'delete', 'id' => $this->id,));
?>

<form action ="<?php echo $url; ?>" method = "post">
   <div>
      <input type = "hidden" name = "id" value = "<?php echo (int) $employee->id; ?>"/>
      <input type = "submit" name = "del" value = "Yes"/>
      <input type = "submit" name = "del" value = "No"/>
   </div>
</form>

ここで、ホームページの edit リンクを使用して従業員を削除すると、結果は次のスクリーンショットのようになります。

結果

削除されたレコード

必要なすべての機能を実装することにより、Employeeモジュールを正常に完了しました。

結論

現在の競争環境では、Zendフレームワークは開発者によって最上位に置かれています。 PHP言語のプログラムまたはアプリケーションの種類に抽象化を提供します。 成熟したフレームワークであり、最新のPHP言語機能をサポートしています。 楽しく、プロフェッショナルで、進化し、現在のテクノロジーに歩調を合わせています。