Symfony Best Practice - 実践編 Chapter3-

hanahirodev.hatenablog.com

せっかくBest Practiceを翻訳したので、手を動かしながら中を見ていきます。 Chapter2まではプロジェクトの初期設定なので、割愛します。

いじった結果は随時GitHubにあげていきます。


DB接続設定

デフォルトではSQLiteを使うように設定されていますが、実際のお仕事ではMySQLを使うことが多いと思いますので、MySQLに切り替えます。

(積読消化。正月休みにがっつり読む予定。)

実践ハイパフォーマンスMySQL 第3版

実践ハイパフォーマンスMySQL 第3版

SQLアンチパターン

SQLアンチパターン

閑話休題。修正が必要なファイルは以下の2箇所。

# app/config/parameters.yml
# 削除
database_url: 'sqlite:///%kernel.root_dir%/data/blog.sqlite'
# 追加
database_host:     127.0.0.1
database_port:     null
database_name:     symfony
database_user:     root
database_password: null
# app/config/config.yml
# Doctrine Configuration (used to access databases and manipulate their information)
doctrine:
    dbal:
        # if you don't want to use SQLite, comment the two following lines
        # driver: "pdo_sqlite"
        # path: "%kernel.root_dir%/data/blog.sqlite"
        # uncomment the following lines to use a database different than SQLite
         driver:   pdo_mysql
         host:     "%database_host%"
         port:     "%database_port%"
         dbname:   "%database_name%"
         user:     "%database_user%"
         password: "%database_password%"
         charset:  UTF8 

デフォルトでMySQLの設定がされてるので、良心的。 ここで以下のコマンドを流すと、app/config/parameters.ymldatabase_nameで指定した名前のデータベースが作成されます。

$ php bin/console doctrine:database:create

さて、画面はどうなるかな。

f:id:hiroyuki-hanai:20161112025849p:plain

あ。。。データがないのか。。。 app/config/config.ymlコメントアウトした"%kernel.root_dir%/data/blog.sqlite"を読んでるっぽい。 SQLiteの中身をダンプして確認。

$ sqlite3 ./app/data/blog.sqlite 
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> .tables
symfony_demo_comment  symfony_demo_post     symfony_demo_user   
sqlite> .output ./dump.txt
sqlite> .dump
sqlite> .output stdout
sqlite>.exit

以下を参照して、SQLiteダンプをMySQLに突っ込む。

blog.gufii.net

$ mysql -uroot symfony < target.sql
ERROR 1064 (42000) at line 2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CLOB NOT NULL, authorEmail VARCHAR(255) NOT NULL, publishedAt DATETIME NOT NULL,' at line 1

MySqlにCLOB型がないみたいなので、target.sqlのCLOBをTEXTに変更

$ mysql -uroot symfony < target.sql
ERROR 1064 (42000) at line 2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOT NULL, authorEmail VARCHAR(255) NOT NULL, publishedAt DATETIME NOT NULL, PRIM' at line 1

NOT DEFERRABLE INITIALLY IMMEDIATEの指定がMySQLだと効かないみたいなので、この部分を削除して、SET FOREIGN_KEY_CHECKS=0;を追加。

詳細はapp/data/target.sql参照 これでMySQLでデモアプリが表示された。


アプリに関する設定

app/config/配下のconfig.ymlについて。「環境ごとに設定を書き換えられるように」Symfonyが以下を用意してくれている。 このコンセプトに反するから、「変更されることが予想されいてない設定は定数として定義しましょう。」ということ。

  • config_prod.ymlは本番環境の設定
  • config_dev.ymlは開発環境の設定
  • config_test.ymlはファンクショナルテスト用の環境設定。ブラウザからはアクセスできない。*1

環境設定ファイルの読み込みは、AppKernel.registerContainerConfiguration()で実行されている。

「semantic dependency injection」とはなんだろう

まずは辞書的な「semantic」の意味を調べる。

セマンティックとは、一般的には「意味」や「意味論」に関することを指す語である。IT用語としては、コンピュータに文書や情報の持つ意味を正確に解釈させ、文書の関連付けや情報収集などの処理を自動的に行わせる技術について用られる語である。

う〜ん。わからん。Best Practiceでは*Extensionを使うのを「semantic dependency injection」と言っているので、「How to Load Service Configuration inside a Bundle」をチェック。

Symfonyでは、様々なサービスを使っていることに気づくでしょう。これらのサービス群は、あなたのアプリのapp/config/ディレクトリに登録されていることでしょう。しかし他のプロジェクトから、そのバンドルを使いたくなったときには、バンドル自体にサービス設定が内包されていた方が良いでしょう。

ふむ。バンドル単体を公開したい人に向けたBestPracticeですかね。バンドルの利用者が設定をごにょごにょしなくても済むように、バンドルの中にサービスの設定を閉じ込めておこうという趣旨であることは理解できました。