Symfony2 How to create your Bundle

2,881 views
2,811 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,881
On SlideShare
0
From Embeds
0
Number of Embeds
340
Actions
Shares
0
Downloads
15
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Symfony2 How to create your Bundle

  1. 1. PDOBundleを作る 2010/11/20 chobi_e
  2. 2. twitter: chobi_e(ちょびえ) 生年月日:1984/5/7 自己紹介
  3. 3. twitter: chobi_e(ちょびえ) 生年月日:1984/5/7 自己紹介 Symfony初心者です><
  4. 4. 自己紹介 元
  5. 5. 自己紹介 モバイル系なんでも屋 元
  6. 6. 自己紹介 モバイル系なんでも屋 元 ・株式会社プロジェクトゼロ ディレクター PHPプログラマ、サーバーエンジニア、ディレクター ・株式会社インクルーズ インフラチームリーダー PHPプログラマ、サーバーエンジニア、 インフラエンジニア、ディレクター
  7. 7. 自己紹介 現在
  8. 8. 自己紹介 現在 ニート
  9. 9. 自己紹介 現在 ニート(ひっそり求職活動中です。)
  10. 10. 親の脛かじりおいしいれす^q^
  11. 11. 最近の活動
  12. 12. 最近の活動 ・Symfony2関連でブログ記事書いてます
  13. 13. 最近の活動 ・Symfony2関連でブログ記事書いてます ・Symfony2を理解するためにBundleを書く ・Symfony2を理解する為にシンプルなアプリケーションを書く ・デザインパターンはPHP5.3になってどう変わったか
  14. 14. 最近の活動2 ・PHP向けのWSGIアプリケーションサーバー
  15. 15. 最近の活動2 ・PHP向けのWSGIアプリケーションサーバー ・libevent+embed SAPIベースでPHP組み込んでます ・Cで全て記述された高速(を目指す)なHTTPサーバー
  16. 16. 最近の活動2 ・PHP向けのWSGIアプリケーションサーバー ・libevent+embed SAPIベースでPHP組み込んでます (今後自前のSAPI実装予定) ・Cで全て記述された高速(を目指す)なHTTPサーバー (meinheldを参考にしています)
  17. 17. 最近の活動2 ・PHP向けのWSGIアプリケーションサーバー ・libevent+embed SAPIベースでPHP組み込んでます (今後自前のSAPI実装予定) ・Cで全て記述された高速(を目指す)なHTTPサーバー (meinheldを参考にしています) ある程度使えるようになったら OSSとして公開しようと思っています。
  18. 18. PDOBundelを作る
  19. 19. Why PDOBundle? ・ライブラリをBundle化する手順を覚える
  20. 20. Why PDOBundle? ・ライブラリをBundle化する手順を覚える ・とりあえず馴染み深いライブラリとしてPDO
  21. 21. Why PDOBundle? ・ライブラリをBundle化する手順を覚える ・とりあえず馴染み深いライブラリとしてPDO ・短期間でDoctrine覚えきれなかったんだ・・・
  22. 22. Doctrine覚えきれなかったんだ
  23. 23. Doctrine覚えきれなかったんだ (大事なことなので2回言いました)
  24. 24. 仕様を考える ・単純にPDOを呼び出すだけBundleにする ・XSDファイルをきちんと書く
  25. 25. 仕様を考える ・単純にPDOを呼び出すだけBundleにする (複雑だとLT内で終わらない) ・XSDファイルをきちんと書く (xml設定でした場合にValidationが効く)
  26. 26. まず初めにPlainなPHPで
  27. 27. <?php $dsn = “mysql:dbname=uhi;”; $dsn .= “host=localhost;”; $dsn .= “charset=utf8”; $pdo = new ¥PDO($dsn, “symfony” ,”reloaded”); $pdo->setAttribute( ¥PDO::ATTR_ERRMODE, ¥PDO::ERRMODE_EXCEPTION); $r = $pdo->query(“select id,name from user”); list($id,$name) = $r->fetch(¥PDO::FETCH_NUM); printf (“Hello %s<br />”,$name);
  28. 28. <?php $dsn = “mysql:dbname=uhi;”; $dsn .= “host=localhost;”; $dsn .= “charset=utf8”; $pdo = new ¥PDO($dsn, “symfony” ,”reloaded”); $pdo->setAttribute( ¥PDO::ATTR_ERRMODE, ¥PDO::ERRMODE_EXCEPTION); $r = $pdo->query(“select id,name from user”); list($id,$name) = $r->fetch(¥PDO::FETCH_NUM); printf (“Hello %s<br />”,$name); Charsetを指定しましょ! Exceptionをなげます
  29. 29. $ php sample-pdo.php
  30. 30. $ php sample-pdo.php
  31. 31. PDOBundleを作る PDOは色々な場所で扱うので
  32. 32. PDOBundleを作る PDOは色々な場所で扱うので 毎回生成するよりも
  33. 33. PDOBundleを作る PDOは色々な場所で扱うので 毎回生成するよりも Symfony2のDIコンテナに登録した
  34. 34. PDOBundleを作る PDOは色々な場所で扱うので 毎回生成するよりも Symfony2のDIコンテナに登録した 方が色々と都合が良いのです
  35. 35. 必要な設定を書き出す
  36. 36. <?php $pdo_config = array(); $pdo_config[“driver”] = “mysql”; $pdo_config[“database”] = “uhi”; $pdo_config[“host”] = “localhost”; $pdo_config[“charset”] = “utf8”; $pdo_config[“user”] = “symfony”; $pdo_config[“password”] = “reloaded”;
  37. 37. <?php $pdo_config = array(); $pdo_config[“driver”] = “mysql”; $pdo_config[“database”] = “uhi”; $pdo_config[“host”] = “localhost”; $pdo_config[“charset”] = “utf8”; $pdo_config[“user”] = “symfony”; $pdo_config[“password”] = “reloaded”; そのまんまですね
  38. 38. 実際にBundleを作るよ
  39. 39. 実際にBundleを作るよ ハ_ハ _ ∩゚∀゚)ノ つくるよ! ) / (_ノ_ノ
  40. 40. $mkdir -p src/Bundle/PDOBundle/¥ {DependencyInjection,Resources/config/schema} cat > src/Bundle/PDOBundle/PDOBundle.php <<EOF <?php namespace Bundle¥PDOBundle; use Symfony¥Component¥HttpKernel¥Bundle¥Bundle; class PDOBundle extends Bundle { } EOF
  41. 41. $mkdir -p src/Bundle/PDOBundle/¥ {DependencyInjection,Resources/config/schema} cat > src/Bundle/PDOBundle/PDOBundle.php <<EOF <?php namespace Bundle¥PDOBundle; use Symfony¥Component¥HttpKernel¥Bundle¥Bundle; class PDOBundle extends Bundle { } EOF catでがんがん貼り付けるよ! 1コマンドで複数ディレクトリを掘るよ!
  42. 42. Bundle/PDOBundle/DependencyInjection/PDOExtension.php namespace Bundle¥PDOBundle¥DependencyInjection; use Symfony¥Component¥DependencyInjection¥Extension¥Extension; use Symfony¥Component¥DependencyInjection¥Loader¥XmlFileLoader; use Symfony¥Component¥DependencyInjection¥ContainerBuilder; use Symfony¥Component¥DependencyInjection¥Definition; use Symfony¥Component¥DependencyInjection¥Reference;
  43. 43. class PDOExtension extends Extension { public function configLoad($config, ContainerBuilder $container){ var_dump($config); } public function getNameSpace(){ return ‘http://mandarine.co/schema/dic/pdo’; } public function getXsdValidationBasePath(){ return __DIR__ . ‘/../Resources/config/schema’; } public function getAlias(){ return ‘pdo’; } }
  44. 44. class PDOExtension extends Extension { public function configLoad($config, ContainerBuilder $container){ var_dump($config); } public function getNameSpace(){ return ‘http://mandarine.co/schema/dic/pdo’; } public function getXsdValidationBasePath(){ return __DIR__ . ‘/../Resources/config/schema’; } public function getAlias(){ return ‘pdo’; } } UniqueなNamespaceを書くんだよ! XSD使わないときはNullだよ! 他とかぶらないAlias名をつけるよ!
  45. 45. Applicationの設定ファイルに追記するよ! ハ_ハ _ ∩゚∀゚)ノ コピペよ! ) / (_ノ_ノ
  46. 46. #app/config/config.yml pdo.config: driver: mysql host: localhost database: moe user: symfony password: reloaded charset: utf8
  47. 47. #app/config/config.yml pdo.config: driver: mysql host: localhost database: moe user: symfony password: reloaded charset: utf8
  48. 48. PDOExtension::configLoadを実装するよ ハ_ハ _ ∩-∀-)ノ ねむいよ! ) / (_ノ_ノ
  49. 49. public function configLoad($config, ContainerBuilder $container) { $def = new Definition(”PDO”); $def->setArguments(array( sprintf(”%s:dbname=%s;host=%s;charset=%s”, $config[”driver”], $config[”database”], $config[”host”], $config[”charset”], $config[”user”], $config[”password”] )); $container->setDefinition(”pdo.connection”,$def); } //…
  50. 50. public function configLoad($config, ContainerBuilder $container) { $def = new Definition(”PDO”); $def->setArguments(array( sprintf(”%s:dbname=%s;host=%s;charset=%s”, $config[”driver”], $config[”database”], $config[”host”], $config[”charset”], $config[”user”], $config[”password”] )); $container->setDefinition(”pdo.connection”,$def); } //… Definitionで作成するクラス名を指定するよ! setArtgumentsでコンストラクタに渡すよ! 指定した名前でコンテナからアクセスできるよ
  51. 51. Controllerで実際に試してみるよ ハ_ハ _ ∩゚∀゚)ノ ためすよ! ) / (_ノ_ノ
  52. 52. //… public function indexAction() { $result = $this->container->get(“pdo.connection”) ->query(“select id, name from moe limit 1”); return $this->render(“Sample:Hello:index.php”, $result->fetch(¥PDO::FETCH_ASSOC) ); } //…
  53. 53. # views/Hello/index.php Hello <?php echo $name;?>
  54. 54. # views/Hello/index.php Hello <?php echo $name;?>
  55. 55. # views/Hello/index.php Hello <?php echo $name;?> ハ_ハ _ ∩゚∀゚)ノ できたよ! ) / (_ノ_ノ
  56. 56. XML+XSDで書き直すよ ハ_ハ _ ∩゚∀゚)ノ まだ続くよ ) / (_ノ_ノ DIextension用の
  57. 57. cat > src/Application/PDOBundle/Resources/config/pdo.xml <<EOF <?xml version="1.0" ?> <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.symfony- project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd"> <parameters> <parameter key="pdo.driver">mysql</parameter> <parameter key="pdo.database">null</parameter> <parameter key="pdo.host">localhost</parameter> <parameter key="pdo.user">root</parameter> <parameter key="pdo.password">null</parameter> <parameter key="pdo.charset">UTF-8</parameter> </parameters> <services> <service id=“pdo.connection” class=“PDO”> <argument>%pdo.driver%:dbname=%pdo.database%;host=%pdo.host%;charset=%pdo.charset%</argument> <argument>%pdo.user%</argument> <argument>%pdo.password%</argument> <call method="setAttribute"> <argument type="constant">¥PDO::ATTR_ERRMODE</argument> <argument type="constant">¥PDO::ERRMODE_EXCEPTION</argument> </call> </service> </services> </container> EOF
  58. 58. public function configLoad($config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__ . ”/../Resources/config”); $loader->load(“pdo.xml”); foreach( array(“driver”,”host”,”database”,”user”,”password”,”charset”) as $key => $value ){ $container->setDefinition(”pdo.”.$key,$value); } } //…
  59. 59. public function configLoad($config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__ . ”/../Resources/config”); $loader->load(“pdo.xml”); foreach( array(“driver”,”host”,”database”,”user”,”password”,”charset”) as $key => $value ){ $container->setDefinition(”pdo.”.$key,$value); } } //… XML定義を元にconfigを処理するよ!
  60. 60. public function configLoad($config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__ . ”/../Resources/config”); $loader->load(“pdo.xml”); foreach( array(“driver”,”host”,”database”,”user”,”password”,”charset”) as $key => $value ){ $container->setDefinition(”pdo.”.$key,$value); } } //…
  61. 61. public function configLoad($config, ContainerBuilder $container) { $loader = new XmlFileLoader($container, __DIR__ . ”/../Resources/config”); $loader->load(“pdo.xml”); foreach( array(“driver”,”host”,”database”,”user”,”password”,”charset”) as $key => $value ){ $container->setDefinition(”pdo.”.$key,$value); } } //… ハ_ハ _ ∩゚∀゚)ノ できたよ! ) / (_ノ_ノ
  62. 62. XSD? XML Schema Definition
  63. 63. XSD? ・簡単に言うとXMLで書いた型定義ファイル
  64. 64. XSD? ・簡単に言うとXMLで書いた型定義ファイル ・XMLの設定でValidationが効くようになります
  65. 65. XSD? ・簡単に言うとXMLで書いた型定義ファイル ・XMLの設定でValidationが効くようになります ・詳しい事はぐぐるといいよ!
  66. 66. XSD? ・簡単に言うとXMLで書いた型定義ファイル ・XMLの設定でValidationが効くようになります ・詳しい事はぐぐるといいよ! ハ_ハ _ ∩>∀<)ノ 実はよくしらないよ ) / (_ノ_ノ
  67. 67. cat > src/Application/PDOBundle/Resources/config/schema/pdo-1.0.xsd <<EOF <?xml version="1.0" encoding="UTF-8" ?> <xsd:schema xmlns=“http://mandarine.co/schema/dic/pdo” xmlns:xsd="http://www.w3.org/2001/XMLSchema“ targetNamespace="http://mandarine.co/schema/dic/pdo“ elementFormDefault="qualified"> <xsd:element name="config" type="config" /> <xsd:complexType name="config"> <xsd:attribute name="driver" type="xsd:string" /> <xsd:attribute name="host" type="xsd:string" /> <xsd:attribute name="database" type="xsd:string" /> <xsd:attribute name="user" type="xsd:string" /> <xsd:attribute name="password" type="xsd:string" /> <xsd:attribute name="charset" type="xsd:string" /> </xsd:complexType> </xsd:schema> EOF
  68. 68. cat > src/Application/PDOBundle/Resources/config/schema/pdo-1.0.xsd <<EOF <?xml version="1.0" encoding="UTF-8" ?> <xsd:schema xmlns=“http://mandarine.co/schema/dic/pdo” xmlns:xsd="http://www.w3.org/2001/XMLSchema“ targetNamespace="http://mandarine.co/schema/dic/pdo“ elementFormDefault="qualified"> <xsd:element name="config" type="config" /> <xsd:complexType name="config"> <xsd:attribute name="driver" type="xsd:string" /> <xsd:attribute name="host" type="xsd:string" /> <xsd:attribute name="database" type="xsd:string" /> <xsd:attribute name="user" type="xsd:string" /> <xsd:attribute name="password" type="xsd:string" /> <xsd:attribute name="charset" type="xsd:string" /> </xsd:complexType> </xsd:schema> EOF extensionのNamespaceと合わせるよ!
  69. 69. おわりに 複雑なクラスは~load()メソッド内で定義する 必要がありますが、XMLを使うことで単純に 定義することもできます。 XSDファイルは、XML読み込み時にエラーチェック が行えるので、typoや型ミスマッチ等を事前に 防ぐことが出来ます。
  70. 70. おわりに 今のところSymfony2はPR3の段階で今後変更 の可能性がありますが、ある程度中身の動作 を理解しておけば多少変わったぐらいでは どおってことないので今回のLTのように実際に 手で写経しまくるのがオススメですよ! ハ_ハ _ ∩゚∀゚)ノ おわるよ ) / (_ノ_ノ
  71. 71. おわりに2 [PR] なんでもイケる
  72. 72. おわりに2 [PR] なんでもイケる 一社に一匹便利なchobi_e
  73. 73. おわりに2 [PR] なんでもイケる 一社に一匹便利なchobi_e 【いりませんか?】

×