Chapter22 画像アップロード

概要と目標 添付ファイルをアップロード
出来るようになろう。

投稿フォームに添付された画像の、
アップロード方法を学習しましょう。

今回のゴール

RERUN

テーブルにフィールドを追加 画像はデータベースに
保存できない。

データベースは画像自体を保存することが出来ない。
そこで画像のファイル名をデータベースに保存する。
ファイル名があれば、img要素で画像を生成できる。
まずは、画像のファイル名を格納するため、テーブルにフィールドを追加する。

画像のファイル名を格納する
フィールドを追加してみよう。

今回は、「phpMyAdmin」というツールを使って、フィールドを追加してみよう。

  1. 「phpMyAdmin」を開く
  2. 左のデータベース一覧から「mini_cms_app」を選択 ・・・ ❶
  3. 表示されたテーブル一覧から「posts」を選択 ・・・ ❷
  4. 上のタブから「構造」を選択 ・・・ ❸
  5. 1 個のカラムを追加する category_id の後へ」を選択し、「実行」をクリック ・・・ ❹
  6. 下記を参考にフィールド情報を設定し、「保存する」をクリック ・・・ ❺
    フィールド情報
    名前 データ型 長さ/値 NULL
    post_image VARCHAR 255 On

投稿フォームの編集 ファイルのアップロードボタンを追加

画像を添付するには、<input type="file">を使う。
ただし、ファイルを添付するにはform要素に、
enctype="multipart/form-data"属性を指定する必要がある。

ファイルアップロードボタンを
追加してみよう。

  1. 「mini-cms」 › 「admin」フォルダ内の「post.php」をテキストエディタで開く
  2. form要素に、とenctype属性を指定し、 ファイルを添付するコントロール部品を追加する
mini-cms/admin/post.php
<form action="add.php" method="post" enctype="multipart/form-data">
  <dl>
    <dt><label for="title">記事のタイトル</label></dt>
    <dd>
      <input type="text" id="title" name="title">
    </dd>
    <dt><label for="category_id">カテゴリー</label></dt>
    <dd>
      <select name="category_id" id="category_id">
        <?php foreach($result as $row) : ?>
        <option value="<?php echo h($row['id']); ?>"><?php echo h($row['category_name']); ?></option>
        <?php endforeach; ?>
      </select>
    </dd>
    <dt><label for="content">記事の内容</label></dt>
    <dd>
      <textarea name="content" id="content" cols="30" rows="10"></textarea>
    </dd>
    <dt><label for="post_image">画像</label></dt>
    <dd>
      <input type="file" id="post_image" name="post_image">
    </dd>
  </dl>
  <p><input type="hidden" name="token" value="<?php echo h($_SESSION['token']); ?>"></p>
  <p><input type="submit" value="投稿"></p>
</form>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「post.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/post.php
  3. コントロール部品ができているかを確認
ブラウザでの表示例

RERUN

添付ファイルの受け取り 添付したファイルの情報は、
$_FILESに格納される。

添付されたファイルの情報は、$_FILESというスーパーグローバル変数に格納される。

$_FILES ・・・ 添付ファイルの情報が格納されているスーパーグローバル変数
$_FILES[name属性の値][キー]

【キー】
"name": ファイル名が格納されている
"type": ファイルのMIMEタイプが格納されている(この値は信用できない)
"tmp_name": 一時的に保存されているファイルパス
"error": アップロードに関するエラーコードが格納されている
         (0 : UPLOAD_ERR_OK (エラーなし))

詳細はPHPマニュアルを参照

添付ファイルを受け取ってみよう。

  1. 「mini-cms」 › 「admin」フォルダ内の「add.php」をテキストエディタで開く
  2. $_FILESで受け取った情報をprint_r関数で出力
    とりあえずデータベースに登録処理を行わないように、$stmt->execute();コメントにしておく
