Upgrade to Pro — share decks privately, control downloads, hide ads and more …

フレームワークの内部構造を 理解するためにフレームワークを 作ってみることにした / phpcon-2021

Haruki Tazoe
October 02, 2021
1k

フレームワークの内部構造を 理解するためにフレームワークを 作ってみることにした / phpcon-2021

Haruki Tazoe

October 02, 2021
Tweet

Transcript

  1. モデルとindex.phpの実装 if (file_exists('./models/' . $contents . '.php')) { include('./models/' .

    $contents . '.php'); $className = "models¥¥" . $contents; $class = new $className(); if ($_SERVER['REQUEST_METHOD'] == "GET") { $response = $class->index($contents); if (!is_null($response)) { if(is_array($response)){ extract($response); } } } } index.phpの抜粋
  2. モデルとindex.phpの実装 namespace models; class Blog { public function index($params) :

    array { return array('str' => 'My name is jdkfx.'); } } Models/Blog.phpの抜粋
  3. コントローラの実装 class BlogController { public function __construct(){} public function index()

    { $blog = new blog(); $response = $blog->index(); if (!is_null($response)) { if(is_array($response)){ extract($response); } } return $response; } public function create() { return “新しい記事を作成するページです.”; } } Controllers/BlogController.phpの抜粋
  4. コントローラの実装 if (file_exists('./controllers/' . $fullpath[1] . '_controller.php')) { include('./controllers/' .

    $fullpath[1] . '_controller.php'); $conName = "controllers¥¥" . $fullpath[1] . "_controller"; $con = new $conName(); if (empty($fullpath[2])) { $response = $con->index(); if (file_exists('./views/' . $contents . '.php')) { include('./views/' . $contents . '.php'); } } else { $conFunc = $fullpath[2]; if (method_exists($con, $conFunc)) { $response = $con->$conFunc(); echo $response; } else { include('./views/error.php'); } } } src/index.phpの抜粋
  5. POSTの受け取り if (file_exists('./controllers/' . $fullpath[1] . '_controller.php')) { include('./controllers/' .

    $fullpath[1] . '_controller.php’); // http://localhost/blog/ などの場合 if (empty($fullpath[2])) { $response = $con->index(); if (file_exists('./views/' . $contents . '.php')) { include('./views/' . $contents . '.php'); } // http://localhost/blog/create などの場合かつ POST される場合 } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { $conFunc = $fullpath[2]; $request = $_POST; if (method_exists($con, $conFunc)) { $response = $con->post($request); } else { include('./views/error.php'); } // 次スライドに続く src/index.phpの抜粋
  6. POSTの受け取り // 前スライドの続き // http://localhost/blog/create などの場合 } else { $conFunc

    = $fullpath[2]; if (method_exists($con, $conFunc)) { $response = $con->$conFunc(); } else { include('./views/error.php'); } } } src/index.phpの抜粋
  7. ビューの実装 class View { public function __construct(){} public function pages($filename,

    $dvalue = null) { $response = $dvalue; include __DIR__ . "/../Views/" . $filename . ".php"; } } Templates/View.phpの抜粋
  8. ルーティングの実装 class Router { // 省略 public function response($request) {

    try { $controllerName = "App¥¥Controllers¥¥" . $this->routes[$request]['controller']; $controller = new $controllerName(); $controllerAction = $this->routes[$request]['action']; if ($this->routes[$request]['method'] === 'GET') { $controller->$controllerAction(); } else if ($this->routes[$request]['method'] === 'POST') { $controller->$controllerAction($_POST); } else { throw new ¥Exception('error!'); } } catch (¥Exception $e) { error_log($e->getFile() . $e->getLine() . $e->getMessage()); } } } Routers/Router.phpの抜粋
  9. ルーティングの実装 $pattern = [ '/' => [ 'method' => 'GET',

    'controller' => 'HomeController', 'action' => 'index', ], '/blog' => [ 'method' => 'GET', 'controller' => 'BlogController', 'action' => 'index', ], // 省略 ]; $router = new Router($pattern); $router->response($_SERVER['REQUEST_URI']); html/index.phpの抜粋
  10. 受け取ったデータの保存 class model { public $pdo; public function __construct() {

    $dsn = 'mysql:dbname=blog;host=phrame_mysql_1'; $user = 'root'; $password = 'password'; $query = "CREATE TABLE IF NOT EXISTS blog.posts ( id INT(11) NOT NULL auto_increment PRIMARY KEY, title VARCHAR(20), messages VARCHAR(50) ) DEFAULT CHARSET=utf8"; // 次ページに続く Models/Model.phpの抜粋
  11. 受け取ったデータの保存 // 前ページの続き try { $this->pdo = new PDO($dsn, $user,

    $password); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->pdo->query($query); } catch (PDOException $e) { error_log($e->getMessage()); exit(); } } } Models/Model.phpの抜粋
  12. 受け取ったデータの保存 public function index() : array { $query = "SELECT

    * FROM blog.posts"; try { $stmt = $this->pdo->query($query); $response = $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log($e->getMessage()); exit(); } return $response; } Models/Blog.phpの抜粋
  13. 受け取ったデータの保存 public function store($request) { $query = "INSERT INTO blog.posts

    (title, messages) VALUES (?, ?)"; try { $stmt = $this->pdo->prepare($query); $response = $stmt->execute(array($request["title"], $request["messages"])); } catch (Exception $e) { error_log($e->getMessage()); exit(); } } Models/Blog.phpの抜粋