Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
25
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@Dicrotect

PHP初心者がつまづいた画像ファイルを上げる際に倒さねばならぬエラーたち

PHP学習を始め3カ月がたち、簡単なphpのコードやSQL文を扱える様になってきました。
その中で、あれ!?となってしまいがちな処理に画像のアップロードがあります。

今回は初心者がつまづきやすい画像をアップロードする際の
代表的なエラーとその対応をまとめました。

今回はサンプルファイルとデータベーステーブルを作成し実際にこのエラーを粉砕していきます。

テストファイルの作成

まずは今回テストするために作成したファイル構成から
スクリーンショット 2015-12-06 16.02.57.png

今回はfile_uploadというサンプルファイルの中に

image       //画像を溜め込むファイル
sample.php //テストコードを書くphpファイル

を作成しています。
sample.phpには画像ファイルのアップロードに必要な

formタグ
move_uploaded_file
INSERT文
を書いています。
スクリーンショット 2015-12-06 17.09.46.png

このコードからスタートして実際にデータベースに上げることができる様に
エラーを解消していきます。
ブラウザはこのように表示されます。
スクリーンショット 2015-12-06 15.28.22.png
なおデータベースは
スクリーンショット 2015-12-06 15.29.08.png
このように簡単に作成しておきました。

画像がアップロードされない!

ではまずこの状態からファイルを送ってみましょう!
・・・・なんの反応もありません。
この状態ではもちろんDBには入りませんね。
まずformタグから見直します。
今の状態では、画像をアップロードするために一つ記述が足りません。
まずはformタグに

enctype="multipart/form-data"

を記述します。
これで画像ファイルのアップロードであることを明示します。

アップロードした画像がファイルに格納されない

これでアップロードの準備が整いました。
早速アップロードしましょう!

スクリーンショット 2015-12-06 16.27.10.png

・・・できません。
今度はブラウザにエラーが表示されています。
どうやらファイルのパーミッションに問題があるようです。

では実際にターミナルを開いてパーミションを確認しています。
vagrant upしているディレクトリ内に入って確認してみます。

vagrant ssh // ディレクトリ内にはいる
cd /var/www/html/file_upload  //今回作成したfile_uploadに移動
ls -la //ディレクトリの詳細情報を確認

スクリーンショット 2015-12-06 16.38.02.png

この状態ではimageフォルダを操作できるのはvagrant権限のみです。
ブラウザからこフォルダを操作するためには
apache権限に変更しなくてはなりません。
これを忘れてコードとひたすら向き合うとこのエラーは解消できません。
このコードをターミナルで入力しましょう。

sudo chown apache:apache image
//sudoで権限を上位にて次の処理の実行
//chownでimageファイルの権限をapachに

スクリーンショット 2015-12-06 16.43.06.png
これでimageファイルの権限がapacheに変更できました。

sprintfの使い方がおかしい

ここまでなおしたら04.jpgという画像ファイルを挿入してみます。
これでデータベースに挿入されたはずです!
スクリーンショット 2015-12-06 16.56.01.png

・・・・・おかしい
データベースに挿入したのは04.jpgというデータのはずですが、
データベースには4と挿入されています。
コードを確認してみましょう。
スクリーンショット 2015-12-06 16.59.40.png

デバックのためアップロードしたファイル名が正しいのか

echo $image //$imageの中身を確認

で確認します。

01.jpgを今度はアップロードしてみます。

スクリーンショット 2015-12-06 17.01.48.png

ブラウザにはアップロードのした画像の名前が正しく表示されています。

では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に変更します。
これで文字列型を格納できるようにしましょう。
文字列型なのでコーテーション""でくくるのもお忘れなく。
実際に画像を挿入してみましょう。

スクリーンショット 2015-12-06 17.13.36.png

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タグで画像の表示

これでブラウザを見てみましょう。

スクリーンショット 2015-12-06 17.26.25.png

はい、表示されていません。
原因を確認するために要素を検証してみます。
スクリーンショット 2015-12-06 17.28.21.png

そしてこれをこのようにいじってみましょう。

スクリーンショット 2015-12-06 17.29.32.png

つまりはパスの指定が間違っていたのですね。
コードを正しいパスに書き換えたら表示されました。
ではこのように変更しましょう。

<img src="<?php echo 'image/'.$image['image'];?>">

//'image/'でファイルが格納されているフォルダを明示
//.で文字連結
//$image['image']で画像ファイルの名前を指定
//変数$imageは上のPHPコードで指定したカラムの内容を連想配列で格納しているのでその中のimageを指定

これでOKですね。

まとめ

これで最初のコードから画像をアップロードするまでのエラーを解消することができました。

確認したいことは

ファイルをフォームに入力する際のenctypeの明示
ファイルの書き込み権限の確認 しapacheに変更
使っている関数の使い方は正しいか。 今回はsrintfの使い方です。
指定しているファイルのパスは正しいか。 
フォルダが増えたりフレームワークをつかったりするとさらに複雑になります。
file_uploaded_move関数にも正しく指定しましょう。

このくらいを確認すれば画像を上げる際に発生したエラーを解消する手がかりになりそうです。
こちらが最終的なコードです。
スクリーンショット 2015-12-06 17.52.45.png

*この記事はIPU Advent Calender
投稿しています。

先輩方の優良な記事の骨休めになってくれたらなとも思います。

では!

25
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
25
Help us understand the problem. What is going on with this article?