[Symfony] JSON レスポンスを返す
/** * @Route("/test.json", name="json") */ public function jsonAction() { // do something return new JsonResponse(array('id' => 12345, 'title' => 'json test')); }
バージョン 2.1
で追加された JsonResponse
をコントローラ内で返すだけです。コンストラクタの引数に渡した配列がそのまま出力されます。
Content-Type も自動で application/json
にしてくれます。更に、JSONP のコールバック処理もできたりします。
※詳しくは JsonResponse
とっても便利☆
[Symfony] サブドメイン別にルーティングを制御する
Symfony 2.2 で正式に追加された機能の様です。
フロントエンドをexample.com
、バックエンドをsystem.example.com
としてそれぞれ別のバンドルで運用する場合の設定例をご紹介。
まずはバックエンド用のバンドルを作成します。
$ php app/console generate:bundle --namespace=Acme/BackendBundle --format=annotation
続いて上記コマンドで自動追記されたBackendBundle
へのルーティングを修正します。
# app/config/routing.yml # バックエンド system: resource: "@BackendBundle/Controller/" type: annotation prefix: / host: system.example.com # 追加! # フロントエンド homepage: resource: "@FrontendBundle/Controller/" type: annotation prefix: /
新しく追加されたhost
によってサブドメインのルーティングを制御できるようになりました。これでsystem.example.com
はすべてBackendBundle
のコントローラにルーティングされます。
とっても簡単!
[Symfony][Capistrano] Capifony で Symfony2 のアプリケーションをデプロイする
今回は Symfony アプリを Capistrano で簡単にデプロイできる Capifony (http://capifony.org) の使い方を紹介します。
実行環境は Ruby 1.9.1 + Capistrano 2.14.2 です。
Capifony をインストールする
RubyGems でインストールします。
$ gem install capifony
続いてデプロイする Symfony プロジェクト上で capifony
コマンドを実行し、イニシャライズします。
$ cd /path/to/own_sf2pj $ capifony .
これで Capifile
と app/config/deploy.rb
の2ファイルが自動生成されました。
更に次のコマンドで、実行できるタスクを確認してみます。
$ cap -T
しかしここで以下のエラーが…。
"
raise_if_conflicts': Unable to activate capifony-2.2.7, because capistrano-2.14.2 conflicts with capistrano (<= 2.14.1, >= 2.13.5)"`
どうやら Capistrano 2.14.2 では動作しないみたいなので、仕方なく 2.14.1 にダウングレードします。
$ gem uninstall capistrano $ gem install capistrano -v 2.14.1
これで無事、正常に利用できるようになりました。
deploy.rb を設定する
僕はとりあえずこんな感じで設定しました。かなり基本的な事のみ設定しています。
今回 Apache ユーザに app/cache
と app/logs
への書き込み権限を ACL で与えていますが、環境によっては ACL が使えないこともあるので、その場合は chown
か chmod
も利用できるみたいです。
デプロイ前の準備をする
以下のコマンドを実行します。
$ cap deploy:setup
これで必要なディレクトリ構造が構築されます。ここで一旦 SSH でデプロイ先サーバに入り、本番用の parameters.yml
を作ります。
$ mkdir -p /var/www/example.com/shared/app/config $ vim /var/www/example.com/shared/app/config/parameters.yml
これで準備 OK です。
そしてデプロイへ...
ローカルに戻り、以下のコマンドを実行します。
$ cap deploy
これで正常にデプロイが完了しました!
因みにこの Capifony、symfony 1.4.x でも利用できるらしいスグレモノです。未だに symfony 1.4.x 系のプロジェクトをいくつか抱えているのでそちらでも試してみようと思います。
[Doctrine][MySQL] アノテーションで unsigned を定義する
Doctrine2 のエンティティプロパティに unsigned を設定する方法が分かりづらかったのでメモ。
/** * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") * @ORM\Column(type="bigint", options={"unsigned"=true}) */ protected $id;
こんな感じで Column::options プロパティを設定します。因みに SQL をダンプすると次のような結果になります。
CREATE TABLE users (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, ...
また type と options に使える値は次のクラスに定義されています。(MySQLの場合)
Doctrine\DBAL\Schema\MySqlSchemaManager
※ Column::columnDefinition で決め打ちしてしまうと、外部キー周りでハマりやすいので極力避けた方がよさげです。
[Symfony][Doctrine] Fixtures からサービスコンテナを取得する
Fixtures 内で、サービスコンテナを呼び出したくなる事はしばしばあります。
例えば User エンティティクラスが Security コンポーネントの UserInterface を実装している場合、PasswordEncoder を使いたくなりますね。 しかしそのままでは AbstractFixture クラス内でサービスコンテナが取得できないので、PasswordEncoder の取りようがありません。
そんな時は、AbstractFixture に ContainerAwareInterface を実装してしまいましょう。
// src/Acme/UserBundle/DataFixtures/ORM/LoadUserClassData.php namespace Acme\UserBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Acme\UserBundle\Entity\User; // ↓追加 use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; class LoadUserClassData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface // ←追加 { // ~ /** * @var ContainerInterface */ private $container; /** * {@inheritDoc} */ public function setContainer(ContainerInterface $container = null) { $this->container = $container; } // ~ }
これで load が実行される前にサービスコンテナが格納されます。
実際に load 時に使用する場合は次の様な感じです。
public function load(ObjectManager $manager) { $factory = $this->container->get('security.encoder_factory'); $user1 = new User(); $user1->setUserName('issei'); $user1->setSalt(hash('sha512', mt_rand(111111, 999999))); $encoder = $factory->getEncoder($user1); $user1->setPassword($encoder->encodePassword('hogehoge', $user1->getSalt())); }
詳しくは公式のドキュメントを参照
http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#using-the-container-in-the-fixtures