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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PDO

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

SQL

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

PHP

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

データベース

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

Q&A

解決済

2回答

3522閲覧

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

earnest_gay

総合スコア615

PDO

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

SQL

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

PHP

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

データベース

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

0グッド

2クリップ

投稿2016/06/17 14:47

タイトルの通りなのですが、
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>

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

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

  • 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での記述にするとしたら
どのようになるのでしょうか?

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

html

1<?php 2 3// $_REQUESTの使用は非推奨 4// $_POSTを利用してもいいが,エラー抑止のためのチェックが面倒なのでfilter_inputを使う 5$no = filter_input(INPUT_POST, 'no'); 6$name = filter_input(INPUT_POST, 'name'); 7$tel = filter_input(INPUT_POST, 'tel'); 8 9try { 10 11 // MySQLに接続してphpdbを選択,文字コードはutf8 12 $pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1;charset=utf8', 'root', '1234', [ 13 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // SQLのエラーに関してもPDOExceptionをスロー 14 ]); 15 16 // プリペアドステートメントを発行 17 $stmt = $pdo->prepare("INSERT INTO address(no, name, tel) VALUES (?, ?, ?)"); 18 19 // ? の部分に値を文字列として安全にあてはめて実行 20 $stmt->execute([$no, $name, $tel]); 21 22} catch (PDOException $e) { 23 24 // 異常があった場合ここにジャンプする 25 // テキストとして「500 Internal Server Error」でメッセージを出して終了 26 header('Content-Type: text/plain; charset=UTF-8', true, 500); 27 exit("ERROR: {$e->getMessage()}"); 28 29} 30 31// HTMLとして結果を出力 32// (文字コードをここで指定すればmetaタグは省略可能) 33header('Content-Type: text/html; charset=UTF-8'); 34 35?> 36<!DOCTYPE html> 37<title>アドレス登録</title> 38<p> 39 登録が完了しました。 40 <a href="index.html">戻る</a> 41</p>

【関連記事】


【追記】

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

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

投稿2016/06/17 18:28

編集2016/06/18 01:06
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

earnest_gay

2016/06/18 20:50

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

2016/06/19 08:10 編集

もしお時間がありましたらこちらを見て頂きたいです。 $stmt = $pdo->prepare("INSERT INTO address(no, name, tel) VALUES (?, ?, ?)"); $stmt = $pdo->prepare("INSERT INTO address VALUES (?, ?, ?)"); 2種類の記述方法があり、 カラム名を指定している記述と カラム名を指定していない記述になりますが どちらも動作は同じでしょうか? 登録するものが5個ぐらいならいいのですが、30個あることを考えると... カラム名を指定しなくてもいいのだとしたら、 可読性も楽になるからいいなぁ~なんて思っています。
mpyw

2016/06/19 08:22 編集

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

2016/06/19 22:00

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

0

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

投稿2016/06/18 01:13

YK1037

総合スコア236

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

earnest_gay

2016/06/19 23:27

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問