プロが教えるわが家の防犯対策術!

PHP初心者です。
ロリポップで登録したPHPMyadminでユーザー名やパスワード等を入力する表を作成しています。
更新又は削除ボタンが押されたときにこういう処理をする、という命令を出すページで躓いています。

<?php
$db = new PDO('mysql:host=●●;dbname=●●;charset=utf8', '●●', '●●');
try {
if (isset($_POST['update'])) {
$stt = $db->prepare('UPDATE `date` SET sid=:sid, uid=:uid, name=:name, email=:email, passwd=:passwd WHERE sid=:sid');
$stt->bindValue(':sid', $_POST['sid']);
$stt->bindValue(':uid', $_POST['uid']);
$stt->bindValue(':name', $_POST['name']);
$stt->bindValue(':email', $_POST['email']);
$stt->bindValue(':passwd', $_POST['passwd']);
} elseif (isset($_POST['delete'])) {
$stt = $db->prepare('DELETE FROM `date` WHERE sid=:sid');
}
$stt->bindValue(':sid', $_POST['sid']);
$stt->execute();
} catch(PDOException $e) {
die('エラーメッセージ'.$e->getMessage());
}
header('Location:●●');
?>

毎回どうしても
$stt->bindValue(':sid', $_POST['sid']);
Fatal error: Call to a member function bindValue() on a non-object
というエラーが出てしまいます。
sidが存在していないのに要求しているのだと思うのですが、PHPMyAdminでsidというカラムはきちんと存在しています。
何が間違っているのでしょうか。
記入している内容にも間違いがあったらご指摘お願いします。
回答よろしくお願いします。

A 回答 (10件)

>> 何が問題で更新・削除処理ができていなかったのでしょうか。



"本 当 に " 最初からずっと

<form action="ファイル名" method="post">
<input type="submit" value="送信" />
</form>

のSUBMITボタンを押して遷移していましたか?これを押さない限りパラメータは何も $_POST に送信されませんよ…失礼ですが、

・最初に method="post" の指定を忘れていた
・あなたがSUBMITボタンを押したつもりだったが実際は別の方法で遷移していた

ぐらいしか思いつきません…
    • good
    • 0
この回答へのお礼

なるほど…。

とても助かりました。
ここまで回答していただき、本当にありがとうございました!

お礼日時:2014/05/28 11:01

