PDOをもっと楽に使うための自作クラス

2014年7月10日

こんにちは、榊原です。
セキュリティが脆弱という噂のPHP(実際にはどんな言語でもセキュリティちゃんとしないと脆弱ですがw)。よくセキュリティを高めるためにPDOを使いなさい!とあちこちで語られますが、実際には面倒なんですよね。意外とこいつ使いにくい。
そこで、私がPDOを使いやすくするために書いてたクラスをご紹介します。

 

SELECT文や単純SQL

先にこの自作クラスの使い方を説明します。単純なsqlは
 

$this->sqlarray($sql,$data);

 
で取り出します。第一引数にsqlを書いて、第二引数に連想配列でデータを放り込みます。
例えば、セキュリティゆるゆるの
 

$sql = "SELECT * FROM hoge WHERE id = ".$_GET["id"];

 
とかだったら、変数部分の$_GET[“id”]を?に置き換えまして

$sql = "SELECT * FROM hoge WHERE id = ?";
$data = array($_GET["id"]);

 
として先ほどのファンクションに放り込んだら応答を連想配列形式に直して返してくれます。連想配列の順番と?の順番は対応するようにします。
連想配列形式にして返してくれるというのが肝で、while ($row = $sth->fetch(PDO::FETCH_ASSOC)) を毎回する手間を省きます。これ可読性低かったので・・・。
 

INSET文

で、インサートはもっと簡単。
 

$this->PDOinsert($postdata,$table);

 
となっており、$postdataにkeyをつけた連想配列を入れて、インサートするテーブル名を第二引数に渡すだけです。
例えば、idが5、nameがhogehogeというデータをインサートしたかったら、

$postdata = array('id'=>5,'name'=>'hogehoge');

 
というデータを作ればいいだけです。わざわざupdate文を書く必要はないです。ちなみに返り値は、last_insert_id()を返します。

UPDATE文

UPDATE文は、INSET文にWHERE文用の$priがついたものです。
 

$this->PDOupdate($postdata,$pri,$table);

 
この$priも連想配列でwhere文を生成しますので、$postdataと同様にkey=>valueの形で連想配列を作ればOKです。
 

クラスの使い方

使い方ですが、
1.以下のクラスをコピペしてそのファイルをincludeする
2.使いたいクラスをつくる時は、「class Login extends _common」みたいな感じでextends _commonをつける
3.データベースのユーザ名、パスワードはそれぞれDB_USER, DB_PASSWORDという名前でdefineで定義しておく
ということをすればOKです。
 
ここまで書いて思ったけど、この説明で使える人だったら、普通にこういうクラスを自作したりセキュリティ対策やってますよね。また気が向いたら、全部分解してfunction単体で使えるようにして紹介しようかしら。
 
それでは、また。

クラス

/*///////////////////////////////////////////////////////////////////
		共通メソッド
/////////////////////////////////////////////////////////////////////*/

class _common {
	protected $cn;

	/*///////////////////////////////////////////////////////////////////
		データベースへのログイン
	/////////////////////////////////////////////////////////////////////*/
	function db_connect($db_name){	//DBへの接続メソッド
		$server = "mysql:host=".DB_HOST."; dbname=$db_name";
		try {
			$db_connect = new PDO($server, DB_USER, DB_PASSWORD,array(
				PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET `utf8`"
			));
			$this->cn = $db_connect;
		} catch(PDOException $e){
			var_dump($e->getMessage());
		}
	}
	
	/*///////////////////////////////////////////////////////////////////
		データベースからの取り出し(array)
	/////////////////////////////////////////////////////////////////////*/
	function sqlarray($sql,$data=null){
		$sth = $this->cn->prepare($sql);
		if($data!=null){
			$sth->execute($data);
		}else{
			$sth->execute();
		}
		$i = 0;
		while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
			$return[] = $row;
		}
		$sth->closeCursor();
		return $return;
	}

	/*///////////////////////////////////////////////////////////////////
		インサート
	/////////////////////////////////////////////////////////////////////*/
	
	function PDOinsert($postdata,$pri,$table){
		$i = 0;
		foreach ($postdata as $key => $value) {
			$value = h($value);
			$update .= " ${key},";
			$change  .= " ?,";
			$updata["$i"] = $value;
			$i++;
		}
		$update = substr($update, 0, -1); 
		$change = substr($change, 0, -1); 

		$sql = "INSERT INTO ${table} (${update}) VALUES (${change})";
		$sth = $this->cn->prepare($sql);
		$sth->execute($updata);

		$sql = "SELECT last_insert_id() as ID";
		$lastid = $this->sqlarray($sql);
		$lastid = $lastid[0]["ID"];
		return $lastid;
	}

	/*///////////////////////////////////////////////////////////////////
		アップデート
	/////////////////////////////////////////////////////////////////////*/

	function PDOupdate($postdata,$table){
		foreach ($postdata as $key => $value) {
			if(isset($value)){
				$value = h($value);
				$update .= " ${key}=?,";
				$updata[] = $value;
			}
		}
		$update = substr($update, 0, -1); 

		foreach ($pri as $key => $value) {
			if(isset($value)){
				$value = h($value);
				$pritext .= " ${key}=${value} AND";
			}
		}
		$pritext = substr($pritext, 0, -3); 

		$sql = "UPDATE $table SET ${update} WHERE ${pritext}";
		$sth = $this->cn->prepare($sql);
		$sth->execute($updata);
		return TRUE;
	}
}

slackチームに参加下さい

ng-onsenui2.slack.com

OnsenUI2(Angular2)について知見を共有する場です。Angular2に限ってOnsenUI2を議論できる場がなかったのでつくりました。これから使い始めるという方はぜひご参加ください。
https://ng-onsenui2.herokuapp.com/

Ionic2.slack.com

日本語情報が少ないのでこちらで知見を共有できればと思います。お陰様で参加者100名を超えました。ありがとうございます。
https://ionic2-ja.herokuapp.com