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

17,133 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
1 Comment
52 Likes
Statistics
Notes
No Downloads
Views
Total views
17,133
On SlideShare
0
From Embeds
0
Number of Embeds
1,310
Actions
Shares
0
Downloads
94
Comments
1
Likes
52
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • フラットな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.

    ×