mini-cms/admin/add.php
<?php
  // セッションの開始
  session_start();

  // ファイルの読み込み
  require_once('../inc/config.php');
  require_once('../inc/functions.php');

  // 投稿ボタンが押されたかをチェック
  if ( $_SERVER['REQUEST_METHOD'] !== 'POST') {
    // ダイレクトでアクセスされた時
    header('Location: post.php');
    exit();
  }

  // CSRF対策 ・・・ トークンのチェック
  check_token();

  // 添付ファイルの配列を出力
  print_r($_FILES['post_image']);

  try {
    // データベースへ接続
    $dbh = new PDO(DSN, DB_USER, DB_PASSWORD);

    // エラー発生時に「PDOException」という例外を投げる設定に変更
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // SQL文の作成
    $sql = 'INSERT INTO posts (title, category_id, content, created) VALUES(?, ?, ?, now())';

    // ステートメント用意
    $stmt = $dbh->prepare($sql);

    // プレースホルダーに値をガッチャンコ
    $stmt->bindValue(1, $_POST['title'], PDO::PARAM_STR);
    $stmt->bindValue(2, (int)$_POST['category_id'], PDO::PARAM_INT);
    $stmt->bindValue(3, $_POST['content'], PDO::PARAM_STR);

    // ステートメントを実行
    // $stmt->execute();

    // データベースとの接続を終了
    $dbh = null;

  } catch (PDOException $e) {
    // 例外発生時の処理
    echo 'エラー' . h($e->getMessage());
    exit();
  }
?>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「post.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/post.php
  3. ファイルを添付し送信した時、添付ファイルの情報が出力されるかを確認
ブラウザでの表示例

RERUN

画像の形式チェック ファイルはなんでも添付できる。
だから慎重にチェックする。

ファイルは基本的になんでも添付できる。
従って画像以外のファイルが添付されている可能性もあるので、
きちんと画像ファイルかを確認する。
$_FILE[name属性の値]['type']でも形式は確認できるが、
この値はあまり信用出来ないので、exif_imagetype関数でチェックするほうがよい。

exif_imagetype関数 ・・・ 画像の形式を取得する関数
exif_imagetype(画像ファイル)
主な戻り値の定数
定数
1 IMAGETYPE_GIF
2 IMAGETYPE_JPEG
3 IMAGETYPE_PNG

詳細はPHPマニュアルを参照

画像ファイルの形式をチェックしてみよう。

  1. 「mini-cms」 › 「admin」フォルダ内の「add.php」をテキストエディタで開く
  2. print_r($_FILES['post_image']);コメントにし、
    添付ファイルが存在し、かつエラーがないかをチェック
mini-cms/admin/add.php
<?php
  // セッションの開始
  session_start();

  // ファイルの読み込み
  require_once('../inc/config.php');
  require_once('../inc/functions.php');

  // 投稿ボタンが押されたかをチェック
  if ( $_SERVER['REQUEST_METHOD'] !== 'POST') {
    // ダイレクトでアクセスされた時
    header('Location: post.php');
    exit();
  }

  // CSRF対策 ・・・ トークンのチェック
  check_token();

  // 添付ファイルの配列を出力
  // print_r($_FILES['post_image']);

  // 添付ファイルが存在し、かつエラーが無いかをチェック
  if ( isset($_FILES['post_image']) && $_FILES['post_image']['error'] === UPLOAD_ERR_OK ) {
    // 添付ファイルがあり、エラーもない時

  }

  try {
    // データベースへ接続
    $dbh = new PDO(DSN, DB_USER, DB_PASSWORD);

    // エラー発生時に「PDOException」という例外を投げる設定に変更
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // SQL文の作成
    $sql = 'INSERT INTO posts (title, category_id, content, created) VALUES(?, ?, ?, now())';

    // ステートメント用意
    $stmt = $dbh->prepare($sql);

    // プレースホルダーに値をガッチャンコ
    $stmt->bindValue(1, $_POST['title'], PDO::PARAM_STR);
    $stmt->bindValue(2, (int)$_POST['category_id'], PDO::PARAM_INT);
    $stmt->bindValue(3, $_POST['content'], PDO::PARAM_STR);

    // ステートメントを実行
    // $stmt->execute();

    // データベースとの接続を終了
    $dbh = null;

  } catch (PDOException $e) {
    // 例外発生時の処理
    echo 'エラー' . h($e->getMessage());
    exit();
  }
?>
  1. $exif_imagetype関数で、添付ファイルの形式をチェックし、
    画像ファイルではなかったら、エラーメッセージを出力し、exit関数で処理を終了
