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

bool(true)int(511)511

bool(true)int(777)777

ご覧のとおり、8進数をエンコードする文字列で問題が発生しました。511(10進数で0777)と評価されるはずですが、実際には777になっています。

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

私は整数検証にさまざまなアプローチを試しました(is_intを使用すると文字列に対して常にfalseが返され、1を掛けると、is_numericはfloatをキャッチせず、型キャストとintvalは8進数を処理するときに望ましくない結果を生成します)。基数10(10進数)、基数16(16進数)、および基数8(8進数)で機能する他のアプローチはありますか?

4

2 に答える 2

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);
于 2011-08-06T14:02:41.430 に答える
0

最初に、8進数が文字列でどのように表されるかを定義する必要があります。"0777" 一部の人々は、のような文字列が77710進値であると言う傾向があるためです。

したがって、検証したい(またはより正確に整数値に変換した)入力を行うときにユーザーがどう思ったかをクラスはどのように知る必要がありますか。

PHP自体が「PHPとして」値を解決する方法を模倣することに関心がある限り、eval(デモ)でシミュレートできます。

<?php

$value = '0777';

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

var_dump($value);

ただし、これは根本的な設計の問題を解決しません。サンドボックスクラスのラインナップにはDecimalIntegerHexadecimalIntegerまたはを用意する必要があります。OctalInteger

于 2011-08-06T14:20:50.227 に答える