あらら、やっと謎が解けました(汗



>> アドレスバーに直接入力してそのエラーが出るのは仕方の無いことなんですか?
>> エラーを処理することは可能でしょうか?

そうですね…最初の回答に回帰しますが

> updateでもdeleteでもないとき、
>
> $db = new PDO('mysql:host=●●;dbname=●●;charset=utf8', 'ユーザー名', 'パスワード');
>
> の次に
>
> $stt->bindValue(':sid', $_POST['sid']);
>
> がいきなり実行されてしまいますが、このときのエラーでしょうか。書き方に問題があります。

直接アクセスすれば「update」も「delete」も送信されないため、ifブロックの中もelseifブロックの中も実行されず、このようになってしまうのです。だから…「updateもdeleteも無かったとき」に対応するしかありません。

私は http://pastebin.com/MpfUnPyp の中では「if」「elseif」だけではなく「else」のときにも "アクションが指定されていません" と表示して中断する処理を書いて対応させました。

この回答への補足

長々とお付き合いしていただき有難うございます。

最終的なソースとしての形はほとんど変わっていないのですが、これは何が問題で更新・削除処理ができていなかったのでしょうか。
WEBサーバーソフトがapacheではなかったということですか?
そして問題はそれだけでしたか?
分からないことだらけですみません…。

補足日時:2014/05/28 01:06
    • good
    • 0

うーん…最初は



>> array(4) { ["_GET"]=> array(0) { } ["_POST"]=> array(0) { } ["input"]=> string(0) "" ["type"]=> NULL }

と出ていたのに、どういう経緯で

>> array(4) {
>> ["_GET"]=>
>> array(0) {
>> }
>> ["_POST"]=>
>> array(6) {
>> ["sid"]=>
>> string(1) "6"
>> ["uid"]=>
>> string(4) "6番目のユーザーのID"
>> ["name"]=>
>> string(9) "6番目のユーザーの氏名"
>> ["email"]=>
>> string(10) "6番目のユーザーのメールアドレス"
>> ["passwd"]=>
>> string(6) "6番目のユーザーのパスワード"
>> ["delete"]=>
>> string(6) "削除"
>> }
>> ["input"]=>
>> string(104) "sid=6&uid=ユーザーのID&name=%E3%83%AC%E3%82%A4%E3%83%B3&email=ユーザーのメールアドレス&passwd=ユーザーのパスワード&delete=%E5%89%8A%E9%99%A4"
>> ["type"]=>
>> string(33) "application/x-www-form-urlencoded"
>> }

と出るように変わったのか教えてください。既に頂いている質問者さんの応答からは「突然変わった」ようにしか読み取れません…

もちろん、どちらもSUBMITボタンからPOSTしてアクセスしていますよね?
(ブラウザのアドレスバーから直接アクセスすれば先ほどのエラーが出て当然です)

この回答への補足

すみません、ブラウザのアドレスバーから直接入力していました…。

ありがとうございます。
削除、更新共にきちんと処理できました。

アドレスバーに直接入力してそのエラーが出るのは仕方の無いことなんですか?
エラーを処理することは可能でしょうか?

補足日時:2014/05/27 23:45
    • good
    • 0

>> こちらのことですか?



そうですね。

この回答への補足

デバック用のコードを外してみましたが、
Fatal error: Call to a member function bindValue() on a non-object
こちらのエラーが出てしまいます…。

デバック用のコードを外すと、最初に投稿した内容と全く変わらないのですが、何か私が見逃している事があればご指摘お願いします。

補足日時:2014/05/27 22:45
    • good
    • 0

>> ["_POST"]=>


>> array(6) {
>> ["sid"]=>
>> string(1) "6"
>> ["uid"]=>
>> string(4) "6番目のユーザーのID"
>> ["name"]=>
>> string(9) "6番目のユーザーの氏名"
>> ["email"]=>
>> string(10) "6番目のユーザーのメールアドレス"
>> ["passwd"]=>
>> string(6) "6番目のユーザーのパスワード"
>> ["delete"]=>
>> string(6) "削除"
>> }

あれ、今度はちゃんと全部取れてますねぇ…

>> ["type"]=>
>> string(33) "application/x-www-form-urlencoded"
>> }

Content-Typeも正常です。この状態でこれらのデバッグ用のコードを削除したらどうなりますか?これで

「削除したらまた Fatal error: Call to a member function bindValue() on a non-object が出た」

なんてことは "あり得ない" と断言できます。どう考えてもあり得ないです。

この回答への補足

デバック用のコードとは少し前に先頭に代入した

<?php
$type = $_SERVER['CONTENT_TYPE'];
$input = file_get_contents('php://input');
var_dump(compact('_GET', '_POST', 'input', 'type'));
exit;

こちらのことですか?

補足日時:2014/05/27 22:08
    • good
    • 0

これは…



・ポストフィールドが空
・Content-Typeも指定されていない

という状態ですね。 <input type="submit" /> で遷移したのではなく、リンクをクリックしたりブラウザにURLを直接入れてアクセスしているような状態と何も変わりないです。

2点ほどまた確認をお願いします。

・ChromeやFirefoxの「LiveHTTPHeaders」というエクステンション(アドオン)を使えばブラウザが実際にどんな通信をしているのかどうか覗き見ることが出来ます。SUBMITボタンを押したときにキャプチャされた内容を貼ってください。

・本当にあなたが思っている通りのHTMLが表示されているかどうか確認してください。フォームのあるページにアクセスして、右クリックのメニューからHTMLソースを閲覧するということですね。PHPが含まれるソースではなく、PHPを実行して得られたHTMLのみのソースのことです。これでformタグになにかおかしいところがあれば間違いなくそれが原因だと断定できます。