mini-cms/admin/add.php
<?php
  // セッションの開始
  session_start();

  // ファイルの読み込み
  require_once('../inc/config.php');
  require_once('../inc/functions.php');

  // 投稿ボタンが押されたかをチェック
  if ( $_SERVER['REQUEST_METHOD'] !== 'POST') {
    // ダイレクトでアクセスされた時
    header('Location: post.php');
    exit();
  }

  // CSRF対策 ・・・ トークンのチェック
  check_token();

  // 添付ファイルの配列を出力
  // print_r($_FILES['post_image']);

  // 添付ファイルが存在し、かつエラーが無いかをチェック
  if ( isset($_FILES['post_image']) && $_FILES['post_image']['error'] === UPLOAD_ERR_OK ) {
    // 添付ファイルがあり、エラーもない時

    // ファイルタイプを取得
    $file_type = exif_imagetype($_FILES['post_image']['tmp_name']);

    // 画像ファイルかをチェック
    if ($file_type != IMAGETYPE_GIF && $file_type != IMAGETYPE_JPEG && $file_type != IMAGETYPE_PNG) {
      // 許可していないファイル形式ならエラー
      echo '画像は「gif」、「jpeg」、「png」形式で指定して下さい。';
      exit();
    }
  }

  try {
    // データベースへ接続
    $dbh = new PDO(DSN, DB_USER, DB_PASSWORD);

    // エラー発生時に「PDOException」という例外を投げる設定に変更
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // SQL文の作成
    $sql = 'INSERT INTO posts (title, category_id, content, created) VALUES(?, ?, ?, now())';

    // ステートメント用意
    $stmt = $dbh->prepare($sql);

    // プレースホルダーに値をガッチャンコ
    $stmt->bindValue(1, $_POST['title'], PDO::PARAM_STR);
    $stmt->bindValue(2, (int)$_POST['category_id'], PDO::PARAM_INT);
    $stmt->bindValue(3, $_POST['content'], PDO::PARAM_STR);

    // ステートメントを実行
    // $stmt->execute();

    // データベースとの接続を終了
    $dbh = null;

  } catch (PDOException $e) {
    // 例外発生時の処理
    echo 'エラー' . h($e->getMessage());
    exit();
  }
?>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「post.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/post.php
  3. 画像ファイル以外を送信した時、エラーが出力されるかを確認
ブラウザでの表示例

RERUN

画像のアップロード 一時ファイルを、
正しい場所に移動する。

画像は一時ファイルとしてアップロードされている。
これを正式なフォルダに移動することがアップロードとなる。
ただし、同じファイル名の画像が添付された時は、
後からアップロードされた時に上書きされてしまうため、
ファイル名が重複しない工夫をする必要がある。

move_uploaded_file関数 ・・・ アップロードされたファイルを移動する関数
move_uploaded_file(一時ファイル, 移動先)

詳細はPHPマニュアルを参照

画像をアップロードしてみよう。

  1. 「mini-cms」 フォルダ内に添付ファイルを格納する「upload」フォルダを作成
  2. 「mini-cms」 › 「admin」フォルダ内の「add.php」をテキストエディタで開く
  3. move_uploaded_file関数で、ファイルを移動
    その際、ファイル名が重複しないようにファイル名の前に現在の日時を付加
