電子書籍の厳選無料作品が豊富!

タイトルと本文だけを投稿するミニブログを作ってMySQLとPHPの練習しています。そこで記事を更新するページedit.phpを作成していますがうまくいきませんでした。下記のコード edit.php(個別記事編集ページ)について指摘・アドバイスください。よろしくお願いします。

★ファイルの構成として下記のとおりで同じ階層にあります。

index.php (タイトルと内容の一覧を表示するページ)
post.php (タイトルと内容を投稿するページ)
article.php (index.phpよりリンクされていている個別ページ)
edit.php (個別記事編集ページ article.php よりリンクされています。)

★データベース情報 dbname=blog
記事を入れるテーブル: post (カラム: no / title / content)


【わからない部分】

・分からない部分は、タイトルと内容のフォームに数値を入れると更新できるのですが、文字を入力するとエラーがでてしまいます。・それと、だんだん こんな書き方でいいのだろうかという思ってきました。
教則本や教えてgooでアドバイスを受けた方のコードを参考にして作りましたが、おそらく、私のコードの書き方が良くないと思います。下記は更新ページのedit.php ですが、更新のためには、SELECT と UPDATE を使わないといけないと思ったもので、SQLの接続を2つに分けました。
一つ目のtry{}では、index.phpより$_GETでURLからno 情報を取り出して、それを元に他の情報を取り出しています。そして2つめのtry{}では、更新情報を入力フォームより受け取り更新しています。そこで、一般的に、更新する際は、どのうよにやっているのだろうという疑問もあります。


<!-- ↓edit.php -->
<?php
try{
$dsn = 'mysql:host=localhost; dbname=blog';
$user = 'root';
$password = '*********';
$pdo = new PDO($dsn, $user,$password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql="SELECT no,title,content FROM post WHERE 1 ";
$sql.=" AND no=?";

$datas = array();
$datas[]=isset($_GET["no"])?$_GET["no"]:"";
$stmt = $pdo->prepare( $sql);
$stmt->execute($datas);

$row = $stmt->fetch(PDO::FETCH_ASSOC);

}catch(PDOException $e){
die($e->getMessage());
}


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

try{
$dsn = 'mysql:host=localhost; dbname=blog';
$user = 'root';
$password = '********';
$pdo = new PDO($dsn, $user,$password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = $pdo->query("UPDATE post SET title={$_POST['title']}, content={$_POST['content']} WHERE no ={$_POST['no']} ");

header('Location: index.php');

$stmt = $pdo->prepare( $sql);
$stmt->execute($datas);

}catch(PDOException $e){
die($e->getMessage());
}
}
}
?>


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>記事更新 Blog</title>
<link rel="stylesheet" href="blog.css">
</head>
<body>
<form method="post" action="edit.php " onsubmit="return confirm( '更新してもよいですか' )";>

<h2>記事投稿</h2>

<p><input type="hidden" name="no" size="40" value="<?php echo $row['no'] ?>"></p>

<p>題名</p>
<p><input type="text" name="title" size="40" value="<?php echo $row['title'] ?>"></p>
<p>本文</p>
<p><textarea name="content" rows="8" cols="40"><?php echo nl2br($row['content']) ?></textarea></p>
<p><input name="update" type="submit" value="更新"></p>

<p><?php echo $error ?></p>

</form>
</body>
</html>

A 回答 (1件)

じっくりみてませんが、ぱっと見へんなところ



>$sql = $pdo->query("UPDATE post SET title={$_POST['title']}, content={$_POST['content']} WHERE no ={$_POST['no']} ");
>header('Location: index.php');
>$stmt = $pdo->prepare( $sql);
>$stmt->execute($datas);

SQL文の作り方がまずおかしい、prepare処理なのだから直接変数を代入しない
ちなみに数字以外がエラーになるのは「SET title=たいとる」のように代入されているからで
せめて「SET title='たいとる'」のようにクウォートで文字列をくくってやらないと・・・
ただ、それをしないためにprepareで処理しているんですけど

$pdo->query()の結果を$sqlに受けちゃっているけど、このへん何をやっているか
ご自身でうまく理解していないのでは?
$pdo->query()は単純なSQL文の実行、$pdo->prepare()は外部からデータを
もってくる場合のSQL文の実行と切り分けて考えてください。

結果、こんな感じ?
$datas=array($_POST['title'], $_POST['content'],$_POST['no']);
$sql="UPDATE post SET title=?,content=? WHERE no =? ";
$stmt = $pdo->prepare( $sql);
$stmt->execute($datas);
    • good
    • 0
この回答へのお礼

ありがとうございます。
prepare()と query()のあたりの理解がしっかりとできていませんでした。なので、2つのやり方で実験して、比べてみることができました。そのせいでかなり勉強になりました。フォームからの入力でも query()を使用した場合は、カンマを含んだ文をフォムームに入れて入力すると、投稿できないのに対して、prepare()を使用した場合は、カンマを含んだ文でも問題なく投稿できました。それにより、SQLインジェクションの勉強にもなりました。

お礼日時:2016/04/14 16:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!