228
238

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SymfonyAdvent Calendar 2015

Day 17

Symfony初心者がつまづきがちな22個のポイント

Last updated at Posted at 2015-12-17

この記事はSymfony Advent Calendar 2015 17日目の記事です。前日の記事は@teematsuさんの「Symfony 2.8とPHP-DIのAuto Wiring」でした。


こんにちは。はじめまして。tarokamikazeです。
すっかりSymfonyおじさんと化した私は、数々の後輩たちにSymfonyに関する相談を受けてきました。
そのなかでも、社内でよく聞かれることをまとめます。

導入編

The Symfony Book を読んだ人、ブログチュートリアルをやってみた人向けです。

01.この案件にSymfony2を使いたいんですが

下記のような条件では、Symfony2はおすすめです。

  • 専用サーバーを使える。
  • 他のPHP フレームワークを触ったことがある。
  • ビジネスロジックが複雑になりそうなシステムを作る。(業務アプリ等)
  • テストは当然書く。 1
  • プログラミング技術を磨きたい。
  • PHPのゆるふわさに嫌気が差してきた。2
  • (特に学習初期は)開発速度を犠牲にできる。ある程度学習コストを許容できる。
  • ドメイン駆動設計に興味がある。

02.公式サイトどこ?

日本語サイト は情報が古いです。本家(英語) を見ましょう。
不満に思う人は、翻訳作業に参加したらいいと思います。

以前参加したSymfony勉強会では
「Symfonyを使うくらいリテラシーのある人は、英語くらい読めるっしょwww」
と言っていました。恐ろしいですね。

03.日本語の本はありますか?

古いですが、「効率的なWebアプリケーションの作り方 ~PHPによるモダン開発入門 」しかなかったんですよ。書名にSymfonyって書いていないという罠。

しかし先日「基本からしっかり学ぶ Symfony2入門 」が出ました! いい時代ですね!

04.ここは読んどけって記事はありますか?

公式が充実してます。それを読めば、たいていのことは載っています。
Symfonyの歩き方/5分でわかるSymfony Best Practices はいい記事ですね。@ryo511 さん、ありがとうございます!

05.おすすめのバンドルは?

06.どのバージョンを使えばいいのでしょう?

ここを読んで考えましょう。Symfonyはサポート期間を明示してくれているので、利用バージョンを考えやすいですよね。

2015年12月現在、個人的には以下のように考えています。

  • 実案件なら、最新版LTSの 2.8
  • 勉強用なら、最新版の 3.0

07.公式の通りにインストールしたけど動かない

本当に公式の通りにインストールしたんですか? 本当に??

多くの人が、なぜかここ を読み飛ばします。
きちんとキャッシュ・ログディレクトリにパーミッションを設定しましょう。

  • Mac なら「2. Using ACL on a system that supports chmod +a」
  • CentOSなら「3. Using ACL on a system that does not support chmod +a」
  • Windowsなら、まずはMacを使わせてもらえるように上司(財布)と交渉しましょう。
    • 無理なら、VirtualBox に Linux を突っ込めばいいんじゃないでしょうかね。

08.フォルダ構成はどうしたらいいの?

Advent Calendarでちょうどいい記事が出ましたね。@issei-mさん、ありがとうございます!

09.設定は何で書けばいいの? XML?

Symfony Best Practicesによると、以下の様な感じです。

  • Routingは、アノテーション
  • DoctrineのEntity定義も、アノテーション
  • サービス設定はyaml 3

10.設定内容が反映されない><

キャッシュクリアしましょう。

php app/console cache:clear

それでもだめなら、apache(php-fpm)を再起動しましょう。
設定次第で、Symfony は app/cache だけではなく、APC(u) にもキャッシュをためます。

11.なんか英語のエラー出た><

まずは落ち着いて、エラーメッセージ読んでください。英語が苦手なら、Google翻訳に頼ってください。
それでもわからなければ、エラーメッセージでググってください。

利用者が多いフレームワークって、簡単なエラーでも記事が引っかかるのでいいですよね。

実装編

実案件で実装を始める人向けです。

12.Modelはどこに書くの?

「貴様の言うModelとは何だ? 」と訊くと、たいてい詰まりますよねw

Symfony2 は、(暗に)ドメイン駆動設計を推奨しています。 4

  • データを取り出したいなら、Repository
  • ビジネスロジックを記述したいなら、サービスを作ってDIコンテナに登録

という風に書けばよいでしょう。

13.確認フォームってどうやったら出せるの?

コツは、「Entity自体ではなく、Postされたarrayをセッションに詰めること」。
Doctrineは、Entity にメタデータを詰めます。このせいで、Entityをセッションに詰めると挙動がおかしくなります。(メタデータがserialize できません)
Formをからめるのであれば、POSTされたarrayをセッションに詰めましょう。

