Symfony2.7インストール〜初期設定->symblog チュートリアル(http://symblog.ganchiku.com/)を作成

## まえおき
PHP歴半年のわたくしは、ここまでたどり着くのに
期間だけで言えばなんやかんや2ヶ月ほどかかりました。。。

とり急ぎ最初の難関であるSymfony2インストールおよび初期設定、
そしてsymblog作成においてエラーが発生した箇所について箇条書きでメモっときます。

初心者で苦労している方に向けて情報共有のつもりで書きました。

なお今回の作成過程でエラーを解消するにあたり、
先人の下記投稿およびGitHubリポジトリには特に助けれられました!

**参考にした記事**
[Symfony2 チュートリアル「symblog」 Symfony 2.3 との相違点まとめ + α](http://qiita.com/sukobuto/items/557bc13a303fcd2c161d)
[https://github.com/seyfer/symblog.meのパート5"タグクラウド"の箇所のソースコード
](https://github.com/seyfer/symblog.me/commit/50bc70029216c1f362e16688563dcc495b040979)

この場を借りて、心より御礼申し上げますm(_ _)m

## 作成環境
Mac上で以下テスト環境を構築し、その中でsymblogを作成

- VirtualBox 4.3.28
- CentOS7
- PHP 5.4.16
- PostgreSQL 9.2.13
- Symfony 2.7

正直、このテスト環境自体の構築に一番時間がかかりましたし、
何度も心が折れかけました。。。

プログラミングやデータベースのスキル習得以外に、ネットワークやサーバー構築、
Linuxの知識・スキルがこれほどまでに必要になるとは夢にも思っていませんでした。

このあたりについては別の記事で共有したいと思います。

## インストール手順

### 0.Symfonyインストーラのインストールと実行権限の変更

    <実行コマンド>
    $ curl -LsS http://symfony.com/installer -o /usr/local/bin/symfony
    $ chmod a+x /usr/local/bin/symfony

### 1.Symfonyインストール

    <実行コマンド>
    $ cd インストールしたい任意のディレクトリ
    $ symfony new [任意のディレクトリ名] 2.7
    (実行結果)
    Downloading Symfony...

    4.52 MB/4.52 MB ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  100%

    Preparing project...

    ✔  Symfony 2.3.31 was successfully installed. Now you can:

    * Change your current directory to /var/www/html/sample/blog

    * Configure your application in app/config/parameters.yml file.

    * Run your application:
        1. Execute the php app/console server:run command.
        2. Browse to the http://localhost:8000 URL.

    * Read the documentation at http://symfony.com/doc

--> !!注意点!!
"2.7"はSymfonyのバージョンを示しており、当然他のバージョンも指定は可能ですが、
私の環境では2.7以下のバージョンだと初期設定すらうまくいかなかったです。。。

## 初期設定
### 1.データベースとメーラー、ロケールの設定
--> データベース(PostgreSQL)とメーラー(gmail)の設定

    <実行コマンド>
    $ vim app/config/parameters.yml

```lang:parameters.yml
parameters:
    database_host: localhost
    database_port: null
    database_name: 任意のデータベース名
    database_user: データベースのユーザー名
    database_password: データベースのパスワード
    mailer_transport: gmail
    mailer_host: smtp.gmail.com
    mailer_user: gmail@gmail.com
    mailer_password: gmail1234
    secret: ...ハッシュ
```

—> ロケール(locale)とデータベースドライバ(pdo_pgsql)の設定

    <実行コマンド>
    $ vim app/config/config.yml

```lang:parameters.yml
...
parameters:
   locale: ja
...
doctrine:
    dbal:
        driver:   pdo_pgsql
...
```

### 2.ベンダー(vendor/)をcomposerで更新

    <実行コマンド>
    (プロジェクトルートで)
    $ curl -sS https://getcomposer.org/installer | php
    $ php composer.phar install
    $ php composer.phar update

### 3.cache, logsのキャッシュを消す&書き込み権限を与える

    <実行コマンド>
    (プロジェクトルートで)
    $ rm -rf app/cache/*
    $ rm -rf app/logs/*
    $ chmod 777 app/cache
    $ chmod 777 app/logs
    $ APACHEUSER=\`ps aux | grep -E '[a]pache|[h]ttpd' | grep -v root | head -1 |     cut -d\  -f1\`
    $ sudo setfacl -R -m u:$APACHEUSER:rwX -m u:`ユーザー名`:rwX app/cache app/logs
    $ sudo setfacl -dR -m u:$APACHEUSER:rwX -m u:`ユーザー名`:rwX app/cache app/logs

### 4.動作要件を満たしているか確認する

    <実行コマンド>
    $ php app/check.php`

    (実行結果)

    Symfony2 Requirements Checker
    \~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    > PHP is using the following php.ini file:
      /etc/php.ini

    > Checking Symfony requirements:
      ................................W......

                                               
     [OK]                                          
     Your system is ready to run Symfony2 projects 
                                               

    Optional recommendations to improve your setup
    \~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     * a PHP accelerator should be installed
       > Install and/or enable a PHP accelerator (highly recommended).


    Note  The command console could use a different php.ini file
    ~~~~  than the one used with your web server. To be on the
          safe side, please check the requirements from your web
          server using the web/config.php script.

### 5.開発用コンソールを閲覧できるようにする

    <実行コマンド>
    $ vim web/config.php

```lang:config.php(ファイル内コメントアウト)
/* コメントアウトここから
if (!isset($_SERVER['HTTP_HOST'])) {
    exit('This script cannot be run from the CLI. Run it from a browser.');
}

if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
    '127.0.0.1',
    '::1',
))) {
    header('HTTP/1.0 403 Forbidden');
    exit('This script is only accessible from localhost.');
}
コメントアウトここまで */
```
    <実行コマンド>
    $ vim web/app_dev.php

```lang:app_dev.php(ファイル内コメントアウト)
/* コメントアウトここから
if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !(in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1')) || php_sapi_name() === 'cli-server')
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
コメントアウトここまで */
```

### 6.一般ユーザーでキャッシュを削除できるようにする

    <実行コマンド>
    $ vim app/autoload.php

```lang:autoload.php(ファイル内追記)
<?php
umask(0000); // 先頭行に記述する
^^^^^^^^^^^^
```

### 7.ブラウザで設定確認

    <ブラウザで下記アクセス>
    (ローカルアドレス)/web/config.php

### 8.ブラウザで最終確認

    <ブラウザで下記アクセス>
    (ローカルアドレス)/web/app_dev.php

※ここまででブラウザ閲覧が不可の際は...
1. Apache自体のドキュメントルートのユーザーパーミッション変更
2. SELinuxによるアクセス制御の設定(適切な設定or無効化する)

が考えられます。初心者にとってはこいつらがかなりの曲者です。
...って今回の作成とは関係ありませんが。これについてはまた別の記事で。

と、こんな感じで初期設定完了。

## symblog作成
### はじめに
基本はチュートリアルに沿って作成を行いますが、環境やバージョン違い、
ベンダーのアップデート?等で一部エラーが発生する箇所が出てきます。
そのあたりを中心に書いていきます。

あとGitHubにリポジトリを作成しておきました。
https://github.com/kk0917/symblog2
※app/config/parameters.ymlは管理対象外にしています...って当たり前ですよね(笑)。

### [パート1] - Symfony2 のコンフィギュレーションとテンプレート
http://symblog.ganchiku.com/docs/configuration-and-templating.html
--> このパートは無難に進んでいきます。

### [パート2] - ページの作成: バリデータ、フォーム、メール送信
http://symblog.ganchiku.com/docs/validators-and-forms.html
--> はい来ました。エラー発生です。

#### <エラー内容>
"メール送信"の項目で使うメソッド「hasFlash()」がSymfony2.3から使えなくなったので、
別のメソッド「flashBag.has()」での書き換えが必要です。

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Controller/PageController.php
・(プロジェクトルート)src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Controller/PageController.php

```lang:PageController.php(hasFlash()メソッドを書き換え)
...
    $this->get('mailer')->send($message);

-   $this->get('session')->setFlash('blogger-notice', 'Your contact enquiry ...');
+   $this->get('session')->getFlashBag()->set('blogger-notice', 'Your contact ...');

    // Redirect - This is important to prevent users re-posting
...
```

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Resources/views/Page/contact.html.twig

```lang:contact.html.twig(hasFlash()メソッドを書き換え・追記)
...
    </header>

    </div>
-   {% if app.session.hasFlash('blogger-notice') %}
+   {% if app.session.flashBag.has('blogger-notice') %}
        <div class="blogger-notice">
-           {{ app.session.flash('blogger-notice') }}
+           {% for flashMessage in app.session.flashBag.get('blogger-notice') %}
+               {{ flashMessage }}
+           {% endfor %}
        </div>
    {% endif %}

    <p>Want to contact symblog?</p>
...
```

### [パート3] - ページの作成: バリデータ、フォーム、メール送信
http://symblog.ganchiku.com/docs/doctrine-2-the-blog-model.html
--> このパートはエラーは発生しませんでした。

### [パート4] - コメントモデル: コメントの追加、 Doctrine リポジトリとマイグレーション
http://symblog.ganchiku.com/docs/extending-the-model-blog-comments.html
--> はい来たエラー！

#### <エラー内容1>
"さらにモデルについて: コメントエンティティの作成"の項目で
ブログのコメント機能で使うデータベーステーブルをSymfony2のメソッドで作成する際に、
カラム名に「予約語」が設定されてしまい、その後のデータフィクスチャでエラーになる。

「予約語」については以下参照ください。

Symfony2公式サイトの[ガイドブック > データベースとDoctrine](http://docs.symfony.gr.jp/symfony2/book/doctrine.html)より抜粋

```
Caution
クラス名やプロパティは、予約されたSQLキーワード(groupや user)にはマップされませんので、
注意してください。例えば、エンティティのクラス名が Group である場合、
デフォルトでは、テーブル名が group となります。
しかし、このテーブル名は、いくつかのエンジンでは SQL エラーとなるでしょう。
Doctrine の Reserved SQL keywords documentation で、こういった名前をどうエスケープするか
参照して下さい。
```

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Entity/Comment.php
・(プロジェクトルート)src/Blogger/BlogBundle/DataFixtures/ORM/CommentFixtures.php
・(プロジェクトルート)src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Entity/Comment.php

```lang:Comment.php(ファイル内変数名&ファイル内メソッドの第一引数を修正)
①コメントエンティティ の項目で修正
...
- protected $user;      <— この変数名だとカラムの自動生成で「user」と予約語になってしまう
+ protected $testuser;  <- 予約語ではない任意の変数名にする
...

②フォームバリデーション ※コメント投稿機能の項目で修正
...
- $metadata->addPropertyConstraint('user', new NotBlank(array(
+ $metadata->addPropertyConstraint(‘testuser', new NotBlank(array(
...
```

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/DataFixtures/ORM/CommentFixtures.php

```lang:CommentFixtures.php(ファイル内メソッド名を修正→複数箇所あり！)
...
- $comment->setUser(…);
+ $comment->setTestuser(…); <— "set"後の先頭1文字目を大文字にするレギュレーションらしいです… 
※複数箇所修正！！
...
```
—> 上記2ファイルを修正した上でフィクスチャをロード
　「php app/console doctrine:fixtures:load」実行してください。

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig

```lang:index.html.twig(ファイル内記述を修正)
・コメント showテンプレート の項目で修正
...
- <p><span class="highlight">{{ comment.user }}</span>…
+ <p><span class="highlight">{{ comment.testuser }}</span>…
...
```

#### <エラー内容2>
"Doctrine 2 マイグレーション(Migrations)"の項目で
マイグレーションのプラグインをインスタンスする記述で名前空間の指定に誤りがある。

**<書き換え対象のファイル>**
・(プロジェクトルート)vendor/doctrine/doctrine-migrations-bundle/DoctrineMigrationsBundle.php

    <実行コマンド>
    $ find . -name "*.php" | grep DoctrineMigrationsBundle
    (実行結果)
    ./vendor/doctrine/doctrine-migrations-bundle/DoctrineMigrationsBundle.php
--> 上記で名前空間を定義しているファイル名が分かったのでファイルの中身を確認

    <実行コマンド>
    $ vim vendor/doctrine/doctrine-migrations-bundle/DoctrineMigrationsBundle.php

```lang:DoctrineMigrationsBundle.php(ファイル内の"namespace"を確認)
...
namespace Doctrine\Bundle\MigrationsBundle;
...
```
-->この空間名でAppKernel.phpにフルパスでインスタンスを記述

    <実行コマンド>
    $ vim app/AppKernel.php

```lang:AppKernel.php(ファイル内インスタンス記述を修正)
...

public function registerBundles()
{
    $bundles = array(
        // ...
-        new Symfony\Bundle\DoctrineMigrationsBundle\DoctrineMigrationsBundle(),
+        new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
        // ...
    );
    // ...
}

...
```

### [パート5] - ビューのカスタマイズ: Twig エクステンション、サイドバーと Assetic
http://symblog.ganchiku.com/docs/customising-the-view-more-with-twig.html
--> またですエラー...。

#### <エラー内容1>
"サイドバー -> タグクラウド"の項目で、修正する必要があるファイルのパスに誤りがある。

    対象ファイルのパス正誤表 
    誤 :src/Blogger/BlogBundle/Repository/BlogRepository.php
    正 :src/Blogger/BlogBundle/Entity/Repository/BlogRepository.php
--> .../BlogBundle/のあとのEntity/ が足りないので注意。

※ここに限らずファイルのパスや全体のディレクトリは
　「$ tree src/Blogger」コマンドで適宜確認しておくと全体の構造を把握できる。

#### <エラー内容2>
上記と同じ"サイドバー -> タグクラウド"の項目で、
layout.html.twigにインクルードするサイドバーエリア用twigファイル(この時点で新規作成)の
renderメソッドの記述に誤りがある

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Resources/views/layout.html.twig

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Resources/views/layout.html.twig

```lang:layout.html.twig(ファイル内記述を修正)
...

 {% block sidebar %}
-    Sidebar content
+    {% render controller("BloggerBlogBundle:Page:sidebar") %}
_______________^^^^^^^^^^^________________________________\^
 {% endblock %}

...
```
--> チュートリアルでは「{% render "BloggerBlogBundle:Page:sidebar" %}」となっていて
上記" ^ "の部分が抜けている

#### <エラー内容3>
上記と同じ"サイドバー -> タグクラウド"の項目で、
新しいTwigファイル、layout.html.twigを新規作成しているのに
src/Blogger/BlogBundle/Resources/config/routing.yml でルーティングの追加をしていない。

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Resources/config/routing.yml

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Resources/config/routing.yml

```lang:routing.yml(ファイル内追記)
BloggerBlogBundle_homepage:
     requirements:
         _method:  GET
 
+BloggerBlogBundle_sidebar:
+    pattern:  /
+    defaults: { _controller: BloggerBlogBundle:Page:sidebar }
+    requirements:
+        _method:  GET
+
BloggerBlogBundle_about:

...
```

#### <エラー内容4>
"サイドバー -> 最近のコメント一覧"の項目で、修正する必要があるファイルのパスに誤りがある。

    対象ファイルのパス正誤表 
    誤 :src/Blogger/BlogBundle/Repository/CommentRepository.php
    正 :src/Blogger/BlogBundle/Entity/Repository/CommentRepository.php
--> .../BlogBundle/のあとのEntity/ が足りないので注意。

#### <エラー内容5>
上記と同じ"サイドバー -> 最近のコメント一覧"の項目で、
パート4の"コメントエンティティ"の項目であった「予約語の回避」関連の
指定するカラム名を修正しないとエラーになる。

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Resources/views/Page/sidebar.html.twig

```lang:sidebar.html.twig(ファイル内記述を修正)
...

- <p class="small"><span class="highlight">{{ comment.user }}</span> commented on 
+ <p class="small"><span class="highlight">{{ comment.testuser }}</span> commented on 

...
```

#### <エラー内容6>
"Twig エクステンション -> ビューの修正"の項目で、
パート4の"コメントエンティティ"の項目であった「予約語の回避」関連の
指定するカラム名を修正しないとエラーになる。

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig

    <実行コマンド>
    $ vim src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig

```lang:index.html.twig(ファイル内記述を修正)
...

- <p><span class="highlight">{{ comment.user }}</span> commented <time datetime="{{ comment.created|date('c') }}">{{ comment.created|d...
+ <p><span class="highlight">{{ comment.testuser }}</span> commented <time datetime="{{ comment.created|date('c') }}">{{ comment.created|c...

...
```

#### <エラー内容7>
"URL にスラッグを使用する -> ブログエンティティの修正"の項目で、
migrations:diffコマンドの実行でテーブルスキーマ変更用に自動生成される
マイグレーションファイル内のSQLがPostgreSQLに対応しておらずエラーとなる。

ので、エラーを回避するために...
**<対応方法>**
1. 自動生成されたマイグレーションファイル内のSQL文を直接修正
2. データベースにログインしのテーブル内カラム値を修正
を行います。

**<書き換え対象のファイル>**
・(プロジェクトルート)app/DoctrineMigrations/VersionYYYYMMDDhhmmss.php
—> $ php app/console doctrine:migrations:diff を実行すると自動生成される
   マイグレーションファイル。Versionのあとはコマンド実行時の年月日時分秒。

    <実行コマンド>
    $ php app/console doctrine:migrations:diff
    (実行結果)
    Generated new migration class to “(プロジェクトルート)/app/DoctrineMigrations/VersionYYMMDDhhmmss.php" from schema differences.
    —>ここで出力されている、自動作成されたファイル内のSQL文を修正

```lang:VersionYYMMDDhhmmss.php(ファイル内記述を修正)
...

public function up(Schema $schema)
{
    // this up() migration is auto-generated, please modify it to your needs
    $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration c    an only be executed safely on \'postgresql\'.');

-        $this->addSql('ALTER TABLE blog ADD slug VARCHAR(255) NOT NULL');
+        $this->addSql('ALTER TABLE blog ADD slug VARCHAR(255)');
}

...
--> slugカラムの追加とNOT NULL制約の付与が同時に実行できないため、
    一旦 NOT NULL を削除しslugカラムの追加を単体で実行するSQL文に書き換える
```

ここで一旦migrations:migrateコマンド実行

    <実行コマンド>
    $ $ php app/console doctrine:migrations:migrate
    (実行結果)
    WARNING! You are about to execute a database migration that could result in schema changes and data lost. Are you sure you wish to continue? (y/n)y <--「y」を入力,Enter

      ++ migrating YYYYMMDDhhmmss

         -> ALTER TABLE blog ADD slug VARCHAR(255)

      ++ migrated (0.04s)

    --> エラーが発生することなくテーブルスキーマの変更(slugカラムの追加)ができました。

データベースのテーブルに処理が反映されているかチェックするために、
PostgreSQLにログインしてblogテーブルのスキーマを確認してみると…

    $ psql -U ユーザー名 データベース名
    ユーザ  user のパスワード: 
    psql (9.2.13)
    "help" でヘルプを表示します.

    database_name=# \d blog
    (実行結果)
                   テーブル "public.blog"
       列    |               型               |  修飾語  
    ---------+--------------------------------+----------
     id      | integer                        | not null
     title   | character varying(255)         | not null
     author  | character varying(100)         | not null
     blog    | text                           | not null
     image   | character varying(20)          | not null
     tags    | text                           | not null
     created | timestamp(0) without time zone | not null
     updated | timestamp(0) without time zone | not null
     slug    | character varying(255)         |          <— カラムは追加されたがまだNOT NULLは未設定
    インデックス:
        "blog_pkey" PRIMARY KEY, btree (id)
    参照元：
        TABLE "comment" CONSTRAINT "fk_9474526cdae07e97" FOREIGN KEY (blog_id) REFERENCES blog(id)

次に、ここまでの作業だとslugカラムにはNOT NULL制約が設定されていないため、
まだテーブルスキーマとエンティティ間の設定に差異が生じている状態となっています。

この状態を利用して、再度migrations:diffコマンドを実行すると、
上記の差異をマイグレーションバンドルが自動的に調べて
slugカラムにNOT NULL制約を付与するためのマイグレーションファイルが自動生成される。

    <実行コマンド>
    $ php app/console doctrine:migrations:diff
    (実行結果)
    Generated new migration class to “(プロジェクトルート)/app/DoctrineMigrations/VersionYYMMDDhhmmss.php" from schema differences.
    —> SQL文に SET NOT NULL が記述されている。

    $ cat app/DoctrineMigrations/VersionYYYYMMDDhhmmss.php
    --> 2度目のmigrations:diffコマンドで生成されたファイルを参照

```lang:VersionYYYYMMDDhhmmss.php(2度目に生成されたマイグレーションファイル)
...

public function up(Schema $schema)
{
    // this up() migration is auto-generated, please modify it to your needs
    $this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration c    an only be executed safely on \'postgresql\'.');

    $this->addSql('ALTER TABLE blog ALTER slug SET NOT NULL');
}
—> SQL文に”SET NOT NULL”が記述されている。ここではSQL文の修正は不要！

...
```

さて、準備が整ったので、ここでmigratios;migrateコマンドを実行すれば…

**っとちょっと待った！！このままコマンドを実行するとまたエラーになります。**

なぜなら、先ほどblogテーブルに追加されたslugカラムの列には
null値がデフォルトとしてセットされてしまっている関係で、
新たにslugカラムにNOT NULL制約が付与できない状態になっているからです。

そのため、migrateコマンドを実行する前に、
まずは**blogテーブル内slugカラム列のnull値を削除する**必要があります。

PostgreSQLにログインして、blogテーブルのレコードでslugカラムの列全てに
null値を削除するSQLを実行します。

    <実行コマンド>
    $ psql -U ユーザー名 データベース名
    ユーザ user のパスワード: 
    psql (9.2.13)
    "help" でヘルプを表示します.

    database_name=# UPDATE blog SET slug = '';
    (実行結果)
    UPDATE 5

そしてそして、ここでようやくmigrateコマンドの実行！

    <実行コマンド>
    $ php app/console doctrine:migrations:migrate
         
                    Application Migrations                    

    WARNING! You are about to execute a database migration that could result in schema changes and data lost. Are you sure you wish to continue? (y/n)y
    Migrating up to 20150902122918 from 20150902120728

      ++ migrating 20150902122918

         -> ALTER TABLE blog ALTER slug SET NOT NULL

      ++ migrated (0.04s)

      ------------------------

      ++ finished in 0.04
      ++ 1 migrations executed
      ++ 1 sql queries

PostgreSQL上でテーブルスキーマを確認すると…

    <実行コマンド>
    $ psql -U ユーザー名 データベース名
    ユーザ user のパスワード: 
    psql (9.2.13)
    "help" でヘルプを表示します.

    database_name=# \d blog
               テーブル "public.blog"
       列    |               型               |  修飾語  
    ---------+--------------------------------+----------
     id      | integer                        | not null
     title   | character varying(255)         | not null
     author  | character varying(100)         | not null
     blog    | text                           | not null
     image   | character varying(20)          | not null
     tags    | text                           | not null
     created | timestamp(0) without time zone | not null
     updated | timestamp(0) without time zone | not null
     slug    | character varying(255)         | not null <-- NOT NULLが付与されている!
    インデックス:
        "blog_pkey" PRIMARY KEY, btree (id)
    参照元：
        TABLE "comment" CONSTRAINT "fk_9474526cdae07e97" FOREIGN KEY (blog_id) REFERENCES blog(id)

以上で無事にテーブルスキーマを変更できました。

### [パート6] - テスト: PHPUnit を使用したユニットテストと機能テスト
http://symblog.ganchiku.com/docs/testing-unit-and-functional-phpunit.html
--> はい、最後のパートです。はいまたエラーです。もう慣れっこです（笑）


#### <エラー内容1>
**このエラーに関してはわたくし固有のものだと思いますが念のため共有します。**
"ユニットテスト->ブログエンティティのテスト - slugify メソッド"の項目で、
Symfony2インストール時にデフォルトで存在する"(プロジェクトルート)/src/AppBundle/~"を
この時点まで削除せずそのままにしていたことでphpunitコマンド実行時にエラー発生。

**<詳細>**
ユニットテストを行う際、phpunitコマンドはapp/phpunit.xmlに記述の通り、
(プロジェクトルート)/src/以下のバンドル内テストフォルダを自動的に参照しテストを実行します。

そのため、app/phpunit.xmlのデフォルト設定だと、
存在するすべてのバンドルのテストフォルダを参照するため、
余計なバンドルがあるとエラーになってしまいます。

ディレクトリ構造全体から上の解説をすると、
AppBundleを残した状態のままだとphpunitコマンドは...

```
src
├── AppBundle(Symfony2インストール時にデフォルトで存在するバンドル)
│   ├── AppBundle.php
│   ├── Controller
│   │   └── DefaultController.php
│   └── Tests <------------------------------ src/以下にあるこのTestsフォルダも参照してしまう
│       └── Controller
│           └── DefaultControllerTest.php 
|
└── Blogger(今回のSymblogで作成したバンドル)
    └── BlogBundle
        ├── BloggerBlogBundle.php
        ├── Controller
        │   ├── ...
        |
        ...(長いので省略)
        |
        ├── Tests <-------------------------- 本当はここだけ見てほしい
        │   ├── Controller
        │   │   └── PageControllerTest.php
        │   ├── Entity
        │   │   ├── BlogTest.php
        │   │   └── CommentTest.php
        │   └── Twig
        │       └── Extensions
        │           └── BloggerBlogExtensionTest.php
        └── Twig
            └── Extensions
                └── BloggerBlogExtension.php
```

このような感じです。
はじめからAppBundleフォルダ削除しておけよって話です。
お恥ずかしいエラーです。でも初心者の方でもしかしたら同じ状況の方いるかもと思い、
念のため紹介でした。

...ということでエラー解消のため、

**<削除対象のフォルダ>**
・(プロジェクトルート)src/AppBundle/*

    <実行コマンド>
    $ rm -rf src/AppBundle

-->フォルダをまるっと削除して~~エラー解消です。~~
(2015/09/07追記)...すいません、嘘です。まだありましたm(_ _)m

バンドルを削除したのですから、カーネルに登録してあるAppBundleの削除と
メインのルーティング設定に記述してあるAppBundleのルートを削除しないと
フロント側のエラーは解消されないです。

**<書き換え対象のファイル>**
・(プロジェクトルート)app/AppKernel.php
・(プロジェクトルート)app/config/routing.yml

    <実行コマンド>
    $vim app/AppKernel.php

```実行結果
...
     new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
-    new AppBundle\AppBundle(), <-- この行を削除
     new Blogger\BlogBundle\BloggerBlogBundle(),
...
```

    <実行コマンド>
    $vim app/config/routing.yml

```実行結果
...
 blogger_blog:
     resource: "@BloggerBlogBundle/Resources/config/routing.yml"
     prefix:   /
- <-- この行を含む以下すべてを削除
-app:
-    resource: "@AppBundle/Controller/"
-    type:     annotation
...
```

#### <エラー内容2>
正確にはエラーではなく気づいたことなのですが...
"Twig エクステンションのテスト"の項目で、修正が必要なファイル名の指示に誤りがある。

**誤りがあるファイル名**
誤 ・(プロジェクトルート)src/Blogger/BlogBundle/Twig/Extensions/BloggerBlogBundle.php
正 ・(プロジェクトルート)src/Blogger/BlogBundle/Twig/Extensions/BloggerBlogExtension.php
--> 上記の通り、存在するファイル名の内容を修正してください。

#### <エラー内容3>
"機能テスト->ブログのコメント追加のテスト"の項目で、
テストのために新規作成するファイル内の記述内容に誤りがある。

**<書き換え対象のファイル>**
・(プロジェクトルート)src/Blogger/BlogBundle/Tests/Controller/BlogControllerTest.php
--> なお書き換え箇所はわたくしの場合は2箇所ありました。下記①は状況に応じて対応してください。

    <実行コマンド>
    $vim src/Blogger/BlogBundle/Tests/Controller/BlogControllerTest.php

```php
修正箇所
...

    public function testAddBlogComment()
    {
        $client = static::createClient();

-       $crawler = $client->request('GET', '/1/a-day-with-symfony');
+       $crawler = $client->request('GET', '/21/a-day-with-symfony');<-- ①

        $this->assertEquals(1, $crawler->filter('h2:contains("A day with Symfony2")')->count());

        // Select based on button value, or id or name for buttons
        $form = $crawler->selectButton('Submit')->form();

        $crawler = $client->submit($form, array(
-           'blogger_blogbundle_commenttype[user]'          => 'name',
-           'blogger_blogbundle_commenttype[comment]'       => 'comment',
+           'blogger_blogbundle_comment[testuser]' => 'name',
+           'blogger_blogbundle_comment[comment]'  => 'comment',<-- ②
        ));

...
```
-->
①はこのチュートリアル途中のエラー修正の関係?で
投稿ダミー記事のIDが初回投稿時の"1"から変更になっている場合に修正が必要な箇所です。

エラー原因を探っててふとブラウザでURLを見ていたらID箇所が"21"となっており、
そのあとデータベースのテーブルも直接確認して同様のID番号でした(あたり前)。

直接データベースを更新したかったのですが、
このブログのテーブルはコメント投稿機能のテーブルで外部キー制約が設定されていて
すぐには変えられなかったので、テストデータの方を修正したっていう背景です。

②はパート4の"コメントエンティティ"の項目であった「予約語の回避」関連の
指定するカラム名を修正しないとエラーになるやつがここでも影響しています。

また$crawler が指定しているコメントタイプにも誤りがあり、
src/Blogger/BlogBundle/Form/CommentType.php の中身を見ていただくと
get()メソッドのreturn値が「return 'blogger_blogbundle_comment';」
となっているのをご確認いただけるかと思います。

#### <~~エラー内容4~~>
エラーではないのですが、最後の"Codeカバレッジ"の項目で、
「Xdebug」がインストールされていない旨を注意メッセージがありました。

    <実行コマンド>
    $ phpunit --coverage-html ./phpunit-report -c app/
    (実行結果)
    PHPUnit 4.8.6 by Sebastian Bergmann and contributors.
    Warning:	The Xdebug extension is not loaded
		No code coverage will be generated.

    ..........

    Time: 1.32 seconds, Memory: 43.25Mb

    OK (10 tests, 33 assertions)

ってな感じです。そんなわけでXdebugをインストールをしようとしたのですが、
今回のわたくしの環境だと利用できないとのことでした。

    <実行コマンド>
    $ yum list installed | grep Xdebug
    (実行結果)
    ...
    ================== N/S matched: Xdebug ========================
    php-pecl-xdebug.x86_64 : PECL package for debugging PHP scripts
    ...

    $ sudo yum install Xdebug
    (実行結果)
    ...
    パッケージ Xdebug は利用できません。
    エラー: 何もしません

...すみませんがとりあえずここ放置で^^;

**てなわけで一応ではありますが以上で一通り作成完了です！**

チュートリアルではパート6の最後で「次章では、...」と書いてありますが、
すでに数年前から更新がないようなので、これまでですかね。

## 最後に...
はい、というわけで一通りの作成過程の中で
エラー箇所洗い出し＆修正対応を行ってまいりました。まるで粗探しの特打ち状態(´Д` )

正直いまの段階でSymfony2が使いこなせるかって言ったら
まったくそんなことはありません。めっちゃぼやっとしてます（笑）。

ただ、初心者にまず大事なのは「とりあえず一通り作れた！」っていう体験です。
この体験があれば、そのあとの掘り下げや実際のスキル習得まで
心折れずに進めていけるものです。初心者、というかこれがわたしのやり方です。

これからまたこのチュートリアルを2,3回作っていく中で
Symfony2の機能や構造、MVCフレームワークの仕組みについて紐解いていき
自身の理解と現場で活きるスキルを身につけてまいりたいと思います。

次回はまた別の記事で、
「symblog作成で紐解くSymfony2(MVCフレームワーク)の魅力」的なタイトルで
より具体的な内容を盛り込んだ形で投稿できればと思っています。

それではまた！