Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

フラットなPHPからフレームワークへ

17,796 views

Published on

PHPカンファレンス2012での発表資料

1ファイルで記述されたPHPコードからフレームワークを使ったコードに変化していく様子を解説することで、フラットなPHPの駄目なところとなぜフレームワークを使うのかを紹介。

http://d.hatena.ne.jp/brtRiver/20120728/1343499474
http://www.ustream.tv/recorded/25417035

Published in: Technology

フラットなPHPからフレームワークへ

  1. 1. フラットなPHPから フレームワークへ 株式会社 adingo 前田 雅央 @brtriver
  2. 2. @brtriver
  3. 3. Steps フラットなPHP リファクタリング フレームワーク * フラットなPHP = 1ファイルで書かれたPHP
  4. 4. Steps フラットなPHP View部分の分離 アプリケーション(ドメイン)部分の分離 Viewにレイアウト機能を追加 ページを追加する フロントコントローラー導入 ライブラリを利用する フレームワーク
  5. 5. どのフレームワークを使う?なぜフレームワークを使う?
  6. 6. Step 0 DBからデータ取得し 取得したデータを HTMLで表示する
  7. 7. <?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, list.php myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  8. 8. <?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, list.php myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  9. 9. <?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, list.php myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  10. 10. <?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, list.php myuser,DBからデータ取得 ); mypassword, array(PDO::ATTR_EMULATE_PREPARES => false)$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  11. 11. <?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, list.php myuser,DBからデータ取得 ); mypassword, array(PDO::ATTR_EMULATE_PREPARES => false)$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> 取得したデータを表示 <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  12. 12. クライアント サーバー リクエスト PHP +Browser HTML レスポンス list.php
  13. 13. Good シンプル 1ファイルたったの26行
  14. 14. Badアプリケーションの拡張性が無い 体系化されていない 再利用性がない
  15. 15. 体系化されていないフォームの送信を行うコードの追加したい... どこに書く? 同じファイル?別ファイルで書く?
  16. 16. コードの再利用性が低い 新しい別ファイルでlist.phpのコードを利用 できない。 新しいページを コピペで作成
  17. 17. クライアント サーバー エ スト PHP + HTML リク ポ ンス レス list.php Browser Bad
  18. 18. クライアント サーバー エ スト PHP + HTML リク ポ ンス レス list.php Browser COPY Bad
  19. 19. クライアント サーバー エ スト PHP + HTML リク ポ ンス レス list.php Browser COPY リクエ スト PHP + HTML レスポ ンス list2.php Bad
  20. 20. Step 1 View部分の分離
  21. 21. show.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  22. 22. show.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, myuser, ); mypassword, ロジック部分 array(PDO::ATTR_EMULATE_PREPARES => false)$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  23. 23. show.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, myuser, ); mypassword, ロジック部分 array(PDO::ATTR_EMULATE_PREPARES => false)$stmt = $pdo->query(SELECT id, title FROM post);?><html> <head> <title>投稿の一覧</title> </head> <body> <h1>投稿の一覧</h1> <ul> View(HTML)部分 <?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?> <li> <a href="show.php?id=<?php echo htmlspecialchars($row[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($row[title], ENT_QUOTES, utf-8) ?> </a> </li> <?php endwhile; ?> </ul> </body></html>
  24. 24. show.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db:charset=utf8, myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);// HTML部分のコードを読み込むrequire templates/list.php; 別ファイルに分離
  25. 25. show.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db:charset=utf8, myuser, mypassword, ロジック部分 array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);// HTML部分のコードを読み込むrequire templates/list.php; 別ファイルに分離
  26. 26. クライアント サーバー リクエスト controllerBrowser PHP list.php
  27. 27. クライアント サーバー リクエスト controllerBrowser PHP list.php
  28. 28. クライアント サーバー リクエスト controllerBrowser PHP list.php レスポンス view HTML template/list.php
  29. 29. クライアント サーバー リクエスト controllerBrowser PHP list.php レスポンス view json template/list-json.php
  30. 30. Good View部分の分離 テンプレートの変更に強い
  31. 31. Step 2 アプリケーション(ドメイン) 部分の分離
  32. 32. index.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db:charset=utf8, myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);
  33. 33. index.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db:charset=utf8, データベースへ接続する myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) );$stmt = $pdo->query(SELECT id, title FROM post);
  34. 34. index.php<?php$pdo = new PDO( mysql:host=localhost;dbname=blog_db:charset=utf8, データベースへ接続する myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) ); 全てのポストを取得する$stmt = $pdo->query(SELECT id, title FROM post);
  35. 35. ドメイン データベースへの接続する 全てのポストを取得する model.php に分離
  36. 36. <?php// model.phpfunction get_database_connection(){ $pdo = new PDO( mysql:host=localhost;dbname=blog_db;charset=utf8, myuser, mypassword, array(PDO::ATTR_EMULATE_PREPARES => false) ); return $pdo; get_database_connection}function get_all_posts(){ $pdo = get_database_connection(); $stmt = $pdo->query(SELECT id, title FROM post); $posts = array(); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $posts[] = $row; } get_all_posts return $posts;} model.php
  37. 37. リファクタリング後のlist.php<?phprequire model.php;$posts = get_all_posts();require templates/list.php; コントローラーは制御するだけ
  38. 38. リファクタリング後のlist.php<?phprequire model.php; ロジック読込$posts = get_all_posts();require templates/list.php; コントローラーは制御するだけ
  39. 39. リファクタリング後のlist.php<?phprequire model.php; ロジック読込$posts = get_all_posts(); 全ポストを取得require templates/list.php; コントローラーは制御するだけ
  40. 40. リファクタリング後のlist.php<?phprequire model.php; ロジック読込$posts = get_all_posts(); 全ポストを取得require templates/list.php; ビュー読込 コントローラーは制御するだけ
  41. 41. Goodアプリケーション(ドメイン)部分の分離 コントローラが本来のコントローラーに シンプルなMVC
  42. 42. クライアント サーバー リクエスト controller Browser PHP list.php レスポンス view HTML template/list.php
  43. 43. クライアント サーバー model Logic get_all_posts model.php リクエスト controller Browser PHP list.php $POSTS レスポンス view HTML template/list.php
  44. 44. Step 3 Viewにレイアウト機能を追加
  45. 45. レイアウト機能 Viewの共通部分を再利用できる仕組み <html> <head> <title>トップページ</title> </head> <body> <h1>こんにちは!こんにちは!</h1> </body> </html> template/layout.php
  46. 46. レイアウト機能 Viewの共通部分を再利用できる仕組み <html> <head> <title>トップページ</title> </head> <body> <h1>こんにちは!こんにちは!</h1> </body> 動的部分を決定 </html> template/layout.php
  47. 47. レイアウト機能 PHPで書き換え <html> <head> <title><?php echo $title ?></title> </head> <body> <?php echo $content ?> </body> </html> template/layout.php
  48. 48. ob_start() ... ob_get_clean()<?php $title = 投稿のリスト ?> list.php<?php ob_start() ?> <h1>投稿のリスト</h1> <ul> <?php foreach ($posts as $post): ?> <li> <a href="show.php?id=<?php echohtmlspecialchars($post[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($post[title], ENT_QUOTES,utf-8) ?> </a> </li> <?php endforeach; ?> </ul><?php $content = ob_get_clean() ?><?php include layout.php ?>
  49. 49. ob_start() ... ob_get_clean()<?php $title = 投稿のリスト ?> list.php<?php ob_start() ?> <h1>投稿のリスト</h1> <ul> <?php foreach ($posts as $post): ?> <li> <a href="show.php?id=<?php echohtmlspecialchars($post[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($post[title], ENT_QUOTES,utf-8) ?> </a> </li> <?php endforeach; ?> </ul><?php $content = ob_get_clean() ?><?php include layout.php ?>
  50. 50. ob_start() ... ob_get_clean()<?php $title = 投稿のリスト ?> list.php<?php ob_start() ?> <h1>投稿のリスト</h1> <ul> <?php foreach ($posts as $post): ?> <li> <a href="show.php?id=<?php echohtmlspecialchars($post[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($post[title], ENT_QUOTES,utf-8) ?> </a> </li> <?php endforeach; ?> </ul><?php $content = ob_get_clean() ?><?php include layout.php ?>
  51. 51. ob_start() ... ob_get_clean()<?php $title = 投稿のリスト ?> list.php<?php ob_start() ?> <h1>投稿のリスト</h1> <ul> <?php foreach ($posts as $post): ?> <li> <a href="show.php?id=<?php echohtmlspecialchars($post[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($post[title], ENT_QUOTES,utf-8) ?> </a> </li> <?php endforeach; ?> </ul><?php $content = ob_get_clean() ?> 出力せずにバッファリング<?php include layout.php ?>
  52. 52. ob_start() ... ob_get_clean()<?php $title = 投稿のリスト ?> list.php<?php ob_start() ?> <h1>投稿のリスト</h1> <ul> <?php foreach ($posts as $post): ?> <li> <a href="show.php?id=<?php echohtmlspecialchars($post[id], ENT_QUOTES, utf-8) ?>"> <?php echo htmlspecialchars($post[title], ENT_QUOTES,utf-8) ?> </a> </li> <?php endforeach; ?> </ul><?php $content = ob_get_clean() ?> 出力せずにバッファリング<?php include layout.php ?>
  53. 53. クライアント サーバー model get_all_posts Logic model.php リクエスト controller Browser PHP list.php $POSTS レスポンス view HTML template/list.php
  54. 54. クライアント サーバー model get_all_posts Logic model.php リクエスト controller Browser PHP list.php $POSTS レスポンス view HTML template/list.php layout HTML layout.php
  55. 55. Good テンプレートの可用性がUPBad テンプレートエンジンの機能より劣る Smarty, Twig...
  56. 56. テンプレートエンジンのメリット Pure PHP<title><?php echo htmlspecialchars($title, ENT_QUOTES, utf-8) ?></title> Twig (escape) <title>{{ title }}</title> Twig (un escape) <title>{{ title¦raw }}</title>
  57. 57. Step 4 ページを追加する blogの詳細ページ(show)
  58. 58. list.phpと同じ仕組を作る<?phprequire_once model.php;$post = get_post_by_id($_GET[id]);require templates/show.php; 特定の記事を取得 show.php
  59. 59. クライアント サーバー model get_post_by_id Logic model.php リクエスト controller Browser PHP show.php $POST レスポンス view HTML template/show.php layout HTML layout.php
  60. 60. クライアント controller サーバー PHP get_all_posts list.php view HTML $POSTS template/list.php layout model Browser HTML Logic layout.php model.php view $POST HTML tempalte/show.php controller get_post_by_id PHP show.php
  61. 61. クライアント controller サーバー PHP get_all_posts list.php view 一覧表示処理 HTML $POSTS template/list.php layout model Browser HTML Logic layout.php model.php view $POST HTML tempalte/show.php controller get_post_by_id PHP show.php
  62. 62. クライアント controller サーバー PHP get_all_posts list.php view 一覧表示処理 HTML $POSTS template/list.php layout model Browser HTML Logic layout.php model.php view $POST HTML 詳細表示処理 tempalte/show.php controller get_post_by_id PHP show.php
  63. 63. クライアント controller サーバー PHP get_all_posts list.php view 一覧表示処理 HTML $POSTS template/list.php layout model Browser HTML Logic layout.php model.php view $POST HTML 詳細表示処理 tempalte/show.php controller get_post_by_id PHP show.php
  64. 64. Good Model, Layoutが共通化できているBad リクエストを受けるPHPは model.phpを忘れずに requireしなければならない
  65. 65. Step 5 フロントコントローラー
  66. 66. フロントコントローラー? 全てのリクエストを 最初に必ず受ける 1つのPHPファイル
  67. 67. Beforeクライアント サーバー http://example.com/list.php controller PHP list.php Browser
  68. 68. Beforeクライアント サーバー http://example.com/list.php controller PHP list.php Browser controller PHP show.php http://example.com/show.php?id=5
  69. 69. Afterクライアント サーバー front controller controllers Browser PHP PHP index.php controllers.php
  70. 70. Afterクライアント サーバーhttp://example.com/index.php/list list_action() front controller controllers Browser PHP PHP index.php controllers.php
  71. 71. Afterクライアント サーバーhttp://example.com/index.php/list list_action() front controller controllers Browser PHP PHP index.php controllers.php show_action(5)http://example.com/index.php/show?id=5
  72. 72. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action();} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]);} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  73. 73. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action();} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]);} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  74. 74. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action();} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]);} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  75. 75. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action();} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]);} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  76. 76. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action(); 一覧表示へのリクエスト} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]);} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  77. 77. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action(); 一覧表示へのリクエスト} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]); 記事詳細へのリクエスト} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  78. 78. フロントコントローラー (routing)require_once model.php;require_once controllers.php;// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action(); 一覧表示へのリクエスト} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]); 記事詳細へのリクエスト} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>; 想定外のリクエスト} index.php
  79. 79. フロントコントローラー(アクション)<?php controllers.php// controllers.phpfunction list_action(){ $posts = get_all_posts(); require templates/list.php;}function show_action($id){ $post = get_post_by_id($id); require templates/show.php;}
  80. 80. フロントコントローラー(アクション)<?php controllers.php// controllers.phpfunction list_action(){ $posts = get_all_posts(); require templates/list.php;} 一覧表示へのリクエストfunction show_action($id){ $post = get_post_by_id($id); require templates/show.php;}
  81. 81. フロントコントローラー(アクション)<?php controllers.php// controllers.phpfunction list_action(){ $posts = get_all_posts(); require templates/list.php;} 一覧表示へのリクエストfunction show_action($id){ $post = get_post_by_id($id); require templates/show.php;} 記事詳細へのリクエスト
  82. 82. Good 設定の読込などの集中管理 ルーティング機能
  83. 83. Point クラスはまだ使ってません クラスで書かなくても ある程度の体系化は可能です
  84. 84. Step6 ライブラリを利用する
  85. 85. ライブラリを利用する HttpFoundation Component
  86. 86. HttpFoundation Component を使うことで.... Webアプリケーションで必須な$_GET, $_POST, レスポンスデータ をオブジェクトで扱える
  87. 87. HttpFoundation Component を使うことで....Pure PHP $id = (isset($_GET[ id ]))? $_GET[ id ]: 0; Object $id = $request->query( id , 0);
  88. 88. HttpFoundation Component を 採用しているプロジェクト Symfony2 Silex Drupal8 phpBB4 ppi2 Laravel4 Zikula ... more
  89. 89. HttpFoundation Component は 今後のデファクトスタンダート Laravel4 ?? FuelPHP2
  90. 90. Pure PHP// リクエストを内部的にルーティング$uri = $_SERVER[REQUEST_URI];if ($uri === (/index.php/list)) { list_action();} elseif ( preg_match("#^/index.php/show#", $uri) &&isset($_GET[id])) { show_action($_GET[id]);} else { header(Status: 404 Not Found); echo <html><body><h1>ページが見つかりません</h1></body></html>;} index.php
  91. 91. Symfony component$request = Request::createFromGlobals();$uri = $request->getPathInfo();if ($uri === /) { $response = list_action();} elseif ($uri === /show && $request->query->has(id)) { $response = show_action($request->query->get(id));} else { $html = <html><body><h1>Page Not Found</h1></body></html>; $response = new Response($html, 404);}$response->send(); index.php
  92. 92. Symfony component$request = Request::createFromGlobals();$uri = $request->getPathInfo();if ($uri === /) { $response = list_action();} elseif ($uri === /show && $request->query->has(id)) { $response = show_action($request->query->get(id));} else { $html = <html><body><h1>Page Not Found</h1></body></html>; $response = new Response($html, 404);}$response->send(); index.php
  93. 93. <?php controllers.php// controllers.phpfunction list_action(){ $posts = get_all_posts(); require templates/list.php;}
  94. 94. <?php controllers.php// controllers.phpfunction list_action(){ $posts = get_all_posts(); require templates/list.php;} テンプレートをレンダリング (echo)
  95. 95. Controllersfunction list_action(){ $posts = get_all_posts(); $html = render_template(templates/list.php, array(posts =>$posts)); return new Response($html);}function render_template($path, $params){ extract($params, EXTR_SKIP); ob_start(); require $path; $html = ob_get_clean(); return $html;}
  96. 96. Controllersfunction list_action(){ $posts = get_all_posts(); $html = render_template(templates/list.php, array(posts =>$posts)); return new Response($html);} Responseオブジェクトを返すfunction render_template($path, $params){ extract($params, EXTR_SKIP); ob_start(); require $path; $html = ob_get_clean(); return $html;}
  97. 97. Controllersfunction list_action(){ $posts = get_all_posts(); $html = render_template(templates/list.php, array(posts =>$posts)); return new Response($html);} Responseオブジェクトを返すfunction render_template($path, $params){ extract($params, EXTR_SKIP); ob_start(); require $path; $html = ob_get_clean(); return $html;}
  98. 98. Controllersfunction list_action(){ $posts = get_all_posts(); $html = render_template(templates/list.php, array(posts =>$posts)); return new Response($html);} Responseオブジェクトを返すfunction render_template($path, $params){ extract($params, EXTR_SKIP); ob_start(); require $path; $html = ob_get_clean(); return $html;} 典型的なPHPテンプレートパターン
  99. 99. CakePHPDietCake
  100. 100. CakePHPDietCake
  101. 101. CakePHPDietCake
  102. 102. Good 簡易的なフレームワークが完成 車輪の再開発を防ぐ 必要な機能だけ利用できる 再利用性が高いBad必要以上の機能が含まれるかもしれない
  103. 103. クライアント サーバー model Logic model.php list_action() リクエスト front controller controllers Browser PHP PHP index.php controllers.php show_action() レスポンス view HTML template/show.php layout HTML layout.php
  104. 104. クライアント サーバー Model MVC リクエスト Browser controller レスポンス view
  105. 105. Final フレームワークを使う とは?
  106. 106. フレームワークを使う フレームワークを使っても やりたいことは変わらない
  107. 107. フレームワークを使う 作りたいのはアプリケーション
  108. 108. フレームワークを使う ルーティング 規約 コントローラー バリデーター ......
  109. 109. Silexで書き換えると...$app = new SilexApplication();.....$app->get(/show, function(Application $app, Request $request){ $get_post_by_id = $app[model.post_by_id]; $post = $get_post_by_id($request->query->get(id)); return $app->render(templates/show.twig, array(post => $post));});
  110. 110. フラットなPHPからSymfony2へ フラットなPHPからSliexへ フラットなPHPからSlimへ 詳しくはぐぐってみてください
  111. 111. フレームワークを使う 自分でゼロから作らなくて良い 万能なフレームワークは無い 実際に使って思想を理解する
  112. 112. まとめ フラットなPHPのデメリットフレームワークの本来の仕事は何か?使われるのではなく使うこと
  113. 113. thank you.

×