- 기존 방식의 문제점
- $sql = "select * from member where id='$id' and pass='$pwd'"
$result = mysql_query($sql);
의 경우 SQL Injection 문제가 발생 $pwd = 'test or 1=1;' 과 같은 문장이 들어오게 된다면
DB 에서는 1=1 에서 참으로 발생되어 OR 구문을 참으로 인식한다. - DB Vender 마다 사용하는 Connection 부분과 Query 부분이 달라 일관성 결여.
- $sql = "select * from member where id='$id' and pass='$pwd'"
- PDO
- 일관된 방법으로 DB에 접근 데이터를 가지고 올 수 있다. 안의 변수만 변경 해주면 된다.
- 사용법 1.
try
{
// MySQL PDO 객체 생성
// mysql을 다른 DB로 변경하면 다른 DB도 사용 가능
$pdo
=
new
PDO(
"mysql:host=$host;dbname=$db"
,
$user
,
$pass
);
// 에러 출력
$pdo
->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch
(Exception
$e
) {
echo
$e
->getMessage();
}
$pdo = null; // 커넥션 닫기.// 에러 출력하지 않음
$pdo
->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
// Warning만 출력
$pdo
->setAttribute
(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
// 에러 출력
$pdo
->setAttribute
(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// SQL 실행.$st
=
$pdo
->prepare(
'INSERT INTO table (col1) VALUE (`val1`)'
);
$st
->execute();
// SQL INJECTION 방지방법// 이름 없는 placeholder. SQL 인젝션 방지.
$st
=
$pdo
->(
'INSERT INTO table (col1, col2, col3) values (?, ?, ?)'
);
// 값을 넘겨주고 실행
$st
->execute([
'val1'
,
'val2'
,
'val2'
]);
// 이름 있는 placeholder. SQL 인젝션 방지
$st
=
$pdo
->(
"INSERT INTO table (col1, col2, col3) value (:col1, :col2, :col3)"
);
// 값을 넘겨주고 실행
$st
->execute([
':col1'
=>
'val1'
,
':col2'
=>
'val2'
,
':col3'
=>
'val3'
]);
- 사용법 2. ( 생활 코딩 )
- INSERT, UPDATE, DELETE# INSERT
$stmt=
$dbh
->prepare(
"INSERT INTO topic (title, description, created) VALUES (:title, :description, now())"
);
$stmt
->bindParam(
':title'
,
$title
);
$stmt
->bindParam(
':description'
,
$description
);
$title
=
$_POST
[
'title'
];
$description
=
$_POST
[
'description'
];
$stmt
->execute();
# DELETE$stmt
=
$dbh
->prepare(
'DELETE FROM topic WHERE id = :id'
);
$stmt
->bindParam(
':id'
,
$id
);
$id
=
$_POST
[
'id'
];
$stmt
->execute();
#UPDATE$stmt
=
$dbh
->prepare(
'UPDATE topic SET title = :title, description = :description WHERE id = :id'
);
$stmt
->bindParam(
':title'
,
$title
);
$stmt
->bindParam(
':description'
,
$description
);
$stmt
->bindParam(
':id'
,
$id
);
$title
=
$_POST
[
'title'
];
$description
=
$_POST
[
'description'
];
$id
=
$_POST
[
'id'
];
$stmt
->execute();
#SELECT$dbh
=
new
PDO(
'mysql:host=localhost;dbname=opentutorials'
,
'root'
,
'111111'
);
$stmt
=
$dbh
->prepare(
'SELECT * FROM topic'
);
$stmt
->execute();
$list
=
$stmt
->fetchAll();
if
(!
empty
(
$_GET
[
'id'
])) {
$stmt
=
$dbh
->prepare(
'SELECT * FROM topic WHERE id = :id'
);
$stmt
->bindParam(
':id'
,
$id
, PDO::PARAM_INT);
$id
=
$_GET
[
'id'
];
$stmt
->execute();
$topic
=
$stmt
->fetch();
}
# 전체 출력. fetchAll() 을 사용 하면 for문으로 출력.
foreach
(
$list
as
$row
) {
echo
"<li><a href=\"?id={$row['id']}\">"
.htmlspecialchars(
$row
[
'title'
]).
"</a></li>"
;
# 1개의 정보 Get 1 Row 일 경우.( $topic 변수 )if
(!
empty
(
$topic
)){
?>
<h2><?=htmlspecialchars(
$topic
[
'title'
])?></h2>
<div
class
=
"description"
>
<?=htmlspecialchars(
$topic
[
'description'
])?>
</div>
- 사용법 3#get rowCount
$del = $dbh->prepare('Delete from fruit');
$del -> execute();
print("Return number of Rows that were deleted:\n");
$count = $del -> rowCount();
print("Deleted $count rows, \n"); - 사용법 4 [LIKE CONDITION]
If you use PDO bindParam to do a search with a LIKE condition you cannot put the percentages and quotes to the param placeholder '%:keyword%'.
This is WRONG:
"SELECT * FROM `users` WHERE `firstname` LIKE '%:keyword%'";
The CORRECT solution is to leave clean the placeholder like this:
"SELECT * FROM `users` WHERE `firstname` LIKE :keyword";
And then add the percentages to the php variable where you store the keyword:
$keyword = "%".$keyword."%";
'Programming > PHP' 카테고리의 다른 글
bindParam vs bindValue (0) | 2016.06.30 |
---|---|
Namespace (0) | 2016.06.30 |