📢 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]]