この回答への補足

すみません、LiveHTTPHeadersの使い方がいまいち分からなかったので、先にHTML表示の確認の結果を送らせていただきます。
更新・削除ボタンがあるページと編集した表が表示されるページのHTMLには特に問題はありませんでした。
今回最初に質問させていただいた内容のページのみ、このようなソースが表示されていました。
これは6番目のユーザーのデータの削除処理を実行したときのものです。


array(4) {
["_GET"]=>
array(0) {
}
["_POST"]=>
array(6) {
["sid"]=>
string(1) "6"
["uid"]=>
string(4) "6番目のユーザーのID"
["name"]=>
string(9) "6番目のユーザーの氏名"
["email"]=>
string(10) "6番目のユーザーのメールアドレス"
["passwd"]=>
string(6) "6番目のユーザーのパスワード"
["delete"]=>
string(6) "削除"
}
["input"]=>
string(104) "sid=6&uid=ユーザーのID&name=%E3%83%AC%E3%82%A4%E3%83%B3&email=ユーザーのメールアドレス&passwd=ユーザーのパスワード&delete=%E5%89%8A%E9%99%A4"
["type"]=>
string(33) "application/x-www-form-urlencoded"
}

ここからは何か分かることがありますか?
chromeはlocalhostの方でMySQLを利用した時にしか使ったことがなく、LiveHTTPHeadersの確認が上手くいっていません。
HTMLの確認だけでは原因が突き止められないということでしたら、その旨を回答していただいてもよろしいですか?

補足日時:2014/05/27 18:06
    • good
    • 0

>> 送信先のスクリプトは更新・削除の処理を行う方ですよね?



そうです。

>> Fatal error: Call to undefined function apache_request_headers()

WebサーバーソフトウェアがApacheじゃないようですね。ではその代わりに

<?php
$type = $_SERVER['CONTENT_TYPE'];
$input = file_get_contents('php://input');
var_dump(compact('_GET', '_POST', 'input', 'type'));
exit;

これで確認をお願いします。推測ですが、 $_POST が空になっていると php://input の方から取れる可能性が高いです。そういう場合はWebブラウザ側が「application/x-www-form-urlencoded」をMIMEタイプに設定して送信していないということになりますね。Webブラウザ側のバグです。

InternetExplorerはバージョンが重要になってきます。9以降であればそれほど問題ないですが、8以前には致命的なバグがたくさんあります。個人的にはFirefoxやGoogleChromeの利用を推奨します。

この回答への補足

送信先のスクリプトの先頭に仰った内容を入れてみましたが

array(4) { ["_GET"]=> array(0) { } ["_POST"]=> array(0) { } ["input"]=> string(0) "" ["type"]=> NULL }

このように出てしまいました…。


バージョンについてのお話、ありがとうございます。
一応InternerExplorer以外にもクロームで確認してみましたが、同じ内容が表示されました。

補足日時:2014/05/27 05:45
    • good
    • 0

<form method="post" action="ファイル名">


<input type="submit" name="update" value="更新" />
</form>

この3行が書かれている時点で更新ボタンを押したら $_POST['update'] = '更新'; として定義されていないとおかしいですよね…うーん…とりあえず送信先のスクリプトの先頭に

<?php
$headers = apache_request_headers();
$input = file_get_contents('php://input');
var_dump(compact('_GET', '_POST', 'headers', 'input'));
exit;

と書いてそこに送信した場合の結果を教えてください。PHPの設定が原因か、ブラウザ側に原因があるか特定を進めます。それと出来れば使用しているブラウザの名前も教えてください。

この回答への補足

送信先のスクリプトは更新・削除の処理を行う方ですよね?
仰っていた内容を先頭に入力したところ、
Fatal error: Call to undefined function apache_request_headers()
というエラーがでました。
$headers = apache_request_headers();
この一行にエラーが出ているとのことです。

