考え、感じる、Web制作。

Web制作の学習や情報についての記事が中心です。

DB操作 newsfeed制作2

newsfeed制作2

今回もnewsfeedの制作を続ける。

init.php追記

下記のDB接続確立前準備の記述を短くしたい。個別記事側でも記述するため。

$db_connect='mysql:host=localhost;dbname=newsfeed;charset=utf8';
$db_user='root';
$db_pass='root';

これらをinit.phpで先に定義してしまう。定義にはdefine文を使う。

  define('DB_CONNECT','mysql:host=localhost;dbname=ys_newsfeed;charset=utf8');
  define('DB_USER','root');
  define('DB_PASS','root');

これにより、index.phpの上記の宣言文が削除できる。try{}の中身を下記に書き換える。

$dbh=new PDO(DB_CONNECT,DB_USER,DB_PASS);

news.phpの記述1

前準備~書き出し準備までの流れを記す。

前準備

まず、init.phpを読み込み、$dbhを初期化する。

require_once dirname(__FILE__).'/init.php';
$dbh="";

リダイレクト

url直打ちをリダイレクトさせる。ROOT_URLもinit.phpでurlをdefineしておく。

if(!isset($_GET['news_id'])||!is_numeric($_GET['news_id'])){
  header('ROOT_URL.index.php');
  exit;
}
DB接続のtry

index.phpと同じ。

try{
  $dbh=new PDO(DB_CONNECT,DB_USER,DB_PASS);
}catch(Exception $e){
  //echo $e->getMessage();エラーメッセージを捕まえて表示させる
  exit('ランタイムエラーが発生しました');
}

SQLインジェクション対策

DBに対する攻撃を予防するための記述。これによりSQLインジェクションを予防し、DBを守ることができる。

$sql="SELECT * FROM news WHERE news_id=:news_id;";
$stmt=$dbh->prepare($sql);
$stmt->bindParam(':news_id',$news_id);
SQLインジェクション

SQLインジェクション(英: SQL Injection)とは、アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。また、その攻撃を可能とする脆弱性のこと。
ウィキペディアより

http://ja.wikipedia.org/wiki/SQL%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3

DBを改竄、削除されるおそれがある攻撃に対し防御策を施す必要がある。

処理の流れ
  1. $sqlsql命令を代入するが、WHEREを確定させず:news_idという入れ物だけ準備。
  2. prepareで自動エスケープを掛けた命令を$stmtに格納。
  3. bindParamで変数を参照値として固定。

レコード取得

$stmtに格納されたsql命令をクエリに投げる。

$stmt->execute();

取得データのfetch

$rowに配列変数として取得したDBのレコードを格納。格納できない場合はfalseが入る。

$row=$stmt->fetch(PDO::FETCH_ASSOC);

レコード格納失敗時の処理

レコード格納が失敗した場合はリダイレクトさせる。

if(false===$row){
  header('Location:http://ROOT_URL/index.php');
  exit;
}

書き出し準備

foreachで変数名の宣言と値の代入を同時に処理。

foreach($row as $k=>$v){
  $$k=$v;
}

news.phpの記述2

body内の書き出し部の記述。
前準備をしっかりしていたため、大変シンプルである。

<?php
print"<dt>".h($news_headline).h($news_date)."</dt>\n";
print"<dd>".nl2br(h($news_article));
print"</dd>\n";
?>

感想

セキュリティ関連の構文は理解が難しい。自分や身内だけが使う前提でvbaを触っていただけのころは気にしていなかったというのもあるが、見慣れない命令と処理系は書き慣れが必要かもしれない。今の時点では十分に理解できているとは言えないが、DB操作の習得で肝になりそうな点が掴めた、ということで良しとしたい。