2011年12月8日木曜日

consoleコマンドリスト

$ php app/console list
のコマンドで、コンソールのコマンドリストを見れます。
別にコンソール上で見ればいいけど、一応一覧をメモっておく。

Symfony version 2.0.6 - app/dev/debug

Usage:
  [options] command [arguments]

Options:
  --help                    -h Display this help message.
  --quiet                  -q Do not output any message.
  --verbose              -v Increase verbosity of messages.
  --version               -V Display this program version.
  --ansi                         Force ANSI output.
  --no-ansi                    Disable ANSI output.
  --no-interaction     -n Do not ask any interactive question.
  --shell                     -s Launch the shell.
  --env                      -e The Environment name.
  --no-debug                 Switches off debug mode.

Available commands:
  help                                  Displays help for a command
  list                                  Lists commands
assetic
  assetic:dump                          Dumps all assets to the filesystem
assets
  assets:install                        Install bundles web assets under a public web directory
cache
  cache:clear                           Clear the cache
  cache:warmup                          Warms up an empty cache
container
  container:debug                       Displays current services for an application
doctrine
  doctrine:cache:clear-metadata         Clear all metadata cache for a entity manager
  doctrine:cache:clear-query            Clear all query cache for a entity manager
  doctrine:cache:clear-result           Clear result cache for a entity manager
  doctrine:database:create              Create the configured databases
  doctrine:database:drop                Drop the configured databases
  doctrine:ensure-production-settings   Verify that Doctrine is properly configured for a production environment.
  doctrine:generate:crud                Generates a CRUD based on a Doctrine entity
  doctrine:generate:entities            Generate entity classes and method stubs from your mapping information
  doctrine:generate:entity              Generates a new Doctrine entity inside a bundle
  doctrine:generate:form                Generates a form type class based on a Doctrine entity
  doctrine:mapping:convert              Convert mapping information between supported formats.
  doctrine:mapping:import               Import mapping information from an existing database
  doctrine:mapping:info                 Show basic information about all mapped entities
  doctrine:query:dql                    Executes arbitrary DQL directly from the command line.
  doctrine:query:sql                    Executes arbitrary SQL directly from the command line.
  doctrine:schema:create                Executes (or dumps) the SQL needed to generate the database schema
  doctrine:schema:drop                  Executes (or dumps) the SQL needed to drop the current database schema
  doctrine:schema:update                Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata
generate
  generate:bundle                       Generates a bundle
  generate:doctrine:crud                Generates a CRUD based on a Doctrine entity
  generate:doctrine:entities            Generate entity classes and method stubs from your mapping information
  generate:doctrine:entity              Generates a new Doctrine entity inside a bundle
  generate:doctrine:form                Generates a form type class based on a Doctrine entity
init
  init:acl                              Mounts ACL tables in the database
router
  router:debug                          Displays current routes for an application
  router:dump-apache                    Dumps all routes as Apache rewrite rules
swiftmailer
  swiftmailer:spool:send                Send emails from the spool

既存のテーブルからEntityを作成!

タイトルのように、既存のテーブルからEntityを作成したい場合は、どうするのかなーと思ってた所、こんな記事がありました。→ How to generate Entities from an Existing Database

2011年12月6日火曜日

controllerに書くアノテーションについて

SensioFrameworkExtraBundle

Symfony2 では、アノテーションとして Routing の情報等を書くけど、そのアノテーションに関する情報がまとまってなくて、どっかにないかなーと思っていたら、ドキュメントにあったので、紹介 + 自分なりにまとめてみます。

とりあえず、アノテーションに以下の5つの機能があるっぽい
  • @Route and @Method : ルーティングの情報や、ルートに許可されるHTTPメソッドを指定
  • @ParamConverter : リクエストの内容をオブジェクトに変換する機能を使用することを指定
  • @Template : テンプレート名を指定する
  • @Cache : HTTPキャッシュを作成するためのアノテーション


@Route and @Method

ドキュメントはコチラ → @Route and @Method

/**
 * @Route("/{id}", requirements={"id" = "\d+"}, defaults={"foo" = "bar"})
  */
public function showAction($id)
{
}
  • @Route() では、第一引数で pattern 情報を指定
  • requirements には, 正規表現などで、Route 情報に制限をかけられる
  • defaults で、デフォルトで渡されるパラメータの値を設定可能
  • @Routeを複数指定することもできる

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

/**
 * @Route("/blog")
 */
class PostController extends Controller
{
    /**
     * @Route("/edit/{id}")
     * @Method({"GET", "POST"})
     */
    public function editAction($id)
    {
    }
}
  • クラスに対して @Route 情報を記述することで、全アクションに対して機能させることも可能
  • @Method({"GET", "POST"}) のように、@Method() を使用して、HTTPメソッドに制限をかけることができる。