確認画面のAction ではセッションに詰めたarrayを、入力画面と同じFormType にbindしてあげればよいのです。

14.Ajax用の API 作りたい!

FOSRestBundle を使ってください。JMSSerializer便利だよぉ。

え、APIがちょっとしかないから、バンドルは導入したくない?しょうがないなぁ。
ここの通りにやればいいんじゃないのかなあ。

ちょっと古いけど、Symfony2 REST API: the best wayも目を通しておいた方がいいでしょう。

15.CSVダウンロード機能を作りたい!

最近のExcelは、XMLも読めますよ?(真顔) 5

冗談はさておき、こことか見たらいいんじゃないでしょうかね。

16.FormやAPIの形式とEntityの形がかけ離れている......つらい......

以下のようなやり方もあります。定義が散るので望ましくはないのですが。6

  1. Form / API の形に合わせたニセEntity(JavaBean的なモノ)をつくる。
  2. ニセEntity にあわせたFormType を用意し、リクエストデータはそれで受ける。
  3. ビジネスロジックに ニセEntity を 投げる。
  4. ビジネスロジック内でニセEntityを、本物のEntityに変換する。その後、永続化処理等を行う。

このときValidationは、form 側でやってもいいですし、変換後の本物EntityをValidatorサービスに投げてもいいでしょう。

17.ログインの仕組みを独自に作りたいんですけど......

悪いことは言わない。やめておけ。

Symfony2のログイン関係の仕組みは、複雑です。
可能な限りネイティブの仕組み、またはFOSUserBundleなどの外部バンドルにまかせたほうがいいです。
昔触ろうとして、一週間かかりました......

Doctrine編

18.Doctrineが不要なカラムもselectしようとしています。なんとかしたい。

ORM とはそういうものです。DBを富豪的に使うのです。
それでも重いというのなら、札束を積んで物理で殴ればよいのです。

19.Lazy Load うざい

デバッグコンソールを見ると、大量のSQLを吐いているときがあります。
原因としては、Doctrine で Entityに OneToMany を設定していると
「親も子も使うことがわかりきっているのに、子供にアクセスしたときにlazy load されて大量のSQLが走ってる」
というケースが多いです。

こういう場合は、DQLをしっかり書きましょう。
DQLでjoinすれば、一発で取ってきてくれます。

ParentRepository.php

class ParentRepository extends EntityRepository
{
    public function findOneWithChild($parentId)
    {
        $qb = $this->createQueryBuilder('p');
        $qb->select('p, c') // selectにもjoin先のaliasを書くのがコツ
            ->join('p.children', 'c')
            ->andWhere('p.id = :parentId')
            ->setParameter(':parentId', $parentId);
        return $qb->getQuery()->getSingleResult();
    }
}

20.論理削除ってどうすればいいの?

まずはここ を読め。話はそれからだ。

StofDoctrineExtensionsBundleSoftdeleteable を使います。
削除日時のカラムがNot Null だったら、削除とみなされます。

21. OneToMany を設定していて、親のEntityと子供のEntityを一気にpersistしようとしたらエラーが出た

こういう単純な例って、なかなか見つからないんですよね。7

test.php
$em = $this->get('doctrine.orm.entity_manager');

$parentEntity = new ParentEntity();
$childEntity = new ChildEntity();
$childEntity->setParent($parentEntity);

$em->persist($parentEntity);
$em->persist($childEntity);

$em->flush();

22.「Update時に、自動的にあのカラムも更新する」とかやりたい。EventLister を使えばいいの?

悪いことは言わない。やめておけ。
頼むから、更新対象のEntityをビジネスロジッククラスに渡して処理するんだ。

この面倒臭さを説明しだすと、ひとつの記事になってしまいます。
とりあえず Doctrineのこのクラス を読んでみてください。理由がわかってもらえるはずです。

ちなみに、更新日時を入れたいだけだったら
StofDoctrineExtensionsBundleTimestampable を使いましょう。


ちなみに22個である理由は、妻が猫好きだからです。
明日は@naoyes さんです!


  1. Symfony2はテストが書きやすいと言われています。

  2. 自然とJavaっぽいコードになります。Java の Spring Framework に似ていると言われています。

  3. JMSDiExtraBundleを使えば、サービスもアノテーションで定義できます。

  4. そういった意味では、Symfonyは単なる「MVC」フレームワークではない何かです。以前参加したSymfony勉強会でも、ドメイン駆動設計の話題でもちきりでした。

  5. 筆者はExcelとCSVを憎んでいます。エンジニアになる前は、Excel職人(運用のひと)でした。

  6. 実例をGithubにあげたい。だが時間がない......

  7. Cascade persist する手もありますが、おすすめされていません

228
238
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
228
238

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?