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

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

ただいまの
回答率

90.49%

  • PHP

    20379questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • HTML

    9000questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • phpMyAdmin

    651questions

    phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

続き:PHP、MySQL、HTMLを使って、画像、テキストを同時にDB保存とトップページで表示できるブログ風のようなものを作りたい。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 352

mumumoon

score 3

 前回(先週)PHP MySQL HTML を使ってブログ風のものを作っています。の続きです。

マニュアルを見ながらやっていますが、理解が中々難しくまた、躓いているので質問させていただきます。

質問の答えから教えていただいた
[PHP]ファイルアップロードサンプル(PHP → DB → HTML)
をもとに考えながら行っていましたが、画像をDBに保存できることもあったのに、急にできなくなったり
指摘を受けたコメントを表示させる部分でforループの中でSQLを実行するのはNGということなので、JOINを使って繋いでみましたが、
表示の部分でDBから引っ張ってきて表示をするのに配列を組むべきなんだろうということはなんとなくわかったのですが、まだうまく書けずです。

画像も同じように記事に紐付けでをSQL文で、繋げて表示をするということをするべきということはなんとなくわかりましたが、コメントを表示させるのができないので、わかっていません。

 知りたいこと

・なぜ画像がDBに保存できなきなくなるのか。

  • DBの紐付けた部分をどのように表示をすれば良いのか。コードも含め。
  • 1つの記事に複数のコメント、1つの画像の付け方

初心者で勉強不足なのはわかっており、今は今までのコピペ文を読み解くようなことをしています。
何卒ご質問をお答えいただけると幸いです。

<記事投稿PHP>
<?php

//ファイルのアップロード部分
    function file_upload()
    {
    // POSTではないとき何もしない
    if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') !== 'POST') {
        return;
    }


    // アップロードファイル
    $upfile = $_FILES['upfile'];

    if (!$upfile['error'] > 0) {
        throw new Exception('ファイルアップロードに失敗しました。');
    }else{



    $tmp_name = $upfile['tmp_name']; 
    //$tmp_name = $_FILES['upfile']['tmp_name'];

    // ファイルタイプチェック
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mimetype = finfo_file($finfo, $tmp_name);

    // 許可するMIMETYPE
    $allowed_types = [
        'jpg' => 'image/jpeg'
        , 'png' => 'image/png'
        , 'gif' => 'image/gif'
    ];
    if (!in_array($mimetype, $allowed_types)) {
        throw new Exception('許可されていないファイルタイプです。');
    }

    // ファイル名(ハッシュ値でファイル名を決定するため、同一ファイルは同盟で上書きされる)
    $filename = sha1_file($tmp_name);

    // 拡張子
    $ext = array_search($mimetype, $allowed_types);


    //画像の新しい名前 テキストに入力する部分
     $new_name = $_FILES['upfile']['name'];

    // 保存作ファイルパス  
     $destination = sprintf('/%s/%s'
        , "Users/・・・/Blog/upfiles"
        , $new_name 
    );


    // アップロードディレクトリに移動
    if (!move_uploaded_file($tmp_name, $destination)) {
        throw new Exception('ファイルの保存に失敗しました。');
}

    // Exif 情報の削除
    $imagick = new  Imagick($destination);
    $imagick->stripimage();
    $imagick->writeimage($destination);


    // データベースに登録
    $sql = 'INSERT INTO `images` (`id`, `path`) VALUES (NULL, :path) ';
    $arr = [];
    $arr[':path'] = $destination;
    $lastInsertId = insert($sql, $arr);

    // 成功時にページを移動する
    header(sprintf('Location: User_TopPage.php', $lastInsertId));

    }


    // ファイルアップロード
    file_upload();
}
} catch (Exception $e) {
    $error = $e->getMessage();
}




//タイトルと本文部分
if(isset($_POST['submit'])){
    echo '';

      $title = $_POST['title'];
      $content = $_POST['content'];

    if (!$title) $error .= 'タイトルがありません。<br>';
    if (mb_strlen($title) > 80) $error .= 'タイトルが長すぎます。<br>';
    if (!$content) $error .= '本文がありません。<br>';

        if (!$error) {
      $pdo = new PDO("mysql:dbname=blog", "root","...");
      $st = $pdo->query("INSERT INTO post(title,content) VALUES('$title','$content')");


      header('Location: User_TopPage.php');
      exit();
        }
  }
?>


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>記事投稿</title>
        <link rel="stylesheet" href="blog.css">
    </head>
