FuelPHPのNumクラスで数値のマスク処理を行う

公式サイトのドキュメントを眺めていたら、
クレカ関連の操作に便利な関数が用意されていることに気が付いたので備忘録がてらメモします。

ほぼ公式サイトの写経なので詳しく知りたい方は下記をご覧になるといいかと思います。
Num – クラス – FuelPHP ドキュメント

使い方

文字列マスク系の関数は2種類あります。
ちなみにNumクラスなので引数は数値を想定しているようです。

mask_string($string = ”, $format = ”, $ignore = ‘ ‘)

第1引数の数値を第2引数のフォーマットで変換します。
第3引数は指定するフォーマット文字列のから無視する文字列を指定するようです。

// $ignoreの指定なし
print_r(Num::mask_string('1234263583742938', '*****'));
> *****

// $ignore指定
print_r( Num::mask_string('1111222233334444', '**** - **** - **** - 0000', ' -'));
> **** - **** - **** - 4444

// ちなみに数値以外の文字列でも大丈夫でした。
print_r(Num::mask_string('ABCDEFG1234567890HIJKLMN', '*****'));
> *****

mask_credit_card($string, $format = null)

メソッド名からクレジットカードの番号マスクに特化しているようですね。
引数のフォーマットは省略可能で、
core/config/num.phpの「credit_card」で定義されています。
(内部的には、configからcredit_cardのフォーマットを読み込んだ後にmask_stringですが。)

return array(

	/**
	 * Defaults used for formatting options
	 *
	 * @var   array
	 */
	'formatting' => array(
		// Num::format_phone()
		'phone' => '(000) 000-0000',
		// Num::smart_format_phone()
		'smart_phone' => array(
			7  => '000-0000',
			10 => '(000) 000-0000',
			11 => '0 (000) 000-0000',
		),
		// Num::format_exp()
		'exp' => '00-00',
		// Num::mask_credit_card()
		'credit_card' => '**** **** **** 0000',
	),

);

フォーマットを変えたい場合は、
1.引数で指定
2.coreのnum.phpをapp/config/num.phpにコピーして「credit_card」を上書き
の2種類がありますが、用途が限定的なので実際に利用する場合は1の方法でいいと思います。

また、内部的に文字列をリビルドしている部分の判定でctype_alnumが利用されているので、
マスクしない部分の指定は、英字か数字を指定すればOKそうです。
(英字か数字を以外がマスク文字列として利用される)

print_r(Num::mask_credit_card('1111222233334444'));
> **** **** **** 4444

// 実質mask_stringなのでこちらも数値以外の文字列でもOK。
print_r(Num::mask_credit_card('aaaabbbbccccdddd'));
> **** **** **** dddd

// フォーマットを指定
print_r(Num::mask_credit_card('1111222233334444', '0000************'));
> 1111************

// 英字・数字ならマスク対象外になる
print_r(Num::mask_credit_card('1111222233334444', 'aaaa B*** 2**** $***'));
> 1111 2*** 3**** $***

クレジットカードの桁数が違う場合

クレジットカード番号の桁数は扱うカード会社さんによって異なるそうです。
基本は16桁ですが、15桁や14桁もあります。
(Fuelのconfigも16桁を想定した記述になっている)

フォーマットはcoreのconfigの設定値を利用’**** **** **** 0000’を利用した実行結果が下記になります。


// 16桁
print_r(Num::mask_credit_card('1111222233334444'));
> **** **** **** 4444

// 15桁
print_r(Num::mask_credit_card('111122223333444'));
> **** **** **** 444

// 14桁
print_r(Num::mask_credit_card('11112222333344'));
> **** **** **** 44

下4桁だけ表示してくださいのような要件だとこのままでは利用できなそうですね。
フォーマットを指定しつつマスク指定部分の文字数を動的に変更する必要がありそうですね。
下記は正規表現を使ってカード番号からマスクのフォーマット事前に生成してから指定するサンプルです。
$patternをうまく変更すれば前後4桁などにも応用ができますね。


// 後ろの4桁までを「*」に置換
$pattern = '/\d(?=\d{4})/';
$replacement = '*';

// 16桁
$card_number = '1111222233334444';
$format = preg_replace($pattern, $replacement, $card_number);
print_r(Num::mask_credit_card($card_number, $format));
> ************4444

// 15桁
$card_number = '111122223333444';
$format = preg_replace($pattern, $replacement, $card_number);
print_r(Num::mask_credit_card($card_number, $format));
> ***********3444

// 14桁
$card_number = '11112222333344';
$format = preg_replace($pattern, $replacement, $card_number);
print_r(Num::mask_credit_card($card_number, $format));
> **********3344

まとめ

結局最後まで書いてて、
一番最後の実行結果は$formatとNum::mask_credit_cardの結果が一致するので、
なんだかんだで正規表現で置換すればいいんじゃないかという結論に達しましたとさ。
(駄文ですいません)

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る