質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.64%

[PHP]画像を表示させることができないです...

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 5,049

newyee

score 151

アップロードされ、保存された画像のパスを指定しても画像を表示させることができないです...
以下が自分が作成したコードとなるのですが、全てを載せると長くなってしまうので、画像の処理に関する部分だけ載せさせていただこうと思います。
ファイルに関しましては、control.php,model.php,view.phpの3つのファイルに分けて作成しております。
以下はcontrol.phpのファイルになります。

$link = get_db_connect();

if($_SERVER['REQUEST_METHOD'] === 'POST'){

    $submit_type = $_POST['submit_type'];
     //die(var_dump($submit_type));

    switch ($submit_type) {
        case 'add_item':

        $product_name = $_POST['product_name'];
        //var_dump($product_name);exit();
        $price = $_POST['price'];
        $stock = $_POST['stock'];
        $status = $_POST['public_status'];

        //登録値チェック
        $err_msg[] = entry_name_check($product_name);
        $err_msg[] = entry_check_price($price);
        $err_msg[] = entry_check_stock($stock);
        //var_dump($price);exit();
        //die(var_dump($stock));

        //アップロードファイル名を変数に代入
        $temp_file = $_FILES['new_img']['tmp_name'];
        //var_dump($temp_file);exit();
        $file_name = $_FILES['new_img']['name'];


        //拡張子取得
        $check_ext = get_ext($file_name);

        //拡張子チェック
        //$err_msg[] = extention_check($check_ext);


        //拡張子を取得(保存)
        $ext = ext($file_name);

        //var_dump($product_id);exit();


        //var_dump($upload_file);exit();


        //var_dump($err_msg);exit();
        $check_err = array_filter($err_msg);

        if(count($check_err) === 0){

            //トランザクション開始
            mysqli_autocommit($link, $false);

            $sql = 'INSERT INTO item_table(product_name,price,img,created_date,status)
                    VALUES(\'' . $product_name . '\',' . $price . ',\'' . $file_name . '\',\'' .  $date . '\',' . $status . ')';

            if(mysqli_query($link,$sql) === TRUE){

                $product_id = mysqli_insert_id($link);

                //var_dump($product_id);exit();


                //item_stock_tableにinsert
                $err_msg[] = insert_item_stock_table($link,$product_id,$stock,$date);

            }else{
                $err_msg[] = 'item_table:insertエラー' . $sql;
            }

            //ファイルパス+ファイル名
            $upload_file = '../include/img/' . $product_id . $ext;

            //アップロード処理
            $err_msg[] = upload_img($temp_file,$upload_file,$check_ext);




            //トランザクション成否判定
            $check_err = array_filter($err_msg);


            if(count($check_err) === 0){

               $success_msg[] = '商品追加成功';

               mysqli_commit($link);

            }else{
               $err_msg[] = '商品追加失敗';
               mysqli_rollback($link);
            }
        }

        break;


//item_table取得
$item_info_list = get_item_table($link);


//ファイル名の拡張子を取得
$item_info_list = img_ext($item_info_list,$file_name);
//var_dump($item_info_list);exit();

//特殊文字をHTMLエンティティに変換
$item_info_list = entity_as_array($item_info_list);

以下はmodel.phpになります。

//アップロード処理
function upload_img($temp_file,$upload_file,$check_ext){

    $err_msg = '';

    if (is_uploaded_file($temp_file)){


       $err_msg = extention_check($check_ext);

        if(empty($err_msg)){

            if (move_uploaded_file($temp_file,$upload_file) === FALSE) {

            $err_msg = 'ファイルをアップロードできません。';            


            } 

        }else{
           $err_msg = 'エラーメーッセージが空ではありません';
        }
    } else {
        $err_msg = 'ファイルが選択されていません。';
    }

    return $err_msg;
}


//拡張牛取得
function get_ext($file_name){
    return substr($file_name,strrpos($file_name,'.') +1);
}

//拡張子チェック
function extention_check($check_ext){

    $err_msg = '';

    if(!($check_ext === 'jpeg' || $check_ext === 'jpg' || $check_ext === 'png')){
        $err_msg = 'ファイル形式が異なります。画像ファイルはjpegまたはpngのみ利用可能です';
    }

    return $err_msg;
}

//拡張子取得(拡張子を含む)
function ext($file_name){

    return substr($file_name,strrpos($file_name,'.'));

}
function get_item_table($link){

    $sql = 'SELECT item_table.product_id,product_name,price,img,status,stock
            FROM item_table 
            JOIN item_stock_table
            ON item_table.product_id = item_stock_table.product_id';

    return get_as_array($link,$sql);        

}

function img_ext($item_info_list,$file_name){
    foreach($item_info_list as $key => $value){
        foreach($value as $keys => $values){
            $item_info_list[$key]['img'] = ext($file_name);
        }
    }

    return $item_info_list;
}
function get_db_connect(){

    // コネクション取得
    if (!$link = mysqli_connect(DB_HOST, DB_USER, DB_PASSWD, DB_NAME)) {
        die('error: ' . mysqli_connect_error());
    }

    // 文字コードセット
    mysqli_set_charset($link, DB_CHARACTER_SET);

    return $link;
}

function get_as_array($link, $sql) {

    // 返却用配列
    $data = array();

    // クエリを実行する
    if ($result = mysqli_query($link, $sql)) {

        if (mysqli_num_rows($result) > 0) {

            // 1件ずつ取り出す
            while ($row = mysqli_fetch_assoc($result)) {
                $data[] = $row;
            }

        }

        // 結果セットを開放
        mysqli_free_result($result);

    }

    return $data;

}

以下はview.phpになります。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>商品管理画面</title>
    <style>
        table,tr,th,td{

            border:solid 1px;

        }
    </style>
</head>
<body>
    <h1>商品管理画面</h1>

    <?php foreach($err_msg as $value){ ?>

        <p><?php echo $value; ?></p>

    <?php } ?>
    <?php foreach($success_msg as $value){ ?>

        <p><?php echo $value; ?></p>

    <?php } ?>

    <a href="item_list.php">購入画面</a>

    <section>
        <h2>新規商品追加</h2>
        <form method="post" enctype="multipart/form-data">

            <div>名前<input type="text" name="product_name"></div>
            <div>値段<input type="text" name="price"></div>
            <div>個数<input type="text" name="stock"></div>
            <div><input type="file" name="new_img"></div>
            <div>
                <select name="public_status">
                    <option value="0">非公開</option>
                    <option value="1">公開</option>
                </select>
            </div>
            <div><input type="submit"value="■□■□■商品追加■□■□■"></div>
            <input type="hidden"name="submit_type" value="add_item">
        </form>
    </section>
    <section>
        <h2>商品情報変更</h2>
        <caption>商品一覧</caption>
        <table>
            <tr>
                <th>商品画像</th>
                <th>商品名</th>
                <th>価格</th>
                <th>在庫数</th>
                <th>ステータス</th>
            </tr>
            <?php foreach($item_info_list as $value){  ?>
                <tr><!-- アップロードされたファイル名をテーブルに保存する -->
                    <td><img src="../include/img/<?php echo $value['product_id'] . $value['img'] ;?>"></td>
                    <td><?php echo $value['product_name']; ?></td>
                    <td><?php echo $value['price']; ?></td>

                    <!-- 在庫数変更フォーム -->
                    <form method="post">
                        <td>
                            <input type="text" name="update_stock" value="<?php echo $value['stock_number'];?>">
                            <input type="submit" value="変更">
                            <input type="hidden" name="submit_type" value="change_value">
                            <input type="hidden" name="product_id" value="<?php echo $value['product_id']?>">
                        </td>
                    </form>

                    <!-- ステータス変更フォーム -->
                    <form method="post">
                        <td>
                            <?php if((int)($value['status']) === 0){ ?>
                                <input type="submit" name="change_status" value="非公開->公開">

                            <?php }else{ ?>

                                <input type="submit" name="change_status" value="公開->非公開">
                            <?php } ?>
                            <input type="hidden" name="status" value="<?php echo $value['status']; ?>">
                            <input type="hidden" name="product_id" value="<?php echo $value['product_id']; ?>">
                            <input type="hidden" name="submit_type" value="change_status">
                        </td>
                     </form>

                </tr>
            <?php } ?>        
        </table>
    </section>
</body>
</html>


表示されない原因に関しましては、「control.php」の「$item_info_list = img_ext($item_info_list,$file_name);」この部分、「model.php」のimg_ext関数だとの指摘を受けたことがあり、実際にこの関数を排除し、他の方法で一応の解決は出来たのですが、原因が分からないままでして。。。

function img_ext($item_info_list,$file_name){
    foreach($item_info_list as $key => $value){
        foreach($value as $keys => $values){
            $item_info_list[$key]['img'] = ext($file_name);
        }
    }

    return $item_info_list;
}


どなたか教えてくださる方いましたら、ご教示いただければ幸いです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

なかなか追いかけるのが大変なコードですね。

画像が表示できないといわれているのは、view.phpでの下記のimgタグでの画像出力部分との認識です。

<?php foreach($item_info_list as $value){  ?>
  <tr><!-- アップロードされたファイル名をテーブルに保存する -->
    <td><img src="../include/img/<?php echo $value['product_id'] . $value['img'] ;?>"></td>

画像のURLの組み立てには、$item_info_listの配列の1要素$valueに由来する2つの変数$value['product_id']$value['img']が登場します。
このうち、$value['product_id']はmodel.phpのget_item_table関数でデータベースより取得した値です。
一方、$value['img']については、ファイルの拡張子を取得しているようですが、$item_info_listへの値の追加はimg_ext関数で行っており、img_ext関数ではext関数で拡張子を取得しているといった流れとなっています。
ここで、img_ext関数の引数である$file_nameに渡される値を考えると、control.phpでの下記処理での$file_nameとなっています。

//ファイル名の拡張子を取得
$item_info_list = img_ext($item_info_list,$file_name);

この$file_nameがどこで設定されているかを見た場合、提示されているコードのみから判断すると、画像アップロード時の処理で代入されている下記の箇所のみであることが分かります。

if($_SERVER['REQUEST_METHOD'] === 'POST'){

    $submit_type = $_POST['submit_type'];
     //die(var_dump($submit_type));

    switch ($submit_type) {
        case 'add_item':

// (略)

        //アップロードファイル名を変数に代入
        $temp_file = $_FILES['new_img']['tmp_name'];
        //var_dump($temp_file);exit();
        $file_name = $_FILES['new_img']['name'];

ですので、画像アップロード時以外は$file_nameは値が設定されておらず、拡張子の取得に失敗しているのではないかと考えられます。

一方、データベースのitem_tableテーブルまたはitem_stock_tableテーブルにあると思われるimg列は、上記の画像アップロード時の$file_name由来のデータが格納されています。
img_ext関数はこのimg列の値を上書きするような動きをしています。
データベースの内容をそのままに対応するのであれば、img_ext関数での処理内容は下記となるかと思います。
control.phpでの処理内容として、テーブルへのINSERT後にget_item_table関数でデータを再取得しているので、$file_nameはimg_ext関数の処理には不要です。

function img_ext($item_info_list){
    foreach($item_info_list as $key => $value){
        foreach($value as $keys => $values){
            $item_info_list[$key]['img'] = ext($item_info_list[$key]['img']);
        }
    }

    return $item_info_list;
}

実際の対応としては、上記を行うのではなく、control.phpのINSERT処理の後に組み立てている画像保存用のパス$upload_fileの値をデータベースのテーブルにあるimg列に格納し、

//ファイルパス+ファイル名
$upload_file = '../include/img/' . $product_id . $ext;


imgタグでの値の参照では、下記のみで画像パスが取得できるようにすればよいのではないかと考えられます。

<?php foreach($item_info_list as $value){  ?>
  <tr><!-- アップロードされたファイル名をテーブルに保存する -->
    <td><img src="<?= $value['img'] ?>"></td>

また、質問に記載のコードでは、データベースへのINSERT処理後にアップロード画像の保存を行っていますが、画像の保存に失敗した場合に画像の存在しないレコードがテーブルに残ることとなりますので、画像の保存→成功したらテーブルへのINSERTの順番で処理を行うこととした方がよいのではないかと思います。
この場合、$upload_fileの組み立てはINSERT処理の前に行うことになりますので、テーブルへのパスの保存も容易となるかと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/20 13:37

    返信大変遅くなってしまいすみません。。。
    ご丁寧なご回答に感謝いたします。
    教えて頂いた、「$upload_file = '../include/img/' . $product_id . $ext;」こちらの画像保存用のパスをデータベーステーブルにあるimg列に格納し、imgタグでの値の参照では、下記のみで画像パスが取得できるようにする、との方法なのですが、画像をデータベーステーブルに保存し、きちんと、画像保存用フォルダにも画像は保存されているのですが、何故か画像を表示させることができません...
    修正しました点に関しましては、以下の通りです。
    //トランザクション開始
    mysqli_autocommit($link, $false);

    $sql = 'INSERT INTO item_table(product_name,price,created_date,status)
    VALUES(\'' . $product_name . '\',' . $price . ',\'' . $date . '\',' . $status . ')';

    if(mysqli_query($link,$sql) === TRUE){

    $product_id = mysqli_insert_id($link);

    //ファイルパス+ファイル名
    $upload_file = '../include/img/' . $product_id . $ext;

    $sql = 'UPDATE item_table SET img = (\'' . $upload_file . '\') WHERE product_id = ' . $product_id;

    if(mysqli_query($link,$sql) === FALSE){
    $err_msg[] = 'item_table:insertエラー' . $sql;
    }

    //var_dump($product_id);exit();


    //item_stock_tableにinsert
    $err_msg[] = insert_item_stock_table($link,$product_id,$stock,$date);

    }else{
    $err_msg[] = 'item_table:insertエラー' . $sql;
    }
    格納するフォルダの位置が悪い...などということは関係しているでしょうか...?



    //アップロード処理
    $err_msg[] = upload_img($temp_file,$upload_file,$check_ext);

    キャンセル

  • 2017/10/20 13:39

    すみません。
    コードの途中の「//アップロード処理」という所の前にご相談の内容を書いてしまいました...

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる