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

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

ただいまの
回答率

88.81%

【PHP】自作ブログ 各記事ページへのリンク【MySQL】

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,011

ceoyama7

score 15

現状

現在、主にPHPで自作ブログを作成している初心者です。
データベースはMySQLを使用しています。
トップページのレイアウト(記事一覧)が完成し、子ページへリンクを繋げる作業中です。
トップページに記事の概要のようなものを複数表示し、
クリックで詳細記事ページに飛ぶようにしたいです。

DBの構造は
Blog-post-(no/title/category/content/time)としています。

わからないこと

各記事のページについて、
まず、aタグにphpで順にリンクを指定すればいいのかと考えたのですが、
1、データベースの内容にURLがないので、どこへのリンクを貼ればいいのかわからない。

そこで、トップページから外枠だけできた詳細記事ページに飛び、
その中でDBから取得した内容を表示すればいいのか、と考えましたが、
2、トップページでクリックされたのがどの記事なのか判定する方法がわからない。

また、現在のコードを後述しますが、
index.phpからreqwireでt_index.phpへ飛んでますが、
理解半分のまま参考にしたサイトから引っ張ってきたコードな為、
3、single.php(記事詳細ページ)への繋げ方がわからない。

繋がっていないためか、single.phpでUndefined variable:postエラーが出てしまいます。

試したこと

初心者なりに今日1日調べてみて、
urlencodeやsetIntなどの関数や、teratail自体にも過去に似たような質問を見つけたのですが、
結果、応用できなかったため質問させていただきました。

<?php

//MySQLへ接続
  $pdo = new PDO("mysql:host=localhost;dbname=blog", "abc", "abc");

//postテーブルを降順に取得
  $st = $pdo->query("SELECT * FROM post ORDER BY no DESC");

//取得したpostデータを全て選択
  $posts = $st->fetchAll();


//選択したpostデータの数だけ繰り返し処理
  for ($i = 0; $i < count($posts); $i++) {


//commentテーブルから各記事に対応するデータを降順に取得
      $st = $pdo->query("SELECT * FROM comment WHERE post_no={$posts[$i]['no']} ORDER BY no DESC");

//コメントを全て選択
    $posts[$i]['comments'] = $st->fetchAll();
  }

//t_index.phpへ繋げる
  require 't_index.php';




?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>Yama_Blog.</title>
    <meta charaset="utf-8">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="stylesheet.css">

</head>
<body>
    <header>

       <nav
          class="navbar navbar-expand-sm navbar-light mb-2" 
          style="background-color:#fff;">

       <a href="index.php" class="navbar-brand">
          <img src="image/logo.png" alt="logo">
       </a>
       <button
         class="navbar-toggler"
         id="navbar-toggler"
         type="button"
         data-toggle="collapse"
         data-target="#navmenu1"
         aria-controls="navmenu1"
         aria-expanded="false"
         aria-label="Toggle navigation">
         <span class="navbar-toggler-icon"></span>
       </button>
       <div class="collapse navbar-collapse" id="navmenu1">
       <div class="navbar-nav">
         <a class="nav-item nav-link" href="profile.php">Profile</a>
         <a class="nav-item nav-link" href="#">Portfolio</a>
         <a class="nav-item nav-link" href="#">Contact</a>
       </div>
       </div>
       </nav>
    </header>
    <div class="container" id="container">
        <div class="row">
            <div class="col-xs-12 col-md-12 col-lg-12" >
<?php foreach ($posts as $post) { ?>
                <a href="single.php" style="color:black;">
                <div class="article col-xs-12 col-md-4 col-lg-4">
                    <p>最終更新日:<?php echo $post['time']; ?></p>
                    <h2><?php echo $post['title']; ?></h2>
                    <p>:<?php echo $post['category']; ?>:</p>
                    <img src="<?php echo $post['image']; ?>" alt="" class="img-fluid">
                    <p><?php echo mb_substr(nl2br($post['content']),0,40,'utf-8',).'...'; ?></p>
                </div>
                </a>
<?php } ?>
            </div>

        </div>
    </div>
    <footer>
        <div class="footer-left">
            <img src="image/logo.png"   alt="logo">    
        </div>
    </footer>

    <script type="text/javascript" src="stylesheet.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</body>