ブラウザはインターネットエクスプローラを使っています。
それからロリポップから登録したPHPMyAdminを利用しています。

補足日時:2014/05/27 04:23
    • good
    • 0

このページにはどうやってアクセスしていますか?フォームからアクセスさせている場合はそのフォームのHTMLを記載してください。

この回答への補足

<?php
require_once 'ユーザー定義関数を指定しているファイル名';

function showOption($start, $end, $default, $step = 1) {
for ($i = $start; $i <= $end; $i += $step) {
print('<option value="'.$i.'"');
if ($i === (int)$default) { print(' selected'); }
print('>'.$i.'</option>');
}
}

try {
$db = new PDO('mysql:host=●●;dbname=●●;charset=utf8', '●●', '●●');
$stt = $db->prepare('SELECT * FROM date WHERE sid = :sid');
$stt->bindValue(':sid', $_GET['sid']);
$stt->execute();
} catch(PDOException $e) {
die('エラーメッセージ:'.$e->getMessage());
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>パーソナルデータ</title>
</head>
<body>
<h3>データ</h3>
<?php
if ($row = $stt->fetch()) {
$uid = htmlspecialchars($rpw['uid']);
$name = htmlspecialchars($row['name']);
$email = htmlspecialchars($row['email']);
$passwd = htmlspecialchars($row['passwd']);
?>
<form method="POST" action="質問に使用したページのファイル名">
<input type="hidden" name="sid" value="<<?php print(e($row['sid'])); ?>" />
<div class="container">
<label for="uid">ユーザーID</label><br />
<input type="text" id="uid" name="uid"
size="10" maxlength="20"
value="<?php print(e($row['uid'])); ?>" />
</div>
<div class="container">
<label for="name">氏名</label><br />
<input type="text" id="name" name="name"
size="10" maxlength="20"
value="<?php print(e($row['name'])); ?>" />
</div>
<div class="container">
<label for="email">メールアドレス</label><br />
<input type="text" id="email" name="email"
size="10" maxlength="30"
value="<?php print(e($row['email'])); ?>" />
</div>
<div class="container">
<label for="passwd">パスワード</label><br />
<input type="text" id="passwd" name="passwd"
size="10" maxlength="20"
value="<?php print(e($row['passwd'])); ?>" />
</div>
<input type="submit" name="update" value="更新" />
<input type="submit" name="delete" value="削除"
onclick="return confirm('削除してもよろしいですか?')" />
</form>
<?php
} else {
print('該当するデータはありません。');
}
?>
</body>
</html>

このページが更新・削除のボタンを押すページです。

補足日時:2014/05/26 22:39
    • good
    • 0

前回の質問


http://detail.chiebukuro.yahoo.co.jp/qa/question …

提示したコード
http://pastebin.com/MpfUnPyp

本当に試していただけましたか?
提示したコードを「コピペ」して実行してもらえましたか?
私のコードをコピペで実行していただければ原因が間違いなく分かるはずなんですが。

> updateでもdeleteでもないとき、
>
> $db =new PDO('mysql:host=●●;dbname=●●;charset=utf8', 'ユーザー名', 'パスワード');
>
> の次に
>
> $stt->bindValue(':sid', $_POST['sid']);
>
> がいきなり実行されてしまいますが、このときのエラーでしょうか。書き方に問題があります。

との見方で

「アクションが指定されていません」

とエラーメッセージが表示されませんか?

この回答への補足

回答ありがとうございます。
すみません、なるべく形を変えたくなかったので不足しているであろうコードなどを足していくようにして色々と試行錯誤していました…。
仰っていたようにコピペをしたら、アクションが指定されていないとのメッセージが表示されました。
見る限り、updateとdeleteの指定が出来ていないのかと思ったのですが、どうしてこのままだと駄目なのか分かりません。
本当に申し訳ないのですが、こうすればいいという具体的な解決方法を教えていただけませんか。

補足日時:2014/05/26 12:36
    • good
    • 0

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