<body>
    <form method="post" action=""enctype="multipart/form-data">
        <div class="posting"> 
            <h2>記事投稿</h2>
            <p>題名</p>
            <p><input name="title" type="text" size="40"></p>
            <p>本文</p>
            <p><textarea name="content" rows="8" cols="40"></textarea></p>
            <p><label for="upfile">画像ファイル</label>
            <input type="file" name="upfile" id="upfile" /></p>
            <input name="submit" type="submit" value="投稿">
    </form>
            <p><input type="button" onclick="window.history.back('http://localhost/Blog/User_TopPage.php');" value="戻る"></p>
            <p><?php echo $error ?></p>
        </div>
</body>
</html>
<User_TopPage>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>TEST Blog</title>
<link rel="stylesheet" type="text/css" href="blog.css">
</head>
<body>
    <a href="User_TopPage.php"><label class="toptest"><h1>TEST Blog</h1></label></a>
<a href="t_post.php"><label class="contentTop"><h4>記事作成</h4></label></a>
<a href="Logout.php"><label class="Logout"><h5>ログアウト</h5></label></a>

</body>
</html>

<?php
  $pdo = new PDO("mysql:dbname=blog", "root","...",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);


  //tableの全部(*)を記事番号の大きい順、すなわち新しい記事から順番に並び替えられる
  //fetchAllメソッドは、全てのレコードを配列として返します。$posts[0]に最も新しい記事、$posts[1]に次の記事…と順番に入ります
  $stmt = $pdo->prepare("SELECT * FROM post ORDER BY no DESC");
  $stmt->execute();
  $posts = $stmt->fetchAll();


$sql = 
"CREATE VIEW
  blogview
  (  
    no,
    title,
    content,
    time,
    path,
    name,
    comment  

  )
AS
  SELECT
    post.no,
    post.title,
    post.content,
    post.time,
    images.path,
    comment.name,
    comment.comment
  FROM
    post AS post
    LEFT JOIN
    comment AS comment
    ON
    post.no = comment.post_no
    LEFT JOIN
    images AS images
    ON
    post.time = images.time"
    ;



  $blogview['comments'] = $stmt->fetchAll();
  $stmt->execute();

$sql = 'SELECT `no`, `path` FROM `blogview`ORDER BY no DESC';
$result = $pdo->query($sql);


 //for ループの中でSQLを実行するのはNGです。JOINを使ってテーブルを連結し、SQLの発行回数を一回で住むようにしよう (質問部分)
  // for ($i = 0; $i < count($posts); $i++) {
  // $st = $pdo->query("SELECT * FROM comment WHERE post_no={$posts[$i]['no']} ORDER BY no DESC"); 
  // $posts[$i]['comments'] = $st->fetchAll();
  // }


  require 't_index.php';
<表示部分>

