可靠的整数类型转换

时间:2011-08-06 13:41:34

标签: php casting integer octal

我正在研究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

正如您所看到的,我遇到了一个编码八进制数的字符串的问题。它应该评估为511(基数10中为0777),但实际上我得到的是777。

因为有一天我可能想要使用这个类来验证表单,并且由于表格总是被PHP视为字符串数组,你可以看到处理恰好是这个插件的字符串的八进制数是有问题的。

我尝试了各种方法来进行整数验证(使用is_int总是为字符串返回false,乘以1,is_numeric不会捕获浮点数,类型转换和intval在处理八进制数时会产生不需要的结果)。是否有一些我可以使用的方法适用于基数10(十进制),基数16(十六进制)和基数8(八进制)?

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

首先需要定义八进制数如何在字符串中表示。因为有些人倾向于说像"0777" 这样的字符串是 777十进制值。

那么你的班级应该如何知道用户在做你想要验证的输入时的想法(或者更正确地转换成整数值)。

如果您担心模仿PHP本身如何将值“解析为PHP”,则可以使用eval(Demo)进行模拟:

<?php

$value = '0777';

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

var_dump($value);

然而,这并没有解决潜在的设计问题。您的沙盒类阵​​容应该有DecimalIntegerHexadecimalIntegerOctalInteger