@ParamConverter

ドキュメントはコチラ → @ParamConverter

リクエストの内容をオブジェクトに変換する機能を使用。

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

/**
 * @Route("/blog/{id}")
 * @ParamConverter("post", class="SensioBlogBundle:Post")
 */
public function showAction(Post $post)
{
}

  • SensioBlogBundle:Post でPostオブジェクトがなかったら 404NotFoundが返される。
  • 全てのコンバーターはParamConverterInterfaceを実装してつくる

詳細はドキュメントを参照。


@Template

ドキュメントはコチラ → @Template

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

:

/**
 * @Template("SensioBlogBundle:Post:show")
 */
public function showAction1($id)
{
    // get the Post
    $post = ...;

    return array('post' => $post);
}

/**
 * @ParamConverter("post", class="SensioBlogBundle:Post")
 * @Template("SensioBlogBundle:Post:show", vars={"post"})
 */
public function showAction2(Post $post)
{
}
  • @Template("SensioBlogBundle:Post:show")のように、テンプレートを指定することが可能
  • vars を指定することで、テンプレートにデータを渡すことも可能


@Cache

ドキュメントはコチラ → @Cache

/**
 * @Cache(expires="tomorrow")
 */
class BlogController extends Controller
{
    /**
     * @Cache(expires="+2 days")
     */
    public function indexAction()
    {
    }
}

このようにして、expiresでキャッシュの有効期限を指定して、キャッシュを簡単に作成可能


詳しくは、ドキュメント参照でお願いします。
とりあえず、アノテーションに関してはこんな感じ!

アノテーションを使用するときはインポートすること!

@Route や @Template のアノテーションを利用するときは、

// these import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

のように、FrameworkExtraBundle の Configuration\Route と Configuration\Template をインポートすること!!

2011年12月5日月曜日

Actionの戻り値について

Symfony2.0 では、Controller の Action の戻り値は、Response オブジェクト。
ってのはまぁ、良いとして、Response オブジェクトの作成方法についてちょっと自分なりにメモしておく。
(間違ってたらコメントください(´・ω・`))

基本的に以下の3パターン。
( http://symfony.com/doc/current/book/controller.htmlより引用 )

① 自分でレスポンスオブジェクトを作成
use Symfony\Component\HttpFoundation\Response;

public function helloAction()
{
    return new Response('Hello world!');
}
リダイレクトする場合は、このパターン


②render関数を Action 内で使用
自分でテンプレートを指定して、レンダリングを行う。render() の戻り値が Response オブジェクトなので、これをそのまま Action の戻り値とする。
use Symfony\Component\HttpFoundation\Response;

public function helloAction()
{
    return $this->render('AcmeHelloBundle:Welcome:hello.html.twig', array('name' => $name));
}


③ テンプレートに渡すパラメータをActionの戻り値にして、Responce オブジェクト作成は フレームワークにやらせる
自分でテンプレートを指定して、レンダリングを行う。render() の戻り値が Response オブジェクトなので、これをそのまま Action の戻り値とする。
use Symfony\Component\HttpFoundation\Response;

public function helloAction()
{
// array('name' => $name) が 内部で AcmeHelloBundle:Welcome:hello.html.twig に渡され、Response オブジェクトが自動で作成される
    return array('name' => $name)
}


多分こんな感じ。

Custom Repository Class

Doctrineでは、Entityというものを使うけど、これは基本的にデータを保持するためだけのクラス。
で、実際に find などの様にデータベース上のデータをフェッチするには、Repository を使用する。

こんな感じ。(http://docs.symfony.gr.jp/symfony2/book/doctrine.htmlより引用)
$product = $this->getDoctrine()
       -$gt;getRepository('AcmeStoreBundle:Product')
       -$gt;find($id);


...で、このgetRepositoryを見てみると、

/**
 * Gets the repository for an entity class.
 *
 * @param string $entityName The name of the entity.
 * @return EntityRepository The repository class.
 */
public function getRepository($entityName)
{
    $entityName = ltrim($entityName, '\\');
    if (isset($this->repositories[$entityName])) {
        return $this->repositories[$entityName];
    }

    $metadata = $this->getClassMetadata($entityName);
    $customRepositoryClassName = $metadata->customRepositoryClassName;

    if ($customRepositoryClassName !== null) {
        $repository = new $customRepositoryClassName($this, $metadata);
    } else {
        $repository = new EntityRepository($this, $metadata);
    }

    $this->repositories[$entityName] = $repository;

    return $repository;
}

の様になっている。

で、ここで注目するのは

if ($customRepositoryClassName !== null) {
    $repository = new $customRepositoryClassName($this, $metadata);
} else {
    $repository = new EntityRepository($this, $metadata);
}

のとこ。つまりカスタムリポジトリクラスがあれば、それを使用するけど、そうじゃなきゃEntityRepositoryを使うよーってことですね。

ってことで、自分で Repositoryを作成するには、EntityRepositoryを継承して独自にカスタマイズすればOK。
データ取得とかはコントローラでなくてモデル側に書いたほうが良いので、そういうのは独自のリポジトリを用意してそこで処理をさせたほうが綺麗!

ってことらしいです。

2011年10月20日木曜日

Doctrine - コマンドメモ

① データベースの作成
php app/console doctrine:database:create

② Entity Class の作成
php app/console doctrine:generate:entity --entity="AcmeStoreBundle:Product" --fields="name:string(255) price:float description:text"
ちなみに、Doctrineで扱えるフィールドタイプについては、http://docs.symfony.gr.jp/symfony2/book/doctrine.html#book-doctrine-field-typesや、http://www.doctrine-project.org/docs/orm/2.0/en/reference/basic-mapping.html#doctrine-mapping-types に載ってあります。



③ テーブル/スキーマの作成
php app/console doctrine:schema:update --force


④ Entity Class の更新
php app/console doctrine:generate:entities Acme

2011年10月17日月曜日

Model (Doctrine) について②

Model (Doctrine) について① の続きです。

詳しくは、Databases and Doctrine ("The Model")を参照してください。

オブジェクトの永続化


INSERTするときは以下のように、Entityに値をセットし、EntituManagerのpersist()を呼び、最後にflush() を実行すれば良い。

use Acme\StoreBundle\Entity\Product;
use Symfony\Component\HttpFoundation\Response;

public function createAction()
{
    // Productインスタンスの作成
    $product = new Product();
    // 値をセット
    $product->setName('A Foo Bar');
    $product->setPrice('19.99');
    $product->setDescription('Lorem ipsum dolor');
    // EntityManager オブジェクトの取得
    $em = $this->getDoctrine()->getEntityManager();
    // データの保存
    $em->persist($product);
    $em->flush();

    return new Response('Created product id '.$product->getId());
}


オブジェクトのフェッチ


Doctrineオブジェクトからフェッチ対象のリポジトリを取得 (getRepository) する。
そのリポジトリオブジェクトに対し、 find, findAll, findBy などでデータを取得できる。

$product = $this->getDoctrine()
    ->getRepository('AcmeStoreBundle:Product')
    ->find($id);

いろんな取得方法がある。

// IDからデータを取得
$product = $repository->find($id);

// 指定したカラムの値からデータを1つ取得
$product = $repository->findOneById($id);
$product = $repository->findOneByName('foo');

// 同様に、指定したカラムの値からデータを取得 (複数)
$products = $repository->findByPrice(19.99);

// 細かい検索条件を付ける場合は以下 (findOneByは1つ、findByは複数取得)
$product = $repository->findOneBy(array('name' => 'foo', 'price' => 19.99));
$product = $repository->findBy(
    array('name' => 'foo'),
    array('price' => 'ASC')
);

// 全て取得
$products = $repository->findAll();

// 自分でクエリーを生成することも簡単
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery(
    'SELECT p FROM AcmeStoreBundle:Product p WHERE p.price > :price ORDER BY p.price ASC'
)->setParameter('price', '19.99');

$products = $query->getResult();

// クエリービルダーを使用することもできる (createQueryBuilder)
$repository = $this->getDoctrine()
    ->getRepository('AcmeStoreBundle:Product');

$query = $repository->createQueryBuilder('p')
    ->where('p.price > :price')
    ->setParameter('price', '19.99')
    ->orderBy('p.price', 'ASC')
    ->getQuery();

$products = $query->getResult();



オブジェクトのアップデートと削除


データをアップデート処理と削除処理について。
ちなみに、update, delete, どちらも最後に flush() を呼ぶ必要があります。

public function updateAction($id)
{
    // データを取得
    $em = $this->getDoctrine()->getEntityManager();
    $product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
    if (!$product) {
        throw $this->createNotFoundException('No product found for id '.$id);
    }
    
    // データに値をセット
    $product->setName('New product name!');
    // データを更新
    // $productの中身を変更して、そのまま flush() すれば更新される。(参照渡しでエンティティを取得しているっぽいね。)
    // よって、persist() とかいちいち呼ぶ必要が無いです。
    $em->flush();

    // 削除はこうやる
    $em->remove($product);
    $em->flush();

    return $this->redirect($this->generateUrl('homepage'));
}


カスタムなリポジトリクラスの作成


前述のように、自分でクエリーを作成 (createQuery) する場合を考える。そのとき、毎回同じコードをコントローラに記述する事になってしまうと煩雑になってしまう。そんなときは、自分でカスタムなリポジトリクラスを作成することで解決できる。

まず、ProductRepository を使いますよーと、アノテーションで記載する。
// src/Acme/StoreBundle/Entity/Product.php
namespace Acme\StoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Acme\StoreBundle\Repository\ProductRepository")
 */
class Product
{
    //...
}

....で、以下のコマンドを実行する

php app/console doctrine:generate:entities Acme

そうすると、リポジトリクラスが作成される(以下)
そこにfindAllOrderedByNameなどのカスタムなプログラムを書いてやる。これでOK。

// src/Acme/StoreBundle/Repository/ProductRepository.php
namespace Acme\StoreBundle\Repository;

use Doctrine\ORM\EntityRepository;

class ProductRepository extends EntityRepository
{
    public function findAllOrderedByName()
    {
        return $this->getEntityManager()
            ->createQuery('SELECT p FROM AcmeStoreBundle:Product p ORDER BY p.name ASC')
            ->getResult();
    }
}

Model (Doctrine) について①

Doctrine は, PHPのORM (Object-relational mapping : オブジェクト指向言語におけるオブジェクトと、MySQLやPostgreSQLの様な、リレーショナルデータベースにおけるレコードとを対照させるもの) で、Symfonyで利用されている。

詳しくは、Databases and Doctrine ("The Model")を参照してください。

データベースの情報を設定

まず、データベースに接続するためには, app/config/parameters.ini でホストなどを指定する。

[parameters]
    database_driver="pdo_mysql"
    database_host="localhost"
    database_name="hoge"
    database_user="moge"
    database_password="piyo"

以下のコマンドを叩けば、app/config/parameters.ini の情報に基づいてデータベースを作成してくれる。
php app/console doctrine:database:create

Entity Class の作成

エンティティを、src/Acme/StoreBundle/Entity/ のような場所 (〇〇Bundle/Entity下) に作成する。(このクラス自体は、データを格納するだけ)

まず、以下のコマンドを実行する。
php app/console doctrine:generate:entity --entity="AcmeStoreBundle:Product" --fields="name:string(255) price:float description:text"

すると、ORM情報をアノテーションとして設定されているエンティティクラスが作成される (以下)。
また、Getter と Setter も用意してくれます。

// src/Acme/StoreBundle/Entity/Product.php
namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Acme\DemoBundle\Entity\Product
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Product
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $name
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var float $price
     *
     * @ORM\Column(name="price", type="float")
     */
    private $price;

    /**
     * @var text $description
     *
     * @ORM\Column(name="description", type="text")
     */
    private $description;


    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set price
     *
     * @param float $price
     */
    public function setPrice($price)
    {
        $this->price = $price;
    }

    /**
     * Get price
     *
     * @return float 
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Set description
     *
     * @param text $description
     */
    public function setDescription($description)
    {
        $this->description = $description;
    }

    /**
     * Get description
     *
     * @return text 
     */
    public function getDescription()
    {
        return $this->description;
    }
}

ORM情報をYAML等のコンフィグファイルで設定したい場合は、--format=yml のオプションを加えることで可能。(その場合のコンフィグファイルは、src/Acme/StoreBundle/Resources/config/doctrine/Product.orm.yml となる)

ちなみに、SQLのキーワードとなってる名前をフィールドにつけようとすると、エラーとなるらしい。その場合は、
/** @Column(name="`number`", type="integer") */
private $number;
のようにエスケープが必要らしいです。(Reserved SQL keywords documentation より)


テーブル/スキーマの作成

次の以下のコマンドを実行すれば、自動的にテーブル/スキーマの作成を行なってくれる。
php app/console doctrine:schema:update --force

とりあえず、今回はココまでっ!!

2011年10月14日金曜日

Twigに関するメモ

Twigに関して、少しメモを。

  • テンプレートの継承が可能 (blocklタグ)
  • {{ ... }}: 変数や式の結果を出力, {{ ... }} で出力されるものは、デフォルトでエスケープしてくれる
  • {% ... %}: for ループや if 文等の、テンプレートのロジックを制御するタグ
  • {# ... #} コメントを記述できる
  • {{ path('_demo_hello' }} のようにして、routing configrationに基づいてパスを記述できる
  • url 関数は絶対 URL を生成
  • 画像やcssなどを読み込む際は、{{ asset('css/blog.css') }} などとすることで、アセットを簡単に扱える

2011年10月13日木曜日

Viewの作成方法

ビューについて少し。

まず、全体のレイアウトは、app/Resources/views/ の中に layout.html.twig で、
ページ毎に異なる部分は、mogeBundle/Resources/views/の中で hello.html.twig で記述。


Twig には、テンプレートの継承機能があり、

layout.html.twigで以下のように書いたとし、
<!-- layout.html.twig -->
{% block title %}Layout{% endblock %}

継承先のhello.html.twigで、
<!-- hello.html.twig -->
{% block title %}Hello{% endblock %}

とすることで、titleブロックのオーバーライドが可能。

ちなみに、デフォルトで存在するレイアウトファイルの中身は以下のようになってる。

<!-- base.html.twig -->
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}Welcome!{% endblock %}</title>
        {% block stylesheets %}{% endblock %}
        <link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
    </body>
</html>

つまり、これを継承して、title, body, javascripts 等のブロックをオーバーライドすれば、OKっぽい。
おもしろい〜。

ちなみに、Twig は、デフォルトですべての出力をエスケープしてくれるらしいです。

Twig Bundle for Textmate

TwigのTextmate Bundleを作成されている方がいたので、一応紹介。

Anomareh / PHP-Twig.tmbundle

Twig用のタグを出力してくれるものです。でも、自分は使わないかな〜。

symfony2 - ページ作成の流れのおさらい

version : 2.0.4

もう少し詳しい情報は、独学Symfony2 : report2 にもあります。

まず, Symfony2でのページ作成は, 以下のSTEPで成り立っている。
◯ Bundleの作成
① Create a route : リクエストのURIから, 対応するコントローラーを指定するための Routing 情報を決める
② Create a controller : リクエストを処理し, 応答を返すための Controller の部分を作成
③ Create a template : テンプレートの作成

Bundleの作成


Bundleの作成
AcmeStudyBundleを作成
php app/console generate:bundle --namespace=Acme/HelloBundle --format=yml
ちなみに, このコマンドを使用しない場合は, 自分でディレクトリやAcmeStudyBundle.phpなどを作成する必要がある。
また、このコマンドを使用して、AppKernelに自動で追加もできます。今回はこれで作成。


Route の作成

app/config/routing.yml にルーティング情報を追加
routeに, /hello/{name} というパターンに対して AcmeStudyBundle:Hello:index が呼ばれるように設定する。

以下のようにして、routingファイルをインポートして使用できる (コマンドでBundleを作成した場合は、勝手にインポートの記述を追加してくれます。便利。)
# app/config/routing.yml
AcmeHelloBundle:
    resource: "@AcmeHelloBundle/Resources/config/routing.yml"
    prefix:   /

# src/Acme/HelloBundle/Resources/config/routing.yml
hello:
    pattern:  /hello/{name}
    defaults: { _controller: AcmeHelloBundle:Hello:index }


Controller の作成

routeに, /hello/{name} というパターンに対して AcmeStudyBundle:Hello:index が呼ばれるように設定する(詳細はドキュメント見てね!)

Routingの設定により、/hello/{name} でアクセスすると, AcmeStudyBundle の HelloController の indexAction が呼ばれる。

View の作成


最後に、アクションに対するビューを作成。どのビューが呼ばれるかは、indexActionに記述されている通り。
ちなみに、Twigはテンプレートの継承が可能なのでスゴイおもしろい!笑



以上が基本的な流れ。

2011年10月12日水曜日

独学Symfony2 : memo コーディング規則

http://docs.symfony.gr.jp/symfony2/contributing/code/standards.html

にコーディング規則がのってました!しかも日本語訳で!
ということでメモ〜

独学Symfony2 : report4

version : BETA3 (正式リリース後, 改変の可能性あり)

今回は Controller について。

ここらへんからは, ドキュメントを読むよりもソースを実際に書いてやっていくほうが勉強になるだろうってことで、要所要所しか説明しない予定です(めんどうだし。。笑)


routing と コントローラー引数


ドキュメントと同じルーティング情報で説明する。

hello:
    pattern: /hello/{first_name}/{last_name}
    defaults: { _controller: AcmeHelloBundle:Hello:index, color: green }
というrouting 設定だとする。この場合, HelloControllerのindexActionが呼ばれるということは, もう明らかである。
そして, first_nameとlast_nameが引数に与えられることもわかる。この引数についてちょっと詳しく見てみる。

  • color:green の記述のために, $color 引数も与えられる。
    function ($first_name, $last_name, $color)
  • 引数の順番は関係ない!
    function ($first_name, $last_name, $color) でも, function ($last_name, $color, $first_name) でも同じこと
    逆に言えば, /hello/{first_name}/{last_name} とルーティングで設定したら, 変数は $first_name と $last_name になるってこと。
  • function ($first_name, $last_name, $color, $foo) のように, ドコにも定義していない $foo はダメ!
    ただ, デフォルト引数にして、function ($first_name, $last_name, $color, $foo = "foo") のようにすればOK
  • function ($first_name, $color) のように, 変数が無い($last_name)場合でも問題ない



コントローラーの一般タスク

RedirectingURLのリダイレクト
return new RedirectResponse($this->generateUrl('hello', array('name' => 'Lucas')));
※ generateUrlは router サービスの generateUrl のショートカット
Forwarding処理を他のコントローラーにデリゲートする
$response = $this->forward('コントローラ指定', array(パラメータ));
return $response;
これで, 指定したコントローラの 〇〇Action(パラメータ) が実行される。
※ これは httpKernel サービスの forward のショートカット
Rendering Templatesテンプレートのレンダリング
$content = $this->renderView('テンプレート', array(渡すパラメータ));
return new Response($content);
renderViewはtemplatingサービスのrenderメソッドのショートカット
これを簡単にかくと
return $this->render('テンプレート', array(渡すパラメータ));
で良い。
Accessing other Services他のサービスを利用
$service = $this->get('サービス名');
とすることで、他のサービスが使用可能。例として, request, response, templating, router, mailer がある。


requestサービス

requestサービスを使うと, セッションを扱ったり POST, GETの値を取得したりできる。
$request = $this->get('request'); // サービス取得

$session = $request->getSession(); // セッションオブジェクトの取得
// ちなみに, セッションオブジェクトの取得は, $session = $this->get('session'); でもよさげ。
$session->set('key','value'); // セッションに保存
$session->get('key'); // セッションから値取得

$request->isXmlHttpRequest(); // Ajaxリクエストかどうか
$request->query->get('page'); // GETパラメータの取得
$request->request->get('page'); // POSTパラメータの取得



まぁ、こんな感じでSymfonyの基礎の基礎を学びました。あとは実際に作成しながら、要所要所書いていく形にします。

独学Symfony2 : report3

version : BETA3 (正式リリース後, 改変の可能性あり)

今回も, ドキュメント的には Creating Pages in Symfony2 の続きになります。

Symfony2プロジェクトの構造

一応, 基本的なSymfony2プロジェクトのディレクトリ構造は, 名前かも判るように
Symfony2プロジェクトのディレクトリ構造
  • app/: アプリケーションのコンフィグファイルを含む
  • src/: 作成するソースなどはここに格納
  • vendor/: 様々なvendorファイルを置く場所
  • web/: 公開ディレクトリ, img, css, js などといったのはココ, あとフロントコントローラもここ!
という感じ。

ちなみに, プロジェクトを公開するときは, web/ のフロントコントローラにおいて,
$kernel = new AppKernel('prod', true);
dev環境では見れても, 上記のようにprod環境をtrueにしていないと、prodには反映されないので注意!
(一度prodで実行すると キャッシュが作成され, 以後はそのキャッシュで動くっぽいな。たぶん。)

また, prod 環境の場合, 速度のための最適化が行われ, そのためにキャッシュを作成するようになっている。そのため, もしprodの環境を変更した場合は, 以下のコマンドを実行すること!

rm -rf app/cache/*


Bundleの構造

そして Symfony2 のアプリケーションは, Bundle によって構成されている。この Bundle のディレクトリ構造は以下のようになっている。
Bundle のディレクトリ構造
  • Controller/ : Bundleのコントローラを格納
  • Resources/config/ : コンフィグレーションファイルを格納 (routing.yml などもここに入れます)
  • Resources/views/ テンプレートファイルを置く (コントローラー名/テンプレート名 という形式で)
  • Resources/public/ webディレクトリにシンボリックリンクが作成されるので, ここに img, css, js を置ける
  • Tests/ Bundleのテストをするためのもの


アプリケーションの設定

app/config/を見ると, config.yml だけでなく, config_[prod,dev,text].yml といったように, それぞれの環境に対するコンフィグレーションファイルが存在する。
まず初めに config.ymlが呼ばれ(これは必ず呼ばれる), その後に, AppKernelクラスの registerContainerConfiguration で, 環境に応じた config_[prod,dev,text].yml が呼ばれる。
これにより, 環境に柔軟な設定が可能。


 

独学Symfony2 : report2

version : BETA3 (正式リリース後, 改変の可能性あり)

When Flat PHP meets Symfony では, FrameWorkを使うことに利点みたいなのを書いていますので, 初めてFrameWorkなるものを使用して開発する!という場合は読んだほうが良いでしょう。(日本語ドキュメントもありました。)
ただ、ここではこの章は省略します。

ということで, Creating Pages in Symfony2 を読んでいきます。
(訳というよりも解説なんで、よろしくですw)


まず, Symfony2でのページ作成は, 以下のSTEPで成り立っている。
◯ Bundleの作成
① Create a route : リクエストのURIから, 対応するコントローラーを指定するための Routing 情報を決める
② Create a controller : リクエストを処理し, 応答を返すための Controller の部分を作成
③ Create a template : テンプレートの作成

ということで、実際にマニュアルに従って作成してみる

Bundleの作成


Bundleの作成
ページ作成を始める前に, まず Bundle というものを作成する必要がある。(Bundleってのは, プラグイン的な物で, Symfony2の中の要素は全て Bundle であるらしい)
で, 作成するには以下のコマンドを実行すれば良い。ちなみに, 以下のコマンドで Cannot write to cache folder みたいなエラーが出たら, cacheフォルダの権限がおかしいので, chmod -R 777 cache してやってね!

php app/console init:bundle "Acme\StudyBundle" src

で, このコマンドの出力結果は以下のようなものだった。
Summary of actions
- The bundle "AcmeStudyBundle" was created at "src/Acme/StudyBundle" and is using the namespace "Acme\StudyBundle".
- The bundle contains a sample controller, a sample template and a sample routing file.

Follow-up actions
- Enable the bundle inside the AppKernel::registerBundles() method.
Resource: http://symfony.com/doc/2.0/book/page_creation.html#create-the-bundle
- Ensure that the namespace is registered with the autoloader.
Resource: http://symfony.com/doc/2.0/book/page_creation.html#autoloading-introduction-sidebar
- If using routing, import the bundle's routing resource.
Resource: http://symfony.com/doc/2.0/book/routing.html#including-external-routing-resources
- Starting building your bundle!
Resource: http://symfony.com/doc/2.0/book/page_creation.html#the-hello-symfony-page

で, この出力にあるように , 実際に見てみると src/Acme/StudyBundle が作成されています。
ちなみに作成されたディレクトリ構造は以下.

StudyBundle/
        AcmeStudyBundle.php
        Controller/
                DefaultController.php
        Resources/
                config/
                        routing.yml
                view/
                        Default/
                                index.html.twig

ちなみに, このコマンドを使用しない場合は, 自分でディレクトリやAcmeStudyBundle.phpなどを作成する必要があります(ドキュメント同ページの Creating a Bundle を参照してください)


app/autoload.phpを確認
app/autoload.php に, 以下の記述を追加することで, ネームスペースがロードされることを確認
$loader->registerNamespaces(array(
    'Acme' => __DIR__.'/../src',
));

AppKernel classを確認
$registerBundles というメソッドに, Bundle を追加することで, Bundle の初期化を行う。
( $bundle に, new Acme\StudyBundle\AcmeStudyBundle(), を追加する)



Route の作成

app/config/routing.yml に, ルーティング情報を追加する。xmlでも, PHPでも良いらしいけど, デフォルトではYAMLであったため, YAMLでやっていきます!

※ routing.yml のインポートも可能! css のインポートみたく @ を付けて
resource: "@AcmeStudyBundle/Resources/config/routing.yml"
のようにする!

routeの詳細は後日ってことで。


Controller の作成

routeに, /hello/{name} というパターンに対して AcmeStudyBundle:Hello:index が呼ばれるように設定する(詳細はドキュメント見てね!)

そうしたとき, /hello/{name} でアクセスすると, AcmeStudyBundle の HelloController の indexAction が呼ばれるわけである。そしてindexActionの引数に$nameが渡される。


use Symfony\Bundle\FrameworkBundle\Controller\Controller;
を使用することで, テンプレートを使用してページを作成できる。ちなみに, ビューは Twig テンプレートが基本らしいですね。
そのテンプレートの配置方法は以下の様にすればいいっぽい (twigを使用することを前提としてます)


#コンテンツ部分 : src/[Bundle]/Resources/views/[コントローラー名]/[アクション名].html.twig
例 ) src/Acme/StudyBundle/Resources/views/Hello/index.html.twig
※ このビューファイルから, {% extends '::layout.html.twig' %} などとして, ↓ のレイアウトを指定するっぽいです。

#レイアウト部分 : app/Resources/views/[レイアウト名].html.twig (cakePHPでいう, views/layout/*.ctpのこと)
例 ) app/Resources/views/layout.html.twig

controllerについてやviewについての詳細はここでは説明しません。。

独学Symfony2 : report1

version : BETA3 (正式リリース後, 改変の可能性あり)

とりあえず、Symfony2の勉強をしようと, ちょいドキュメントを読んでます。
そのまとめというか、訳というか。実際のページ作成とかは, まず触ってみたいので, ドキュメントのまとめより、自分なりに触った際の解説をしていこうかと。。

Symfony2 and HTTP Fundamentalsl

Symfony2のアプリケーションの, 要求~応答までの流れとしては,
① リクエストはまず FrontController なるものに処理され, SymfonyKernelの部分へと渡される。
② そこで Routing 機能により, 要求されたURIから適切な Controller が選ばれる。
③ その Controller が呼ばれ, ユーザーに応答を返す
という感じになっているようです。(まぁ, Cakephp も似たような感じだよね。)


Symfony2 Components について

Symfonyには20以上の多くのComponentが存在します。
おそらく, /vendor/symfony/src/Symfony/Component/* にあるやつかな。(ちなみに21つありました。)

このページで説明していたのは以下のもの

コンポーネント名 説明
HttpFoundation HTTP要求/応答, また, セッションやファイルアップロードなどのクラスを含む
Routing リクエストのURIを処理するためのもの
Form フォーム作成や, フォームの送信データを扱うためのもの
Validation バリデーションのためのクラス (まぁ、名前のとおりですよね(全部名前の通りなんですがw))
ClassLoader クラスのロードを自動的に行うためのもの (Cakeでいう, ClassRegistry みたいなやつかな? まだよくわから〜ん)
Templating テンプレートのレンダリングに関する処理を扱うためのクラス
Security アプリケーション内部のセキュリティを扱うためのもの
Translation 翻訳のためのもの

また, すべてのコンポーネントは切り離されているため, Symfony2 フレームワークを使用していないプロジェクトでも、使用できるようになっているらしいです。

独学Symfony2 : report0 [インストール]

version : BETA3 (正式リリース後, 改変の可能性あり)


2011年6月4日のSymfony2勉強会に向けて, Symfony2 standard ディストリビューションのインストールを行ったので, そのメモを。
ちなみに OS は Mac OS X 10.6 です。

とりあえずgitとAPCのインストール

① まず, homebrewをインストールします
ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"


② git のインストール
brew install git


③ homebrewのアップデート
brew update を行うのだが, このコマンドでエラーが生じて途中で止まってしまったため, 以下を実行
$ cd /usr/local/
$ git remote add origin git://github.com/mxcl/homebrew.git
$ git fetch origin
$ git reset --hard origin/master

そして, homebrewをアプデ!! (ちなみに, ② のgitインストールは, ここで必要っぽい)
brew update

④ Symfony2でAPC(Alternative PHP Cache) があるとよいので, APCをインストール
brew install apc

ちなみに, この時の出力は以下 (青字の部分は, あとでphp.iniの最後に追記すること)

To finish installing APC:
* Add the following lines to php.ini:
[apc]
extension="/usr/local/Cellar/apc/3.1.6/apc.so"
apc.enabled=1
apc.shm_segments=1
apc.shm_size=64M
apc.ttl=7200
apc.user_ttl=7200
apc.num_files_hint=1024
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.enable_cli=1
* Restart your webserver
* Copy "/usr/local/Cellar/apc/3.1.6/apc.php" to any site to see APC's usage.
==> Summary
/usr/local/Cellar/apc/3.1.6: 2 files, 204K, built in 17 seconds


⑤ 次にとうとうSymfony2をダウンロード!

symfony sandbox というものがあるらしく , git で 入れても良いのだが, Symfony2 standard ディストリビューション ということで, ちょっとよくわからなかった。ただ、勉強会ではSymfony2(Standard Edition)のインストール方法 等を学ぶということで, とりあえず http://symfony.com/download からダウンロードしたものを使用した。

まぁ, これを展開するだけです。

⑥ app/check.php にアクセスし, 正しくインストールされているか確認
例として, 以下のような感じです。



⑦ インストールできていれば, web/ ディレクトリをDocumentRootにする。
これは apache の方の設定ですね。



⑧ .....ということだけど, intlが無いって言われてしまったので, intlモジュール入れました!

brew install icu4c

php-5.3.6 をダウンロードし, その中の ext/intlに移動し以下のコマンドを実行
phpize
./configure --enable-intl --with-icu-dir=/usr/local/Cellar/icu4c/4.4.1
make
make test
sudo make install.

php.ini に, extension=intl.so を追記し, apache再起動


これでOKかな?大変だった〜。


参考にさせて頂いたサイトは以下
Symfony2勉強会向けのセットアップ準備(Mac向け)
Homebrewのupdateでエラー

ブログ開設〜

Dev.GrAFR の方でも、少し書いてたけど、しょっと本格的にSymfony2を使うことになってきたので、専用にSymfony2用の開発ブログを解説しましたー(^^)

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More