0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【PHP+MySQL】恐竜画像登録&画像表示にトライ!!!(恐竜シリーズプチ最終回)

Last updated at Posted at 2020-03-14

はじめに

[改良恐竜登録ツール(PHP+MYSQL版)]
(https://qiita.com/knowledge87sun/items/aea1c603cab586b7bcf5)
でも恐竜登録ツールを作成した。
しかし、何かが足りない。
恐竜登録と言えば、画像!!!

前回の記事で、DBに保存した画像の表示方法をまとめた。

今回は今までの内容を結集した恐竜画像登録&画像表示プログラムを作成してみた。

1.プログラム概要

機能1.登録済み恐竜画像を表示

dino_image1.jpg

例)7のリンクをクリックすると、インドミナスレックスの画像を表示。

dino_image2.jpg

機能2.恐竜の画像登録

(1)カテゴリーを確定後、登録したい恐竜(ティラノサウルス)を選択。
登録恐竜一覧には、画像登録済みの恐竜が表示されている。

dino_image3.jpg

(2)ファイル選択ダイアログで、登録したい画像を選択して確定ボタンを押す。
(tirano_mini.jpg(選択した画像)が表示される。)

dino_image4.jpg

(3)登録が完了すると、登録済みの恐竜一覧にリンクが表示される。
dino_image5.jpg

(4)リンクをクリックすると登録された画像が表示される。
dino_image6.jpg

2.実際のコード

(1)画像格納用のテーブル(tbl_dinoimg)の作成
id:恐竜のID
ext:画像ファイルのmimeタイプ
img:画像ファイルをバイナリデータにしたもの


create table tbl_dinoimg (
 id integer,
 img mediumblob,
 ext varchar(10),
 primary key(id)
);
common_dino2_image.php
<?php 

  function NewPdo($dbname)
  {
    $dsn = 'mysql:dbname='.$dbname.';host=localhost:3308;charset=utf8mb4';
    $user = 'root';
    $password = 'root123';
    $dbh = new PDO($dsn, $user, $password);
    return $dbh;
  
  }

  function Checkdino($db0,$qry0,$val1,$type1)
  {
    $result3=$db0->prepare($qry0);
    //パラメータをセット
    $result3->bindparam(1,$val1);
    $result3->bindparam(2,$type1);
    $result3->execute();
    //検索結果を配列に格納する
    $select_data=$result3->fetch();
    return $select_data;
  }
  //クエリ実行して得られる全データ(パラメータ)
  function get_SelectTypeData($db0,$query0,$val1)
  {
    $result_a=$db0->prepare($query0);
    $result_a->bindparam(1,$val1);
    $result_a->execute();
    return $result_a;
  }
  //クエリ実行して得られる全データ
  function get_AllData($db0,$query0)
  {
    $result_a=$db0->prepare($query0);
    $result_a->execute();
    return $result_a;
  }
  //$str1:検索対象文字列,$str_mark:探したい文字: 戻り値、探したい文字より前にある文字列
  function get_BeforeMarkString($str1,$str_mark)
  {
    $idx0=strpos($str1, $str_mark);
    $retstr=substr($str1,0,$idx0);
    return $retstr;
  }

  //$str1:検索対象文字列,$str_mark:探したい文字、探したい文字より後にある文字列
  function get_AfterMarkString($str1,$str_mark)
  {
    $idx0=strpos($str1, $str_mark);
    $retstr=substr($str1,$idx0+1);
    return $retstr;
  }
 ?>  

start_dino_image.php

<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<title>恐竜画像登録</title>
<body>
<h1>恐竜画像登録!!</h1>

<?php 

  require "common_dino2_image.php";
  //画像フォーム部分
  $dbname='db_dino';
  $dbh=NewPdo($dbname);
  
  $query_type0 = "SELECT DISTINCT type0 from tbl_dino";
 ?>

  <!-- tbl_dinoに登録されている恐竜カテゴリーと一覧を表示する部分 -->
  <form action="start_dino_image.php" method="post">
カテゴリー:
  <?php $result_a=get_AllData($dbh,$query_type0); 
  $cate0=isset($_POST['dtype01'])?htmlspecialchars($_POST['dtype01']):null;

   ?> 
  <select name="dtype01" style="width: 100px">
    <?php while($select_data=$result_a->fetch(PDO::FETCH_ASSOC)){
      //$cate0が$select_data['type0']と等しい場合
      if($cate0 == $select_data['type0']){ 
        echo "<option selected>".$select_data['type0']."</option>";
      //$cate0が$select_data['type0']と等しくない場合
      }else{
        echo "<option>".$select_data['type0']."</option>";
      }
    }  
    ?>
  </select>
  <input type="submit" name = "btn2" value="確定">
  </form>

<?php 

  $dbname='db_dino';
  $dbh=NewPdo($dbname);
  $query_select_type0 = "SELECT dname0 from tbl_dino where type0 = ?";
  $result3=get_SelectTypeData($dbh,$query_select_type0,$cate0);

 ?>
  <form action="start_dino_image.php" enctype="multipart/form-data" method="post">
対象恐竜:
  <select name="dname" style="width: 280px">
    <?php $dino0=isset($_POST['dname'])?htmlspecialchars($_POST['dname']):null; ?>
    <?php while($select_data=$result3->fetch(PDO::FETCH_ASSOC)){
      echo "<option>".$select_data['dname0']."</option>";
    }
    ?>
  </select><br>
  <label>画像/動画アップロード</label>
  <input type="file" name="upfile">
  <input type="hidden" name="btn3" value="<?=$cate0?>">
  <input type="submit" value="確定">
  </form>


