現在phpとmysqlで掲示板を製作しています
title.phpでタイトルを書き込み、タイトルをリンクとして表示させ、リンクをクリックすると関連したtolk.phpに飛ぶ仕組みをにしています。
title.phpでboardsのidをtolk.phpに渡し、resテーブルにboards.idでINSERTしてます。
下記のSQL文でしたところ2つの処理は一緒の結果(タイトルの中でしたことは、他では表示されずそこでしか表示されない)になっているのですが、WHEREでも2つのテーブルを関連付けできているということですか?
また、このような処理?(関連した特定の場所でしか見えないこと)をなんと言いますか?
テーブル名:boards
id:int(11)
title:varchar(255)
uptime:datetime
テーブル名:res
id:int(11)
boards_id:int(11)
res_time:datetime
message:text
$stmt = $pdo->prepare('SELECT * FROM res WHERE boards_id=?');
$params = [];
$params[] = $boards_id;
$stmt->execute($params);
$stmt = $pdo->prepare('SELECT * FROM boards INNER JOIN res ON boards.id = res.id WHERE boards_id=?');
$params = [];
$params[] = $boards_id;
$stmt->execute($params);
<?php
// title.php
ini_set('display_errors', true);
error_reporting(E_ALL);
session_start();
require 'database.php';
$username = $_SESSION['username'];
$error = [];
date_default_timezone_set('Asia/Tokyo');
$title = filter_input(INPUT_POST, 'title');
$uptime = date("Y-m-d H:i:s");
if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST'){
if($title === ''){
$error[] = 'タイトルは入力必須です。';
}else if(strlen($title) > 10){
$error[] = 'タイトルは10文字以内で入力してください。';
}
if(count($error) === 0){
try{
$stmt = $pdo->prepare('INSERT INTO boards (id,title,uptime) VALUES (null,?,?)');
$params = [];
$params[] = $title;
$params[] = $uptime;
$stmt->execute($params);
header('Location:title.php');
exit;
}catch(PDOException $e){
echo $e->getMessage();
}
}
}
try{
$stmt = $pdo->query('SELECT * FROM boards ORDER BY id DESC');
$count = $stmt->rowCount();
$rows = $stmt->fetchAll();
}catch(PDOException $e){
echo $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- <link rel="stylesheet" href="/css/styles.css"> -->
<meta charset="utf-8">
<title>メインページ</title>
<h1>掲示板へようこそ</h1>
</head>
<body>
<?php if(count($error) > 0) : ?>
<?php foreach($error as $e) : ?>
<p><?php echo h($e); ?></p>
<?php endforeach; ?>
<?php endif; ?>
<section>
<h2>新規投稿</h2>
<!-- 書き込み用フォーム -->
<form action="" method="post">
<label for="title">タイトル</label><br>
<input type="text" name="title" id="title"><br>
<button type="submit">部屋を立てる</button>
</form>
</section>
<section>
<h2>投稿一覧</h2>
<p>現在の投稿は<span><?php echo $count; ?></span>件です</p>
<?php if(!empty($count)): ?>
<?php foreach($rows as $row): ?>
<div class="linkbox">
<a href='tolk.php?boards_id=<?php echo $row['id']; ?>'>
<?php echo h($username); ?>
<?php echo h($row['uptime']); ?> <br>
<?php echo h($row['title']); ?>
<?php var_dump($row['id']); ?>
<a href="delete.php?delete_title_id=<?php echo $row['id'] ?>">削除</a>
<a href="change.php?change_title_id=<?php echo $row['id'] ?>">編集</a>
</a>
</div>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>投稿はまだありません。</p>
<?php endif; ?>
</section>
</body>
</html>
<?php
// tolk.php
ini_set('display_errors', true);
error_reporting(E_ALL);
session_start();
require 'database.php';
$username = $_SESSION['username'];
$boards_id = filter_input(INPUT_GET, 'boards_id');
// $boards_id = $_GET['id'];
$error = [];
date_default_timezone_set('Asia/Tokyo');
$message = filter_input(INPUT_POST, 'message');//POST、入力された値を格納、未定義も防ぐ
$res_time = date("Y-m-d H:i:s");
if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST'){
if($message === ''){
$error[] = 'メッセージは入力必須です。';
}else if(strlen($message) > 100){
$error[] = 'メッセージは100文字以内で入力してください。';
}
if(count($error) === 0){
try{
$stmt = $pdo->prepare('INSERT INTO res (id,boards_id,message,res_time) VALUES (null,?,?,?)');
$params = [];
$params[] = $boards_id;
$params[] = $message;
$params[] = $res_time;
$stmt->execute($params);
header("Location:tolk.php?boards_id=$boards_id");//変数展開では、ダブルコーテーション
exit;
}catch(PDOException $e){
echo $e->getMessage();
}
}
}
try{
$stmt = $pdo->prepare('SELECT * FROM res WHERE boards_id=?');
$params = [];
$params[] = $boards_id;
$stmt->execute($params);
$count = $stmt->rowCount();
$rows = $stmt->fetchAll();
}catch(PDOException $e){
echo $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<link rel="stylesheet" href="/css/styles.css">
<meta charset="utf-8">
<title>メインページ</title>
<h1>掲示板へようこそ</h1>
</head>
<body>
<?php if(count($error) > 0) : ?>
<?php foreach($error as $e) : ?>
<p><?php echo h($e); ?></p>
<?php endforeach; ?>
<?php endif; ?>
<section>
<h2>新規投稿</h2>
<form action="" method="post">
<label for="message">メッセージ</label><br>
<input type="text" name="message" id="message"><br>
<button type="submit">投稿</button>
</form>
</section>
<section>
<h2>投稿一覧</h2>
<p>現在の投稿は<span><?php echo $count; ?></span>件</p>
<?php if(!empty($rows)): ?>
<?php foreach($rows as $row): ?>
<div class="linkbox">
<?php echo h($username); ?>
<?php echo h($row['res_time']); ?><br>
<?php echo h($row['message']); ?>
<a href="delete.php?id=<?php echo $row['id'] ?>">削除</a>
<a href="change.php?id=<?php echo $row['id'] ?>">編集</a>
</div>
<?php var_dump($row['id']); ?>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>投稿はまだありません。</p>
<?php endif; ?>
</section>
</body>
</html>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
2つの処理は一緒の結果(タイトルの中でしたことは、他では表示されずそこでしか表示されない)になっているのですが、WHEREでも2つのテーブルを関連付けできているということですか?
Whereで関連付けされているのではなく、from 句で結合により関連付けられています。
Whereでは関連付けられた結果に対しての条件を指定しています。
また、このような処理?(関連した特定の場所でしか見えないこと)をなんと言いますか?
関連付けたものを取り出す項目はSelect句で指定します。
selectで指定していない項目は、selectの結果としては見えない事になります。
質問内容からは、見えないのではなく、単にその項目を取り出していないだけだと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
質問の趣旨とズレますけど、
resテーブルのidってなんのidですか?
resテーブル内のユニークなidを保持するためなのか、それともboard.idと紐付けるためのidなのか。
boards.id = res.id
って条件でJOINしてしまう前提で話をすすめると、
じゃぁテーブルres内で一つ一つの書き込みのユニーク性を
res_timeでみるのでしょうか、
全く同じタイミングで複数のboard宛に書き込みが生じた場合、
idとres_timeを組み合わせて削除できなくもないけど、
あまり良くない設計と言えます。
テーブル名:res
id:int(11)
boards_id:int(11) ←これを追加しましょう
res_time:datetime
message:text
INNER JOIN res ON boards.id = res.boards_id
などとして連結します。
こうすることで、res個別の削除はres.idを指定して簡単にできます。
FROM句とJOIN句で、テーブルの結合をON句に書かれた条件で行ったものに対して、
WHERE句の条件で絞り込みを行うものです。
例えば
SELECT * FROM boards, res
WHERE boards.id = res.boards_id AND boards.id = ?
ORDER BY res.res_time;
のようにも書けなくもないですが、
テーブルboardsとテーブルresの全行を総当りで結合させたものの中から、
WHERE boards.id = res.boards_id AND boards.id = ?
の条件で絞り込みを行うため、得られる結果は一見同じに見えますが、
将来テーブルの行数が何千、何万、何十万同士を総当りで結合させる無駄な処理をした後に
絞り込みを行うと、総当たりの無駄な処理+膨大な量からの無駄な絞り込みということになり、
そういう無駄を省くためにも、
FROM句にJOIN句をつないでテーブルの結合を効率良く行うのがセオリーです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.11%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
Takumiboo
2020/01/31 10:56
本題と全く関係ないですが、会話などを意味する「トーク」であれば「talk」ですよ。
yambejp
2020/01/31 10:56
ちょっと何をききたいのか把握できません
「このような処理?(関連した特定の場所でしか見えないこと)をなんと言いますか? 」
SQL文だけ抽出して、そのどの部分に対する質問なのかをはっきり
した方が良いと思います