2011-08-06 15 views
1

私はPHP用のデータバリデーターパッケージを扱っています(主に、名前空間などの5.3の新機能の一部としての演習として)。私は実際のバリデーションを行うためにプラグインクラスを使用するメインバリデータークラスを用意する予定です。信頼できる整数型キャスト

私が構築している最初の検証プラグインは、整数の単なる単純なものです。ソースは以下の通りです:

namespace validator\validatorplugins; 

class Integer implements ValidatorPlugin 
{ 
    private 
     $field = NULL; 

    public function cast() 
    { 
     return ($this -> field = (int) ($this -> field * 1)); 
    } 

    public function isValid() 
    { 
     if (!$isValid = is_int ($this -> field * 1)) 
     { 
      $this -> field = NULL; 
     } 
     return ($isValid); 
    } 

    public function __construct ($field) 
    { 
     $this -> field = $field; 
    } 

    public function __toString() 
    { 
     return ((string) $this -> field); 
    } 
} 

私は上記のクラスの次のテストを使用しています:

$a = new Integer (0xDEADBEEF); 
var_dump ($a -> isValid()); 
var_dump ($a -> cast()); 
echo ($a . "\n\n"); 

$b = new Integer ('0xDEADBEEF'); 
var_dump ($b -> isValid()); 
var_dump ($b -> cast()); 
echo ($b . "\n\n"); 

$c = new Integer (0777); 
var_dump ($c -> isValid()); 
var_dump ($c -> cast()); 
echo ($c . "\n\n"); 

$d = new Integer ('0777'); 
var_dump ($d -> isValid()); 
var_dump ($d -> cast()); 
echo ($d . "\n\n"); 

を私は次のような結果になっています上記のテストケースから:

をbool(true)int(3735928559)3735928559

bool(true)int(3735928559)3735928559

個の

ブール値(真)int型(511)511

ブール値(真)int型(777)777

あなたが見ることができるように、私は進をエンコードした文字列で問題に遭遇しました数。それは511(ベース10の0777)と評価する必要がありますが、実際には777を取得しています。

いつもこのクラスを使ってフォームを検証したいと思うかもしれませんし、フォームがPHPで文字列の配列として扱われているので、このプラグインで文字列である8進数を処理するのは問題があります。

私は整数検証にさまざまなアプローチを試みました(is_intは文字列には常にfalseを返し、1を掛けると浮動小数点数をキャッチしません。型キャストとintvalは8進数を扱うときに望ましくない結果をもたらします)。ベース10(10進数)、ベース16(16進数)、ベース8(8進数)で使用できる他の方法がありますか?

+0

再生にはうれしいですが、実用的なケースを見つけるべきです。フォームが常に文字列値である場合、整数をチェックしたくありません。 * 10進整数を表す文字列*、または8進数などを表す文字列をチェックしたいと思います。だから過剰理論化せずに問題を導入しないでください。私は本当にあなたの問題を理解していないので、これを書いているだけです。あなたの実装からは、そのクラスが何をすべきかは完全にはっきりしていません(検証よりも*もっと*そうです)。おそらく変数型の問題のような設計上の問題でしょう。 – hakre

答えて

3

intvalは、オプションの引数$baseがあります

intval('0777', 8); // 511 
intval('0777', 10); // 777 
intval('0777'); // 777 
intval(0777); // 511 

ですから、このような何か行うことができます:あなたが最初進数を文字列で表現される方法を定義する必要があります

$i = '0777'; 

$base = 10; 
if (strtolower(substr($i, 0, 2)) === '0x') $base = 16; 
else if (substr($i, 0, 1) === '0') $base = 8; 

intval($i, $base); 
0

を。一部の人々は、"0777"のような文字列がの小数点以下の桁であると言う傾向があるためです。

これで、検証したい(正確には整数値に変換する)入力を行うときに、ユーザーがどのようなことを考えたかをクラスでどのように知るべきですか。

限りあなたはPHP自体が「PHPとして」価値をどのように解決するか模倣する懸念しているとして、あなたはevalのと(Demo)をシミュレートすることができます:

<?php 

$value = '0777'; 

$value = eval("return $value;"); 

var_dump($value); 

しかしこれは根本的な設計上の問題を解決していません。サンドボックスクラスのラインナップには、DecimalIntegerまたはまたはOctalIntegerが必要です。

関連する問題