クーポンで割引率を出す

PHPのシンタックス

  1. HOME
  2. フォーム~クーポンセール~

割引率と価格を安全に渡す

このページでご購入で20% OFFになります!

値の改ざん防止

割引率や商品にクーポンコードや商品IDを付けておき、サーバーとやり取りする情報は識別IDだけにしておく!
コードやIDを引数にして別ファイルに用意した配列やデータベースから取り出した値を使って表示したり計算をする。

割引率と価格の値の共有ファイル

<?php
//配列データは外部ファイルやデータベースからの読み込みにした方がいい
$couponList = ["kkpp" => 0.75, "nnpp" => 0.8, "aapp" => 0.85];
$priceList = ["xp10" => 12000, "win11" => 38000];

function getCouponRate($code) //コードで割引率を調べて返す
{
  global $couponList;
  $isCouponCode = array_key_exists($code, $couponList); //該当するコードがあるかチェック
  if ($isCouponCode) {
    return $couponList[$code]; //割引率を返す
  } else {
    return NULL; //見つからなかったらNULLを返す
  }
}

function getPrice($id) //商品IDで価格を調べて返す
{
  global $priceList;
  $isGoodsID = array_key_exists($id, $priceList);
  if ($isGoodsID) {
    return $priceList[$id]; //価格を返す
  } else {
    return Null; //見つからなかったらNULLを返す
  }
}
array_key_exists()を使って問合せのあったクーポンコードと商品IDのキーが配列に存在するかどうかを事前にチェックしています。結果がfalseのときはNULL(未定義)を返します。

POSTされたリクエストを処理

<?php
require_once("es.php"); //フォーム~入力データのチェック~で参照してね
if (!checkEn($_POST)) { //文字エンコードの検証
  $encoding = mb_internal_encoding(); //PHPが使うエンコードを調べる
  $err = "Encoding Error! The espected encoding is" . $encoding;
  exit($err); //エラーメッセージを出してコードのキャンセルする
}
$_POST = es($_POST); //HTMLエスケープ(xss対策)
?>

<?php
$errors = [];
if (isset($_POST['couponCode'])) {
  $couponCode = $_POST['couponCode'];
} else {
  $couponCode = ""; //未設定
}

if (isset($_POST['goodsID'])) {
  $goodsID = $_POST['goodsID'];
} else {
  $goodsID = ""; //未設定
}
?>

<?php
require_once("saleData.php");
$discount = getCouponRate($couponCode); //割引率
$tanka = getPrice($goodsID); //単価
if (is_null($discount) || is_null($tanka)) {
  $err = '<div class = "error">不正な操作がありました。</div>';
  exit($err);
}
?>

<?php
if (isset($_POST['kosu'])) {
  $kosu = $_POST['kosu'];
  if (!ctype_digit($kosu)) {
    $errors[] = "個数は整数で入力してください。";
  }
} else {
  $errors[] = "個数が未設定";
}
?>

<?php
if (count($errors) > 0) {
  echo '<ol class = "error">';
  foreach ($errors as $value) {
    echo "<li>", $value, "</li>";
  }
  echo "</ol>";
} else {
  $price = $tanka * $kosu;
  $discount_price = floor($price * $discount);
  $off_price = $price - $discount_price;
  $off_per = (1 - $discount) * 100;
  $tanka_fm = number_format($tanka);
  $discount_price_fm = number_format($discount_price);
  $off_price_fm = number_format($off_price);

  echo "単価:{$tanka_fm}円、", "個数:{$kosu}個", "<br><br>";
  echo "金額:{$discount_price_fm}円", "<br>";
  echo "(割引:-{$off_price_fm}円、", "{$off_per}% OFF)", "<br>";
}
?>

<!-- 戻りボタン -->
<form method="POST" action="sale.php">
  <ul class="nolist">
    <li><input type="submit" value="戻る"></li>
  </ul>
</form>

購入ページ

<?php
require_once("es.php"); //フォーム~入力データのチェック~で参照してね
if (!checkEn($_POST)) { //文字エンコードの検証
  $encoding = mb_internal_encoding(); //PHPが使うエンコードを調べる
  $err = "Encoding Error! The espected encoding is" . $encoding;
  exit($err); //エラーメッセージを出してコードのキャンセルする
}
$_POST = es($_POST); //HTMLエスケープ(xss対策)
?>

<!-- 割引率と単価の値を直接書かずに式で求める -->
<?php
require_once("saleData.php");
$couponCode = "nnpp";
$goodsID = "win11";

//コードとIDから割引率と単価を調べる
$discount = getCouponRate($couponCode);
$tanka = getPrice($goodsID);

//割引率と単価に値があるかチェック
if (is_null($discount) || is_null($tanka)) {
  $err = '<div class = "error">不正な操作がありました。</div>';
  exit($err);
}
?>

<?php
$off = (1 - $discount) * 100;
if ($discount > 0) {
  echo "<b>このページでご購入で{$off}% OFFになります!</b>";
}
$tanka_fm = number_format($tanka);
?>

<!-- 入力フォーム -->
<form method="POST" action="discountCoupon.php">
  <!-- 隠しフィールドにコードとIDを設定してPOSTする -->
  <input type="hidden" name="couponCode" value="<?php echo $couponCode; ?>">
  <input type="hidden" name="goodsID" value="<?php echo $goodsID; ?>">
  <ul class="nolist">
    <li><label>単価:<?php echo $tanka_fm; ?>円</label></li>
    <li><label>個数:<input type="number" name="kosu" value="<?php echo $kosu; ?>"></label></li>
    <li><input type="submit" value="購入する"></li>
  </ul>
</form>