連載
» 2018年11月06日 05時00分 公開

.NET開発者のためのPHPアプリお手軽開発入門:VS CodeとPHPとSQL Serverで作るToDoリストアプリ:完成編 (2/2)

[かわさきしんじ,Insider.NET編集部]
前のページへ 1|2       

updateitem.phpファイル

 ToDoアイテムの状態(完了したかどうか)を更新する処理は、updateitem.phpファイルにまとめた。実際のコードは以下の通りだ。

<?php
require "util.php";

if (isset($_GET["id"]) && isset($_GET["val"])) {
  $id = (int) $_GET["id"];
  $val = (bool) $_GET["val"];

  try {
    $pdo = openDB();
    $tsql = "UPDATE todoitems SET done = :val WHERE id = :id";
    $stmt = $pdo->prepare($tsql);
    $stmt->execute([":id" => $id, ":val" => $val]);
  } catch (Exception $e) {
    header("Content-Type: text/plain; charset=UTF-8", true, 500);
    exit();
  } finally {
    $stmt = null;
    $pdo = null;
  }
}
$host = $_SERVER["HTTP_HOST"];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = "index.php";
header("Location: http://$host$uri/$extra");
exit();


ToDoアイテムの完了状態を更新するコード(updateitem.phpファイル)

 前回に見た新規アイテムを追加するコードと基本構造は同等で、冒頭でデータベース接続を取得し、必要な処理を行った後に、header関数でindex.phpファイルに遷移するようになっている。また、前ページで見たように、コード冒頭ではrequireによりutil.phpファイルを読み込んで、そこで定義されているopenDB関数を呼び出している。

 行っていることもSQL文の内容が列の挿入から、列の更新に変わっただけだ。ただし、前回は「PDOオブジェクトのprepareメソッドによるプリペアドステートメント(PDOStatementオブジェクト)の作成」→「PDOStatementオブジェクトのbindValueメソッドによるパラメーターマークとパラメーター値のバインド」→「PDOStatementオブジェクトのexecuteメソッドによるプリペアドステートメントの実行」という流れで処理を行っていたが、今回はパラメーターマークとパラメーター値のバインド、プリペアドステートメントの実行をexecuteメソッドだけで行っている点が異なる。

<?php
// …… 省略 ……
if (isset($_GET["id"]) && isset($_GET["val"])) {
  // …… 省略 ……

  try {
    $pdo = openDB();
    $tsql = "UPDATE todoitems SET done = :val WHERE id = :id";
    $stmt = $pdo->prepare($tsql);
    $stmt->execute([":id" => $id, ":val" => $val]);
  } catch (Exception $e) {
    // …… 省略 ……
  } finally {
    // …… 省略 ……
  }
}
// …… 省略 ……


プリペアドステートメントの作成、パラメーターのバインド、実行を2行で行う

 SQLStatementオブジェクトのexecuteメソッドには連想配列の形で入力パラメーター値を渡すことができ、今回はそちらの方法を使ってみた。ただし、bindValueメソッドでは、「PDO::PARAM_STR」などの定数を使って、各パラメーター値の型を指定できるが、executeメソッドではパラメーター値は全てPDO::PARAM_STR型として扱われることには注意が必要だ。厳密に型指定を行いたいのであれば、bindValueメソッドやbindParamメソッドを使用するようにしよう。

 もう1つ注意したいのは、コード先頭のif文の内容だ。

<?php
// …… 省略 ……
if (isset($_GET["id"]) && isset($_GET["val"])) {
  $id = (int) $_GET["id"];
  $val = (bool) $_GET["val"];

  // …… 省略 ……
}
// …… 省略 ……


