質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.45%

  • PHP

    24602questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • SQL

    3091questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • データベース

    858questions

    データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

  • PDO

    392questions

    PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

DBへ登録するときの方法はPDOとsqlどっちがいいのか

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 1,728

kuzurotto

score 395

タイトルの通りなのですが、
DBへ登録するときの方法はPDOとsqlとかっていう2種類の方法がありますよね?

Ⅰ.何故2種類あって、どっちを使った方がいいのでしょうか?

オブジェクト型?手続き型?よくわかりませんが、
書籍の多くにはsqlでの記述が多い中
ネットでの情報の多くにはPDOでの記述の方が多いように感じられます。

私の持っている書籍にもsqlでの記述しかありません。
その為、書籍で勉強して、分からないことをいざネットで聞くと
PDOとか見慣れない記述での返答が多い為、
「え?なにコレ?」ってなってしまいます。(過去の話)

Ⅱ.参考までに教えて頂きたいのですが、
下記サンプル記述をPDOでの記述にするとしたら
どのようになるのでしょうか?

Ⅲ.とりあえずPDOはアロー演算子で色々指定して展開させていく、
みたいな認識なのですがこの認識で大丈夫でしょうか?

また、その場合、チートシートではありませんが
->の先で使えるものの一覧のようなものはないのでしょうか?

おさらいの意味も含めてⅠとⅡとⅢについて解説お願いします。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>アドレス登録</title>
</head>
<body>
<?php

$con = mysql_connect('127.0.0.1', 'root', '1234');
if (!$con) {
  exit('データベースに接続できませんでした。');
}

$result = mysql_select_db('phpdb', $con);
if (!$result) {
  exit('データベースを選択できませんでした。');
}

$result = mysql_query('SET NAMES utf8', $con);
if (!$result) {
  exit('文字コードを指定できませんでした。');
}

$no   = $_REQUEST['no'];
$name = $_REQUEST['name'];
$tel  = $_REQUEST['tel'];

$result = mysql_query("INSERT INTO address(no, name, tel) VALUES('$no', '$name', '$tel')", $con);
if (!$result) {
  exit('データを登録できませんでした。');
}

$con = mysql_close($con);
if (!$con) {
  exit('データベースとの接続を閉じられませんでした。');
}

?>
<p>登録が完了しました。<br /><a href="index.html">戻る</a></p>
</body>
</html>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+11

本題に入りたいところですが,質問のコードには以下のような問題点があります.

  • SQLインジェクションに対する致命的な脆弱性がある.これがある場合アプリケーションを絶対にWeb上に公開してはいけないレベル.
  • HTMLとロジックが混ざっている.HTMLを書き始める前にページ表示に必要なすべての変数を用意しておき,それが終わったらHTMLの書き出しだけに徹するべき.
  • HTMLを書いている最中にdieで異常終了すると壊れたHTMLだけが残ってしまう.異常終了する可能性が消えるまでHTMLを書き出してはいけない.

タイトルの通りなのですが、 
DBへ登録するときの方法はPDOとsqlとかっていう2種類の方法がありますよね?

言葉の定義を一応はっきりさせておきます.

  • SQL…データベースを扱う共通言語
  • MySQL…データベース製品の1つ
  • mysql関数群…MySQLをPHPから操作するための関数群で,PHP5.3で非推奨,PHP7.0で廃止.
  • mysqliクラス/mysqli関数群…MySQLをPHPから操作するためのクラス/関数群で,↑の後継.
  • PDOクラス…あらゆるデータベースを共通に扱うためのクラス.

Ⅰ.何故2種類あって、どっちを使った方がいいのでしょうか?

どの選択肢を採用するかについてですが,まず,記述量や例外処理のしやすさを考慮すると,オブジェクト指向は避けて通れません.関数名をみてもらうと分かりますが,mysqliの手続き型は関数名からして長いため,非常に記述が冗長になります. (mysqli_stmt_bind_param mysqli_stmt_get_result とかとくに酷い例)