<?php 
$pdo = new PDO("mysql:dbname=blog", "root","…",[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
 ?>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST Blog</title>
<link rel="stylesheet" href="blog.css">
</head>
<body>
<?php foreach ($posts as $post) { ?>
  <div class="post">
    <h2><?php echo $post['title'] ?></h2>  
    <p><?php echo nl2br($post['content']) ?></p>

<!-- image -->
 <?php foreach ($result as $row) { ?>
      <div class="iamges">
      <?php echo '<img src="'.$row['path'];?>
      </div>
    <?php } ?>

<!-- コメント部分 -->
    <?php foreach ($blogviews['comments'] as $blogview) { ?>
      <div class="comment">
        <h3><?php echo $blogview['name'] ?></h3>
        <p><?php echo nl2br($blogview['comment']) ?></p>
        <!-- <p>>?php echo ($) -->
      </div>
    <?php } ?>

    <p class="commment_link">
      投稿日:<?php echo $post['time'] ?> 
      <a href="comment.php?no=<?php echo $post['no'] ?>">コメント</a>
    </p>
  </div>
<?php } ?>
</body>

</html>

 変更点

imagesのテーブル構造です。

  • なぜ画像がDBに保存できなきなくなるのか。 はもう一度書き直したところ、Permissionエラーが出たので、ファイルの権限を変えたらDB内に保存できるようになりました。

変更点2

CREATE viewで作成したものです。
これを使ってコメントと画像を上手くtitle,conetnt を使って表示させようとしているところです。

User_TopPageの部分に

$blogview['comments'] = $stmt->fetchAll();
 $stmt->execute();

$sql = 'SELECT `no`, `path` FROM `blogview`ORDER BY no DESC';
$result = $pdo->query($sql);

表示部分のところにimgタグを入れました。

 <?php foreach ($result as $row) { ?>
      <div class="iamges">
      <?php echo '<img src="'.$row['path'];?>
      </div>
    <?php } ?>

この2つを追加したところ

このような地獄絵図になりました。


- path部分は(pathについて理解はあまりできていません)
    ```php  
//画像の新しい名前 テキストに入力する部分  
$new_name = $_FILES['upfile']['name'];  

// 保存作ファイルパス    
$destination = sprintf('/%s/%s'  
, "Users/・・・/Blog/upfiles"  
, $new_name   
);  
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • k-fukuda

    2018/07/30 16:07

    データーベース(テーブル)の構造も載せたほうが良いかと思います。おそらくカラムの制約に引っかかる値をinsertしようとしています。

    キャンセル

  • namda

    2018/08/02 16:13

    $row['path']には具体的にどんなpathが入っていますか?保存場所と公開場所があってないと表示できません。

    キャンセル

  • mumumoon

    2018/08/02 18:52

    $row['path']には、 $destination = sprintf("/%s/%s", "Users/…/Blog/upfiles", $new_name ); が出力されます。ただ、日本語のファイル名.pngは表示されない状態です。

    キャンセル

回答 1

0

      <?php echo '<img src="'.$row['path'];?>
//                                         ↑が足りない
 <?php foreach ($result as $row) { ?>
      <div class="iamges">
            <img src="<?php echo str_replace(’Users/.../’, ’’, $row['path']);?>" />
      </div>
    <?php } ?>

タグがオカシイですね。下のように直せば動くと思います。
ただ乗せてるスクリーンショットからは挙動が異なるようにおもいます。
それでも駄目な場合は $row['path'] の出力値を実装コードでは無く具体値(パスの途中はぼかしていいので)をお願いします。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/08/03 11:39

    具体値というのがこれであっているのかわかりませんが、DB上に入っている値は/Users/.../Blog/upfiles/Gomi.pngという感じになっています。

    キャンセル

  • 2018/08/07 18:22

    その場合、画像をがhttp://サイトのドメイン/Users/.../Blog/upfiles/Gomi.pngで見れないと表示できません。
    表示できますか?

    キャンセル

  • 2018/08/07 18:50

    表示できませんでした。
    この部分がどうなっていると表示ができるのでしょうか。

    キャンセル

  • 2018/08/07 19:03

    画像のあるパスとphpを公開しているパスはどこまで共通のパスですか?
    例えば
    /Users/.../Blog/blog.php
    であり
    URLはhttp://サイトのドメイン/Blog/blog.php
    なら
    画像のsrcは/Blog/upfiles/Gomi.pngになければなりません。

    キャンセル

  • 2018/08/07 21:17

    localhost/Blog/Use_TopPage.phpが公開しているパスで、画像は
    Users/.../Blog/upfiles/Gomi.pngにありますので、Blogまで一緒です。
    http://localhost/Blog/upfiles/Gomi.pngでは画像の表示ができました。

    キャンセル

  • 2018/08/07 22:51

    であれば表示するときにDBから取得した値( `$row['path']` )から `Users/.../` を削除するようにすると動くと思います。
    この場合 `str_replace(’Users/.../’, ’’, $row['path'])` で動きそうな気がします。
    だめなら出力されたソースを見て微調整してください。

    キャンセル

  • 2018/08/07 22:54

    参考サイトと同じように保存しておけば、何の苦労もしないはずですけど。

    キャンセル

  • 2018/08/08 07:23

    「画像がBlog/upfiles/配下にある」というルール付けであればDBにはファイル名だけ保存された方が無駄なリソース使わずに済むと思います。
    保存場所変えたときにDBの情報まで変えなきゃいけなくなりますし。

    キャンセル

  • 2018/08/08 12:18

    それ言い始めるとDB管理じゃなくてディレクトリ一覧でよくね?なりますよ…

    キャンセル

  • 2018/08/08 12:21 編集

    namda さん
    参考サイト自分が書いた記事なんだけど、質問者さん、自ら改悪して自分でハマってるんですよ。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る

  • PHP

    20379questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • HTML

    9000questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • phpMyAdmin

    651questions

    phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

  • トップ
  • PHPに関する質問
  • 続き:PHP、MySQL、HTMLを使って、画像、テキストを同時にDB保存とトップページで表示できるブログ風のようなものを作りたい。