mini-cms/admin/add.php
<?php
  // セッションの開始
  session_start();

  // ファイルの読み込み
  require_once('../inc/config.php');
  require_once('../inc/functions.php');

  // 投稿ボタンが押されたかをチェック
  if ( $_SERVER['REQUEST_METHOD'] !== 'POST') {
    // ダイレクトでアクセスされた時
    header('Location: post.php');
    exit();
  }

  // CSRF対策 ・・・ トークンのチェック
  check_token();

  // 添付ファイルの配列を出力
  // print_r($_FILES['post_image']);

  // 添付ファイルが存在し、かつエラーが無いかをチェック
  if ( isset($_FILES['post_image']) && $_FILES['post_image']['error'] === UPLOAD_ERR_OK ) {
    // 添付ファイルがあり、エラーもない時

    // ファイルタイプを取得
    $file_type = exif_imagetype($_FILES['post_image']['tmp_name']);

    // 画像ファイルかをチェック
    if ($file_type != IMAGETYPE_GIF && $file_type != IMAGETYPE_JPEG && $file_type != IMAGETYPE_PNG) {
      // 許可していないファイル形式ならエラー
      echo '画像は「gif」、「jpeg」、「png」形式で指定して下さい。';
      exit();
    }

    // 画像のアップロード先
    $file_dir = '../upload/';

    // ファイル名を生成 (ファイル名の前に現在の日時を付加)
    $file_name = date('YmdHis') . '-' . $_FILES['post_image']['name'];

    // ファイルを一時フォルダから移動
    move_uploaded_file($_FILES['post_image']['tmp_name'], $file_dir. $file_name);
  }

  try {
    // データベースへ接続
    $dbh = new PDO(DSN, DB_USER, DB_PASSWORD);

    // エラー発生時に「PDOException」という例外を投げる設定に変更
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // SQL文の作成
    $sql = 'INSERT INTO posts (title, category_id, content, created) VALUES(?, ?, ?, now())';

    // ステートメント用意
    $stmt = $dbh->prepare($sql);

    // プレースホルダーに値をガッチャンコ
    $stmt->bindValue(1, $_POST['title'], PDO::PARAM_STR);
    $stmt->bindValue(2, (int)$_POST['category_id'], PDO::PARAM_INT);
    $stmt->bindValue(3, $_POST['content'], PDO::PARAM_STR);

    // ステートメントを実行
    // $stmt->execute();

    // データベースとの接続を終了
    $dbh = null;

  } catch (PDOException $e) {
    // 例外発生時の処理
    echo 'エラー' . h($e->getMessage());
    exit();
  }
?>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「post.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/post.php
  3. 画像ファイルを添付した際、画像が「upload」フォルダに移動することを確認。
ブラウザでの表示例

RERUN


データベースに画像のファイル名を
保存してみよう。

  1. 「mini-cms」 › 「admin」フォルダ内の「add.php」をテキストエディタで開く
  2. INSERTに画像のフィールドを追加し、 $stmt->execute();コメントを外す
mini-cms/admin/add.php
<?php
  // セッションの開始
  session_start();

  // ファイルの読み込み
  require_once('../inc/config.php');
  require_once('../inc/functions.php');

  // 投稿ボタンが押されたかをチェック
  if ( $_SERVER['REQUEST_METHOD'] !== 'POST') {
    // ダイレクトでアクセスされた時
    header('Location: post.php');
    exit();
  }

  // CSRF対策 ・・・ トークンのチェック
  check_token();

  // 添付ファイルの配列を出力
  // print_r($_FILES['post_image']);

  // ファイル名の初期値
  $file_name = '';

  // 添付ファイルが存在し、かつエラーが無いかをチェック
  if ( isset($_FILES['post_image']) && $_FILES['post_image']['error'] === UPLOAD_ERR_OK ) {
    // 添付ファイルがあり、エラーもない時

    // ファイルタイプを取得
    $file_type = exif_imagetype($_FILES['post_image']['tmp_name']);

    // 画像ファイルかをチェック
    if ($file_type != IMAGETYPE_GIF && $file_type != IMAGETYPE_JPEG && $file_type != IMAGETYPE_PNG) {
      // 許可していないファイル形式ならエラー
      echo '画像は「gif」、「jpeg」、「png」形式で指定して下さい。';
      exit();
    }

    // 画像のアップロード先
    $file_dir = '../upload/';

    // ファイル名を生成 (ファイル名の前に現在の日時を付加)
    $file_name = date('YmdHis') . '-' . $_FILES['post_image']['name'];

    // ファイルを一時フォルダから移動
    move_uploaded_file($_FILES['post_image']['tmp_name'], $file_dir. $file_name);
  }

  try {
    // データベースへ接続
    $dbh = new PDO(DSN, DB_USER, DB_PASSWORD);

    // エラー発生時に「PDOException」という例外を投げる設定に変更
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // SQL文の作成
    $sql = 'INSERT INTO posts (title, category_id, content, post_image, created) VALUES(?, ?, ?, ?, now())';

    // ステートメント用意
    $stmt = $dbh->prepare($sql);

    // プレースホルダーに値をガッチャンコ
    $stmt->bindValue(1, $_POST['title'], PDO::PARAM_STR);
    $stmt->bindValue(2, (int)$_POST['category_id'], PDO::PARAM_INT);
    $stmt->bindValue(3, $_POST['content'], PDO::PARAM_STR);
    $stmt->bindValue(4, $file_name, PDO::PARAM_STR);

    // ステートメントを実行
    $stmt->execute();

    // データベースとの接続を終了
    $dbh = null;

  } catch (PDOException $e) {
    // 例外発生時の処理
    echo 'エラー' . h($e->getMessage());
    exit();
  }
?>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「post.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/post.php
  3. 画像のファイル名が「posts」テーブルに格納されるかを確認
ブラウザでの表示例

RERUN

画像の表示 画像が存在したら、
img要素を作ればいい。

アップロードした画像を表示するには、データベースに保存した画像のファイル名を使って、
img要素を作ればよい。

詳細ページに、
画像を表示してみよう。

  1. 「mini-cms」 フォルダ内の「datail.php」をテキストエディタで開く
  2. 画像が存在したら、img要素で画像を表示する
mini-cms/detail.php
  <h1><?php echo h($result['title']); ?></h1>
  <?php if( !empty($result['post_image']) ) : ?>
  <figure>
    <img src="upload/<?php echo h($result['post_image']); ?>" alt="<?php echo h($result['title']); ?>">
  </figure>
  <?php endif; ?>
  <ul>
    <li>公開日: <time datetime="<?php echo h($result['created']); ?>"><?php echo h(date('Y年m月d日', strtotime($result['created']))); ?></time></li>
    <li>カテゴリ: <?php echo h($result['category_name']); ?></li>
  </ul>
  <p>
    <?php echo nl2br(h($result['content']), false); ?>
  </p>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「index.php」にアクセス
    http://localhost/php-lessons/mini-cms/
  3. 画像を添付した記事の詳細ページに行き、画像が表示されるかを確認
ブラウザでの表示例

RERUN

編集フォームの修正 画像は初期値として設定できない。

編集フォームにも添付ファイルのコントロール部品を設置する。
ただし、添付ファイルのコントロール部品には、初期値を設定できない。
従って、画像がある記事は、img要素で画像を表示し、
ファイル名を<input type="hidden">に埋め込み、「update.php」に送る。

編集フォームの修正しよう。

  1. 「mini-cms」 › 「admin」フォルダ内の「edit.php」をテキストエディタで開く
  2. form要素enctype属性を指定し、添付ファイルのコントロール部品を追加
    なお、画像が存在する記事は、img要素で画像を表示し、 <input type="hidden">で、
    画像のファイル名を送信
mini-cms/admin/edit.php
<form action="update.php" method="post" enctype="multipart/form-data">
  <dl>
    <dt><label for="title">記事のタイトル</label></dt>
    <dd>
      <input type="text" id="title" name="title" value="<?php echo h($result['title']); ?>">
    </dd>
    <dt><label for="category_id">カテゴリー</label></dt>
    <dd>
      <select name="category_id" id="category_id">
        <?php foreach($categories as $category) : ?>
        <?php
          $selected = '';
          // ループで出力するカテゴリと、データベースから取得したカテゴリが一致するかチェック
          if ($category['id'] == $result['category_id']) {
            // 一致した場合
            $selected = ' selected';
          }
        ?>
        <option value="<?php echo h($category['id']); ?>"<?php echo h($selected); ?>><?php echo h($category['category_name']); ?></option>
        <?php endforeach; ?>
      </select>
    </dd>
    <dt><label for="content">記事の内容</label></dt>
    <dd>
      <textarea name="content" id="content" cols="30" rows="10"><?php echo h($result['content']); ?></textarea>
    </dd>
    <dt><label for="post_image">画像</label></dt>
    <dd>
    <?php if( !empty($result['post_image']) ) : ?>
      <img src="../upload/<?php echo h($result['post_image']); ?>" width="240" alt="<?php echo h($result['title']); ?>"><br>
    <?php endif; ?>
      <input type="file" id="post_image" name="post_image">
    </dd>
  </dl>
  <p><input type="hidden" name="id" value="<?php echo h($result['id']); ?>"></p>
  <p><input type="hidden" name="post_image" value="<?php echo h($result['post_image']); ?>"></p>
  <p><input type="hidden" name="token" value="<?php echo h($_SESSION['token']); ?>"></p>
  <p><input type="submit" value="変更"></p>
