現在PHPの入門書にて、WEBサイトからDBへスタッフの名前とパスワードを追加した後、そのパスワードを修正するというプログラムを練習していましたところ、追加まではうまくいくのですが、修正を実行した際にエラーメッセージが出てしまいます。
該当箇所を見たのですが、どうしても原因が特定できず、お力をお借りできればと思い、投稿させて頂きました。
何卒よろしくお願いいたします。
以下、実行しているコードになります。
================================
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>タイトル</title> </head> <body> <?php try { $staff_code=$_POST['code']; $staff_name=$_POST['name']; $staff_pass=$_POST['pass']; $staff_name=htmlspecialchars($staff_name); $staff_pass=htmlspecialchars($staff_pass); $dsn='mysql:dbname=shop;host=localhost'; $user='root'; $password=''; $dbh=new PDO($dsn,$user,$password); $dbh->query('SET NAMES utf8'); $sql='UPDATE mst_staff SET name=?,password=? WHERE code=?'; $stmt=$dbh->prepare($sql); $data[]=$staff_name; $data[]=$staff_pass; $data[]=$staff_code; $stmt->execute($data); $dbh=null; } catch(Exception $e) { print 'ただいま障害により大変ご迷惑をおかけしております。'; exit(); } ?> 修正しました。<br/> <br/> <a href="staff_list.php">戻る</a> </body> </html>
================================
ちなみに15行目は
「 $staff_name=$_POST['name'];」
になります。
以下のような質問にはグッドを送りましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 間違っている
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答2件
1
Noticeは致命的なエラーではありませんが、不適切な表現ということです
error_reportingにてE_NOTICE
端的にいえば
$staff_name=$_POST['name'];
と記載する場合nameというパラメータを必ずpostしなくてはなりません。
もし値がない場合が想定されるのであれば
PHP
1$staff_name=isset($_POST['name'])?$_POST['name']:""; 2
のような処理をいれてください
場合によってはfilter_inputで処理してもよいかと思います
PHP
1$staff_name=filter_input(INPUT_POST,'name'); 2
filter_inputすればデフォルト値の設定や想定値との整合性のバリデートなど可能です。
投稿2016/09/12 06:33
総合スコア108937
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
1
ベストアンサー
場当たりな対処を施したコード
php
1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>タイトル</title> 6 </head> 7 <body> 8 9 <?php 10 try { 11 12 /* 13 * グローバル変数に直接アクセスしない 14 * 15 $staff_code = $_POST['code']; 16 $staff_name = $_POST['name']; 17 $staff_pass = $_POST['pass']; 18 */ 19 20 $staff_code = filter_input(INPUT_POST, 'code'); 21 $staff_name = filter_input(INPUT_POST, 'name'); 22 $staff_pass = filter_input(INPUT_POST, 'pass'); 23 24 /* 25 * SQLに渡す変数を htmlspecialchars 使うのは論外 26 * 27 $staff_name = htmlspecialchars($staff_name); 28 $staff_pass = htmlspecialchars($staff_pass); 29 */ 30 31 32 /** 33 * try 〜 catch でエラーを細くするためには、以下の設定が必要 34 */ 35 $options = array( 36 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 37 ); 38 39 $dsn = 'mysql:dbname=shop;host=localhost;charset=utf8;'; 40 $user = 'root'; 41 $password = ''; 42 $dbh = new PDO($dsn, $user, $password, $options); 43 44 /* 45 * 文字コードは $dsn で 46 $dbh->query('SET NAMES utf8'); 47 */ 48 49 $sql = 'UPDATE mst_staff SET name=?,password=? WHERE code=?'; 50 $stmt = $dbh->prepare($sql); 51 $data[] = $staff_name; 52 $data[] = $staff_pass; 53 $data[] = $staff_code; 54 $stmt->execute($data); 55 56 /** 57 * いらない 58 $dbh = null; 59 */ 60 } catch (Exception $e) { 61 print 'ただいま障害により大変ご迷惑をおかけしております。'; 62 63 /** 64 * ここで exit すると、htmlが崩れる 65 */ 66 // exit(); 67 } 68 ?> 69 70 修正しました。<br/> 71 <br/> 72 <a href="staff_list.php">戻る</a> 73 74 </body> 75</html>
欲を言えばこうしたい
php
1<?php 2try { 3 if (null != filter_input_array(INPUT_POST)) { 4 $staff_code = filter_input(INPUT_POST, 'code'); 5 $staff_name = filter_input(INPUT_POST, 'name'); 6 $staff_pass = filter_input(INPUT_POST, 'pass'); 7 8 $options = array( 9 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 10 ); 11 12 $dsn = 'mysql:dbname=shop;host=localhost;charset=utf8;'; 13 $user = 'root'; 14 $password = ''; 15 $dbh = new PDO($dsn, $user, $password, $options); 16 17 $sql = 'UPDATE mst_staff SET name=?,password=? WHERE code=?'; 18 $stmt = $dbh->prepare($sql); 19 $data[] = $staff_name; 20 $data[] = $staff_pass; 21 $data[] = $staff_code; 22 $stmt->execute($data); 23 } 24} catch (Exception $e) { 25 $err = 'ただいま障害により大変ご迷惑をおかけしております。'; 26} 27?> 28<!DOCTYPE html> 29<html> 30 <head> 31 <meta charset = "UTF-8"> 32 <title>タイトル</title> 33 </head> 34 <body> 35 <?php if (isset($err)) : ?> 36 <p><?= $err; ?></p> 37 <?php elseif (null != filter_input_array(INPUT_POST)) : ?> 38 <p>更新しました。</p> 39 <?php endif; ?> 40 <a href = "staff_list.php">戻る</a> 41 </body> 42</html>
グローバル変数に直接アクセスしない
ご指摘ありがとございます。
このページでは{}内なのでローカル変数かと思っておりましたが、
確かに上位ページではグローバルの領域にこの変数を定義しておりま
すので、それでグローバル変数に該当するという事なのですね。ちなみにグローバル変数に直接アクセスしないのは、プログラミング
においては当たり前のルールなのでしょうか。
始めたばかりの初心者で申し訳ございません。
ここでグローバル変数と言っているのは、$_POST['xxxx']
の事です。
$_POST, だけではなく、$_SERVER や $_GET も然り。マニュアルでは「スーパーグローバル」と表現されています。
$GLOBALS もそうですが、この変数は「どこからでもアクセスできる」と同時に「どこからでも書き換えできる」性質があります。「どこからでもアクセスできる」ことはそれほど問題ないのですが、「どこからでも書き換えできる」ということが、意図せず発生した場合、バグの特定が困難になり、コードの保守性・安全性を損なう結果になってしまうので、出来る限り、ソースコードに $_POST や $_GET が登場しないように書きましょうといういわば、作法です。
また、filter_input()
関数を使って間接的に取得することで、グローバル変数に影響を与えなく出来るという事なのですね。
そうですね。同時に、
$val = (isset($_POST['key'])) ? $_POST['key'] : null;
という冗長な書き方をせずに済みます。
SQLに渡す変数を htmlspecialchars 使うのは論外
こちらは脆弱性対策のためのサニタイジングとして入れていたのですが、
SQLに渡す変数では使ってはいけないのですね。
理由としては、変数に何らかの影響が出てしまうという事なのでしょうか。
例えば以下のようなことなのでしょうか。
http://php-archive.net/php/htmlspecialchars/
いいえ。これは全く無関係です。
単純に、SQLインジェクション対策のための関数ではないので、ここで使ってはいけないということです。
SQLインジェクション対策のために必要なことは、PDO においては、プリペアドステートメントを利用します。
とある、PHPの初心者向けの書籍のせいで、誤用が広まっている…
そもそも、これがSQLインジェクションに有用な関数なのであれば、PHPの開発チームは htmlspecialchars
って関数名はつけないでしょう。おかしいと思いません?(→ 某書籍の作者さん、どうですか?)
文字コードは「$dsn」で「$dbh->query('SET NAMES utf8');」
DBを指定するときに文字コードを指定すべきなのですね。
今のバージョンでは、そうすべきです。古いバージョンのPHPでは、SET NAMES utf8 を使うことは許容されます。(それ以外に方法がないから)
いらない「$dbh=null;」
こちらはSQLへの接続を閉じるために必要かと思っておりましたが不要なのでしょうか。
こちらは、接続が切れたら勝手に NULL になります。あえて書く必要はありません。
ここで exit すると、htmlが崩れる
これはexitの後が表示されなくなってしまうという事なのでしょうか。
exit; で処理が止まるので、<html> 以下は表示されるが、</body></html> の部分は出力されなくなりますね。
html
1<html> 2<body> 3... 4
となって、</body> や </html> がないって、気持ち悪いですよね…
html 的には、</body> や </html>は省略可能ですが…
欲を言えばこうしたい
こちらのソースでは、PHP処理をHTML内より抜き取り、HTMLには別のコードを追加して
おりますが、そこではエラーの場合に(
INPUT_POST)という場所から変数を持ってきて更新するという処理が書かれているのでしょうか。
php
1if (null != filter_input_array(INPUT_POST)) { 2... 3}
の部分ですね。
この if 文がないと、$sql = 'UPDATE mst_staff SET name=?,password=? WHERE code=?';
以下の部分も実行され、UPDATE mst_staff SET name='',password='' WHERE code=''
というSQLが実行されてしまいます。
POSTされたデータが存在しないなら、あえてSQLを実行する意味はありません。
投稿2016/09/12 06:23
編集2016/09/12 10:26
退会済みユーザー
総合スコア0
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント

退会済みユーザー
2016/09/12 10:50
関連した質問
受付中
回答2
クリップ0
更新
2023/01/17
PHPでSQL文が正しく入力されない
受付中
回答1
クリップ0
更新
2023/01/19
気づけばプロ並みPHP改訂版③ DB接続
受付中
回答1
クリップ2
更新
2023/01/29
jsとgasによるdoPostとfetch間によるhtmlファイルの受け渡しについて
解決済
回答2
クリップ0
更新
2023/01/16
PHPで変数をechoした後に改行しようとするとなぜかエラーが出る
解決済
回答1
クリップ0
更新
2023/01/18
PHPでお問い合わせ入力データをデータベースに保存したい
受付中
回答2
クリップ0
更新
2023/01/29
JavaScriptでフォームの回答をクエリで引き継ぎ
受付中
回答1
クリップ0
更新
2023/01/29
PHPのプログラムを組んでいたらSQLSTATE[HY093]: Invalid parameter numberといエラーが出てきて調べても全く直し方が分かりませんでした
解決済
回答1
クリップ0
更新
2023/01/26
MySQLで検索機能(PHP)
同じタグがついた質問を見る
MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。
PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。