画像アップロードを作る場合、通常のデータ登録の他に、ファイルアップロード機能を実装しなければならない。これがけっこうめんどい。
でも、画像をバイナリデータとして、直接MySQLに保存することもできる。
テーブル設計
-- -- データベース: `images` -- -- -------------------------------------------------------- -- -- テーブルの構造 `posts` -- CREATE TABLE IF NOT EXISTS `posts` ( `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `imgdat` blob NOT NULL, `mime` VARCHAR(64) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
BLOBはバイナリデータを扱うデータ型
imgdatフィールドに画像のバイナリデータ、mimeフィールドにMIMEタイプを保存する。
ディレクトリ構造
create_image.php ・・・バイナリデータを画像ファイルに変換するファイル
edit.php ・・・アップロードページ
view.php ・・・アップロードされた画像を表示するページ
アップロードページの作成(edit.php)
フォーム部
<form enctype="multipart/form-data" action="./edit.php" method="POST"> <input type="hidden" name="MAX_FILE_SIZE" value="300000" /> <input name="image" type="file" /> <p><input type="submit" name="save" value="Submit" /><p> </form>
formにはenctype=”multipart/form-data”を指定すること。
MAX_FILE_SIZEでアップロード可能なサイズを指定しておいた方がいい。
制御部
<?php $url = "localhost"; $user = "root"; $pass = "root"; $db = "images"; if (!empty($_POST)) { // バイナリデータ $fp = fopen($_FILES["image"]["tmp_name"], "rb"); $imgdat = fread($fp, filesize($_FILES["image"]["tmp_name"])); fclose($fp); $imgdat = addslashes($imgdat); // 拡張子 $dat = pathinfo($_FILES["image"]["name"]); $extension = $dat['extension']; // MIMEタイプ if ( $extension == "jpg" || $extension == "jpeg" ) $mime = "image/jpeg"; else if( $extension == "gif" ) $mime = "image/gif"; else if ( $extension == "png" ) $mime = "image/png"; // MySQL登録 $link = mysql_connect( $url, $user, $pass ) or die("MySQLへの接続に失敗しました。"); $sdb = mysql_select_db( $db, $link ) or die("データベースの選択に失敗しました。"); $sql = "INSERT INTO `images`.`posts` (`imgdat`, `mime`) VALUES ('".$imgdat."', '".$mime."')"; $result = mysql_query( $sql, $link ) or die("クエリの送信に失敗しました。"); mysql_close($link) or die("MySQL切断に失敗しました。"); } ?>
アップロードされたファイルは、スーパーグローバル変数 $_FILES に連想配列として格納される。
そこからバイナリデータとMIMEタイプをMySQLに保存する。
表示ページの作成(view.php)
<?php $url = "localhost"; $user = "root"; $pass = "root"; $db = "images"; $link = mysql_connect( $url, $user, $pass ) or die("MySQLへの接続に失敗しました。"); $sdb = mysql_select_db( $db, $link ) or die("データベースの選択に失敗しました。"); $sql = "SELECT * FROM images.posts"; $result = mysql_query( $sql, $link ) or die("クエリの送信に失敗しました。"); $rows = mysql_num_rows( $result ); mysql_close( $link ) or die("MySQL切断に失敗しました。"); if($rows){ while($row = mysql_fetch_array($result)) { echo '<img src="./create_image.php?id='.$row["ID"].'" />'; } } ?>
ここで重要なのは、バイナリデータを描画するのは create_image.phpファイルであるということ。
create_image.php
<?php $url = "localhost"; $user = "root"; $pass = "root"; $db = "images"; $id = $_GET['id']; $link = mysql_connect( $url, $user, $pass ) or die("MySQLへの接続に失敗しました。"); $sdb = mysql_select_db( $db, $link ) or die("データベースの選択に失敗しました。"); $sql = "SELECT * FROM images.posts WHERE ID = '".$id."'"; $result = mysql_query( $sql, $link ) or die("クエリの送信に失敗しました。"); $rows = mysql_num_rows( $result ); mysql_close( $link ) or die("MySQL切断に失敗しました。"); if( $rows ){ while($row = mysql_fetch_array($result)) { header( "Content-Type: ".$row['mime'] ); echo $row['imgdat']; } } ?>
このファイルにGETでidを渡すことにより、バイナリデータを画像として描画している。
Comments
ずっとデータベースに接続されないので、どうしたらいいのか教えてもらいたいです
大変参考になる、コードのご提示ありがとうございます。
現在、参考にさせていただき、勉強させていただております。
PHP初心者のため少しうまくいかないので、書き込みさせていただきました。
アップロードページの作成(edit.php)では、アップロードすれば
きちんとデータベースに反映しております。
その後の表示ページの作成(view.php)でデータベースからの画像データの表示がうまくいきませんでした。
たとえばデータベースに3つデータを入れていた場合、view.phpを実行させると
画像1画像2画像3
と表示されるべきとことが
画像アイコン画像アイコン画像アイコン
(×画像が3つ表示)
という表示で、うまく画像データをひっぱってきてないのです。
create_image.phpを参考にして、色々試行錯誤したところ
たとえば、
create_image.php?id=1
と直接URL指定してやると
エラーメッセージは出ますがデータはひっぱtってきているようなのです。
Warning: Cannot modify header information – headers already sent by (output started at /home/users/1/lolipop.jp-91051b7cfdd9c77e/web/test2/create_image.php:5) in /home/users/1/lolipop.jp-91051b7cfdd9c77e/web/test2/create_image.php on line 25
����JFIFHH��C ��C ���c����A!1A”2Q#aq�B��3br�RS��$5CTc���������(!1A”Qa3q2B��� ?��`=�� ���g�I�(�ZXy�{,j ж�8����7G9�H���G���(1r��i�AE��,�45�����}�gG,�־ߦ9�J���3����’��T,�����Q�tĹȷj6�!Gc�R]ln��1>E��b�g5�,��)��܀G��Ov=���i�b Rqn`�nm dqü
何か原因がわかればと思い、メールさせていただきました。
あー・・自分も同じ現象ですね。
厳密にえばview.phpで表示されない部分だけですが・・・
create_img.phpもまったく何も表示されません。
初心者の私もソースのコピペで同様の現象が起きました。HTMLではMINEタイプではなくMIMEタイプですので。
テーブル設計でSQLのCREATE TABLE文中の`mine`⇒`mime`に修正。
MYSQLで作成後だったのでPhpMyAdminで修正。
edit.phpファイルの22行目で$mine⇒$mimeに修正。
27行目の$sql = 文中の`mine`⇒`mime`に修正。VALUESの$mine⇒$mimeに修正。
create_image.phpファイルで18行目の$row[‘mine’]⇒$row[‘mime’]に修正。
すべてのphpソースファイルのエンコードをUTF-8(BOMなし)に変換して保存。
ブラウザもUTF-8にすると表示できました。
“mime” がすべて “mine” になっていましたね。。
すみません、修正しました。