Symfony-quick-guide
symfony-はじめに
PHP Webフレームワークは、Webアプリケーションの開発に役立つクラスのコレクションです。 Symfonyは、最新のWebアプリケーションを迅速に開発するためのオープンソースのMVCフレームワークです。 symfonyはフルスタックのWebフレームワークです。 再利用可能なPHPコンポーネントのセットが含まれています。 フレームワークから独立して、アプリケーションでSymfonyコンポーネントを使用できます。
symfonyには膨大な量の機能と活発なコミュニティがあります。 YAML、XML、または注釈を使用した柔軟な構成があります。 symfonyは、独立したライブラリとPHPユニットと統合します。 symfonyは主にRuby on Rails、Django、SpringのWebアプリケーションフレームワークに触発されています。 Symfonyコンポーネントは、Composer、Drupal、phpBBなどの多くのオープンソースプロジェクトで使用されています。
Symfonyフレームワークは、HTTPを理解し、他のコンポーネントで使用される素晴らしいリクエストおよびレスポンスオブジェクトを提供するHttpFoundationコンポーネントなど、いくつかのコンポーネントで構成されています。 その他は、データの検証に役立つValidatorなどの単なるヘルパーコンポーネントです。 カーネルコンポーネントはシステムの中核です。 カーネルは基本的に、環境を管理する「メインクラス」であり、httpリクエストを処理する責任があります。
Symfonyのよく組織された構造、きれいなコード、優れたプログラミングプラクティスにより、Web開発が容易になります。 symfonyは非常に柔軟で、マイクロサイトを構築し、数十億の接続を持つエンタープライズアプリケーションを処理するために使用されます。
Symfonyフレームワーク-機能
symfonyはWebアプリケーションの開発を最適化するように設計されており、リリースごとに機能が増えます。
Symfony Frameworkの顕著な特徴のいくつかは次のとおりです-
- Model-View-Controllerベースのシステム
- 高性能PHPフレームワーク
- 柔軟なURIルーティング
- 再利用可能なコードと保守が容易なコード
- セッション管理
- エラーログ
- いくつかのプラットフォームをサポートするフル機能のデータベースクラス
- 巨大で活発なコミュニティをサポート
- 分離され再利用可能なコンポーネントのセット
- アプリケーションの標準化と相互運用性
- クロスサイトリクエストフォージェリおよびその他の攻撃に対するセキュリティ
- Twigテンプレートエンジン
symfonyは開発者に多くの柔軟性を提供します。 デバッグ、コードの読みやすさ、拡張可能なプログラムの開発に優れた機能を備えています。
symfonyはフルスタックのWebフレームワークです。 Webアプリケーションを作成するための非常に効果的なツールです。 多くの企業がSymfonyサービスをクライアントに提供しています。
以下は、Symfony Frameworkを使用することで得られる利点の一部です。
- マイクロフレームワーク-Symfonyを使用して特定の機能を開発できます。 フレームワーク全体を再開発またはインストールする必要はありません。
- 開発時間のオーバーヘッドを削減します。
- 非常に成熟したテンプレートエンジンで、ユーザーにコンテンツをすばやく配信します。
- 互換性と拡張性-プログラマはすべてのフレームワーククラスを簡単に拡張できます。
Symfonyフレームワーク-アプリケーション
Symfonyコンポーネントは、Drupal、Laravel、phpBB、Behat、Doctrine、Joomlaなどの他のアプリケーションの一部として使用できます。
- Drupal 8 -Drupalは、オープンソースのコンテンツ管理PHPフレームワークです。 Drupal 8はSymfonyのコアレイヤーを使用し、それを拡張してDrupalモジュールのサポートを提供します。
- Thelia -TheliaはSymfonyベースのeコマースソリューションです。 当初、TheliaはPHPコードとMySQLで記述されていましたが、より高速なアプリケーションを作成するには遅れていました。 この欠点を克服するために、TheliaはSymfonyと統合して、カスタマイズ可能な方法でアプリケーションを開発しました。
- Dailymotion -Dailymotionは、フランスに拠点を置く世界最大の独立系ビデオエンターテイメントWebサイトの1つです。 大規模なコミュニティでオープンソースフレームワークを移行することを決定した後、Dailymotion開発者は、柔軟性のためにSymfonyコンポーネント機能を使用することを決定しました。
Symfony-インストール
この章では、Symfonyフレームワークをマシンにインストールする方法について説明します。 symfonyフレームワークのインストールは非常にシンプルで簡単です。 Symfonyフレームワークでアプリケーションを作成するには2つの方法があります。 最初の方法は、Symfonyフレームワークでプロジェクトを作成するアプリケーションであるSymfony Installerを使用することです。 2番目の方法は、作曲家ベースのインストールです。 次のセクションで、各方法を1つずつ詳しく見ていきましょう。
システム要求
インストールに移行する前に、次のシステム要件が必要です。
- Webサーバー(次のいずれか)
- WAMP(Windows)
- LAMP(Linux)
- XAMP(マルチプラットフォーム)
- MAMP(Macintosh)
- Nginx(マルチプラットフォーム)
- Microsoft IIS(Windows)
- PHPビルトイン開発Webサーバー(マルチプラットフォーム)
- オペレーティングシステム:クロスプラットフォーム
- ブラウザサポート:IE(Internet Explorer 8以降)、Firefox、Google Chrome、Safari、Opera *PHPの互換性:PHP 5.4以降。 最大のメリットを得るには、最新バージョンを使用してください。
このチュートリアルでは、PHPの組み込み開発Webサーバーを使用します。
Symfonyインストーラー
Symfonyインストーラーは、SymfonyフレームワークでWebアプリケーションを作成するために使用されます。 次のコマンドを使用して、Symfonyインストーラーを構成しましょう。
$ sudo mkdir -p/usr/local/bin
$ sudo curl -LsS https://symfony.com/installer -o/usr/local/bin/symfony
$ sudo chmod a+x/usr/local/bin/symfony
これで、マシンにSymfonyインストーラーがインストールされました。
初めてのSymfonyアプリケーションを作成する
次の構文は、最新バージョンでSymfonyアプリケーションを作成するために使用されます。
構文
symfony new app_name
ここで、app_nameは新しいアプリケーション名です。 任意の名前を指定できます。
例
symfony new HelloWorld
上記のコマンドを実行すると、次の応答が表示されます。
Downloading Symfony...
0 B/5.5 MiB ░░░░░░░░░░░
……………………………………………………………
……………………………………………………………
Preparing project...
✔ Symfony 3.2.7 was successfully installed. Now you can:
* Change your current directory to/Users/../workspace/firstapp
*Configure your application in app/config/parameters.yml file.
* Run your application:
1. Execute the php bin/console server:run command.
2. Browse to the http://localhost:8000 URL.
*Read the documentation at http://symfony.com/doc
このコマンドは、Symfonyフレームワークの最新バージョンの空のプロジェクトを含む「firstapp/」という新しいディレクトリを作成します。
特定のバージョンをインストールする
特定のSymfonyバージョンをインストールする必要がある場合は、次のコマンドを使用します。
symfony new app_name 2.8
symfony new app_name 3.1
Composerベースのインストール
Composerを使用してSymfonyアプリケーションを作成できます。 うまくいけば、あなたのマシンに作曲家をインストールしました。 コンポーザーがインストールされていない場合は、ダウンロードしてインストールします。
次のコマンドは、コンポーザーを使用してプロジェクトを作成するために使用されます。
$ composer create-project symfony/framework-standard-edition app_name
特定のバージョンを指定する必要がある場合は、上記のコマンドで指定できます。
アプリケーションを実行する
プロジェクトディレクトリに移動し、次のコマンドを使用してアプリケーションを実行します。
cd HelloWorld
php bin/console server:run
上記のコマンドを実行した後、ブラウザーを開き、URL* http://localhost:8000/*を要求します。 次の結果が生成されます。
結果
Symfony-アーキテクチャ
symfonyは基本的に高品質のコンポーネントとバンドルのコレクションです。 コンポーネントは、単一のコア機能を提供するクラスのコレクションです。 たとえば、* Cacheコンポーネント*はキャッシュ機能を提供し、これを任意のアプリケーションに追加できます。 コンポーネントはSymfonyアプリケーションの構成要素です。 Symfonyには30以上の高品質コンポーネントがあり、Laravel、Silexなどの多くのPHPフレームワークで使用されています。
バンドルはプラグインに似ていますが、作成と使用が簡単です。 実際、Symfonyアプリケーションはそれ自体が他のバンドルで構成されるバンドルです。 単一のバンドルは、任意の数のSymfonyコンポーネントとサードパーティコンポーネントを使用して、Webframework、データベースアクセスなどの機能を提供できます。 symfonyのコアWebフレームワークはFrameworkBundleと呼ばれるバンドルであり、FrameworkExtraBundleと呼ばれるバンドルがあり、これはWebアプリケーションを記述するためのより洗練されたオプションを提供します。
コンポーネント、バンドル、およびSymfonyアプリケーション間の関係は、次の図で指定されています。
Webフレームワーク
symfonyは主に、比較的簡単に高品質のWebアプリケーションを作成するように設計されています。 単純なWebサイトから高度なRESTベースのWebサービスまで、さまざまなタイプのWebアプリケーションを作成するためのさまざまなオプションを提供します。 symfonyはWebフレームワークを個別のバンドルとして提供します。 Symfony Webフレームワークで使用される一般的なバンドルは次のとおりです-
- FrameworkBundle
- FrameworkExtraBundle *DoctrineBundle
symfony Webフレームワークは、Model-View-Controller(MVC)アーキテクチャに基づいています。* モデル*は、ビジネスエンティティの構造を表します。 表示*は、状況に応じて可能な限り最良の方法でモデルをユーザーに表示します。 *Controller はユーザーからのすべてのリクエストを処理し、Modelと対話することで実際の作業を行い、最終的にビューにユーザーに表示するために必要なデータを提供します。
symfonyのWebフレームワークは、エンタープライズグレードのアプリケーションに必要なすべての高レベル機能を提供します。 以下は、Symfony Webアプリケーションのシンプルなワークフローです。
ワークフローは、次の手順で構成されています。
- ステップ1 *-ユーザーは、ブラウザを介してアプリケーションにリクエストを送信します。
- ステップ2 *-ブラウザはWebサーバー、たとえばApache Webサーバーにリクエストを送信します。
- ステップ3 *-Webサーバーはリクエストを基になるPHPに転送し、次にPHPがSymfony Webフレームワークに送信します。
- ステップ4 *-HttpKernelはSymfony Webフレームワークのコアコンポーネントです。 HttpKernelは、ルーティングコンポーネントを使用して特定のリクエストのコントローラーを解決し、ターゲットコントローラーにリクエストを転送します。
- ステップ5 *-すべてのビジネスロジックはターゲットコントローラーで実行されます。
- ステップ6 *-コントローラーはModelと対話し、ModelはDoctrine ORMを介してDatasourceと対話します。
- ステップ7 *-コントローラーがプロセスを完了すると、コントローラー自体またはView Engineを介して応答を生成し、Webサーバーに送り返します。
- ステップ8 *-最後に、Webサーバーによって要求されたブラウザーに応答が送信されます。
symfony-コンポーネント
前述のように、SymfonyコンポーネントはスタンドアロンのPHPライブラリであり、特定の機能を提供します。これは、任意のPHPアプリケーションで使用できます。 Symfonyのすべてのリリースで、有用な新しいコンポーネントが導入されています。 現在、Symfonyフレームワークには30以上の高品質コンポーネントがあります。 この章では、Symfonyコンポーネントの使用法について学びましょう。
Symfonyコンポーネントのインストール
symfonyコンポーネントはcomposerコマンドを使用して簡単にインストールできます。 次の汎用コマンドを使用して、Symfonyコンポーネントをインストールできます。
cd/path/to/project/dir
composer require symfony/<component_name>
簡単なphpアプリケーションを作成して、 Filesystem コンポーネントをインストールしてみましょう。
ステップ1 *-アプリケーションのフォルダー、 *filesystem-example を作成します
cd/path/to/dev/folder
mdkir filesystem-example
cd filesystem-example
- ステップ2 *-次のコマンドを使用して、ファイルシステムコンポーネントをインストールします。
composer require symfony/filesystem
ステップ3 *-ファイル *main.php を作成し、次のコードを入力します。
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
$fs = new Filesystem();
try {
$fs->mkdir('./sample-dir');
$fs->touch('./sample-dir/text.txt');
} catch (IOExceptionInterface $e) {
echo $e;
}
?>
最初の行は非常に重要で、Composerコマンドを使用してインストールされたすべてのコンポーネントから必要なすべてのクラスをロードします。 次の行では、Filesystemクラスを使用します。
ステップ4 *-次のコマンドを使用してアプリケーションを実行すると、新しいフォルダー *sample-dir とその下にファイル test.txt が作成されます。
php main.php
Symfonyコンポーネントの詳細
symfonyは、単純な機能(ファイルシステムなど)から高度な機能(イベント、コンテナーテクノロジー、依存性注入など)までのコンポーネントを提供します。 すべてのコンポーネントについて、次のセクションで1つずつお知らせください。
ファイルシステム
ファイルシステムコンポーネントは、ファイルの作成、フォルダーの作成、ファイルの存在など、ファイルとディレクトリに関連する基本的なシステムコマンドを提供します。 ファイルシステムコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/filesystem
ファインダ
Finderコンポーネントは、指定されたパスでファイルとディレクトリを見つけるための流れるようなクラスを提供します。 パス内のファイルを反復処理する簡単な方法を提供します。 Finderコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/finder
コンソール
コンソールコンポーネントは、ターミナルで実行できるコマンドを簡単に作成するためのさまざまなオプションを提供します。 symfonyは Command コンポーネントを広範囲に使用して、新しいアプリケーションの作成、バンドルの作成などのさまざまな機能を提供します。 WebサーバーのPHPビルドでさえ、インストールセクションにあるように、Symfonyコマンド php bin/console server:run を使用して呼び出すことができます。 Console コンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/console
単純なアプリケーションを作成し、 Console コンポーネントを使用してコマンド HelloCommand を作成し、呼び出します。
- ステップ1 *-次のコマンドを使用してプロジェクトを作成します。
cd/path/to/project
composer require symfony/console
ステップ2 *-ファイル *main.php を作成し、次のコードを含めます。
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Console\Application;
$app = new Application();
$app->run();
?>
*Application* クラスは、ベアボーンコンソールアプリケーションに必要な機能を設定します。
ステップ3 *-アプリケーション *php main.php を実行すると、次の結果が生成されます。
Console Tool
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output,
2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
list Lists commands
ステップ4 *- *main.php 自体に Command クラスを拡張する HelloCommand というクラスを作成します。
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class HelloCommand extends Command {
}
アプリケーションは、 Command コンポーネントで使用可能な次の4つのクラスを使用します。
- コマンド-新しいコマンドを作成するために使用
- InputInterface -ユーザー入力の設定に使用
- InputArgument -ユーザー入力を取得するために使用
- OutputInterface -コンソールに出力を印刷するために使用
ステップ5 *-関数 configure()*を作成し、名前、説明、およびヘルプテキストを設定します。
protected function configure() {
$this
->setName('app:hello')
->setDescription('Sample command, hello')
->setHelp('This command is a sample command')
}
ステップ6 *-コマンドの入力引数 *user を作成し、必須として設定します。
protected function configure() {
$this
->setName('app:hello')
->setDescription('Sample command, hello')
->setHelp('This command is a sample command')
->addArgument('name', InputArgument::REQUIRED, 'name of the user');
}
ステップ7 *-2つの引数 *InputArgument および OutputArgument を使用して関数* execute()*を作成します。
protected function execute(InputInterface $input, OutputInterface $output) {
}
ステップ8 *- *InputArgument を使用して、ユーザーが入力したユーザーの詳細を取得し、 OutputArgument を使用してコンソールに出力します。
protected function execute(InputInterface $input, OutputInterface $output) {
$name = $input->getArgument('name');
$output->writeln('Hello, ' . $name);
}
ステップ9 *- *Application クラスの add メソッドを使用して、 HelloCommand をアプリケーションに登録します。
$app->add(new HelloCommand());
完全なアプリケーションは次のとおりです。
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class HelloCommand extends Command {
protected function configure() {
$this
->setName('app:hello')
->setDescription('Sample command, hello')
->setHelp('This command is a sample command')
->addArgument('name', InputArgument::REQUIRED, 'name of the user');
}
protected function execute(InputInterface $input, OutputInterface $output) {
$name = $input->getArgument('name');
$output->writeln('Hello, ' . $name);
}
$app = new Application();
$app->add(new HelloCommand());
$app->run();
}
?>
- ステップ10 *-さて、次のコマンドを使用してアプリケーションを実行すると、結果は予想どおりHello、Jonになります。
php main.php app:hello Jon
Symfonyには、アプリケーションでコマンドを呼び出すために使用できるSymfony Webアプリケーションのbinディレクトリに console と呼ばれるビルド済みのバイナリが付属しています。
プロセス
プロセスコンポーネントは、サブプロセスでシステムコマンドを安全かつ効率的な方法で実行するオプションを提供します。 プロセスコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/process
ClassLoader
ClassLoaderコンポーネントは、 PSR-0 および PSR-4 クラスローダー標準の両方の実装を提供します。 クラスの自動ロードに使用できます。 近い将来に減価償却されます。 Composerベースのクラスローダーは、このコンポーネントよりも優先されます。 ClassLoaderコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/class-loader
PropertyAccess
PropertyAccessコンポーネントは、文字列表記を使用してオブジェクトと配列の詳細を読み書きするためのさまざまなオプションを提供します。 たとえば、キー price を持つ配列 Product は、 [price] 文字列を使用して動的にアクセスできます。
$product = array(
'name' => 'Cake'
'price' => 10
);
var priceObj = $propertyAccesserObj->getValue($product, '[price]');
PropertyAccessコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/property-access
PropertyInfo
PropertyInfoコンポーネントはPropertyAccessコンポーネントに似ていますが、PHPオブジェクトでのみ機能し、より多くの機能を提供します。
class Product {
private $name = 'Cake';
private $price = 10;
public function getName() {
return $this->name;
}
public function getPrice() {
return $this->price;
}
}
$class = Product::class;
$properties = $propertyInfoObj->getProperties($class);
/*
Example Result
--------------
array(2) {
[0] => string(4) "name"
[1] => string(5) "price"
}
*/
PropertyInfoコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/property-info
EventDispatcher
EventDispatcherコンポーネントは、PHPでイベントベースのプログラミングを提供します。 イベントをディスパッチしてそれらをリッスンすることにより、オブジェクトが互いに通信できるようにします。 イベントとイベントリスナの章で、イベントの作成方法とリスニング方法を学習します。
EventDispatcherコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/event-dispatcher
DependencyInjection
DependencyInjectionコンポーネントは、依存関係を持つオブジェクトを作成するための簡単で効率的なメカニズムを提供します。 プロジェクトが大きくなると、深い依存関係を持つ多くのクラスが機能するため、正しく処理する必要があります。 そうしないと、プロジェクトは失敗します。 DependencyInjectionは、依存関係を処理するためのシンプルで堅牢なコンテナーを提供します。 コンテナと依存関係注入の概念については、サービスコンテナの章で学習します。
DependencyInjectionコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/dependency-injection
シリアライザー
シリアライザーコンポーネントは、PHPオブジェクトをXML、JSON、バイナリなどの特定の形式に変換するオプションを提供し、データを失うことなく元のオブジェクトに戻すことができます。
シリアライザーコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/serializer
設定
構成コンポーネントは、XML、YAML、PHP、およびiniタイプの構成をロード、解析、読み取り、および検証するオプションを提供します。 データベースから構成の詳細をロードするためのさまざまなオプションも提供します。 これは、Webアプリケーションを明確かつ簡潔に構成するのに役立つ重要なコンポーネントの1つです。 構成コンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/config
ExpressionLanguage
ExpessionLanguageコンポーネントは、本格的な式エンジンを提供します。 式は、値を返すことを目的とした1行のライナーです。 式エンジンを使用すると、式から値を簡単にコンパイル、解析、取得できます。 システム管理者など、PHP以外のプログラマーが1つ以上の式を構成環境(ファイル)で使用できるようにします。 ExpressionLanguageコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/expression-language
OptionsResolver
OptionsResolverコンポーネントは、システムで使用されるオプションシステムを検証する方法を提供します。 たとえば、データベース設定は配列に配置され、dboptionはホスト、ユーザー名、パスワードなどをキーとして使用します。 データベースに接続するために使用する前に、エントリを検証する必要があります。 OptionsResolverは、単純なクラスOptionsResolverとデータベース設定を解決するメソッドリゾルバを提供することでこのタスクを簡素化し、検証の問題があればそれを報告します。
$options = array(
'host' => '<db_host>',
'username' => '<db_user>',
'password' => '<db_password>',
);
$resolver = new OptionsResolver();
$resolver->setDefaults(array(
'host' => '<default_db_host>',
'username' => '<default_db_user>',
'password' => '<default_db_password>',
));
$resolved_options = $resolver->resolve($options);
OptionsResolverコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/options-resolver
ドテンフ
Dotenvコンポーネントは、。envファイルおよび *getenv()、$ _ ENV 、または $ _ SERVER を介してアクセスできるように定義された変数を解析するためのさまざまなオプションを提供します。 Dotenvコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/dotenv
キャッシュ
キャッシュコンポーネントは、拡張 PSR-6 実装を提供します。 Webアプリケーションにキャッシュ機能を追加するために使用できます。 PSR-6 に準拠しているため、簡単に開始でき、別のPSR-6ベースのキャッシュコンポーネントの代わりに簡単に使用できます。 キャッシュコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/cache
Intl
Intlコンポーネントは、C Intl拡張機能の代替ライブラリです。 Intlコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/intl
翻訳
翻訳コンポーネントは、アプリケーションを国際化するためのさまざまなオプションを提供します。 通常、異なる言語の翻訳の詳細は、言語ごとに1つのファイルに保存され、アプリケーションの実行時に動的にロードされます。 翻訳ファイルを作成するには、さまざまな形式があります。 翻訳コンポーネントは、プレーンPHPファイル、CSV、ini、Json、Yaml、ICUリソースファイルなど、あらゆるタイプの形式をロードするためのさまざまなオプションを提供します。 翻訳コンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/translation
ワークフロー
ワークフローコンポーネントは、有限状態マシンを処理するための高度なツールを提供します。 この機能をシンプルでオブジェクト指向の方法で提供することにより、Workflowコンポーネントは比較的簡単にPHPで高度なプログラミングを可能にします。 詳細については、高度なコンセプトの章で説明します。
ワークフローコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/workflow
Yaml
Yamlコンポーネントには、YAMLファイル形式を解析してPHP配列に変換するオプションがあります。 また、プレーンなphp配列からYAMLファイルを書き込むこともできます。 Yamlコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/yaml
Ldap
Ldapコンポーネントは、LDAPまたはActive Directoryサーバーに接続し、それに対してユーザーを認証するためのPHPクラスを提供します。 Windowsドメインコントローラーに接続するオプションを提供します。 Ldapコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/ldap
デバッグ
デバッグコンポーネントは、PHP環境でデバッグを有効にするためのさまざまなオプションを提供します。 通常、PHPコードのデバッグは困難ですが、デバッグコンポーネントは単純なクラスを提供して、デバッグプロセスを容易にし、クリーンで構造化しています。 デバッグコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/debug
ストップウォッチ
Stopwatchコンポーネントは、PHPコードのプロファイルを作成するStopwatchクラスを提供します。 簡単な使用法は次のとおりです。
use Symfony\Component\Stopwatch\Stopwatch;
$stopwatch = new Stopwatch();
$stopwatch->start('somename');
//our code to profile
$profiled_data = $stopwatch->stop('somename');
echo $profiled_data->getPeriods()
ストップウォッチコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/stopwatch
VarDumper
VarDumperコンポーネントは、優れた* dump()*機能を提供します。 VarDumperコンポーネントを組み込み、ダンプ機能を使用して機能を向上させてください。 VarDumperコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/var-dumper
BrowserKit
BrowserKitコンポーネントは、抽象的なブラウザークライアントインターフェイスを提供します。 Webアプリケーションをプログラムでテストするために使用できます。 たとえば、フォームを要求し、サンプルデータを入力して送信し、プログラムでフォーム内の問題を見つけることができます。 BrowserKitコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/browser-kit
PHPUnit Bridge
PHPUnit Bridgeコンポーネントは、PHPUnitテスト環境を改善するための多くのオプションを提供します。 PHPUnit Bridgeコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/phpunit-bridge
資産
資産コンポーネントは、Webアプリケーションでの一般的な資産処理を提供します。 CSS、HTML、JavaScriptなどのアセットのURLを生成し、バージョンメンテナンスも実行します。 アセットコンポーネントの詳細は、View Engineの章で確認します。 資産コンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/asset
CssSelector
CssSelectorコンポーネントは、CSSベースのセレクターをXPath式に変換するオプションを提供します。 Web開発者はXPath式よりもCSSベースのセレクター式を知っていますが、HTMLおよびXMLドキュメントで要素を見つけるための最も効率的な式は* XPath式*です。
CssSelectorを使用すると、開発者は_CSS Selectors_に式を記述できますが、コンポーネントは実行前にXPath式に変換します。 したがって、開発者には、CSSセレクターの単純さとXPath式の効率という利点があります。
CssSelectorコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/css-selector
DomCrawler
DomCrawlerコンポーネントは、DOMコンセプトを使用してHTMLおよびXMLドキュメントで要素を検索するためのさまざまなオプションを提供します。 また、XPath式を使用して要素を検索するオプションも提供します。 DosCrawlerコンポーネントをCssSelectorコンポーネントとともに使用して、XPath式の代わりにCSSセレクターを使用できます。 DomCrawlerコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/dom-crawler
Form
フォームコンポーネントを使用すると、Webアプリケーションでフォームを簡単に作成できます。 フォームのプログラミングの詳細については、フォームの章で説明します。 フォームコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/form
HttpFoundation
HttpFoundationコンポーネントは、HTTP仕様にオブジェクト指向レイヤーを提供します。 デフォルトでは、PHPはHTTPリクエストおよびレスポンスの詳細を $ _ GET、$ _ POST、$ _ FILES、$ _ SESSION などの配列ベースのオブジェクトとして提供します。 Cookieの設定などのHTTPベースの機能は、単純で単純な古い関数* setCookie()*を使用して実行できます。 HttpFoundationは、Request、Response、RedirectResponseなどのクラスの小さなセットですべてのHTTP関連機能を提供します。これらのクラスについては後の章で学習します。
HttpFoundationコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/http-foundation
HttpKernel
HttpKernelコンポーネントは、Symfony Webセットアップのコアコンポーネントです。 Request オブジェクトの受信から Response オブジェクトの返送まで、Webアプリケーションに必要なすべての機能を提供します。 Symfony Webアプリケーションの完全なアーキテクチャは、Symfony Webフレームワークのアーキテクチャで説明されているように、HttpKernelによって提供されます。
HttpKernelコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/http-kernel
ルーティング
ルーティングコンポーネントは、HTTP要求を事前定義された構成変数のセットにマップします。 ルーティングは、アプリケーションのどの部分でリクエストを処理するかを決定します。 ルーティングの章でルーティングの詳細を学びます。
ルーティングコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/filesystem
テンプレート
テンプレートコンポーネントは、効率的なテンプレートシステムを構築するために必要なインフラストラクチャを提供します。 Symfonyは、Viewエンジンの実装にテンプレートコンポーネントを使用します。 テンプレートの詳細については、Viewエンジンの章で説明します。
テンプレートコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/templating
バリデーター
Validatorコンポーネントは、 JSR-303 Bean Validation Specification の実装を提供します。 Web環境でフォームを検証するために使用できます。 Validatorの詳細については、検証の章で説明します。
検証コンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/validator
セキュリティ
セキュリティコンポーネントは、HTTP基本認証、HTTPダイジェスト認証、インタラクティブフォームベース認証、X.509証明書ログインなど、Webアプリケーションに完全なセキュリティシステムを提供します。 また、組み込みのACLシステムを介して、ユーザーロールに基づいた承認メカニズムも提供します。 詳細については、高度なコンセプトの章で説明します。
セキュリティコンポーネントは、次のコマンドを使用してインストールできます。
composer require symfony/security
Symfony-サービスコンテナー
どのアプリケーションでも、オブジェクトはアプリケーションの成長とともに増加する傾向があります。 オブジェクトが増加すると、オブジェクト間の依存関係も増加します。 アプリケーションの成功には、オブジェクトの依存関係を適切に処理する必要があります。
コンポーネントの章で説明したように、Symfonyはオブジェクトの依存関係を処理するための簡単で効率的なコンポーネント DependencyInjection を提供します。 サービスコンテナは、適切に解決された依存関係を持つオブジェクトのコンテナです。 この章では、DependencyInjectionコンポーネントの使用方法を学びましょう。
*Greeter* クラスを作成しましょう。 Greeterクラスの目的は、次の例に示すようにユーザーに挨拶することです。
$greeter = new Greeter('Hi');
$greeter->greet('Jon');//print "Hi, Jon"
Greeterクラスの完全なコードは次のとおりです。
class Greeter {
private $greetingText;
public function __construct($greetingText) {
$this->greetingText = $greetingText;
}
public function greet($name) {
echo $this->greetingText . ", " . $name . "\r\n";
}
}
次に、Greeterクラスをサービスコンテナに追加しましょう。 Symfonyは、新しいコンテナを作成する ContainerBuilder を提供します。 コンテナが作成されると、コンテナのregisterメソッドを使用してGreeterクラスをコンテナに登録できます。
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('Hi');
ここでは、静的な引数を使用して、あいさつ文Hiを指定しています。 symfonyはパラメーターの動的設定も提供します。 動的パラメータを使用するには、名前を選択し、%の間で指定する必要があります。パラメータは、コンテナの setParameter メソッドを使用して設定できます。
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('%greeter.text%');
$container->setParameter('greeter.text', 'Hi');
適切な設定でGreeterクラスを登録しました。 これで、コンテナ get メソッドを使用して、適切に設定されたGreeterオブジェクトを提供するようにコンテナに要求できます。
$greeter = $container->get('greeter');
$greeter->greet('Jon');//prints "Hi, Jon"
Greeterクラスをコンテナに正常に登録し、コンテナから取得して使用しました。 ここで、Greeterクラスを使用する別のクラス User を作成し、それを登録する方法を見てみましょう。
class User {
private $greeter;
public $name;
public $age;
public function setGreeter(\Greeter $greeter) {
$this->greeter = $greeter;
}
public function greet() {
$this->greeter->greet($this->name);
}
}
Userクラスは、セッターメソッドの1つである setGreeter を使用して_Greeter_クラスを取得します。 このシナリオのために、Symfonyはメソッド addMethodCall とクラス Reference を提供して、次のコードに示すように別のクラスを参照します。
use Symfony\Component\DependencyInjection\Reference;
$container
->register('user', 'User')
->addMethodCall('setGreeter', array(new Reference('greeter')));
最後に、 Greeter と User の2つのクラスを登録しました。 これで、次のコードに示すように、適切に設定されたGreeterクラスを持つUserオブジェクトをコンテナから安全にフェッチできます。
$container->setParameter('greeter.text', 'Hi');
$user = $container->get('user');
$user->name = "Jon";
$user->age = 20;
$user->greet();//Prints "Hi, Jon"
PHP自体を使用してコンテナー内のオブジェクトを構成する方法を見てきました。 symfonyは他のメカニズムも提供します。 これらはXMLおよびYAML構成ファイルです。 YAMLを使用してコンテナーを構成する方法を見てみましょう。 そのためには、* symfony/configencyおよび symfony/yaml コンポーネントと symfony/dependency-injection コンポーネントをインストールします。
cd/path/to/dir
mkdir dependency-injection-example
cd dependency-injection-example
composer require symfony/dependency-injection
composer require symfony/config
composer require symfony/yaml
YAML設定は、 services.yml という別のファイルに書き込まれます。 YAML設定は、 parameters と services の2つのセクションで構成されています。 パラメーターセクションでは、すべての必須パラメーターを定義します。 サービスセクションはすべてのオブジェクトを定義します。 サービスセクションは、さらに class、arguments 、 calls という複数のセクションに分かれています。 クラスは、実際のクラスを指定します。 引数は、コンストラクターの引数を指定します。 最後に、呼び出しはセッターメソッドを指定します。 @記号@greeterを使用して別のクラスを参照できます。
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
これで、次のコードに示すように、 FileLoader および YamlFileLoader を使用して services.yml をロードおよび構成できます。
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
$yamlContainer = new ContainerBuilder();
$loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__));
$loader->load('services.yml');
$yamlUser = $yamlContainer->get('user');
$yamlUser->name = "Jon";
$yamlUser->age = 25;
$yamlUser->greet();
完全なコードリストは次のとおりです。
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
class Greeter {
private $greetingText;
public function __construct($greetingText) {
$this->greetingText = $greetingText;
}
public function greet($name) {
echo $this->greetingText . ", " . $name . "\r\n";
}
}
class User {
private $greeter;
public $name;
public $age;
public function setGreeter(\Greeter $greeter) {
$this->greeter = $greeter;
}
public function greet() {
$this->greeter->greet($this->name);
}
}
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('%greeter.text%');
$container
->register('user', 'User')
->addMethodCall('setGreeter', array(new Reference('greeter')));
$container->setParameter('greeter.text', 'Hi');
$greeter = $container->get('greeter');
$greeter->greet('Jon');
$user = $container->get('user');
$user->name = "Jon";
$user->age = 20;
$user->greet();
$yamlContainer = new ContainerBuilder();
$loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__));
$loader->load('services.yml');
$yamlHello = $yamlContainer->get('greeter');
$yamlHello->greet('Jon');
$yamlUser = $yamlContainer->get('user');
$yamlUser->name = "Jon";
$yamlUser->age = 25;
$yamlUser->greet();
?>
services.yml
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
symfony Webフレームワークは、依存性注入コンポーネントを広範囲に使用します。 すべてのコンポーネントは、集中化されたサービスコンテナによってバインドされます。 symfonyのWebフレームワークは、コンテナを container プロパティを介してすべての Controller で公開します。 ロガー、メーラーなど、その中に登録されているすべてのオブジェクトを取得できます。
$logger = $this->container->get('logger');
$logger->info('Hi');
コンテナに登録されているオブジェクトを見つけるには、次のコマンドを使用します。
cd/path/to/app
php bin/console debug:container
インストールの章で作成された hello Webアプリには、約200以上のオブジェクトがあります。
symfony-イベントとEventListener
symfonyは、 EventDispatcher コンポーネントを通じてイベントベースのプログラミングを提供します。 エンタープライズアプリケーションでは、高度にカスタマイズ可能なアプリケーションを作成するために、イベントベースのプログラミングが必要です。 イベントは、オブジェクトが相互作用するための主要なツールの1つです。 イベントがないと、オブジェクトは効率的に相互作用しません。
イベントベースのプログラミングのプロセスは、次のように要約できます。 Event source というオブジェクトは、中央ディスパッチャオブジェクトに、user.registeredなどのイベントを登録するように要求します。 リスナーと呼ばれる1つ以上のオブジェクトは、user.registeredなどの特定のイベントをリッスンすることを中央ディスパッチャオブジェクトに要求します。 ある時点で、イベントソースオブジェクトは中央のディスパッチャオブジェクトにイベントをディスパッチするように要求します。たとえば、user.registeredは、必要な情報を備えたイベントオブジェクトとともに送信します。 中央ディスパッチャは、すべてのリスナーオブジェクトにイベントについて通知します。たとえば、user.registeredとそのEvent *オブジェクトです。
イベントベースのプログラミングでは、イベントソース、イベントリスナー、イベントディスパッチャー、およびイベント自体の4つのタイプのオブジェクトがあります。
概念を理解するための簡単なアプリケーションを作成しましょう。
ステップ1 *-プロジェクト、 *event-dispatcher-example を作成します。
cd/path/to/dir
mkdir event-dispatcher-example
cd event-dispatcher-example
composer require symfony/event-dispatcher
ステップ2 *-クラス *.User を作成します。
class User {
public $name;
public $age;
}
$user = new User();
$user->name = "Jon";
$user->age = 25
ステップ3 *-イベント、 *UserRegisteredEvent を作成します。
use Symfony\Component\EventDispatcher\Event;
class UserRegisteredEvent extends Event {
const NAME = 'user.registered';
protected $user;
public function __construct(User $user) {
$this-<user = $user;
}
public function getUser() {
return $this-<user;
}
}
$event = new UserRegisteredEvent($user);
ここで、 UserRegisteredEvent は User オブジェクトにアクセスできます。 イベントの名前は user.registered です。
ステップ4 *-リスナー *UserListener を作成します。
class UserListener {
public function onUserRegistrationAction(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n";
echo $user->age . "\r\n";
}
}
$listener = new UserListener();
- ステップ5 *-イベントディスパッチャオブジェクトを作成します。
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
ステップ6 *-ディスパッチャーオブジェクトとそのメソッド *addListener を使用して、リスナーとイベントを接続します。
$dispatcher
->addListener(
UserRegisteredEvent::NAME,
array($listener, 'onUserRegistrationAction'));
次のコードに示すように、匿名関数をイベントリスナーとして追加することもできます。
$dispatcher
->addListener(
UserRegisteredEvent::NAME,
function(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n";
});
ステップ7 *-最後に、イベントディスパッチャーのメソッド *dispatch を使用して、イベントを起動/ディスパッチします。
$dispatcher->dispatch(UserRegisteredEvent::NAME, $event);
完全なコードリストは次のとおりです。
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class User {
public $name;
public $age;
}
class UserRegisteredEvent extends Event {
const NAME = 'user.registered';
protected $user;
public function __construct(User $user) {
$this->user = $user;
}
public function getUser() {
return $this->user;
}
}
class UserListener {
public function onUserRegistrationAction(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n";
echo $user->age . "\r\n";
}
}
$user = new User();
$user->name = "Jon";
$user->age = 25;
$event = new UserRegisteredEvent($user);
$listener = new UserListener();
$dispatcher = new EventDispatcher();
$dispatcher
->addListener(
UserRegisteredEvent::NAME,
function(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n";
});
$dispatcher
->addListener(
UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction'));
$dispatcher->dispatch(UserRegisteredEvent::NAME, $event);
?>
結果
Jon
Jon
25
symfony Webフレームワークには多くのイベントがあり、それらのイベントのリスナーを登録し、それに応じてプログラムできます。 サンプルイベントの1つはkernel.exceptionであり、対応するイベントは GetResponseForExceptionEvent であり、応答オブジェクト(Web要求の出力)を保持します。 これは、ユーザーにランタイムエラーを表示する代わりに、例外をキャッチし、一般的なエラー情報で応答を変更するために使用されます。
symfony-式
前に説明したように、式言語はSymfonyアプリケーションの顕著な特徴の1つです。 symfony式は、主に設定環境で使用するために作成されます。 これにより、プログラマーでなくても簡単にWebアプリケーションを構成できます。 式をテストする簡単なアプリケーションを作成しましょう。
ステップ1 *-プロジェクト *expression-language-example を作成します。
cd/path/to/dir
mkdir expression-language-example
cd expression-language-example
composer require symfony/expression-language
- ステップ2 *-式オブジェクトを作成します。
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$language = new ExpressionLanguage();
- ステップ3 *-簡単な式をテストします。
echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ;
echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;
- ステップ4 *-symfony式は強力であり、式言語でもPHPオブジェクトとそのプロパティをインターセプトできます。
class Product {
public $name;
public $price;
}
$product = new Product();
$product->name = 'Cake';
$product->price = 10;
echo "Product price is " . $language
->evaluate('product.price', array('product' => $product,)) . "\r\n";
echo "Is Product price higher than 5: " . $language
->evaluate('product.price > 5', array('product' => $product,)) . "\r\n";
ここで、式 product.price および product.price> 5 は、 $ product オブジェクトのプロパティ price をインターセプトし、結果を評価します。
完全なコーディングは次のとおりです。
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$language = new ExpressionLanguage();
echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ;
echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;
class Product {
public $name;
public $price;
}
$product = new Product();
$product->name = 'Cake';
$product->price = 10;
echo "Product price is " . $language
->evaluate('product.price', array('product' => $product,)) . "\r\n";
echo "Is Product price higher than 5: " . $language
->evaluate('product.price > 5', array('product' => $product,)) . "\r\n";
?>
結果
Evaluated Value: 22
Compiled Code: (130 % 34)
Product price is 10
Is Product price higher than 5: 1
Symfony-バンドル
Symfonyバンドルは、特定の構造に編成されたファイルとフォルダーのコレクションです。 バンドルは、複数のアプリケーションで再利用できるようにモデル化されています。 メインアプリケーション自体はバンドルとしてパッケージ化されており、通常は AppBundle と呼ばれます。
バンドルは、AdminBundle(管理セクション)、BlogBundle(サイトのブログ)などのアプリケーションに固有にパッケージ化できます。 このようなバンドルは、アプリケーション間で共有できません。 代わりに、ブログなどのアプリケーションの特定の部分を汎用バンドルとしてモデル化して、あるアプリケーションから別のアプリケーションにバンドルを単純にコピーして、ブログ機能を再利用できます。
バンドルの構造
バンドルの基本構造は次のとおりです。
- コントローラー-すべてのコントローラーをここに配置する必要があります。
- DependencyInjection -依存性注入に関連するすべてのコードと構成をここに配置する必要があります。
- Resources/config -バンドル関連の設定はここに配置されます。
- Resources/view -バンドル関連のビューテンプレートはここに配置されます。
- リソース/パブリック-バンドル関連のスタイルシート、JavaScript、画像などがここに配置されます。
- テスト-バンドル関連のユニットテストファイルはここに配置されます。
バンドルを作成する
*HelloWorld* アプリケーションで簡単なバンドル *finddevguidesDemoBundle* を作成してみましょう。
ステップ1 *-名前空間を選択します。 バンドルのネームスペースには、ベンダー名とバンドル名を含める必要があります。 この例では、 *finddevguides \ DemoBundle です。
ステップ2 *- *Bundle クラスを拡張して空のクラス finddevguidesDemoBundle を作成し、 src/finddevguides/DemoBundle の下に配置します。
namespace finddevguides\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class finddevguidesDemoBundle extends Bundle {
}
ステップ3 *-アプリケーションがサポートするバンドルのリストにクラスを *AppKernel クラスに登録します。
public function registerBundles() {
$bundles = array(
//...
//register your bundle
new finddevguides\DemoBundle\finddevguidesDemoBundle(),
);
return $bundles;
}
これは、空のバンドルを作成するためにすべて必要であり、他のすべての概念はアプリケーションの概念と同じです。 また、symfonyはコンソールコマンド generate:bundle を提供して、新しいバンドルを作成するプロセスを簡素化します。これは次のとおりです。
php bin/console generate:bundle --namespace = finddevguides/DemoBundle
結果
Welcome to the Symfony bundle generator!
Are you planning on sharing this bundle across multiple applications? [no]: no
Your application code must be written in bundles. This command helps
you generate them easily.
Give your bundle a descriptive name, like BlogBundle.
Bundle name [finddevguides/DemoBundle]:
In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest finddevguidesDemoBundle.
Bundle name [finddevguidesDemoBundle]:
Bundles are usually generated into the src/directory. Unless you're
doing something custom, hit enter to keep this default!
Target Directory [src/]:
What format do you want to use for your generated configuration?
Configuration format (annotation, yml, xml, php) [annotation]:
Bundle generation
> Generating a sample bundle skeleton into app/../src/finddevguides/DemoBundle
created ./app/../src/finddevguides/DemoBundle/
created ./app/../src/finddevguides/DemoBundle/finddevguidesDemoBundle.php
created ./app/../src/finddevguides/DemoBundle/Controller/
created ./app/../src/finddevguides/DemoBundle/Controller/DefaultController.php
created ./app/../tests/finddevguidesDemoBundle/Controller/
created ./app/../tests/finddevguidesDemoBundle/Controller/DefaultControllerTest.php
created ./app/../src/finddevguides/DemoBundle/Resources/views/Default/
created ./app/../src/finddevguides/DemoBundle/Resources/views/Default/indexl.twig
created ./app/../src/finddevguides/DemoBundle/Resources/config/
created ./app/../src/finddevguides/DemoBundle/Resources/config/services.yml
> Checking that the bundle is autoloaded
> Enabling the bundle inside app/AppKernel.php
updated ./app/AppKernel.php
> Importing the bundle's routes from the app/config/routing.yml file
updated ./app/config/routing.yml
> Importing the bundle's services.yml from the app/config/config.yml file
updated ./app/config/config.yml
Everything is OK! Now get to work :).
単純なWebアプリケーションの作成
この章では、Symfonyフレームワークで簡単なアプリケーションを作成する方法について説明します。 前に説明したように、Symfonyで新しいプロジェクトを作成する方法を知っています。
「学生」の詳細の例を挙げることができます。 まず、次のコマンドを使用して「student」という名前のプロジェクトを作成します。
symfony new student
コマンドを実行すると、空のプロジェクトが作成されます。
コントローラ
symfonyは、Model-View-Controller(MVC)開発パターンに基づいています。 MVCは、アプリケーションロジックをプレゼンテーションから分離するソフトウェアアプローチです。 コントローラはSymfonyフレームワークで重要な役割を果たします。 アプリケーション内のすべてのWebページは、コントローラーで処理する必要があります。
*DefaultController* クラスは*“ src/AppBundle/Controller” *にあります。 独自のコントローラークラスを作成できます。
“ src/AppBundle/Controller” *の場所に移動して、新しい *StudentController クラスを作成します。
以下は、 StudentController クラスの基本的な構文です。
StudentController.php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class StudentController {
}
これで、StudentControllerが作成されました。 次の章では、コントローラーについてさらに詳しく説明します。
ルートを作成する
コントローラーが作成されたら、特定のページにルーティングする必要があります。 ルーティングはリクエストURIを特定のコントローラーのメソッドにマップします。
ルーティングの基本的な構文は次のとおりです。
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class StudentController {
/* *
* @Route("/student/home")
*/
public function homeAction() {
return new Response('Student details application!');
}
}
上記の構文では、* @ Route(“/student/home”)*がルートです。 ページのURLパターンを定義します。
- homeAction()*はアクションメソッドであり、ページを作成してResponseオブジェクトを返すことができます。
ルーティングについては、次の章で詳しく説明します。 ここで、URL「http://localhost:8000/student/home」をリクエストすると、次の結果が生成されます。
結果
Symfony-コントローラー
コントローラーは、Symfonyアプリケーションに入ってくる各リクエストを処理する責任があります。 コントローラーは要求から情報を読み取ります。 次に、応答オブジェクトを作成してクライアントに返します。
Symfonyによると、 DefaultController クラスは*“ src/AppBundle/Controller” *にあります。 次のように定義されています。
DefaultController.php
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller {
}
ここで、 HttpFoundation コンポーネントはHTTP仕様のオブジェクト指向レイヤーを定義し、 FrameworkBundle にはほとんどの「ベース」フレームワーク機能が含まれています。
リクエストオブジェクト
Requestクラスは、HTTP要求メッセージのオブジェクト指向表現です。
リクエストオブジェクトの作成
要求は、* createFromGlobals()*メソッドを使用して作成できます。
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
グローバルを使用してリクエストをシミュレートできます。 PHPグローバルに基づいてリクエストを作成する代わりに、リクエストをシミュレートすることもできます。
$request = Request::create(
'/student',
'GET',
array('name' => 'student1')
);
ここで、* create()*メソッドは、URI、メソッド、およびいくつかのパラメーターに基づいてリクエストを作成します。
リクエストオブジェクトのオーバーライド
- overrideGlobals()*メソッドを使用して、PHPグローバル変数をオーバーライドできます。 次のように定義されています。
$request->overrideGlobals();
リクエストオブジェクトへのアクセス
Webページのリクエストには、ベースコントローラーの* getRequest()*メソッドを使用して、コントローラー(アクションメソッド)でアクセスできます。
$request = $this->getRequest();
リクエストオブジェクトの特定
アプリケーションでリクエストを識別する場合、*“ PathInfo” *メソッドはリクエストURLの一意のIDを返します。 次のように定義されています。
$request->getPathInfo();
応答オブジェクト
コントローラーの唯一の要件は、Responseオブジェクトを返すことです。 Responseオブジェクトは、指定されたリクエストからのすべての情報を保持し、クライアントに送り返します。
以下は簡単な例です。
例
use Symfony\Component\HttpFoundation\Response;
$response = new Response(‘Default'.$name, 10);
次のように、JSONでResponseオブジェクトを定義できます。
$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');
応答コンストラクター
コンストラクタには3つの引数が含まれています-
- 応答内容
- 状態コード
- HTTPヘッダーの配列
基本的な構文は次のとおりです。
use Symfony\Component\HttpFoundation\Response;
$response = new Response(
'Content',
Response::HTTP_OK,
array('content-type' => 'text/html')
);
たとえば、コンテンツ引数を次のように渡すことができます。
$response->setContent(’Student details’);
同様に、他の引数も渡すことができます。
応答を送信する
- send()*メソッドを使用して、クライアントに応答を送信できます。 次のように定義されています。
$response->send();
クライアントを別のURLにリダイレクトするには、 RedirectResponse クラスを使用できます。
次のように定義されています。
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse('http://finddevguides.com/');
FrontController
アプリケーションに着信するすべてのリクエストを処理する単一のPHPファイル。 FrontControllerは、アプリケーションの内部的に異なる部分への異なるURLのルーティングを実行します。
以下は、FrontControllerの基本的な構文です。
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$request = Request::createFromGlobals();
$path = $request->getPathInfo();//the URI path being requested
if (in_array($path, array('', '/'))) {
$response = new Response(’Student home page.');
} elseif (‘/about’ === $path) {
$response = new Response(’Student details page’);
} else {
$response = new Response('Page not found.', Response::HTTP_NOT_FOUND);
}
$response->send();
ここで、* in_array()*関数は、特定の値の配列を検索します。
Symfony-ルーティング
ルーティングはリクエストURIを特定のコントローラーのメソッドにマップします。 一般的に、任意のURIには次の3つの部分があります-
- ホスト名セグメント
- パスセグメント
- クエリセグメント
たとえば、URI/URLでは、 http://www.finddevguides.com/index?q = data、www.finddevguides.com はホスト名セグメント、indexはパスセグメント、q = dataはクエリセグメントです。 。 一般に、ルーティングは一連の制約に対してページセグメントをチェックします。 一致する制約がある場合、値のセットが返されます。 主な価値の1つはコントローラーです。
アノテーション
注釈は、Symfonyアプリケーションの構成において重要な役割を果たします。 注釈は、コーディング自体で構成を宣言することにより、構成を簡素化します。 注釈は、クラス、メソッド、およびプロパティに関するメタ情報を提供することに他なりません。 ルーティングはアノテーションを広範囲に使用します。 ルーティングは注釈なしで実行できますが、注釈によりルーティングが大幅に簡素化されます。
以下は注釈のサンプルです。
/* *
* @Route(“/student/home”)
*/
public function homeAction() {
//...
}
ルーティングの概念
「student」プロジェクトで作成された_StudentController_クラスを検討してください。
StudentController.php
//src/AppBundle/Controller/StudentController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class StudentController extends Controller {
/* *
* @Route(“/student/home”)
*/
public function homeAction() {
//...
}
/* *
* @Route(“/student/about”)
*/
public function aboutAction() {
}
}
ここで、ルーティングは2つのステップを実行します。 /student/home に移動すると、最初のルートが一致し、* homeAction()が実行されます。 それ以外の場合、 */student/about に移動すると、2番目のルートが一致し、* aboutAction()*が実行されます。
ワイルドカード形式の追加
ページ2および3に対応する_/student/2および/student/3_のようなURLを持つ学生レコードのページ分割されたリストがあるとします。 その後、ルートのパスを変更する場合は、ワイルドカード形式を使用できます。
例
//src/AppBundle/Controller/BlogController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class StudentController extends Controller {
/* *
* @Route(“/student/{page}", name = “student_about”, requirements = {"page": "\d+"})
*/
public function aboutAction($page) {
//...
}
}
ここで、 \ d + は、任意の長さの数字に一致する正規表現です。
プレースホルダーを割り当てる
ルーティングでプレースホルダー値を割り当てることができます。 次のように定義されています。
//src/AppBundle/Controller/BlogController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class StudentController extends Controller {
/* *
* @Route(“/student/{page}", name = “student_about”, requirements = {"page": "\d+"})
*/
public function aboutAction($page = 1) {
//...
}
}
ここで、/studentに移動すると、* student_aboutルート*が一致し、 $ page のデフォルト値は1になります。
ページへのリダイレクト
ユーザーを別のページにリダイレクトする場合は、* redirectToRoute()および redirect()*メソッドを使用します。
public function homeAction() {
//redirect to the "homepage" route
return $this->redirectToRoute('homepage');
//redirect externally
\return $this->redirect('http://example.com/doc');
}
URLを生成する
URLを生成するには、そのルートのパスで使用されるルート名 student_name およびワイルドカード名 student-names を考慮します。 URLを生成するための完全なリストは、次のように定義されます。
class StudentController extends Controller {
public function aboutAction($name) {
//...
///student/student-names
$url = $this->generateUrl(
‘student_name’,
array(‘name’ =>
’student-names’)
);
}
}
StudentController
次のように、StudentControllerクラスでルーティングする簡単な例を考えてみましょう。
StudentController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class StudentController {
/* *
* @Route("/student/home")
*/
public function homeAction() {
$name = 'Student details application';
return new Response(
'<html><body>Project: '.$name.'</body></html>'
);
}
}
ここで、url * http://localhost:8000/student/home” を要求すると、次の結果が生成されます。
同様に、* aboutAction()*の別のルートを作成することもできます。
Symfony-ビューエンジン
ビューレイヤーは、MVCアプリケーションのプレゼンテーションレイヤーです。 プレゼンテーションロジックからアプリケーションロジックを分離します。
コントローラは、HTML、CSS、またはその他のコンテンツを生成する必要がある場合、タスクをテンプレートエンジンに転送します。
テンプレート
テンプレートは基本的に、HTML、XMLなどのテキストベースのドキュメントを生成するために使用されるテキストファイルです。 時間を節約し、エラーを減らすために使用されます。
デフォルトでは、テンプレートは2つの異なる場所に存在できます-
*app/Resources/views/* -アプリケーションのビューディレクトリには、アプリケーションバンドルのアプリケーションのレイアウトとテンプレートを含めることができます。 また、サードパーティのバンドルテンプレートも上書きします。
*vendor/path/to/Bundle/Resources/views/* -各サードパーティバンドルには、そのテンプレートが「Resources/views/」ディレクトリに含まれています。
小枝エンジン
symfonyは Twig と呼ばれる強力なテンプレート言語を使用します。 Twigを使用すると、簡潔で読みやすいテンプレートを非常に簡単に作成できます。 Twigテンプレートはシンプルで、PHPタグを処理しません。 Twigは、空白制御、サンドボックス、および自動HTMLエスケープを実行します。
構文
Twigには3種類の特別な構文が含まれています-
- \ {\ {… }} -変数または式の結果をテンプレートに出力します。
- \ {%… %} -テンプレートのロジックを制御するタグ。 主に機能の実行に使用されます。
- \ {#… #} -コメントの構文。 単一行または複数行のコメントを追加するために使用されます。
twigベーステンプレートは*「app/Resources/views/basel.twig」*にあります。
例
小枝エンジンを使用した簡単な例を見てみましょう。
StudentController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class StudentController extends Controller {
/* *
* @Route("/student/home")
*/
public function homeAction() {
return $this->render('student/homel.twig');
}
}
ここでは、* render()*メソッドがテンプレートをレンダリングし、そのコンテンツをResponseオブジェクトに入れます。
次に、「views」ディレクトリに移動して「student」というフォルダを作成し、そのフォルダ内に「homel.twig」というファイルを作成します。 ファイルに次の変更を追加します。
homel.twig
//app/Resources/views/student/homel.twig
<h3>Student application!</h3>
「http://localhost:8000/student/home」というURLをリクエストすることで結果を取得できます。
デフォルトでは、Twigにはタグ、フィルター、および関数の長いリストが付属しています。 1つずつ詳しく見ていきましょう。
Tags
Twigは次の重要なタグをサポートしています-
Do
*do* タグは、何も出力しないことを除いて、正規表現と同様の機能を実行します。 その構文は次のとおりです-
{% do 5 + 6 %}
含める
includeステートメントにはテンプレートが含まれ、そのファイルのレンダリングされたコンテンツを現在のネームスペースに返します。 その構文は次のとおりです-
{% include 'templatel' %}
拡張する
extendsタグは、テンプレートを別のテンプレートから拡張するために使用できます。 その構文は次のとおりです-
{% extends "templatel" %}
ブロック
ブロックはプレースホルダーとして機能し、コンテンツを置き換えます。 ブロック名は、英数字とアンダースコアで構成されます。 例えば、
<title>{% block title %}{% endblock %}</title>
埋め込む
*embed* タグは、インクルードと拡張の両方の組み合わせを実行します。 別のテンプレートのコンテンツを含めることができます。 また、テンプレートを拡張するときなど、含まれているテンプレート内で定義されたブロックをオーバーライドすることもできます。 その構文は次のとおりです-
{% embed “new_template.twig” %}
{# These blocks are defined in “new_template.twig" #}
{% block center %}
Block content
{% endblock %}
{% endembed %}
フィルタ
フィルターセクションを使用すると、テンプレートデータのブロックに通常のTwigフィルターを適用できます。 例えば、
{% filter upper %}
symfony framework
{% endfilter %}
ここでは、テキストが大文字に変更されます。
For
*For* ループは、シーケンス内の各アイテムを取得します。 例えば、
{% for x in 0..10 %}
{{ x }}
{% endfor %}
If
Twigの if ステートメントはPHPに似ています。 式はtrueまたはfalseに評価されます。 例えば、
{% if value == true %}
<p>Simple If statement</p>
{% endif %}
フィルター
Twigにはフィルターが含まれています。 レンダリングされる前にコンテンツを変更するために使用されます。 以下は、注目に値するフィルターの一部です。
長さ
長さフィルターは、文字列の長さを返します。 その構文は次のとおりです-
{% if name|length > 5 %}
...
{% endif %}
下
下側のフィルターは値を小文字に変換します。 例えば、
{{ 'SYMFONY'|lower }}
それは次の結果を生成します-
symfony
同様に、大文字を試すことができます。
交換する
置換フィルターは、プレースホルダーを置換することにより、指定された文字列をフォーマットします。 例えば、
{{ "tutorials point site %si% and %te%."|replace({'%si%': web, '%te%': "site"}) }}
それは次の結果を生成します-
tutorials point website
タイトル
タイトルフィルターは、値のタイトルケースバージョンを返します。 例えば、
{{ 'symfony framework '|title }}
それは次の結果を生成します-
Symfony Framework
Sort
並べ替えフィルターは配列を並べ替えます。 その構文は次のとおりです-
{% for user in names|sort %}
...
{% endfor %}
Trim
トリムフィルターは、文字列の先頭と末尾から空白(またはその他の文字)を削除します。 例えば、
{{ ' Symfony! '|trim }}
それは次の結果を生成します-
Symfony!
関数
Twigは機能をサポートしています。 特定の結果を取得するために使用されます。 以下は、重要なTwig関数の一部です。
属性
*attribute* 関数を使用して、変数の「動的」属性にアクセスできます。 その構文は次のとおりです-
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
例えば、
{{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
定数
定数関数は、指定された文字列の定数値を返します。 例えば、
{{ constant('Namespace\\Classname::CONSTANT_NAME') }}
サイクル
サイクル関数は、値の配列を循環します。 例えば、
{% set months = [‘Jan’, ‘Feb’, ‘Mar’] %}
{% for x in 0..12 %}
{ cycle(months, x) }}
{% endfor %}
Date
引数を日付に変換して、日付の比較を可能にします。 例えば、
<p>Choose your location before {{ 'next Monday'|date('M j, Y') }}</p>
それは次の結果を生成します-
Choose your location before May 15, 2017
引数は、PHPでサポートされている日時形式のいずれかである必要があります。
2番目の引数としてタイムゾーンを渡すことができます。
Dump
ダンプ機能は、テンプレート変数に関する情報をダンプします。 例えば、
{{ dump(user) }}
Max
max関数は、シーケンスの最大値を返します。 例えば、
{{ max(1, 5, 9, 11, 15) }}
Min
min関数は、シーケンスの最小値を返します。 例えば、
{{ min(1, 3, 2) }}
含める
include関数は、テンプレートのレンダリングされたコンテンツを返します。 例えば、
{{ include('templatel') }}
ランダム
ランダム関数は、ランダムな値を生成します。 例えば、
{{ random([‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’]) }}
{# example output: Jan #}
範囲
範囲関数は、整数の算術級数を含むリストを返します。 例えば、
{% for x in range(1, 5) %}
{{ x }},
{% endfor %}
それは次の結果を生成します-
1,2,3,4,5
レイアウト
レイアウトは、複数のビューの共通部分を表します。 たとえば、ページヘッダーとフッター。
テンプレートの継承
テンプレートは別のテンプレートで使用できます。 これは、テンプレート継承の概念を使用して実現できます。 テンプレートの継承により、ブロックとして定義されたWebサイトのすべての共通要素を含む基本「レイアウト」テンプレートを構築できます。
テンプレートの継承についてさらに理解するために、簡単な例を見てみましょう。
例
「app/Resources/views/basel.twig」にある基本テンプレートを検討してください。 ファイルに次の変更を追加します。
*basel.twig*
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>{% block title %}Parent template Layout{% endblock %}</title>
</head>
</html>
次に、_“ app/Resources/views/default/indexl.twig“ _にあるインデックステンプレートファイルに移動します。 以下の変更を追加します。
*indexl.twig*
{% extends 'basel.twig' %}
{% block title %}Child template Layout{% endblock %}
ここで、 \ {%extends%} タグはテンプレートエンジンに最初にベーステンプレートを評価するように通知します。これにより、レイアウトが設定され、ブロックが定義されます。 その後、子テンプレートがレンダリングされます。 子テンプレートは、基本レイアウトを拡張し、タイトルブロックをオーバーライドできます。 ここで、URL「http://localhost:8000」をリクエストすると、その結果を取得できます。
資産
アセットは、CSSスタイルシート、JavaScriptファイル、画像ファイルなどのWebアセットのURL生成とバージョン管理を管理します。
JavaScript
JavaScriptファイルを含めるには、任意のテンプレートで javascripts タグを使用します。
{# Include javascript #}
{% block javascripts %}
{% javascripts '@AppBundle/Resources/public/js/*' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
スタイルシート
スタイルシートファイルを含めるには、任意のテンプレートで stylesheets タグを使用します
{# include style sheet #}
{% block stylesheets %}
{% stylesheets 'bundles/app/css/*' filter = 'cssrewrite' %}
<link rel = "stylesheet" href="{{ asset_url }}"/>
{% endstylesheets %}
{% endblock %}
画像
画像を含めるには、画像タグを使用できます。 次のように定義されています。
{% image '@AppBundle/Resources/public/images/example.jpg' %}
<img src = "{{ asset_url }}" alt = "Example"/>
{% endimage %}
複合資産
多くのファイルを1つにまとめることができます。 これにより、HTTP要求の数が減り、フロントエンドのパフォーマンスが向上します。
{% javascripts
'@AppBundle/Resources/public/js/*'
'@AcmeBarBundle/Resources/public/js/form.js'
'@AcmeBarBundle/Resources/public/js/calendar.js' %}
<script src = "{{ asset_url }}"></script>
{% endjavascripts %}
symfony-Doctrine ORM
Symfony Webフレームワークでは、モデルが重要な役割を果たします。 それらはビジネスエンティティです。 これらは顧客から提供されるか、バックエンドデータベースから取得され、ビジネスルールに従って操作され、データベースに保持されます。 これらは、ビューによって表示されるデータです。 この章では、モデルとバックエンドシステムとの相互作用について学習します。
データベースモデル
モデルをバックエンドリレーショナルデータベースアイテムにマップして、モデルを安全かつ効率的に取得して永続化する必要があります。 このマッピングは、オブジェクトリレーショナルマッピング(ORM)ツールを使用して実行できます。 Symfonyは、サードパーティのPHPデータベースORMツールである Doctrine とSymfonyを統合する別個のバンドル DoctrineBundle を提供します。
ドクトリンORM
デフォルトでは、Symfonyフレームワークはデータベースを操作するコンポーネントを提供しません。 しかし、それは Doctrine ORM と密接に統合します。 Doctrineにはデータベースストレージとオブジェクトマッピングに使用されるいくつかのPHPライブラリが含まれています。
次の例は、Doctrineの機能、データベースの設定方法、データの保存および取得方法を理解するのに役立ちます。
Doctrine ORMの例
この例では、最初にデータベースを構成し、Studentオブジェクトを作成してから、その中でいくつかの操作を実行します。
これを行うには、次の手順に従う必要があります。
ステップ1:Symfonyアプリケーションを作成する
次のコマンドを使用して、Symfonyアプリケーション dbsample を作成します。
symfony new dbsample
ステップ2:データベースを構成する
通常、データベース情報は「app/config/parameters.yml」ファイルで設定されます。
ファイルを開き、次の変更を追加します。
*parameter.yml*
parameters:
database_host: 127.0.0.1
database_port: null
database_name: studentsdb
database_user: <user_name>
database_password: <password>
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
secret: 037ab82c601c10402408b2b190d5530d602b5809
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: utf8mb4
これで、Doctrine ORMはデータベースに接続できます。
ステップ3:データベースを作成する
次のコマンドを発行して、「studentsdb」データベースを生成します。 このステップはDoctrine ORMでデータベースをバインドするために使用されます。
php bin/console doctrine:database:create
コマンドを実行すると、空の「studentsdb」データベースが自動的に生成されます。 画面に次の応答が表示されます。
Created database `studentsdb` for connection named default
ステップ4:地図情報
マッピング情報は「メタデータ」に他なりません。 Studentクラスとそのプロパティが特定のデータベーステーブルにどのようにマッピングされるかをDoctrine ORMに正確に通知するルールのコレクションです。
さて、このメタデータは、YAML、XMLなど、さまざまな形式で指定するか、アノテーションを使用してStudentクラスを直接渡すことができます。 次のように定義されています。
Student.php
ファイルに次の変更を追加します。
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/* *
* @ORM\Entity
* @ORM\Table(name = "students")
*/
class Student {
/* *
* @ORM\Column(type = "integer")
*@ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
*/
private $id;
/* *
* @ORM\Column(type = "string", length = 50)
*/
private $name;
/* *
* @ORM\Column(type = "text")
*/
private $address;
}
ここでは、テーブル名はオプションです。 テーブル名が指定されていない場合、エンティティクラスの名前に基づいて自動的に決定されます。
ステップ5:エンティティをバインドする
Doctrineはあなたのためにシンプルなエンティティクラスを作成します。 エンティティの構築に役立ちます。
次のコマンドを発行して、エンティティを生成します。
php bin/console doctrine:generate:entities AppBundle/Entity/Student
その後、次の結果が表示され、エンティティが更新されます。
Generating entity "AppBundle\Entity\Student"
> backing up Student.php to Student.php~
> generating AppBundle\Entity\Student
Student.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/* *
* @ORM\Entity
* @ORM\Table(name="students")
*/
class Student {
/* *
* @ORM\Column(type="integer")
*@ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/* *
* @ORM\Column(type = "string", length = 50)
*/
private $name;
/* *
* @ORM\Column(type = "text")
*/
private $address;
/* *
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/* *
* Set name
*
* @param string $name
*
* @return Student
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/* *
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
/**
*Set address
*
*@param string $address
*
*@return Student
*/
public function setAddress($address) {
$this->address = $address;
return $this;
}
/* *
* Get address
*
* @return string
*/
public function getAddress() {
return $this->address;
}
}
ステップ6:検証のマッピング
エンティティを作成したら、次のコマンドを使用してマッピングを検証する必要があります。
php bin/console doctrine:schema:validate
それは次の結果を生成します-
[Mapping] OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file
Studentsテーブルを作成していないため、エンティティは同期していません。 次のステップでSymfonyコマンドを使用して、studentsテーブルを作成しましょう。
ステップ7:スキーマを作成する
DoctrineはStudentエンティティに必要なすべてのデータベーステーブルを自動的に作成できます。 これは、次のコマンドを使用して実行できます。
php bin/console doctrine:schema:update --force
コマンドを実行すると、次の応答が表示されます。
Updating database schema...
Database schema updated successfully! "1" query was executed
このコマンドは、データベースの外観と実際の外観を比較し、データベーススキーマをあるべき場所に更新するために必要なSQLステートメントを実行します。
ここで、次のコマンドを使用してスキーマを再度検証します。
php bin/console doctrine:schema:validate
それは次の結果を生成します-
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files
ステップ8:ゲッターとセッター
「エンティティのバインド」セクションで見たように、次のコマンドはStudentクラスのすべてのゲッターとセッターを生成します。
$ php bin/console doctrine:generate:entities AppBundle/Entity/Student
ステップ9:オブジェクトをデータベースに永続化する
これで、Studentエンティティを対応するStudentテーブルにマッピングしました。 これで、Studentオブジェクトをデータベースに永続化できるはずです。 バンドルのStudentControllerに次のメソッドを追加します。
StudentController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Student;
class StudentController extends Controller {
/* *
* @Route("/student/add")
*/
public function addAction() {
$stud = new Student();
$stud->setName('Adam');
$stud->setAddress('12 north street');
$doct = $this->getDoctrine()->getManager();
//tells Doctrine you want to save the Product
$doct->persist($stud);
//executes the queries (i.e. the INSERT query)
$doct->flush();
return new Response('Saved new student with id ' . $stud->getId());
}
}
ここでは、ベースコントローラーのgetDoctrine()を介してgetManager()メソッドを使用して、Doctrineマネージャーにアクセスし、Doctrineマネージャーのpersist()メソッドを使用して現在のオブジェクトを永続化します。 * persist()メソッドはコマンドをキューに追加しますが、 flush()*メソッドは実際の作業を行います(学生オブジェクトを保持します)。
ステップ10:データベースからオブジェクトを取得する
StudentControllerで、学生の詳細を表示する関数を作成します。
*StudentController.php*
/* *
* @Route("/student/display")
*/
public function displayAction() {
$stud = $this->getDoctrine()
->getRepository('AppBundle:Student')
->findAll();
return $this->render('student/displayl.twig', array('data' => $stud));
}
ステップ11:ビューを作成する
表示アクションを指すビューを作成しましょう。 ビューディレクトリに移動し、ファイル「displayl.twig」を作成します。 ファイルに次の変更を追加します。
*displayl.twig*
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
<h2>Students database application!</h2>
<table class = "table">
<tr>
<th>Name</th>
<th>Address</th>
</tr>
{% for x in data %}
<tr>
<td>{{ x.Name }}</td>
<td>{{ x.Address }}</td>
</tr>
{% endfor %}
</table>
ブラウザでURL「http://localhost:8000/student/display」をリクエストすることで結果を取得できます。
画面に次の出力が生成されます-
ステップ12:オブジェクトを更新する
StudentControllerのオブジェクトを更新するには、アクションを作成し、次の変更を追加します。
/* *
* @Route("/student/update/{id}")
*/
public function updateAction($id) {
$doct = $this->getDoctrine()->getManager();
$stud = $doct->getRepository('AppBundle:Student')->find($id);
if (!$stud) {
throw $this->createNotFoundException(
'No student found for id '.$id
);
}
$stud->setAddress('7 south street');
$doct->flush();
return new Response('Changes updated!');
}
ここで、URL「http://localhost:8000/Student/update/1」をリクエストすると、次の結果が生成されます。
画面に次の出力が生成されます-
ステップ13:オブジェクトを削除する
オブジェクトの削除も同様であり、エンティティ(doctrine)マネージャーのremove()メソッドを呼び出す必要があります。
これは、次のコマンドを使用して実行できます。
/* *
* @Route("/student/delete/{id}")
*/
public function deleteAction($id) {
$doct = $this->getDoctrine()->getManager();
$stud = $doct->getRepository('AppBundle:Student')->find($id);
if (!$stud) {
throw $this->createNotFoundException('No student found for id '.$id);
}
$doct->remove($stud);
$doct->flush();
return new Response('Record deleted!');
}
symfony-フォーム
symfonyは、HTMLフォームを簡単かつ安全に処理するためのさまざまな組み込みタグを提供します。 Symfonyのフォームコンポーネントは、フォームの作成と検証プロセスを実行します。 モデルとビューレイヤーを接続します。 事前定義されたモデルから本格的なhtmlフォームを作成するための一連のフォーム要素を提供します。 この章では、フォームについて詳しく説明します。
フォームフィールド
symfonyフレームワークAPIは、フィールドタイプの大規模なグループをサポートします。 各フィールドタイプについて詳しく見ていきましょう。
FormType
Symfonyフレームワークでフォームを生成するために使用されます。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
//...
$builder = $this->createFormBuilder($studentinfo);
$builder
->add('title', TextType::class);
- ここで、$ * studentinfo はStudentタイプのエンティティです。 *createFormBuilder は、HTMLフォームを作成するために使用されます。 addメソッドは、フォーム内の入力要素を*追加*するために使用されます。 title は、学生のタイトルプロパティを指します。 *TextType
- class* はhtmlテキストフィールドを指します。 symfonyはすべてのhtml要素にクラスを提供します。
テキストタイプ
TextTypeフィールドは、最も基本的な入力テキストフィールドを表します。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\TextType;
$builder->add(‘name’, TextType::class);
ここでは、名前はエンティティにマッピングされます。
TextareaType
textarea HTML要素をレンダリングします。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
$builder->add('body', TextareaType::class, array(
'attr' => array('class' => 'tinymce'),
));
EmailType
EmailTypeフィールドは、HTML5電子メールタグを使用してレンダリングされるテキストフィールドです。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\EmailType;
$builder->add('token', EmailType::class, array(
'data' => 'abcdef', ));
PasswordType
PasswordTypeフィールドは、入力パスワードテキストボックスを表示します。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
$bulder->add('password', PasswordType::class);
RangeType
RangeTypeフィールドは、HTML5範囲タグを使用してレンダリングされるスライダーです。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\RangeType;
//...
$builder->add('name', RangeType::class, array(
'attr' => array(
'min' => 100,
'max' => 200
)
));
PercentType
PercentTypeは、入力テキストフィールドをレンダリングし、パーセンテージデータの処理に特化しています。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\PercentType;
//...
$builder->add('token', PercentType::class, array(
'data' => 'abcdef',
));
DateType
日付形式をレンダリングします。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\DateType;
//...
$builder->add(‘joined’, DateType::class, array(
'widget' => 'choice',
));
ここで、ウィジェットはフィールドをレンダリングする基本的な方法です。
次の機能を実行します。
- choice -3つの選択入力をレンダリングします。 選択の順序は、formatオプションで定義されます。
- text -テキストタイプ(月、日、年)の3つのフィールド入力をレンダリングします。
- single_text -日付型の単一の入力をレンダリングします。 ユーザーの入力は、形式オプションに基づいて検証されます。
CheckboxType
単一の入力チェックボックスを作成します。 これは、ブール値を持つフィールドに対して常に使用する必要があります。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
//...
$builder-<add(‘sports’, CheckboxType::class, array(
'label' =< ‘Are you interested in sports?’,
'required' =< false,
));
RadioType
単一のラジオボタンを作成します。 ラジオボタンが選択されている場合、フィールドは指定された値に設定されます。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\RadioType;
//...
$builder->add('token', RadioType::class, array(
'data' => 'abcdef',
));
ラジオボタンのチェックを外すことはできません。値は、同じ名前の別のラジオボタンがチェックされた場合にのみ変化することに注意してください。
RepeatedType
これは、値が一致する必要がある2つの同一のフィールドを作成する特別なフィールド「グループ」です。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
//...
$builder->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => true,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
));
これは主に、ユーザーのパスワードまたはメールを確認するために使用されます。
ButtonType
シンプルなクリック可能なボタン。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
//...
$builder->add('save', ButtonType::class, array(
'attr' => array('class' => 'save'),
));
ResetType
すべてのフィールドを初期値にリセットするボタン。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\ResetType;
//...
$builder->add('save', ResetType::class, array(
'attr' => array('class' => 'save'),
));
ChoiceType
多目的フィールドは、ユーザーが1つ以上のオプションを「選択」できるようにするために使用されます。 選択タグ、ラジオボタン、またはチェックボックスとしてレンダリングできます。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
//...
$builder->add(‘gender’, ChoiceType::class, array(
'choices' => array(
‘Male’ => true,
‘Female’ => false,
),
));
SubmitType
フォームデータを送信するには、送信ボタンを使用します。 その構文は次のとおりです-
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
//...
$builder->add('save', SubmitType::class, array(
'attr' => array('class' => 'save'),
))
フォームヘルパー関数
フォームヘルパー関数は、テンプレートでフォームを簡単に作成するために使用される小枝関数です。
form_start
有効なアクション、ルート、またはURLを指すHTMLフォームタグを返します。 その構文は次のとおりです-
{{ form_start(form, {'attr': {'id': 'form_person_edit'}}) }}
form_end
form_startを使用して作成されたHTMLフォームタグを閉じます。 その構文は次のとおりです-
{{ form_end(form) }}
テキストエリア
オプションでインラインリッチテキストJavaScriptエディターでラップされたtextareaタグを返します。
チェックボックス
type =“ checkbox”のXHTML準拠の入力タグを返します。 その構文は次のとおりです-
echo checkbox_tag('choice[]', 1);
echo checkbox_tag('choice[]', 2);
echo checkbox_tag('choice[]', 3);
echo checkbox_tag('choice[]', 4);
input_password_tag
type =“ password”のXHTML準拠の入力タグを返します。 その構文は次のとおりです-
echo input_password_tag('password');
echo input_password_tag('password_confirm');
input_tag
type =“ text”のXHTML準拠の入力タグを返します。 その構文は次のとおりです-
echo input_tag('name');
ラベル
指定されたパラメーターを持つラベルタグを返します。
ラジオボタン
type =“ radio”のXHTML準拠の入力タグを返します。 その構文は次のとおりです-
echo ' Yes '.radiobutton_tag(‘true’, 1);
echo ' No '.radiobutton_tag(‘false’, 0);
reset_tag
type =“ reset”のXHTML準拠の入力タグを返します。 その構文は次のとおりです-
echo reset_tag('Start Over');
選択する
世界のすべての国が入力された選択タグを返します。 その構文は次のとおりです-
echo select_tag(
'url', options_for_select($url_list),
array('onChange' => 'Javascript:this.form.submit();'));
提出する
type =“ submit”のXHTML準拠の入力タグを返します。 その構文は次のとおりです-
echo submit_tag('Update Record');
次のセクションでは、フォームフィールドを使用してフォームを作成する方法を学習します。
学生フォームアプリケーション
Symfonyフォームフィールドを使用して、簡単な学生詳細フォームを作成しましょう。 これを行うには、次の手順に従う必要があります-
ステップ1:Symfonyアプリケーションを作成する
次のコマンドを使用して、Symfonyアプリケーション formsample を作成します。
symfony new formsample
エンティティは通常、「src/AppBundle/Entity/」ディレクトリの下に作成されます。
ステップ2:エンティティを作成する
「src/AppBundle/Entity/」ディレクトリの下に「StudentForm.php」ファイルを作成します。 ファイルに次の変更を追加します。
StudentForm.php
<?php
namespace AppBundle\Entity;
class StudentForm {
private $studentName;
private $studentId;
public $password;
private $address;
public $joined;
public $gender;
private $email;
private $marks;
public $sports;
public function getStudentName() {
return $this->studentName;
}
public function setStudentName($studentName) {
$this->studentName = $studentName;
}
public function getStudentId() {
return $this->studentId;
}
public function setStudentId($studentid) {
$this->studentid = $studentid;
}
public function getAddress() {
return $this->address;
}
public function setAddress($address) {
$this->address = $address;
}
public function getEmail() {
return $this->email;
}
public function setEmail($email) {
$this->email = $email;
}
public function getMarks() {
return $this->marks;
}
public function setMarks($marks) {
$this->marks = $marks;
}
}
ステップ3:StudentControllerを追加する
ディレクトリ「src/AppBundle/Controller」に移動し、「StudentController.php」ファイルを作成して、次のコードを追加します。
StudentController.php
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\StudentForm;
use AppBundle\Form\FormValidationType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RangeType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\PercentType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
class StudentController extends Controller {
/* *
* @Route("/student/new")
*/
public function newAction(Request $request) {
$stud = new StudentForm();
$form = $this->createFormBuilder($stud)
->add('studentName', TextType::class)
->add('studentId', TextType::class)
->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'The password fields
must match.', 'options' => array('attr' => array('class' => 'password-field')),
'required' => true, 'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Re-enter'),
))
->add('address', TextareaType::class)
->add('joined', DateType::class, array(
'widget' => 'choice',
))
->add('gender', ChoiceType::class, array(
'choices' => array(
'Male' => true,
'Female' => false,
),
))
->add('email', EmailType::class)
->add('marks', PercentType::class)
->add('sports', CheckboxType::class, array(
'label' => 'Are you interested in sports?', 'required' => false,
))
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
return $this->render('student/newl.twig', array(
'form' => $form->createView(),
));
}
}
ステップ4:ビューをレンダリングする
「app/Resources/views/student/」ディレクトリに移動し、「newl.twig」ファイルを作成して、次の変更を追加します。
{% extends 'basel.twig' %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:14px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:24px;
width:250px;
margin: 0 0 10px 10px;
}
#simpleform textarea {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:120px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform select {
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background: grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Student details:</h3>
<div id="simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
ここで、URL「http://localhost:8000/student/new」をリクエストすると、次の結果が生成されます。
結果
symfony-検証
検証は、アプリケーションを設計する際の最も重要な側面です。 着信データを検証します。 この章では、フォームの検証について詳しく説明します。
検証の制約
バリデータは、制約に対してオブジェクトを検証するように設計されています。 オブジェクトを検証する場合は、1つまたは複数の制約をそのクラスにマップしてから、それを検証サービスに渡します。 デフォルトでは、オブジェクトを検証するときに、対応するクラスのすべての制約がチェックされ、実際に通過するかどうかが確認されます。 symfonyは次の注目すべき検証制約をサポートします。
NotBlank
プロパティが空白ではないことを検証します。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\NotBlank()
*/
protected $studentName;
}
このNotBlank制約は、studentNameプロパティが空白にならないようにします。
NotNull
値が厳密にnullと等しくないことを検証します。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\NotNull()
*/
protected $studentName;
}
Eメール
値が有効なメールアドレスであることを検証します。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\Email(
*message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
*)
*/
protected $email;
}
無効です
値がnullと正確に等しいことを検証します。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\IsNull()
*/
protected $studentName;
}
長さ
指定された文字列の長さが最小値と最大値の間にあることを検証します。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
*@Assert\Length(
* min = 5,
*max = 25,
* minMessage = "Your first name must be at least {{ limit }} characters long",
*maxMessage = "Your first name cannot be longer than {{ limit }} characters"
* )
*/
protected $studentName;
}
範囲
指定された数値が最小値と最大値の間にあることを検証します。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\Range(
*min = 40,
* max = 100,
*minMessage = "You must be at least {{ limit }} marks”,
* maxMessage = "Your maximum {{ limit }} marks”
*)
*/
protected $marks;
}
Date
値が有効な日付であることを検証します。 有効なYYYY-MM-DD形式に従います。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\Date()
*/
protected $joinedAt;
}
選択
この制約は、指定された値が指定された有効な選択肢のセットの1つであることを保証するために使用されます。 また、アイテムの配列内の各アイテムがそれらの有効な選択肢の1つであることを検証するためにも使用できます。 その構文は次のとおりです-
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/* *
* @Assert\Choice(choices = {"male", "female"}, message = "Choose a valid gender.")
*/
protected $gender;
}
ユーザーのパスワード
これにより、入力値が現在の認証済みユーザーのパスワードと等しいことが検証されます。 これは、ユーザーがパスワードを変更できるが、セキュリティのために古いパスワードを入力する必要があるフォームで役立ちます。 その構文は次のとおりです-
namespace AppBundle\Form\Model;
use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
class ChangePassword {
/* *
* @SecurityAssert\UserPassword(
*message = "Wrong value for your current password"
* )
*/
protected $oldPassword;
}
この制約は、古いパスワードがユーザーの現在のパスワードと一致することを検証します。
検証例
検証の概念を理解するための簡単なアプリケーション例を作成しましょう。
- ステップ1 *-検証アプリケーションを作成します。
次のコマンドを使用して、Symfonyアプリケーション validationsample を作成します。
symfony new validationsample
ステップ2 *-ファイル *FormValidation という名前のエンティティを、“ src/AppBundle/Entity/” *ディレクトリの下の“ FormValidation.php” *に作成します。 ファイルに次の変更を追加します。
FormValidation.php
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class FormValidation {
/* *
* @Assert\NotBlank()
*/
protected $name;
/* *
* @Assert\NotBlank()
*/
protected $id;
protected $age;
/* *
* @Assert\NotBlank()
*/
protected $address;
public $password;
/* *
* @Assert\Email(
*message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
*)
*/
protected $email;
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
public function getId() {
return $this->id;
}
public function setId($id) {
$this->id = $id;
}
public function getAge() {
return $this->age;
}
public function setAge($age) {
$this->age = $age;
}
public function getAddress() {
return $this->address;
}
public function setAddress($address) {
$this->address = $address;
}
public function getEmail() {
return $this->email;
}
public function setEmail($email) {
$this->email = $email;
}
}
ステップ3 *-StudentControllerで *validateAction メソッドを作成します。 ディレクトリ*“ src/AppBundle/Controller” に移動し、“ studentController.php” *ファイルを作成して、その中に次のコードを追加します。
StudentController.php
use AppBundle\Entity\FormValidation;
/* *
* @Route("/student/validate")
*/
public function validateAction(Request $request) {
$validate = new FormValidation();
$form = $this->createFormBuilder($validate)
->add('name', TextType::class)
->add('id', TextType::class)
->add('age', TextType::class)
->add('address', TextType::class)
->add('email', TextType::class)
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$validate = $form->getData();
return new Response('Form is validated.');
}
return $this->render('student/validatel.twig', array(
'form' => $form->createView(),
));
}
ここでは、Formクラスを使用してフォームを作成し、フォームを処理しました。 フォームが送信され、有効な場合、フォーム検証済みメッセージが表示されます。 それ以外の場合、デフォルトのフォームが表示されます。
- ステップ4 *-StudentControllerで上記で作成したアクションのビューを作成します。 ディレクトリ「app/Resources/views/student/」*に移動します。 *「validatel.twig」*ファイルを作成し、その中に次のコードを追加します。
{% extends 'basel.twig' %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:14px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:24px;
width:250px;
margin: 0 0 10px 10px;
}
#simpleform textarea {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:120px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform select {
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background: grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Student form validation:</h3>
<div id = "simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
ここでは、フォームタグを使用してフォームを作成しました。
ステップ5 *-最後に、アプリケーション、 *http://localhost:8000/student/validate を実行します。
結果:最初のページ
結果:最終ページ
symfony-ファイルのアップロード
Symfony Formコンポーネントは、ファイル入力要素を処理する FileType クラスを提供します。 画像、ドキュメントなどを簡単にアップロードできます。 FileType機能を使用して簡単なアプリケーションを作成する方法を学びましょう。
ステップ1 *-次のコマンドを使用して、新しいアプリケーション *fileuploadsample を作成します。
symfony new fileuploadsample
ステップ2 *-次のコードに示すように、名前、年齢、写真を持つエンティティ *Student を作成します。
src/AppBundle/Entity/Student.php
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert; class Student {
/* *
* @Assert\NotBlank()
*/
private $name;
/* *
* @Assert\NotBlank()
*/
private $age;
/* *
* @Assert\NotBlank(message="Please, upload the photo.")
*@Assert\File(mimeTypes={ "image/png", "image/jpeg" })
*/
private $photo;
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getAge() {
return $this->age;
}
public function setAge($age) {
$this->age = $age;
return $this;
}
public function getPhoto() {
return $this->photo;
}
public function setPhoto($photo) {
$this->photo = $photo;
return $this;
}
}
ここでは、写真プロパティにファイルを指定しました。
- ステップ3 *-次のコードに示すように、生徒用コントローラー、StudentController、および新しいメソッドaddActionを作成します。
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Student;
use AppBundle\Form\FormValidationType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class StudentController extends Controller {
/* *
* @Route("/student/new")
*/
public function newAction(Request $request) {
$student = new Student();
$form = $this->createFormBuilder($student)
->add('name', TextType::class)
->add('age', TextType::class)
->add('photo', FileType::class, array('label' => 'Photo (png, jpeg)'))
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$file = $student->getPhoto();
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getParameter('photos_directory'), $fileName);
$student->setPhoto($fileName);
return new Response("User photo is successfully uploaded.");
} else {
return $this->render('student/newl.twig', array(
'form' => $form->createView(),
));
}
}
}
ここでは、学生エンティティのフォームを作成し、リクエストを処理しました。 フォームがユーザーによって送信され、有効な場合、パラメーター photos_directory を使用して、アップロードされたファイルをアップロードディレクトリに移動しました。
ステップ4 *-以下のフォームタグを使用して、ビュー *newl.twig を作成します。
{% extends 'basel.twig' %}
{% block javascripts %}
<script language = "javascript" src = "https://code.jquery.com/jquery-2.2.4.min.js"></script>
{% endblock %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:12px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:grey;
height:24px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background:grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Student form</h3>
<div id="simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
ステップ5 *-次のように、パラメータ設定ファイルでパラメータ *photos_directory を設定します。
app/config/config.xml
parameters: photos_directory: '%kernel.root_dir%/../web/uploads/photos'
- ステップ6 *-次に、アプリケーションを実行してhttp://localhost:8000/student/newを開き、写真をアップロードします。 アップロードされた写真はphotos_directoryにアップロードされ、成功したメッセージが表示されます。
結果:最初のページ
結果:ファイルアップロードページ
Symfony-Ajaxコントロール
AJAXは、Webプログラミングの最新技術です。 ページを更新することなく、Webページ内のデータを非同期で送受信するオプションを提供します。 この章でSymfony AJAXプログラミングを学びましょう。
symfonyフレームワークは、リクエストタイプがAJAXであるかどうかを識別するオプションを提供します。 Symfony HttpFoundationコンポーネントのリクエストクラスには、この目的のためのメソッドisXmlHttpRequest()があります。 AJAX要求が行われた場合、現在の要求オブジェクトのisXmlHttpRequest()メソッドはtrueを返し、そうでない場合はfalseを返します。
このメソッドは、サーバー側でAJAX要求を適切に処理するために使用されます。
if ($request->isXmlHttpRequest()) {
//Ajax request
} else {
//Normal request
}
Symfonyは、JSON形式のレスポンスを作成するためのJSONベースのレスポンスクラスJsonResponseも提供します。 これら2つの方法を組み合わせて、シンプルでクリーンなAJAXベースのWebアプリケーションを作成できます。
AJAX-作業例
新しいページ student/ajax を学生アプリケーションに追加し、学生情報を非同期に取得してみましょう。
- ステップ1 *-StudentController(src/AppBundle/Controller/StudentController.php)にajaxActionメソッドを追加します。
/* *
* @Route("/student/ajax")
*/
public function ajaxAction(Request $request) {
$students = $this->getDoctrine()
->getRepository('AppBundle:Student')
->findAll();
if ($request->isXmlHttpRequest() || $request->query->get('showJson') == 1) {
$jsonData = array();
$idx = 0;
foreach($students as $student) {
$temp = array(
'name' => $student->getName(),
'address' => $student->getAddress(),
);
$jsonData[$idx++] = $temp;
}
return new JsonResponse($jsonData);
} else {
return $this->render('student/ajaxl.twig');
}
}
ここで、リクエストがAJAXの場合、生徒情報を取得し、JSONとしてエンコードし、 JsonResponse オブジェクトを使用して返します。 それ以外の場合は、対応するビューをレンダリングするだけです。
手順2 *-Studentビューディレクトリ *app/Resources/views/student/ にビューファイル ajaxl.twig を作成し、次のコードを追加します。
{% extends 'basel.twig' %}
{% block javascripts %}
<script language = "javascript"
src = "https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script language = "javascript">
$(document).ready(function(){
$("#loadstudent").on("click", function(event){
$.ajax({
url: '/student/ajax',
type: 'POST',
dataType: 'json',
async: true,
success: function(data, status) {
var e = $('<tr><th>Name</th><th>Address</th></tr>');
$('#student')l('');
$('#student').append(e);
for(i = 0; i < data.length; i++) {
student = data[i];
var e = $('<tr><td id = "name"></td><td id = "address"></td></tr>');
$('#name', e)l(student['name']);
$('#address', e)l(student['address']);
$('#student').append(e);
}
},
error : function(xhr, textStatus, errorThrown) {
alert('Ajax request failed.');
}
});
});
});
</script>
{% endblock %}
{% block stylesheets %}
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
{% endblock %}
{% block body %}
<a id = "loadstudent" href = "#">Load student information</a>
</br>
</br>
<table class = "table">
<tbody id = "student"></tbody>
</table>
{% endblock %}
ここでは、AJAX呼び出しを使用して生徒情報を読み込むためのアンカータグ(id:Loadstudent)を作成しました。 AJAX呼び出しは、JQueryを使用して行われます。 ユーザーがクリックすると、loadstudentタグに関連付けられたイベントがアクティブになります。 次に、AJAX呼び出しを使用して生徒情報を取得し、必要なHTMLコードを動的に生成します。
ステップ3-最後に、アプリケーション http://localhost:8000/student/ajax を実行し、[学生情報の読み込み]アンカータブをクリックします。
結果:最初のページ
結果:学生情報のあるページ
symfony-クッキーとセッション管理
Symfony HttpFoundationコンポーネントは、オブジェクト指向の方法でCookieおよびセッション管理を提供します。 Cookie はクライアント側のデータストレージを提供し、少量のデータのみをサポートします。 通常、ドメインごとに2KBであり、ブラウザによって異なります。 *セッション*はサーバー側のデータストレージを提供し、大量のデータをサポートします。 Symfony WebアプリケーションでCookieとセッションを作成する方法を見てみましょう。
クッキー
SymfonyはCookieクラスを提供してCookieアイテムを作成します。 クッキーの色を作成してみましょう。これは24時間で期限が切れ、値は blue です。 Cookieクラスのコンストラクターパラメーターは次のとおりです。
- name(type:string)-クッキー名
- 値(タイプ:文字列)-Cookie値
- expire(タイプ:整数/文字列/日時)-有効期限情報
- path(type:string)-Cookieが利用可能なサーバーパス
- domain(type:string)– Cookieが利用可能なドメインアドレス
- セキュア(タイプ:ブール値)-CookieをHTTPS接続で送信する必要があるかどうか
- httpOnly(タイプ:ブール)-CookieがHTTPプロトコルでのみ使用可能かどうか
use Symfony\Component\HttpFoundation\Cookie;
$cookie = new Cookie('color', 'green', strtotime('tomorrow'), '/',
'somedomain.com', true, true);
symfonyは、次の文字列ベースのCookie作成オプションも提供します。
$cookie = Cookie::fromString('color = green; expires = Web, 4-May-2017 18:00:00 +0100;
path=/; domain = somedomain.com; secure; httponly');
ここで、作成されたCookieを次のようにhttp応答オブジェクトのヘッダーに添付する必要があります。
$response->headers->setCookie($cookie);
Cookieを取得するには、次のようにRequestオブジェクトを使用できます。
$cookie = $request->cookie->get('color');
ここでは、 request→ cookie は PropertyBag タイプであり、PropertyBagメソッドを使用して操作できます。
セッション
symfonyはSessionInterfaceインターフェースを実装するSessionクラスを提供します。 重要なセッションAPIは次のとおりです。
*start* -セッションを開始します。
Session $session = new Session();
$session->start();
*invalidate* -すべてのセッションデータをクリアし、セッションIDを再生成します。
*set* -キーを使用してセッションにデータを保存します。
$session->set('key', 'value');
セッション値には任意のデータを使用でき、単純な整数から複雑なオブジェクトまで使用できます。
*get* -キーを使用してセッションからデータを取得します。
$val = $session->get('key');
*remove* -セッションからキーを削除します。
*clear* -セッションデータを削除します。
フラッシュバッグ
セッションは、 FlashBag と呼ばれる別の便利な機能を提供します。 これは、ページのリダイレクト中にのみデータを保持するセッション内の特別なコンテナです。 HTTPリダイレクトで役立ちます。 ページにリダイレクトする前に、データを通常のセッションコンテナの代わりにFlashBagに保存し、保存したデータを次のリクエスト(リダイレクトされたページ)で利用できるようにします。 その後、データは自動的に無効になります。
$session->getFlashBag()->add('key', 'value');
$session->getFlashBag()->get('key');
symfony-国際化
- 国際化(i18n)*および*ローカリゼーション(l10n)*は、Webアプリケーションの顧客カバレッジの向上に役立ちます。 symfonyは、この目的のために優れた翻訳コンポーネントを提供します。 この章で翻訳コンポーネントの使用方法を学びましょう。
翻訳を有効にする
デフォルトでは、Symfony Webフレームワークは翻訳コンポーネントを無効にします。 有効にするには、設定ファイルapp/config/config.ymlにトランスレーターセクションを追加します。
framework: translator: { fallbacks: [en] }
翻訳ファイル
翻訳コンポーネントは、翻訳リソースファイルを使用してテキストを翻訳します。 リソースファイルは、PHP、XML、およびYAMLで記述できます。 リソースファイルのデフォルトの場所は app/Resources/translations です。 言語ごとに1つのリソースファイルが必要です。 フランス語の messages.fr.yml というリソースファイルを作成してみましょう。
I love Symfony: J'aime Symfony
I love %name%: J'aime %name%
左側のテキストは英語で、右側のテキストはフランス語です。 2行目はプレースホルダーの使用を示しています。 プレースホルダー情報は、翻訳を使用しながら動的に追加できます。
使用法
デフォルトでは、ユーザーのシステムのデフォルトロケールはSymfony Webフレームワークによって設定されます。 デフォルトのロケールがWebアプリケーションで設定されていない場合、英語にフォールバックします。 ロケールは、WebページのURLでも設定できます。
http://www.somedomain.com/en/index
http://www.somedomain.com/fr/index
この例でURLベースのロケールを使用して、翻訳の概念を簡単に理解してみましょう。 DefaultController(src/AppBundle/Controller/DefaultController.php)のルート /\ {_ locale}/translation/sample で新しい関数 translationSample を作成します。 \ {_ locale}はデフォルトのロケールを指定するためのSymfonyの特別なキーワードです。
/* *
* @Route("/{_locale}/translation/sample", name="translation_sample")
*/
public function translationSample() {
$translated = $this->get('translator')->trans('I love Symfony');
return new Response($translated);
}
ここでは、コンテンツを現在のロケールに翻訳する翻訳方法 trans を使用しました。 この場合、現在のロケールはURLの最初の部分です。 ここで、アプリケーションを実行し、ブラウザにページ http://localhost:8000/en/translation/sample をロードします。
結果は英語で「I love symfony」になります。 ここで、ブラウザにページ http://localhost:8000/fr/translation/sample をロードします。 これで、テキストは次のようにフランス語に翻訳されます。
同様に、twigテンプレートには \ {%trans%} ブロックがあり、ビューでも翻訳機能を有効にします。 これを確認するには、 translationTwigSample と対応するビューを app/Resources/views/translate/indexl.twig に追加します。
/* *
* @Route("/{_locale}/translation/twigsample", name="translation_twig_sample")
*/
public function translationTwigSample() {
return $this->render('translate/indexl.twig');
}
View
{% extends 'basel.twig' %}
{% block body %}
{% trans with {'%name%': 'Symfony'} from "app" into "fr" %}I love %name% {% endtrans %}
{% endblock %}
ここで、transブロックはプレースホルダーも指定します。 ページ結果は次のとおりです。
symfony-ロギング
ロギングは、Webアプリケーションにとって非常に重要です。 Webアプリケーションは、一度に数百から数千のユーザーによって使用されます。 Webアプリケーションの周りの出来事のプレビューを取得するには、ロギングを有効にする必要があります。 ロギングがなければ、開発者はアプリケーションのステータスを見つけることができません。 エンドカスタマーが問題を報告するか、プロジェクトスタックホルダーがパフォーマンスの問題を報告する場合、開発者にとって最初のツールはロギングです。 ログ情報を確認することにより、問題の考えられる理由についてのアイデアを得ることができます。
Symfonyは、Monologロギングフレームワークを統合することにより、優れたロギング機能を提供します。 Monolog は、PHP環境でのロギングの事実上の標準です。 ロギングはすべてのSymfony Webアプリケーションで有効になっており、サービスとして提供されます。 次のように、ベースコントローラを使用してロガーオブジェクトを取得するだけです。
$logger = $this->get('logger');
ロガーオブジェクトが取得されると、それを使用して情報、警告、エラーを記録できます。
$logger->info('Hi, It is just a information. Nothing to worry.');
$logger->warn('Hi, Something is fishy. Please check it.');
$logger->error('Hi, Some error occured. Check it now.');
$logger->critical('Hi, Something catastrophic occured. Hurry up!');
symfony Webアプリケーション設定ファイル app/config/config.yml には、ロガーフレームワーク用の個別のセクションがあります。 ロガーフレームワークの動作を更新するために使用できます。
Symfony-メール管理
電子メール機能は、Webフレームワークで最も要求されている機能です。 簡単なアプリケーションでも連絡フォームがあり、詳細は電子メールでシステム管理者に送信されます。 Symfonyは、市場で入手可能な最高のPHP電子メールモジュールである SwiftMailer を統合します。 SwiftMailerは、最新のクラウドベースのメーラーアプリケーションに旧式のsendmailを使用してメールを送信するオプションを提供する優れたメールライブラリです。
シンプルなメールを送信して、Symfonyでのメール送信の概念を理解しましょう。 メーラー機能を作成する前に、 app/config/parameters.yml でメーラー設定の詳細を設定します。 次に、 DefaultController に新しい関数 MailerSample を作成し、次のコードを追加します。
/* *
* @Route("/mailsample/send", name="mail_sample_send")
*/
public function MailerSample() {
$message = \Swift_Message::newInstance()
->setSubject('Hello Email')
->setFrom('[email protected]')
->setTo('[email protected]')
->setBody(
$this->renderView('Emails/samplel.twig'), 'text/html' );
$this->get('mailer')->send($message);
return new Response("Mail send");
}
ここでは、 SwiftMailer コンポーネントを使用してメッセージを作成し、 Twig テンプレートを使用してメッセージの本文をレンダリングしました。 次に、コントローラーの get メソッドからキー「mailer」を使用してメーラーコンポーネントを取得しました。 最後に、 send メソッドを使用してメッセージを送信し、 Mail send メッセージを出力しました。
ここで、 http://localhost:8000/mailsample/send ページを実行すると、結果は次のようになります。
Symfony-単体テスト
単体テストは、大規模プロジェクトで進行中の開発に不可欠です。 単体テストは、アプリケーションのコンポーネントを自動的にテストし、何かが機能していないときに警告します。 単体テストは手動で実行できますが、多くの場合自動化されています。
PHPUnit
symfonyフレームワークは、PHPUnitユニットテストフレームワークと統合されます。 Symfonyフレームワークの単体テストを作成するには、PHPUnitをセットアップする必要があります。 PHPUnitがインストールされていない場合は、ダウンロードしてインストールします。 適切にインストールされている場合、次の応答が表示されます。
phpunit
PHPUnit 5.1.3 by Sebastian Bergmann and contributors
単体テスト
単体テストは、ユニットとも呼ばれる単一のPHPクラスに対するテストです。
AppBundleのLibs/ディレクトリにクラスStudentを作成します。 *“ src/AppBundle/Libs/Student.php” *にあります。
Student.php
namespace AppBundle\Libs;
class Student {
public function show($name) {
return $name. “ , Student name is tested!”;
}
}
次に、「tests/AppBundle/Libs」ディレクトリにStudentTestファイルを作成します。
StudentTest.php
namespace Tests\AppBundle\Libs;
use AppBundle\Libs\Student;
class StudentTest extends \PHPUnit_Framework_TestCase {
public function testShow() {
$stud = new Student();
$assign = $stud->show(‘stud1’);
$check = “stud1 , Student name is tested!”;
$this->assertEquals($check, $assign);
}
}
テストを実行する
ディレクトリでテストを実行するには、次のコマンドを使用します。
$ phpunit
上記のコマンドを実行すると、次の応答が表示されます。
PHPUnit 5.1.3 by Sebastian Bergmann and contributors.
Usage: phpunit [options] UnitTest [UnitTest.php]
phpunit [options] <directory>
Code Coverage Options:
--coverage-clover <file> Generate code coverage report in Clover XML format.
--coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
--coverage-html <dir> Generate code coverage report in HTML format.
次に、Libsディレクトリで次のようにテストを実行します。
$ phpunit tests/AppBundle/Libs
結果
Time: 26 ms, Memory: 4.00Mb
OK (1 test, 1 assertion)
Symfony-高度なコンセプト
この章では、Symfonyフレームワークのいくつかの高度な概念について学びます。
HTTPキャッシュ
Webアプリケーションでキャッシュすると、パフォーマンスが向上します。 たとえば、ショッピングカートWebアプリケーションのホットな製品は、限られた時間だけキャッシュできるため、データベースにアクセスすることなく迅速に顧客に提示できます。 以下は、キャッシュのいくつかの基本的なコンポーネントです。
キャッシュアイテム
キャッシュアイテムは、キー/値のペアとして保存される情報の単一ユニットです。 key は文字列で、 value は任意のPHPオブジェクトにすることができます。 PHPオブジェクトは、シリアル化によって文字列として保存され、アイテムの読み取り中にオブジェクトに変換されます。
キャッシュアダプター
キャッシュアダプターは、アイテムをストアに格納する実際のメカニズムです。 ストアは、メモリ、ファイルシステム、データベース、redisなどです。 キャッシュコンポーネントは、アダプターがキャッシュアイテムをバックエンドストアに保存できる AdapterInterface を提供します。 多くの組み込みキャッシュアダプターが利用可能です。 それらのいくつかは次のとおりです-
- 配列キャッシュアダプター-キャッシュアイテムはPHP配列に格納されます。
- ファイルシステムキャッシュアダプター-キャッシュアイテムはファイルに保存されます。
- PHPファイルキャッシュアダプター-キャッシュアイテムはphpファイルとして保存されます。
- APCuキャッシュアダプター-キャッシュアイテムは、PHP APCu拡張を使用して共有メモリに保存されます。
- Redis Cache Adapter-キャッシュアイテムはRedisサーバーに保存されます。
- PDOおよびDoctrine DBALキャッシュアダプター-キャッシュアイテムはデータベースに保存されます。
- チェーンキャッシュアダプター-レプリケーションのために複数のキャッシュアダプターを組み合わせます。
- プロキシキャッシュアダプター-キャッシュアイテムは、CacheItemPoolInterfaceを実装するサードパーティのアダプターを使用して保存されます。
キャッシュプール
キャッシュプールは、キャッシュアイテムの論理リポジトリです。 キャッシュプールは、キャッシュアダプターによって実装されます。
シンプルなアプリケーション
キャッシュの概念を理解するための簡単なアプリケーションを作成しましょう。
ステップ1 *-新しいアプリケーション *cache-example を作成します。
cd/path/to/app
mkdir cache-example
cd cache-example
- ステップ2 *-キャッシュコンポーネントをインストールします。
composer require symfony/cache
- ステップ3 *-ファイルシステムアダプターを作成します。
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
ステップ4 *-アダプタの *getItem および set メソッドを使用してキャッシュアイテムを作成します。 getItemは、キーを使用してキャッシュアイテムを取得します。 キーが永続的でない場合、新しいアイテムが作成されます。 setメソッドは実際のデータを保存します。
$usercache = $cache->getitem('item.users');
$usercache->set(['jon', 'peter']);
$cache->save($usercache);
ステップ5 *- *getItem、isHit 、および get メソッドを使用してキャッシュアイテムにアクセスします。 isHitはキャッシュアイテムの可用性を通知し、getメソッドは実際のデータを提供します。
$userCache = $cache->getItem('item.users');
if(!$userCache->isHit()) {
echo "item.users is not available";
} else {
$users = $userCache->get();
var_dump($users);
}
ステップ6 *- *deleteItem メソッドを使用してキャッシュアイテムを削除します。
$cache->deleteItem('item.users');
完全なコードリストは次のとおりです。
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
$usercache = $cache->getitem('item.users');
$usercache->set(['jon', 'peter']);
$cache->save($usercache);
$userCache = $cache->getItem('item.users');
if(!$userCache->isHit()) {
echo "item.users is not available";
} else {
$users = $userCache->get();
var_dump($users);
}
$cache->deleteItem('item.users');
?>
結果
array(2) {
[0]=>
string(3) "jon"
[1]=>
string(5) "peter"
}
デバッグ
デバッグは、アプリケーションの開発中に最も頻繁に行われるアクティビティの1つです。 symfonyは、デバッグのプロセスを容易にするための別個のコンポーネントを提供します。 Debugクラスの enable メソッドを呼び出すだけでSymfonyデバッグツールを有効にできます。
use Symfony\Component\Debug\Debug
Debug::enable()
symfonyは、デバッグ用に ErrorHandler と ExceptionHandler の2つのクラスを提供します。 ErrorHandlerはPHPエラーをキャッチして例外、ErrorExceptionまたはFatalErrorExceptionに変換しますが、ExceptionHandlerはキャッチされなかったPHP例外をキャッチし、有用なPHP応答に変換します。 ErrorHandlerとExceptionHandlerはデフォルトで無効になっています。 registerメソッドを使用して有効にすることができます。
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
ErrorHandler::register();
ExceptionHandler::register();
Symfony Webアプリケーションでは、デバッグ環境*はDebugBundleによって提供されます。 AppKernelの *registerBundles メソッドでバンドルを登録して有効にします。
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
}
プロファイラ
アプリケーションの開発には、世界クラスのプロファイリングツールが必要です。 プロファイリングツールは、実行時間、個々のモジュールの実行時間、データベースアクティビティにかかった時間、メモリ使用量など、アプリケーションに関するすべての実行時情報を収集します。 Webアプリケーションには、要求の時間、応答の作成にかかる時間など、はるかに多くの情報が必要です。 上記の指標に加えて。
symfonyは、デフォルトでWebアプリケーションでそのようなすべての情報を有効にします。 symfonyは WebProfilerBundle と呼ばれるWebプロファイリング用の個別のバンドルを提供します。 AppKernelのregisterBundlesメソッドでバンドルを登録することにより、WebアプリケーションでWebプロファイラーバンドルを有効にできます。
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
}
Webプロファイルコンポーネントは、アプリケーション構成ファイル app/config/config.xml の* web_profileセクション*で構成できます。
web_profiler:
toolbar: false
position: bottom
symfonyアプリケーションは、ページの下部にプロファイルされたデータを個別のセクションとして表示します。
symfonyは、* DataCollectorInterfaceインターフェース*とtwigテンプレートを使用して、プロファイルデータにページに関するカスタム詳細を追加する簡単な方法も提供します。 要するに、Symfonyを使用すると、優れたプロファイリングフレームワークを比較的簡単に提供することにより、Web開発者は世界クラスのアプリケーションを作成できます。
セキュリティ
前述したように、Symfonyはセキュリティコンポーネントを通じて堅牢なセキュリティフレームワークを提供します。 セキュリティコンポーネントは、次の4つのサブコンポーネントに分かれています。
- symfony/security-core-コアセキュリティ機能。
- symfony/security-http-HTTPプロトコルの統合セキュリティ機能。
- symfony/security-csrf-Webアプリケーションでのクロスサイトリクエストフォージェリに対する保護。
- symfony/security-acl-高度なアクセス制御リストベースのセキュリティフレームワーク。
簡単な認証と承認
簡単なデモアプリケーションを使用して、認証と承認の概念を学びましょう。
ステップ1 *-次のコマンドを使用して、新しいWebアプリケーション *securitydemo を作成します。
symfony new securitydemo
ステップ2 *-セキュリティ構成ファイルを使用して、アプリケーションのセキュリティ機能を有効にします。 セキュリティ関連の設定は、個別のファイル *security.yml に配置されます。 デフォルトの構成は次のとおりです。
security:
providers:
in_memory:
memory: ~
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
#http_basic: ~
#form_login: ~
デフォルト設定では、メモリベースのセキュリティプロバイダーとすべてのページへの匿名アクセスが有効になっています。 ファイアウォールセクションは、パターンに一致するファイル ^/(_(profiler | wdt)| css | images | js)/ をセキュリティフレームワークから除外します。 デフォルトのパターンには、スタイルシート、画像、JavaScript(およびプロファイラーなどの開発ツール)が含まれます。
- ステップ3 *-メインセクションに次のようにhttp_basicオプションを追加して、HTTPベースのセキュリティ認証システムを有効にします。
security:
# ...
firewalls:
# ...
main:
anonymous: ~
http_basic: ~
#form_login: ~
- ステップ4 *-メモリプロバイダーセクションにユーザーを追加します。 また、ユーザーのロールを追加します。
security:
providers:
in_memory:
memory:
users:
myuser:
password: user
roles: 'ROLE_USER'
myadmin:
password: admin
roles: 'ROLE_ADMIN'
ロールROLE_USERの_user_とロールROLE_ADMINの_admin_の2人のユーザーを追加しました。
- ステップ5 *-エンコーダーを追加して、現在ログインしているユーザーの完全な詳細を取得します。 エンコーダーの目的は、Web要求から現在のユーザーオブジェクトの完全な詳細を取得することです。
security:
# ...
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
# ...
symfonyは、ユーザー名、ロール、パスワードなどのユーザーの詳細を取得するためのインターフェイス UserInterface を提供します。 要件へのインターフェイスを実装し、エンコーダセクションで構成する必要があります。
たとえば、ユーザーの詳細がデータベースにあるとします。 次に、新しいUserクラスを作成し、UserInterfaceメソッドを実装して、データベースからユーザーの詳細を取得する必要があります。 データが使用可能になると、セキュリティシステムはそのデータを使用してユーザーを許可/拒否します。 symfonyはメモリプロバイダーのデフォルトのユーザー実装を提供します。 アルゴリズムを使用して、ユーザーパスワードを復号化します。
ステップ6 *- *bcrypt アルゴリズムを使用してユーザーパスワードを暗号化し、構成ファイルに配置します。 bcrypt アルゴリズムを使用したため、ユーザーオブジェクトは、構成ファイルで指定されたパスワードの暗号化を解除し、ユーザーが入力したパスワードとの照合を試みます。 symfonyコンソールアプリケーションは、パスワードを暗号化する簡単なコマンドを提供します。
php bin/console security:encode-password admin
Symfony Password Encoder Utility
================================
------------------ -----------------------------------
Key Value
------------------ ------------------------------------
Encoder used Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder
Encoded password
$2y$12$0Hy6/.MNxWdFcCRDdstHU.hT5j3Mg1tqBunMLIUYkz6..IucpaPNO
------------------ ------------------------------------
! [NOTE] Bcrypt encoder used: the encoder generated its own built-in salt.
[OK] Password encoding succeeded
- ステップ7 *-コマンドを使用して暗号化されたパスワードを生成し、構成ファイルで更新します。
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/securityl
security:
# http://symfony.com/doc/current/securityl#b-configuring-how-users-are-loaded
providers:
in_memory:
memory:
users:
user:
password: $2y$13$WsGWNufreEnVK1InBXL2cO/U7WftvfNvH
Vb/IJBH6JiYoDwVN4zoi
roles: 'ROLE_USER'
admin:
password: $2y$13$jQNdIeoNV1BKVbpnBuhKRuOL01NeMK
F7nEqEi/Mqlzgts0njK3toy
roles: 'ROLE_ADMIN'
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
firewalls:
# disables authentication for assets and the profiler,
# adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
# activate different ways to authenticate
# http://symfony.com/doc/current/securityl#a-co
nfiguring-howyour-users-will-authenticate
http_basic: ~
# http://symfony.com/doc/current/cookbook/security/
form_login_setupl
#form_login: ~
- ステップ8 *-次に、アプリケーションの一部のセクションにセキュリティを適用します。 たとえば、ロールのユーザーROLE_ADMINに管理セクションを制限します。
security:
# ...
firewalls:
# ...
default:
# ...
access_control:
# require ROLE_ADMIN for/admin*
- { path: ^/admin, roles: 'ROLE_ADMIN' }
- ステップ9 *-次のようにDefaultControllerに管理ページを追加します。
/* *
* @Route("/admin")
*/
public function adminLandingAction() {
return new Response('<html><body>This is admin section.</body></html>');
}
- ステップ10 *-最後に、管理ページにアクセスして、ブラウザのセキュリティ設定を確認します。 ブラウザはユーザー名とパスワードを要求し、設定されたユーザーのみを許可します。
結果
ワークフロー
ワークフローは、多くのエンタープライズアプリケーションで使用される高度な概念です。 eコマースアプリケーションでは、製品配信プロセスはワークフローです。 製品は最初に請求され(注文の作成)、ストアから調達され、パッケージ化され(パッケージング/発送準備完了)、ユーザーに発送されます。 問題がある場合、製品はユーザーから返品され、注文は元に戻されます。 アクションのフローの順序は非常に重要です。 たとえば、請求せずに製品を提供することはできません。
symfonyコンポーネントは、ワークフローを定義および管理するオブジェクト指向の方法を提供します。 プロセスの各ステップは place と呼ばれ、ある場所から別の場所に移動するために必要なアクションは transition と呼ばれます。 ワークフローを作成するための場所と遷移のコレクションは、*ワークフロー定義*と呼ばれます。
休暇管理用の簡単なアプリケーションを作成して、ワークフローの概念を理解しましょう。
ステップ1 *-新しいアプリケーション *workflow-example を作成します。
cd/path/to/dev
mkdir workflow-example
cd workflow-example
composer require symfony/workflow
ステップ2 *- *applied_by、leave_on および status 属性を持つ新しいクラス Leave を作成します。
class Leave {
public $applied_by;
public $leave_on;
public $status;
}
ここで、apply_byは退職を希望する従業員を指します。 leave_onは休暇の日付を指します。 ステータスは休暇ステータスを指します。
- ステップ3 *-休暇管理には4つの場所があります。適用、in_process、承認/拒否です。
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
$builder = new DefinitionBuilder();
$builder->addPlaces(['applied', 'in_process', 'approved', 'rejected']);
ここでは、 DefinitionBuilder を使用して新しい定義を作成し、 addPlaces メソッドを使用して場所を追加しました。
- ステップ4 *-ある場所から別の場所に移動するために必要なアクションを定義します。
$builder->addTransition(new Transition('to_process', 'applied', 'in_process'));
$builder->addTransition(new Transition('approve', 'in_process', 'approved'));
$builder->addTransition(new Transition('reject', 'in_process', 'rejected'));
ここには、 to_process、approve 、および reject の3つの遷移があります。 to_process遷移はleaveアプリケーションを受け入れ、場所をapplyからin_processに移動します。 移行の承認は、休暇申請を承認し、場所を承認済みに移動します。 同様に、拒否遷移は休暇申請を拒否し、場所を拒否に移動します。 addTransitionメソッドを使用してすべての遷移を作成しました。
- ステップ5 *-ビルドメソッドを使用して定義をビルドします。
$definition = $builder->build();
- ステップ6 *-オプションで、定義をgraphvizドット形式としてダンプできます。これは、参照目的で画像ファイルに変換できます。
$dumper = new GraphvizDumper();
echo $dumper->dump($definition);
- ステップ7 *-オブジェクトの現在の場所/ステータスを保存するために使用されるマーキングストアを作成します。
$marking = new SingleStateMarkingStore('status');
ここでは、 SingleStateMarkingStore クラスを使用してマークを作成し、現在のステータスをオブジェクトのstatusプロパティにマークしています。 この例では、オブジェクトはLeaveオブジェクトです。
- ステップ8 *-定義とマーキングを使用してワークフローを作成します。
$leaveWorkflow = new Workflow($definition, $marking);
ここでは、 Workflow クラスを使用してワークフローを作成しました。
ステップ9 *- *Registry クラスを使用して、ワークフローフレームワークのレジストリにワークフローを追加します。
$registry = new Registry();
$registry->add($leaveWorkflow, Leave::class);
ステップ10 *-最後に、ワークフローを使用して、 *can メソッドを使用して特定の遷移が適用されるかどうかを確認し、適用される場合は、applyメソッドを使用して遷移を*適用*します。 遷移が適用されると、オブジェクトのステータスはある場所から別の場所に移動します。
$workflow = $registry->get($leave);
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo "Can we approve the start process now? " . $workflow->can($leave, 'to_process') . "\r\n";
$workflow->apply($leave, 'to_process');
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo $leave->status . "\r\n";
$workflow->apply($leave, 'approve');
echo $leave->status . "\r\n";
完全なコーディングは次のとおりです-
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
class Leave {
public $applied_by;
public $leave_on;
public $status;
}
$builder = new DefinitionBuilder();
$builder->addPlaces(['applied', 'in_process', 'approved', 'rejected']);
$builder->addTransition(new Transition('to_process', 'applied', 'in_process'));
$builder->addTransition(new Transition('approve', 'in_process', 'approved'));
$builder->addTransition(new Transition('reject', 'in_process', 'rejected'));
$definition = $builder->build();
//$dumper = new GraphvizDumper();
//echo $dumper->dump($definition);
$marking = new SingleStateMarkingStore('status');
$leaveWorkflow = new Workflow($definition, $marking);
$registry = new Registry();
$registry->add($leaveWorkflow, Leave::class);
$leave = new Leave();
$leave->applied_by = "Jon";
$leave->leave_on = "1998-12-12";
$leave->status = 'applied';
$workflow = $registry->get($leave);
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo "Can we approve the start process now? " . $workflow->can($leave, 'to_process') . "\r\n";
$workflow->apply($leave, 'to_process');
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo $leave->status . "\r\n";
$workflow->apply($leave, 'approve');
echo $leave->status . "\r\n";
?>
結果
Can we approve the leave now?
Can we approve the start process now? 1
Can we approve the leave now? 1
in_process
approved
Symfony-RESTエディション
最新のアプリケーションでは、RESTサービスはコアとなる基本的な構成要素の1つです。 Webベースのアプリケーションであれ、洗練されたモバイルアプリケーションであれ、フロントエンドは通常、バックエンドRESTサービス用に適切に設計されたインターフェイスです。 Symfony RESTエディションは、RESTベースのWebアプリケーションをキックスタートするための既製のテンプレートを提供します。
Symfony RESTエディションを使用してテンプレートRESTアプリケーションをインストールする方法を学びましょう。
- ステップ1 *-次のコマンドを使用してSymfony RESTエディションをダウンロードします。
composer create-project gimler/symfony-rest-edition --stability=dev path/to/install
これにより、Symfony RESTエディションがダウンロードされます。
- ステップ2 *-質問をして構成を試みます。 すべての質問について、データベースを除くデフォルトの回答を選択します。 データベースの場合、pdo_sqliteを選択します。 PHPのsqlite拡張機能がまだインストールされていない場合は、有効にする必要があります。
- ステップ3 *-次に、次のコマンドを使用してアプリケーションを実行します。
php app/console server:run
- ステップ4 *-最後に、http://localhost:8000/を使用してブラウザでアプリケーションを開きます。
それは次の結果を生成します-
Symfony-CMFエディション
コンテンツ管理システムは、Webアプリケーションシナリオで最大の市場の1つです。 コンテンツ管理システムに利用できる多くのフレームワークがあり、ほとんどすべての言語で利用できます。 ほとんどのフレームワークは、エンドカスタマーとしての作業は簡単ですが、開発者としての作業は非常に難しく、その逆も同様です。
symfonyは、開発者が開始するためのシンプルで簡単なフレームワークを提供します。 エンドユーザーが期待するすべての基本機能も備えています。 つまり、エンドユーザーに優れたエクスペリエンスを提供するのは開発者の責任です。
Symfony CMFエディションを使用してCMSアプリケーションテンプレートをインストールする方法を見てみましょう。
- ステップ1 *-次のコマンドを使用してSymfony CMFサンドボックスをダウンロードします。
composer create-project symfony-cmf/sandbox cmf-sandbox
これにより、Symfony CMFがダウンロードされます。
- ステップ2 *-質問をして構成を試みます。 すべての質問について、データベースを除くデフォルトの回答を選択します。 データベースの場合、pdo_sqliteを選択します。 PHPのsqlite拡張機能がまだインストールされていない場合は、有効にする必要があります。
- ステップ3 *-コンソールアプリケーションを使用して、次のようにデモデータベースを作成します。
php app/console doctrine:database:create
- ステップ4 *-次のコマンドを使用して、デモデータをデータベースにロードします。
php app/console doctrine:phpcr:init:dbal --force
php app/console doctrine:phpcr:repository:init
php app/console doctrine:phpcr:fixtures:load -n
- ステップ5 *-次に、次のコマンドを使用してアプリケーションを実行します。
php app/console server:run
- ステップ6 *-最後に、http://localhost:8000/を使用してブラウザでアプリケーションを開きます。
それは次の出力を生成します-
symfony-動作例
この章では、完全なMVCベースの* BookStoreアプリケーション*をSymfony Frameworkで作成する方法を学びます。 手順は次のとおりです。
ステップ1:プロジェクトを作成する
次のコマンドを使用して、Symfonyで「BookStore」という名前の新しいプロジェクトを作成しましょう。
symfony new BookStore
ステップ2:コントローラーとルートを作成する
「src/AppBundle/Controller」ディレクトリにBooksControllerを作成します。 次のように定義されています。
BooksController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class BooksController {
/* *
* @Route("/books/author")
*/
public function authorAction() {
return new Response('Book store application!');
}
}
これでBooksControllerが作成されました。次に、アクションをレンダリングするビューを作成します。
ステップ3:ビューを作成する
「apps/Resources/views/」ディレクトリに「Books」という名前の新しいフォルダーを作成しましょう。 フォルダ内に「authorl.twig」ファイルを作成し、以下の変更を追加します。
authorl.twig
<h3> Simple book store application</h3>
次に、BooksControllerクラスでビューをレンダリングします。 次のように定義されています。
BooksController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class BooksController extends Controller {
/* *
* @Route("/books/author")
*/
public function authorAction() {
return $this->render('books/authorl.twig');
}
}
これで、基本的なBooksControllerが作成され、結果がレンダリングされます。 URL「http://localhost:8000/books/author」を使用して、ブラウザで結果を確認できます。
ステップ4:データベースの構成
「app/config/parameters.yml」ファイルでデータベースを構成します。
ファイルを開き、次の変更を追加します。
parameter.yml
# This file is auto-generated during the composer install
parameters:
database_driver: pdo_mysql
database_host: localhost
database_port: 3306
database_name: booksdb
database_user: <database_username>
database_password: <database_password>
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
secret: 0ad4b6d0676f446900a4cb11d96cf0502029620d
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: utf8mb4
これで、Doctrineはデータベース「booksdb」に接続できます。
ステップ5:データベースを作成する
次のコマンドを発行して、「booksdb」データベースを生成します。 このステップはDoctrineでデータベースをバインドするために使用されます。
php bin/console doctrine:database:create
コマンドを実行すると、空の「booksdb」データベースが自動的に生成されます。 画面に次の応答が表示されます。
それは次の結果を生成します-
Created database `booksdb` for connection named default
ステップ6:情報のマッピング
「src/AppBundle/Entity」にあるEntityディレクトリ内にBookエンティティクラスを作成します。
アノテーションを使用してBookクラスを直接渡すことができます。 次のように定義されています。
Book.php
ファイルに次のコードを追加します。
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/* *
* @ORM\Entity
* @ORM\Table(name = "Books")
*/
class Book {
/* *
* @ORM\Column(type = "integer")
*@ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
*/
private $id;
/* *
* @ORM\Column(type = "string", length = 50)
*/
private $name;
/* *
* @ORM\Column(type = "string", length = 50)
*/
private $author;
/* *
* @ORM\Column(type = "decimal", scale = 2)
*/
private $price;
}
ここでは、テーブル名はオプションです。
テーブル名が指定されていない場合、エンティティクラスの名前に基づいて自動的に決定されます。
ステップ7:エンティティをバインドする
Doctrineはあなたのためにシンプルなエンティティクラスを作成します。 エンティティの構築に役立ちます。
次のコマンドを発行して、エンティティを生成します。
php bin/console doctrine:generate:entities AppBundle/Entity/Book
その後、次の結果が表示され、エンティティが更新されます。
Generating entity "AppBundle\Entity\Book”
> backing up Book.php to Book.php~
> generating AppBundle\Entity\Book
Book.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/* *
* @ORM\Entity
* @ORM\Table(name = "Books")
*/
class Book {
/* *
* @ORM\Column(type = "integer")
*@ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
*/
private $id;
/* *
* @ORM\Column(type = "string", length = 50)
*/
private $name;
/* *
* @ORM\Column(type = "string", length = 50)
*/
private $author;
/* *
* @ORM\Column(type = "decimal", scale = 2)
*/
private $price;
/* *
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/* *
* Set name
*
* @param string $name
*
* @return Book
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/* *
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
/* *
* Set author
*
* @param string $author
*
* @return Book
*/
public function setAuthor($author) {
$this->author = $author;
return $this;
}
/* *
* Get author
*
* @return string
*/
public function getAuthor() {
return $this->author;
}
/* *
* Set price
*
* @param string $price
*
* @return Book
*/
public function setPrice($price) {
$this->price = $price;
return $this;
}
/* *
* Get price
*
* @return string
*/
public function getPrice() {
return $this->price;
}
}
ステップ8:検証のマッピング
エンティティを作成したら、次のコマンドを使用してマッピングを検証する必要があります。
php bin/console doctrine:schema:validate
それは次の結果を生成します-
[Mapping] OK - The mapping files are correct
[Database] FAIL - The database schema is not in sync with the current mapping file.
Booksテーブルを作成していないため、エンティティは同期していません。 次のステップでSymfonyコマンドを使用してBooksテーブルを作成しましょう。
ステップ9:スキーマの作成
DoctrineはBookエンティティに必要なすべてのデータベーステーブルを自動的に作成できます。 これは、次のコマンドを使用して実行できます。
php bin/console doctrine:schema:update --force
コマンドを実行すると、次の応答が表示されます。
Updating database schema...
Database schema updated successfully! "1" query was executed
ここで、次のコマンドを使用してスキーマを再度検証します。
php bin/console doctrine:schema:validate
それは次の結果を生成します-
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files.
ステップ10:ゲッターとセッター
「エンティティのバインド」セクションで見たように、次のコマンドはBookクラスのすべてのゲッターとセッターを生成します。
$ php bin/console doctrine:generate:entities AppBundle/Entity/Book
ステップ11:データベースからオブジェクトを取得する
BooksControllerで、書籍の詳細を表示するメソッドを作成します。
BooksController.php
/* *
* @Route("/books/display", name="app_book_display")
*/
public function displayAction() {
$bk = $this->getDoctrine()
->getRepository('AppBundle:Book')
->findAll();
return $this->render('books/displayl.twig', array('data' => $bk));
}
ステップ12:ビューを作成する
表示アクションを指すビューを作成しましょう。 ビューディレクトリに移動し、ファイル「displayl.twig」を作成します。 ファイルに次の変更を追加します。
displayl.twig
{% extends 'basel.twig' %}
{% block stylesheets %}
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
{% endblock %}
{% block body %}
<h2>Books database application!</h2>
<table class = "table">
<tr>
<th>Name</th>
<th>Author</th>
<th>Price</th>
</tr>
{% for x in data %}
<tr>
<td>{{ x.Name }}</td>
<td>{{ x.Author }}</td>
<td>{{ x.Price }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
ブラウザでURL「http://localhost:8000/books/display」をリクエストすることで結果を取得できます。
結果
ステップ13:ブックフォームを追加する
システムに本を追加する機能を作成しましょう。 次のように、BooksControllerに新しいページ、newActionメソッドを作成します。
//use section
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
//methods section
/* *
* @Route("/books/new")
*/
public function newAction(Request $request) {
$stud = new StudentForm();
$form = $this->createFormBuilder($stud)
->add('name', TextType::class)
->add('author', TextType::class)
->add('price', TextType::class)
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
return $this->render('books/newl.twig', array('form' => $form->createView(),));
}
ステップ14:ブックフォームのビューを作成する
新しいアクションを指すビューを作成しましょう。 ビューディレクトリに移動し、ファイル「newl.twig」を作成します。 ファイルに次の変更を追加します。
{% extends 'basel.twig' %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:14px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:24px;
width:250px;
margin: 0 0 10px 10px;
}
#simpleform textarea {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:120px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform select {
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background: grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Book details:</h3>
<div id = "simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
それは出力として次の画面を生成します-
ステップ15:書籍情報を収集して保存する
newActionメソッドを変更し、フォームの送信を処理するコードを含めましょう。 また、書籍情報をデータベースに保存します。
/**
* @Route("/books/new", name="app_book_new")
*/
public function newAction(Request $request) {
$book = new Book();
$form = $this->createFormBuilder($book)
->add('name', TextType::class)
->add('author', TextType::class)
->add('price', TextType::class)
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$book = $form->getData();
$doct = $this->getDoctrine()->getManager();
//tells Doctrine you want to save the Product
$doct->persist($book);
//executes the queries (i.e. the INSERT query)
$doct->flush();
return $this->redirectToRoute('app_book_display');
} else {
return $this->render('books/newl.twig', array(
'form' => $form->createView(),
));
}
}
ブックがデータベースに保存されたら、ブック表示ページにリダイレクトします。
ステップ16:ブックを更新する
ブックを更新するには、アクションupdateActionを作成し、次の変更を追加します。
/* *
* @Route("/books/update/{id}", name = "app_book_update" )
*/
public function updateAction($id, Request $request) {
$doct = $this->getDoctrine()->getManager();
$bk = $doct->getRepository('AppBundle:Book')->find($id);
if (!$bk) {
throw $this->createNotFoundException(
'No book found for id '.$id
);
}
$form = $this->createFormBuilder($bk)
->add('name', TextType::class)
->add('author', TextType::class)
->add('price', TextType::class)
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$book = $form->getData();
$doct = $this->getDoctrine()->getManager();
//tells Doctrine you want to save the Product
$doct->persist($book);
//executes the queries (i.e. the INSERT query)
$doct->flush();
return $this->redirectToRoute('app_book_display');
} else {
return $this->render('books/newl.twig', array(
'form' => $form->createView(),
));
}
}
ここでは、2つの機能を処理しています。 リクエストにidのみが含まれる場合、データベースからそれをフェッチして、ブックフォームに表示します。 また、リクエストに完全な書籍情報が含まれている場合は、データベースの詳細を更新し、書籍表示ページにリダイレクトします。
ステップ17:オブジェクトの削除
オブジェクトを削除するには、エンティティ(doctrine)マネージャーのremove()メソッドを呼び出す必要があります。
これは、次のコードを使用して実行できます。
/* *
* @Route("/books/delete/{id}", name="app_book_delete")
*/
public function deleteAction($id) {
$doct = $this->getDoctrine()->getManager();
$bk = $doct->getRepository('AppBundle:Book')->find($id);
if (!$bk) {
throw $this->createNotFoundException('No book found for id '.$id);
}
$doct->remove($bk);
$doct->flush();
return $this->redirectToRoute('app_book_display');
}
ここで、ブックを削除し、ブック表示ページにリダイレクトしました。
ステップ18:表示ページに追加/編集/削除機能を含める
次に、表示ビューで本体ブロックを更新し、次のようにリンクの追加/編集/削除を含めます。
{% block body %}
<h2>Books database application!</h2>
<div>
<a href = "{{ path('app_book_new') }}">Add</a>
</div>
<table class = "table">
<tr>
<th>Name</th>
<th>Author</th>
<th>Price</th>
<th></th>
<th></th>
</tr>
{% for x in data %}
<tr>
<td>{{ x.Name }}</td>
<td>{{ x.Author }}</td>
<td>{{ x.Price }}</td>
<td><a href = "{{ path('app_book_update', { 'id' : x.Id }) }}">Edit</a></td>
<td><a href = "{{ path('app_book_delete', { 'id' : x.Id }) }}">Delete</a></td>
</tr>
{% endfor %}
</table>
{% endblock %}
それは出力として次の画面を生成します-
symfonyは、一連のPHPコンポーネント、アプリケーションフレームワーク、コミュニティ、および哲学で構成されています。 symfonyは非常に柔軟で、上級ユーザー、専門家のすべての要件を満たすことができ、PHPを使用するすべての初心者にとって理想的な選択です。