</html>
<!DOCTYPE html>
<html lang="ja">
<head>
...   
</head>
<body>
    <header>
    ...
    </header>
    <div class="container" id="container">
        <div class="row">
            <div class="article col-xs-12 col-md-12" >
                <p><?php echo nl2br($post['content']); ?></p>
            </div>

        </div>
    </div>
    <footer>

    </footer>

    <script type="text/javascript" src="stylesheet.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</body>

</html>

ぐちゃぐちゃなコードであるかとは思いますが、よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

追加で、

3、single.php(記事詳細ページ)への繋げ方がわからない。
  繋がっていないためか、single.phpでUndefined variable:postエラーが出てしまいます。

こちらは、

                <p><?php echo nl2br($post['content']); ?></p>

この部分で発生しているエラーですね。
Undefined variable:post はそのままの意味で、$post が未定義ですという意味になります。
代入などが行われていない変数を参照したというエラーです。

基本的なことになりますが、PHPなどのWebアプリでは、
リンクやフォームなどでページが遷移するたびに、全ての変数は初期化されます。
そのため、 single.php の前のページで$postを作っていても、
single.phpに遷移した時点で未定義となってしまっているということになります。

そこでどうするかというと、
mts10806さんが回答されているように
QueryStringなどを使って情報を遷移先に受け渡してやるということになります。


ここからは余談となりますが、
もし学習されるのであれば、個人的には、いきなり一から組み上げていくのではなく、
何かしら初心者向けの書籍を購入し写経していく(単にコードを移す)ところから始めることをおすすめします。
できるだけシンプルな構成の手本を元に、まずは確実に動くコードを組み上げ、
そこから少しずつ改造したりしながら理解していくというアプローチが一番つまずきづらいと思います。
(もし、今回の質問のコードが何かの書籍を参考にされたものであったならすみません…)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/09 13:11

    返答ありがとうございます!
    恐らくpostが渡されてないんやろうなとは思ってたのですが、渡し方がわからず、今回QueryStringの存在を知れたことが進歩となりました。

    自分でも、出来ることの範疇を超えて作ってるなとは思うのですが、ここまで来たら無理矢理にでもブログを作ってしまって、1から勉強し直した事を記録しておく備忘録的な使い方をしようと思ってます!

    キャンセル

+2

コードあまり読んでませんが、「記事を特定」できればいいので、データベース上のキーとなる情報がリンクに含まれていれば良いですよね。

single.php?id=1234

のようにQuery String指定してsingle.phpで$_GET['id']で取得したidでDB問い合わせを行えば良いと思います。

teratailのリンクURLは参考になるかと。teratailはフレームワーク利用されているのでQuery StringというよりURL解析ですが考え方は同じです。
リンクURLにキーとなる情報を含ませる。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/09 14:57

    ちなみに.php/?no=1234
    のように/を挟んでしまうとディレクトリが変わってしまいます。
    必ず.php?no=1234 と渡したいプログラムに直”?”を続けてください

    キャンセル

  • 2019/04/09 15:08 編集

    singleで表示する場合、index.phpをsingle内でincludeすればいいのかな、と思っています。

    (コメント見ないで続けてしまいました、無視してください。再度ご返答ありがとうございます!)

    キャンセル

  • 2019/04/09 15:11

    comment じゃなくてpostでしたね。失礼。
    SQLはこう。
    SELECT * FROM post WHERE post_no=$post_no

    > index.phpをsingle内でincludeすればいいのかな、
    表示に不要なデータ全てを取得するのは無駄です。別途取得用の処理を作ってください。

    しいてなら、selectのSQLを実行する部分を検索条件有無でwhere有無を切り分けて共通化するくらいですが、もう少し先の話。

    キャンセル

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

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

関連した質問

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