<?php 

  //ファイルアップロードがあったとき
  try{
    $dbname='db_dino';
    $dbh=NewPdo($dbname);
    //$pdo = new PDO("mysql:host=127.0.0.1;dbname=mediatest;charset=utf8", $user, $pass);
    if (isset($_FILES['upfile']['error']) && is_int($_FILES['upfile']['error']) && $_FILES['upfile']['name'] !== ""){
    //エラーチェック
      switch ($_FILES['upfile']['error']) {
        case UPLOAD_ERR_OK: // OK
          break;
        case UPLOAD_ERR_NO_FILE:   // 未選択
          throw new RuntimeException('ファイルが選択されていません', 400);
        case UPLOAD_ERR_INI_SIZE:  // php.ini定義の最大サイズ超過
          throw new RuntimeException('ファイルサイズが大きすぎます', 400);
        default:
          throw new RuntimeException('その他のエラーが発生しました', 500);
      }
      
  
      //拡張子を見る
      $tmp = pathinfo($_FILES['upfile']['name']);
      $extension = $tmp["extension"];
      if($extension === "jpg" || $extension === "jpeg" || $extension === "JPG" || $extension === "JPEG"){
        $ext1 = "image/jpeg";
      }
      elseif($extension === "png" || $extension === "PNG"){
        $ext1 = "image/png";
      }
      else{
        echo "非対応ファイルです.<br/>";
        echo ("<a href=\"start_dino_image.php\">戻る</a><br/>");
        exit(1);
      }
      //カテゴリーと恐竜名からidを探す
      $sql_select="SELECT * FROM tbl_dino WHERE dname0=? and type0=?";
      $dname1=isset($_POST['dname'])?htmlspecialchars($_POST['dname']):null;
      $type1=isset($_POST['btn3'])?htmlspecialchars($_POST['btn3']):null;
      $select_data1=Checkdino($dbh,$sql_select,$dname1,$type1);
      $dino_id=$select_data1['id'];

      //画像・動画をバイナリデータにする.
      $raw_data = file_get_contents($_FILES['upfile']['tmp_name']);
    
    }
    $dbname='db_dino';
    $dbh=NewPdo($dbname);
    
    $sql_del = "DELETE FROM tbl_dinoimg WHERE id=?";
    //画像・動画をDBから削除
    $result1=$dbh->prepare($sql_del);
    //パラメータをセット
    $result1->bindparam(1,$dino_id);
    $result1->execute();

    //画像・動画をDBに格納.
    $sql_ist = "INSERT INTO tbl_dinoimg(id, img, ext) VALUES (?,?,?)";
    $result1=$dbh->prepare($sql_ist);
    //パラメータをセット
    $result1->bindparam(1,$dino_id,PDO::PARAM_INT);
    $result1->bindparam(2,$raw_data,PDO::PARAM_LOB);
    $result1->bindparam(3,$ext1,PDO::PARAM_STR);
    $result1->execute();
    echo $dino_id."<br>";
  }

  catch(PDOException $e){
    echo("<p>500 Inertnal Server Error</p>");
    exit($e->getMessage());
  }

 ?>


<?php  
  //tbl_dinoimgに登録されている恐竜idと名前を表示する。
  $sql_idall="SELECT T1.id,T1.dname0,T1.type0 FROM tbl_dino T1";
  $sql_idall = $sql_idall." INNER JOIN tbl_dinoimg T2 ON T1.id=T2.id ORDER BY T2.id";

  $dbname='db_dino';
  $dbh=NewPdo($dbname);

  $result1=get_AllData($dbh,$sql_idall);
  echo "<br><h4>登録恐竜一覧</h4><br>";
  while ($row = $result1 -> fetch(PDO::FETCH_ASSOC)){
    $id=$row['id'];
 ?> 
  <!-- idと恐竜名とカテゴリー名 -->
    <a href="dino_display_image.php?id=<?=$id?>"><?=$id?></a>:<?= $row['dname0'] ?>(<?= $row['type0'] ?>)
<?php 
    echo ("\n"."<br/>");
  }
  $dbh=null;
  
 ?>

</body>
</html>

実はこの格納した画像を表示する事が超大変だった。
(前回の記事の部分)
よくある下記のコードでは、画面に表示されるのはどこまでも深い
黒一色の画面だったのだ。


header("Content-Type: image/jpeg");
echo ($row['img']);

そのうちにbase64というキーワードを見つけることになる。
1.DBから画像バイナリデータを取得
2.base64でエンコード
3.2を画像のmimeタイプで表示
という手順があることが分かった

dino_display_image.php
<?php 
  if(isset($_GET['id']) && $_GET['id'] !== ""){
    $id = $_GET['id'];
  }
  else{
    header("Location: start_dino_image.php");
  }
  try {
    require "common_dino2_image.php";
    $dbname='db_dino';
    $dbh = NewPdo($dbname);
    $sql_select = "SELECT ext,img FROM tbl_dinoimg WHERE id = ?";
    $result1=$dbh->prepare($sql_select);
    //パラメータをセット
    $result1->bindparam(1,$id,PDO::PARAM_INT);
    $result1->execute();
    $row = $result1 -> fetch(PDO::FETCH_ASSOC);
    //取得した画像バイナリデータをbase64で変換。
    $img = base64_encode($row['img']); 
 ?>
	<!-- エンコードした情報をimgタグに表示 -->
    <img src="data:<?php echo $row['ext'] ?>;base64,<?php echo $img; ?>"><br>
    <a href="start_dino_image.php">戻る</a>

<?php 


  }
  catch (PDOException $e) {
    echo("<p>500 Inertnal Server Error</p>");
    exit($e->getMessage());
  }
 ?>

参考URL

PHPでbase64の使い方を知ろう!サンプルコードで速攻理解

今後に向けて

PHPでは一応恐竜シリーズの区切りがついた。
他のプログラミング言語でも、このシリーズにトライしたいと考えている。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?