はじめに
[改良恐竜登録ツール(PHP+MYSQL版)]
(https://qiita.com/knowledge87sun/items/aea1c603cab586b7bcf5)
でも恐竜登録ツールを作成した。
しかし、何かが足りない。
恐竜登録と言えば、画像!!!
前回の記事で、DBに保存した画像の表示方法をまとめた。
今回は今までの内容を結集した恐竜画像登録&画像表示プログラムを作成してみた。
1.プログラム概要
機能1.登録済み恐竜画像を表示
例)7のリンクをクリックすると、インドミナスレックスの画像を表示。
機能2.恐竜の画像登録
(1)カテゴリーを確定後、登録したい恐竜(ティラノサウルス)を選択。
登録恐竜一覧には、画像登録済みの恐竜が表示されている。
(2)ファイル選択ダイアログで、登録したい画像を選択して確定ボタンを押す。
(tirano_mini.jpg(選択した画像)が表示される。)
(3)登録が完了すると、登録済みの恐竜一覧にリンクが表示される。
2.実際のコード
(1)画像格納用のテーブル(tbl_dinoimg)の作成
id:恐竜のID
ext:画像ファイルのmimeタイプ
img:画像ファイルをバイナリデータにしたもの
create table tbl_dinoimg (
id integer,
img mediumblob,
ext varchar(10),
primary key(id)
);
<?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;
}
?>
<!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タイプで表示
という手順があることが分かった
<?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では一応恐竜シリーズの区切りがついた。
他のプログラミング言語でも、このシリーズにトライしたいと考えている。