</form>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/
  3. 画像がある記事の「編集」をクリックし、画像が表示されるかを確認
ブラウザでの表示例

RERUN

更新処理 画像が添付された時だけ更新。

画像は必ず更新されるとは限らない。
更新する画像が添付されていた場合は、形式などのチェックをして更新するが、
添付されていない場合で、編集前から画像が設定されている場合は注意が必要。
編集前から設定されている画像をUPDATE文で指定しないと、
画像が消えてしまう。

更新処理をしてみよう。

  1. 「mini-cms」 › 「admin」フォルダ内の「update.php」をテキストエディタで開く
  2. 画像が添付された場合はそのファイルを、 添付されたいない場合は、
    編集前に設定されている画像を、UPDATEに追加する
mini-cms/admin/update.php
<?php
  // セッションの開始
  session_start();

  // ファイルの読み込み
  require_once('../inc/config.php');
  require_once('../inc/functions.php');

  // 変更ボタンが押されたかをチェック
  if ( $_SERVER['REQUEST_METHOD'] !== 'POST') {
    // ダイレクトでアクセスされた時
    header('Location: index.php');
    exit();
  }

 // CSRF対策 ・・・ トークンのチェック
  check_token();

 // ファイル名の初期値
  $file_name = $_POST['post_image'];

  // 添付ファイルが存在し、かつエラーが無いかをチェック
  if ( isset($_FILES['post_image']) && $_FILES['post_image']['error'] === UPLOAD_ERR_OK ) {
    // 添付ファイルがあり、エラーもない時

    // ファイルタイプを取得
    $file_type = exif_imagetype($_FILES['post_image']['tmp_name']);

    // 画像ファイルかをチェック
    if ($file_type != IMAGETYPE_GIF && $file_type != IMAGETYPE_JPEG && $file_type != IMAGETYPE_PNG) {
      // 許可していないファイル形式ならエラー
      echo '画像は「gif」、「jpeg」、「png」形式で指定して下さい。';
      exit();
    }

    // 画像のアップロード先
    $file_dir = '../upload/';

    // ファイル名を生成 (ファイル名の前に現在の日時を付加)
    $file_name = date('YmdHis') . '-' . $_FILES['post_image']['name'];

    // ファイルを一時フォルダから移動
    move_uploaded_file($_FILES['post_image']['tmp_name'], $file_dir. $file_name);
  }

  try {
    // データベースへ接続
    $dbh = new PDO(DSN, DB_USER, DB_PASSWORD);

    // エラー発生時に「PDOException」という例外を投げる設定に変更
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // SQL文の作成
    $sql = 'UPDATE posts SET title=?, category_id=?, content=?, post_image=? WHERE id = ?';

    // ステートメント用意
    $stmt = $dbh->prepare($sql);

    // プレースホルダーに値をガッチャンコ
    $stmt->bindValue(1, $_POST['title'] , PDO::PARAM_STR);
    $stmt->bindValue(2, (int)$_POST['category_id'] , PDO::PARAM_INT);
    $stmt->bindValue(3, $_POST['content'] , PDO::PARAM_STR);
    $stmt->bindValue(4, $file_name , PDO::PARAM_STR);
    $stmt->bindValue(5, (int)$_POST['id'] , PDO::PARAM_INT);

    // ステートメントを実行
    $stmt->execute();

    // データベースとの接続を終了
    $dbh = null;

  } catch (PDOException $e) {
    // 例外発生時の処理
    echo 'エラー' . h($e->getMessage());
    exit();
  }
?>
  1. 上書き保存
  2. ブラウザで「mini-cms」 › 「admin」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/mini-cms/admin/
  3. 画像がある記事の「編集」をクリックし、画像が添付した際更新されるかを確認
ブラウザでの表示例

RERUN

まとめ 添付ファイルの処理は、
少々めんどくさい。

添付ファイルは必ず形式をチェックし、一時ファイルを正式なフォルダに移動する。

  • 添付ファイルは、形式をチェックする
  • 一時ファイルから移動する際に、ファイル名を変更する