📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
| 622行目: | 622行目: | ||
?> | ?> | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | |||
== パラメータをエスケープする == | |||
SQL文で使用する値が固定値の場合は問題無いが、例えば、フォーム等に入力した条件を使用してSQL文を生成する場合、<br> | |||
SQLインジェクション攻撃を防ぐためにパラメータをエスケープする必要がある。<br> | |||
<br> | |||
エスケープするためには、<code>mysqli_real_escape_string</code>関数を使用する。<br> | |||
<br> | |||
string mysqli_real_escape_string(mysqli link_identifier, string escapestr) | |||
現在使用している文字コードで、escapestrの特殊文字をエスケープして、mysqli_query関数で安全に利用できる形式に変換する。 | |||
バイナリデータを挿入する場合は、必ず、mysqli_real_escape_string関数を使用しなければならない。 | |||
引数: | |||
link_identifier MySQLリンクID | |||
escapestr エスケープされる文字列 | |||
戻り値: | |||
成功する場合はエスケープ後の文字列、失敗する場合はfalseを返す。 | |||
<br> | |||
マジッククオートを有効化している場合も似たような効果が得られるが、<br> | |||
マジッククオートは無効化して、<code>mysqli_real_escape_string</code>関数を使用して必要に応じてエスケープすることが推奨されている。<br> | |||
<br> | |||
例えば、SQL文において、値にシングルクォーテーション(')等が含まれる場合、<br> | |||
<code>mysqli_real_escape_string</code>関数を実行することで、SQL文で直接記述できない値に対して<code>\</code>を付加してエスケープ処理を自動的に行う。<br> | |||
<syntaxhighlight lang="php"> | |||
$test = "book's"; | |||
mysqli_real_escape_string($test); //--> $test = "book¥'s" | |||
</syntaxhighlight> | |||
<br> | |||
以下の例では、POSTで送信されたユーザ名とパスワードをエスケープ処理を実行してSQL文を生成している。<br> | |||
<syntaxhighlight lang="php"> | |||
function quote_smart($link, $value) | |||
{ | |||
// 数値以外をクオートする | |||
if(!is_numeric($value)) | |||
{ | |||
$value = "'" . mysqli_real_escape_string($link, $value) . "'"; | |||
} | |||
return $value; | |||
} | |||
$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s", quote_smart($_POST['username']), quote_smart($_POST['password'])); | |||
mysqli_query($link, $query); | |||
</syntaxhighlight> | |||
<br> | |||
以下の例では、上記のセクションのINSERT文を書き直している。<br> | |||
<syntaxhighlight lang="php"> | |||
<?php | |||
function quote_smart($link, $value) | |||
{ | |||
// 数値以外をクオートする | |||
if(!is_numeric($value)) | |||
{ | |||
$value = "'" . mysqli_real_escape_string($link, $value) . "'"; | |||
} | |||
return $value; | |||
} | |||
$link = mysqli_connect('localhost', 'user', 'passwd', 'uriage'); | |||
if(!$link) | |||
{ | |||
die('接続失敗です。'.mysqli_error()); | |||
} | |||
print('<p>接続に成功しました。</p>'); | |||
$db_selected = mysqli_select_db($link, 'uriage'); | |||
if(!$db_selected) | |||
{ | |||
die('データベースの選択に失敗しました。'.mysqli_error()); | |||
} | |||
print('<p>uriageデータベースを選択しました。</p>'); | |||
// 文字コードをutf8mb4 に変更 | |||
if(!mysqli_set_charset($link, "utf8mb4")) | |||
{ | |||
printf('文字コードの変更に失敗しました。'.mysqli_error($link)); | |||
exit(); | |||
} | |||
print('<p>レコードを追加します。</p>'); | |||
$id = 5; | |||
$name = "Toyama's Wine"; | |||
$sql = sprintf("INSERT INTO shouhin(id, name) VALUES(%s, %s)", quote_smart($link, $id), quote_smart($link, $name)); | |||
print('<p>エスケープ後のデータ:'.quote_smart($name).'</p>'); //--> $name = Toyama¥'s Wine | |||
$result_flag = mysqli_query($link, $sql); | |||
if(!$result_flag) | |||
{ | |||
die('INSERTクエリが失敗しました。'.mysqli_error()); | |||
} | |||
print('<p>追加後のレコードを取得します。</p>'); | |||
$result = mysqli_query($link, 'SELECT id,name FROM shouhin'); | |||
if(!$result) | |||
{ | |||
die('SELECTクエリが失敗しました。'.mysqli_error()); | |||
} | |||
while($row = mysqli_fetch_assoc($result)) | |||
{ | |||
print('<p>'); | |||
print('id='.$row['id']); | |||
print(',name='.$row['name']); | |||
print('</p>'); | |||
} | |||
$close_flag = mysqli_close($link); | |||
if($close_flag) | |||
{ | |||
print('<p>切断に成功しました。</p>'); | |||
} | |||
?> | |||
</syntaxhighlight> | |||
<br> | |||
SQL文に含まれていたシングルクオーテーションがエスケープ処理されて、Toyama¥'s Wineに変換されていることが確認できる。<br> | |||
このように、'のような特殊な意味を持つ文字を、単なる文字の'として処理することができる。<br> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Web]] | [[カテゴリ:Web]] | ||