$_GET連想配列にidとvalが含まれているかをチェックするコード

 [DONE]リンクまたは[UNDONE]リンクをクリックすると「updateitem.php?id=……&val=……」というURLがリクエストされる。PHPでは、GETメソッドでリクエストされたPHPファイルのURLパラメーターは「$_GET」という名前の連想配列に保存される。リンクを素直にクリックしてくれれば、これらの値が$_GET連想配列に含まれているはずだが、このファイルをアドレスバーから直接呼び出すことも可能なため、ここではisset関数を使って、$_GET連想配列にこれら2つのキーが存在し、それらがNULLでないことを確認している。その後、実際の値を取り出して、UPDATE文でデータを更新するようにしている。isset関数を使わずにそのまま「if ($_GET["id"]) && $_GET["val"]) {」のように書くと、コードの実行上は問題ないように見えるが、実際には例外が発生することもあるので注意しよう。

 なお、index.phpファイルで既に見たように、未完了のToDoアイテムに表示される[DONE]リンクではvalパラメーターの値が1に、完了したToDoアイテムに表示される[UNDONE]リンクではvalパラメーターの値が0に指定されている。updateitem.phpファイルではこれらの値をtrue/falseと見なして、列の更新を行っている。

deleteitem.phpファイル

 列の削除は[DELETE]リンクのクリック時にdeleteitem.phpファイルで行われる。このリンクにはURLパラメーターとして、削除対象のToDoアイテムのidが含まれている。そのため、そのidを指定して、DELETE文を実行するだけだ。

<?php
require "util.php";

if (isset($_GET["id"])) {
  $id = (int) $_GET["id"];

  try {
    $pdo = openDB();
    $tsql = "DELETE todoitems WHERE id = :id";
    $stmt = $pdo->prepare($tsql);
    $stmt->execute([":id" => $id]);
  } catch (Exception $e) {
    header("Content-Type: text/plain; charset=UTF-8", true, 500);
    exit();
  } finally {
    $stmt = null;
    $pdo = null;
  }
}
$host = $_SERVER["HTTP_HOST"];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = "index.php";
header("Location: http://$host$uri/$extra");
exit();


ToDoアイテムを削除するコード(deleteitem.phpファイル)

 ファイルの基本構造はupdateitem.phpと同様であり、実行するSQL文が異なるだけなので、詳細な解説は不要だろう。

additem.phpファイル

 最後に残ったadditem.phpファイルは、util.phpファイルを使用すること以外は前回と同様だ。

<?php
require "util.php";

if (isset($_POST["submit"])) {
  try {
    $pdo = openDB();

    $tsql = "INSERT INTO todoitems (item, done) VALUES (?, 0)";
    $stmt = $pdo->prepare($tsql);
    $item = $_POST["item"];
    $stmt->bindValue(1, $item, PDO::PARAM_STR);
    $stmt->execute();
  } catch (Exception $e) {
    header("Content-Type: text/plain; charset=UTF-8", true, 500);
    exit();
  } finally {
    $stmt = null;
    $pdo = null;
  }
}
$host = $_SERVER["HTTP_HOST"];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = "index.php";
header("Location: http://$host$uri/$extra");
exit();


新規ToDoアイテムを追加するコード(additem.phpファイル)

 これについては説明は不要だろう。詳細は前回の記事を参照されたい。

 最後に、アプリが実際に動作しているところを以下に示す。前回同様、これはVS CodeのPHP Server拡張機能を使ってVS Codeでローカルにホストしているところだ。

ToDoリストでToDoアイテムの状態を変更したり、削除したりしているところ ToDoリストでToDoアイテムの状態を変更したり、削除したりしているところ


 今回はToDoアイテムの状態を変更したり、アイテムを削除したりするコードについて見ながら、PHPコードを記述する際の注意点を幾つか紹介した。次回はこのアプリをIISへ展開し、落ち穂拾い的に幾つかのトピックを紹介する予定だ。

「.NET開発者のためのPHPアプリお手軽開発入門」のインデックス

.NET開発者のためのPHPアプリお手軽開発入門

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

編集部からのお知らせ

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。