よって,mysqliクラスかPDOクラスかの2択になります.ここは好みも分かれますが,一般的にPDOのほうが推奨される理由としては

  • PDO1つだけ覚えておけばすべてのデータベースに応用が効く
  • mysqliが多機能な一方,PDOのほうがメソッドの数や利用されるクラスの種類も少なくてシンプル

といったものがあるでしょう.

Ⅲ.とりあえずPDOはアロー演算子で色々指定して展開させていく、 
みたいな認識なのですがこの認識で大丈夫でしょうか?

最初はそんな感じでいいと思います.手続き型のときの第1引数が->を生やされたオブジェクトになる,というイメージです.多くの場合はこの法則が成立します.

Ⅱ.参考までに教えて頂きたいのですが、 
下記サンプル記述をPDOでの記述にするとしたら 
どのようになるのでしょうか?

指摘した問題点もすべて修正したコードを掲載します.

<?php

// $_REQUESTの使用は非推奨
// $_POSTを利用してもいいが,エラー抑止のためのチェックが面倒なのでfilter_inputを使う
$no = filter_input(INPUT_POST, 'no');
$name = filter_input(INPUT_POST, 'name');
$tel = filter_input(INPUT_POST, 'tel');

try {

    // MySQLに接続してphpdbを選択,文字コードはutf8
    $pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1;charset=utf8', 'root', '1234', [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // SQLのエラーに関してもPDOExceptionをスロー
    ]);

    // プリペアドステートメントを発行
    $stmt = $pdo->prepare("INSERT INTO address(no, name, tel) VALUES (?, ?, ?)");

    // ? の部分に値を文字列として安全にあてはめて実行
    $stmt->execute([$no, $name, $tel]);

} catch (PDOException $e) {

    // 異常があった場合ここにジャンプする
    // テキストとして「500 Internal Server Error」でメッセージを出して終了
    header('Content-Type: text/plain; charset=UTF-8', true, 500);
    exit("ERROR: {$e->getMessage()}");

}

// HTMLとして結果を出力
// (文字コードをここで指定すればmetaタグは省略可能)
header('Content-Type: text/html; charset=UTF-8');

?>
<!DOCTYPE html>
<title>アドレス登録</title>
<p>
    登録が完了しました。
    <a href="index.html">戻る</a>
</p>

【関連記事】


【追記】

このコードには形式的にはCSRF脆弱性があるので,余力があればそれについても調査してみてください.

(但し今回の場合はメールアドレスを登録しなければならないので,必ずしも脆弱性とは言えません.またCSRFは脆弱性の中では比較的軽微なほうです.)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/19 05:50

    ありがとうございます!
    リンク先拝見させていただきます!

    キャンセル

  • 2016/06/19 17:04 編集

    もしお時間がありましたらこちらを見て頂きたいです。

    $stmt = $pdo->prepare("INSERT INTO address(no, name, tel) VALUES (?, ?, ?)");

    $stmt = $pdo->prepare("INSERT INTO address VALUES (?, ?, ?)");

    2種類の記述方法があり、
    カラム名を指定している記述と
    カラム名を指定していない記述になりますが
    どちらも動作は同じでしょうか?

    登録するものが5個ぐらいならいいのですが、30個あることを考えると...
    カラム名を指定しなくてもいいのだとしたら、
    可読性も楽になるからいいなぁ~なんて思っています。

    キャンセル

  • 2016/06/19 17:22 編集

    カラムをすべて指定する場合は省略可能ですが,実際は先頭カラムに自動インクリメントされる主キーを持っているのが普通なので,省略できるケースは少なくなってしまうと思います.

    キャンセル

  • 2016/06/20 07:00

    ありがとうございます!

    キャンセル

0

pdo だと、ラッパークラスを作成しておけば、使い回しもできるのと
mysql,sqlserver の両方に接続可能で
こっちを覚えておくと
汎用的にシステムに対応する事が出来ると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/20 08:27

    ありがとうございいます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.45%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    24602questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • SQL

    3091questions

    SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

  • データベース

    858questions

    データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

  • PDO

    392questions

    PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。