アプリ版:「スタンプのみでお礼する」機能のリリースについて

ZAMPPを使用しPHP/MYSQLの勉強をし始めた者です。以下のエラーが出て先に進めません。どこが悪いのか教えてください。

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'ODBC'@'localhost' (using password: NO) in C:\xampp\htdocs\todo.php on line 33

Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in C:\xampp\htdocs\todo.php on line 33

問題のプログラムです。
<?php
//----------------------------------------------------------------------
//TODO管理プログラム
//----------------------------------------------------------------------
$db_dns = "mysql:host=localhost;dbname=phptest;";
$user = "root";
$pass = "";

//-------SQL

$create_query = <<<______
CREATE TABLE items(
todo_idINTEGER PRIMARY KEY AUTO_INCREMENT,
memoTEXT,
flagTEXT,
ctimeINTEGER);
______;

//-----------------------------------------------------------------------
//データベースの初期化
$db = new PDO($db_dns,$user,$pass);
//データベースが利用できるか確認
$select_stmt = $db->query("SELECT*FROM items LIMIT1");
if(!$select_stmt){//テーブが作成されていない場合
$db->exec($create_query);
$now = time();
$db->exec("INSERT INTO items(memo,flag,ctime)".
"VALUES('データの初期化','done',$now)");
}
//------------------------------------------------------------------------
//TODOを追加する
if(isset($_GET['newitem']) && $_GET['newitem'] != ""){
$memo = mysql_real_escape_string($_GET['newitem']);
$now = time();
$db->exec("INSERT INTO items(memo,flag,ctime)".
"VALUES('$memo','new',$now)");
}
//TODOを消化する
$to_id = intval($_GET['done']);
if ($todo_id > 0){
$db->exec("UPDATE items SET flag='done'".
"WHERE todo_id=$todo_id");
}
//-----------------------------------------------------------------------------
//現在のTODOを表示するHTML
$list = "";
//未消化のTODOを抽出
$sql="SELECT*FROM items WHERE flag='new'ORDER BY ctime DESC";
$r = $db->query($sql);
foreach ($r->fetchALL() as $row){
$todo_id = $row["todo_id"];
$memo = htmlspecialchars($row["memo"]);
$ctime = date("Y-m-d",$row["ctime"]);
$btn = "[<a href = '?done=$todo_id'>x</a>]";
$list .= "<li>$btn $memo ($ctime)</li>";
}
//消化済みTODOを最大5件抽出
$sql = "SELECT * FROM items WHERE flag = 'done'".
"ORDER BY ctime DESC LIMIT 5";
$r = $db->query($sql);
foreach ($r->fetchALL() as $row){
$memo = htmlspecialchars($row["memo"]);
$ctime = date("Y-m-d",$row["ctime"]);
$list .= "<li><s>$memo ($ctime)</s></li>";
}
//-------------------------------------------------------------------------------
//以下でHTMLを表示
?><html><body>
<h1>TODO</h1>
<?php echo $list ?>
<form>
<h3>新しいTODO</h3>
<input type = "text" name= "newitem"/>
<input type ="submit" value="追加"/>
</form>
</body></html>

本当に困り果てています。賢者の方、知恵をお貸しください。

A 回答 (2件)

エラーの原因は、mysql_real_escape_string 関数の使用方法の誤りです。



【エラー場所】
 33行目:$memo = mysql_real_escape_string($_GET['newitem']);


PHPの関数リファレンスを確認すると、以下の記載があります。


説明
---------------------
string mysql_real_escape_string (
string $unescaped_string [, resource $link_identifier ] )


link_identifier
---------------------
MySQL 接続。指定されない場合、mysql_connect() により
直近にオープンされたリンクが指定されたと仮定されます。
そのようなリンクがない場合、引数を指定せずに
mysql_connect() がコールした時と同様にリンクを確立します。
リンクが見付からない、または、確立できない場合、
E_WARNING レベルのエラーが生成されます。


macatoさんのプログラムでは、PDOにてDB接続を行っています。

 21行目:$db = new PDO($db_dns,$user,$pass);

mysql_connect 関数にて作成した
DBリンク(コネクション)がないために、
エラーが発生します。

PDOでDBリンクを作成しているので、
SQLのサニタイズは、
PDOのプリペアドステートメントを
利用なさるのが、正しいと思います。


以下にプログラムのサンプルを記載します。
※動作確認は行っていませんので悪しからず。

$memo = trim($_GET['newitem']);
$now = time();
$sth = $dbh->prepare("INSERT INTO items(memo,flag,ctime) VALUES (?, 'new', ?)");
$sth->bindParam(1, $memo);
$sth->bindParam(2, $now);
$sth->execute();
    • good
    • 0

mysql_real_escape_string() は、mysql_connect() での接続が確立しなければ使えません。


PDO を使うならば、プリペアードステートメントを使いましょう。
MySQL4.0 との接続でも、エミュレートされてます。
http://jp.php.net/manual/ja//pdo.prepare.html
    • good
    • 0

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