PHP学習を始め3カ月がたち、簡単なphpのコードやSQL文を扱える様になってきました。
その中で、あれ!?となってしまいがちな処理に画像のアップロードがあります。
今回は初心者がつまづきやすい画像をアップロードする際の
代表的なエラーとその対応をまとめました。
今回はサンプルファイルとデータベーステーブルを作成し実際にこのエラーを粉砕していきます。
テストファイルの作成
まずは今回テストするために作成したファイル構成から ![スクリーンショット 2015-12-06 16.02.57.png](https://qiita-image-store.s3.amazonaws.com/0/80553/98e17343-a369-efbf-387b-c3c9b25ff9e0.png "スクリーンショット 2015-12-06 16.02.57.png")今回はfile_uploadというサンプルファイルの中に
image //画像を溜め込むファイル
sample.php //テストコードを書くphpファイル
を作成しています。
sample.phpには画像ファイルのアップロードに必要な
formタグ
move_uploaded_file
INSERT文
を書いています。
このコードからスタートして実際にデータベースに上げることができる様に
エラーを解消していきます。
ブラウザはこのように表示されます。
なおデータベースは
このように簡単に作成しておきました。
画像がアップロードされない!
ではまずこの状態からファイルを送ってみましょう! ・・・・なんの反応もありません。 この状態ではもちろんDBには入りませんね。 まずformタグから見直します。 今の状態では、画像をアップロードするために一つ記述が足りません。 まずはformタグにenctype="multipart/form-data"
を記述します。
これで画像ファイルのアップロードであることを明示します。
アップロードした画像がファイルに格納されない
これでアップロードの準備が整いました。 早速アップロードしましょう!・・・できません。
今度はブラウザにエラーが表示されています。
どうやらファイルのパーミッションに問題があるようです。
では実際にターミナルを開いてパーミションを確認しています。
vagrant up
しているディレクトリ内に入って確認してみます。
vagrant ssh // ディレクトリ内にはいる
cd /var/www/html/file_upload //今回作成したfile_uploadに移動
ls -la //ディレクトリの詳細情報を確認
この状態ではimageフォルダを操作できるのはvagrant
権限のみです。
ブラウザからこフォルダを操作するためには
apache
権限に変更しなくてはなりません。
これを忘れてコードとひたすら向き合うとこのエラーは解消できません。
このコードをターミナルで入力しましょう。
sudo chown apache:apache image
//sudoで権限を上位にて次の処理の実行
//chownでimageファイルの権限をapachに
これでimageファイルの権限がapacheに変更できました。
sprintfの使い方がおかしい
ここまでなおしたら`04.jpg`という画像ファイルを挿入してみます。 これでデータベースに挿入されたはずです! ![スクリーンショット 2015-12-06 16.56.01.png](https://qiita-image-store.s3.amazonaws.com/0/80553/64c39d0a-062f-12bd-e3d3-0b699c55e696.png "スクリーンショット 2015-12-06 16.56.01.png")・・・・・おかしい
データベースに挿入したのは04.jpgというデータのはずですが、
データベースには4と挿入されています。
コードを確認してみましょう。
デバックのためアップロードしたファイル名が正しいのか
echo $image //$imageの中身を確認
で確認します。
01.jpg
を今度はアップロードしてみます。
ブラウザにはアップロードのした画像の名前が正しく表示されています。
ではINSERT文ないの記述を確認します。
現在は
$sql = sprintf('INSERT INTO upload_sample SET image=%d',$image);
sprinf
を使ってimageカラムに$image(ファイルの名前)を挿入しています。
ここで確認しなくてはならないのがデータの形式です。
現在のコードではsprintf
でデータを購入したい箇所に%d
を指定しています。
%d
はint型を挿入する際に用います。
そこでコードを
$sql = sprintf('INSERT INTO upload_sample SET image="%s"',$image);
%d
の箇所を%s
に変更します。
これで文字列型を格納できるようにしましょう。
文字列型なのでコーテーション""
でくくるのもお忘れなく。
実際に画像を挿入してみましょう。
0.1.jpgが正しく表示されています。
画像が表示されない
では次にデータベースにあげた0.6.jpgをブラウザに表示させます。 $sql = 'SELECT * FROM upload_sample WHERE id = 6';
//upload_sample テーブルの中からidが6のものを表示
$sql = mysqli_query($db,$sql) or die (mysqli_error($db));
$image = mysqli_fetch_assoc($sql);
<img src="<?php echo $image['image'];?>" >
//imgタグで画像の表示
これでブラウザを見てみましょう。
はい、表示されていません。
原因を確認するために要素を検証してみます。
そしてこれをこのようにいじってみましょう。
つまりはパスの指定が間違っていたのですね。
コードを正しいパスに書き換えたら表示されました。
ではこのように変更しましょう。
<img src="<?php echo 'image/'.$image['image'];?>">
//'image/'でファイルが格納されているフォルダを明示
//.で文字連結
//$image['image']で画像ファイルの名前を指定
//変数$imageは上のPHPコードで指定したカラムの内容を連想配列で格納しているのでその中のimageを指定
これでOKですね。
まとめ
これで最初のコードから画像をアップロードするまでのエラーを解消することができました。確認したいことは
ファイルをフォームに入力する際のenctype
の明示
ファイルの書き込み権限の確認 しapache
に変更
使っている関数の使い方は正しいか。 今回はsrintf
の使い方です。
指定しているファイルのパスは正しいか。
フォルダが増えたりフレームワークをつかったりするとさらに複雑になります。
file_uploaded_move
関数にも正しく指定しましょう。
このくらいを確認すれば画像を上げる際に発生したエラーを解消する手がかりになりそうです。
こちらが最終的なコードです。
*この記事はIPU Advent Calenderに
投稿しています。
先輩方の優良な記事の骨休めになってくれたらなとも思います。
では!