验证POST数据类

时间:2017-04-03 10:23:16

标签: php validation class

由于eval()的使用,这是question I asked earlier的扩展,被认为是不安全的做法。所以我采取了另一种方法,但我遇到了一个问题。我不知道如何将它转换为一个类。当我尝试使用call_user_func_array时,我的尝试以错误结束。它无法在课堂上找到这个功能。你能给我一些暗示,所以我开始了吗?谢谢!

我尝试运行代码时收到的错误消息是Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'testlength' not found or invalid function name但是在所有验证方法上。这是我不明白的。这就是我想帮助理解为什么它不起作用。

class ruleValidator
{

    protected $postData = array();
    protected $ruleSet  = array();
    var $exceptions = 'Å,Ä,Þ,å,ä,þ,Ø,Ö,Ð,ø,ö,ð,Æ,Ü,æ,ü,á,é,í,ñ,ó,ú,ü,Á,É,Í,Ñ,Ó,Ê,Ú,Ü,ß';

    function __construct(){
        $this->exceptions = explode(',',$exceptions);
    }

    function testlength($string,$threshold)
    {
        return strlen($string)<$threshold?
            'Your %s is too short.': // TRUE
            '';                      // FALSE
    }

    function testnumeric($string,$offset,$length,$switch=true)
    {
        if(is_numeric(substr($string,$offset,$length))===$switch)
        {
            return $switch?
                'Your %s has to begin with a character.': // Truely TRUE
                'Your %s is containing non numeric characters. Please enter only digits.'; // Falsely TRUE
        }
    }

    function testemail($string)
    {
        return filter_var($string, FILTER_VALIDATE_EMAIL)?
            '':                                   // TRUE
            'Your email is not in a valid form.'; // FALSE
    }

    function testpattern($string,$pattern='/^[0-9]{8,10}$/')
    {
        return preg_match($pattern, $string)?
            '': // TRUE
            'Your %s is entered incorrect. Please use the correct format when entering data.'; // FALSE
    }

    function testequalto($string1,$string2)
    {
        return $string1==$string2?
            '':                                       // TRUE
            'Your %s fields do not match eachother.'; // FALSE
    }

    function testchecked($bool)
    {
        return $bool===true?
            '':                                               // TRUE
            'You are required to check this %s to continue.'; // FALSE
    }


    function testspecchar($string,$excludes=array())
    {
        if(is_array($excludes)&&!empty($excludes))
        {
            foreach($excludes as $exclude)
            {
                $string=str_replace($exclude,'',$string);        
            }    
        }

        if(preg_match('/[^a-z0-9 ]+/i',$string))
        {
            return 'Your %s contains illegal characters.'; // TRUE
        }

        return;                                            // FALSE

    }

}

这是一个数组,其中包含如何在验证器中收到POST数据以及我用于表单中不同字段的规则。

    $exceptions = explode(',','Å,Ä,Þ,å,ä,þ,Ø,Ö,Ð,ø,ö,ð,Æ,Ü,æ,ü,á,é,í,ñ,ó,ú,ü,Á,É,Í,Ñ,Ó,Ê,Ú,Ü,ß');
    $postData = array
    (
        'name'             => 'Mikael',
        'familyname'       => 'Eriksson`',
        'username'         => 'Mik',
        'password'         => 'testtest',
        'password-confirm' => 'testtesty',
        'email'            => 'try.to@guess.it,se',
        'phone'            => '0000000000a',
        'policy'           => 0
    );
    $ruleSet = array
    (
        'name'=>array
        (
            'testlength'=>2,
            'testnumeric'=>array(0,1),
            'testspecchar'=>array($exceptions)
        ),
        'familyname'=>array
        (
            'testlength'=>2,
            'testnumeric'=>array(0,1),
            'testspecchar'=>array($exceptions)
        ),
        'username'=>array
        (
            'testlength'=>4,
            'testnumeric'=>array(0,1),
            'testspecchar'=>array()
        ),
        'email'=>array
        (
            'testemail'=>array()
        ),
        'phone'=>array
        (
            'testnumeric'=>array(0,strlen($postData['phone']),false),
            'testpattern'=>'/^[0-9]{8,10}$/'
        ),
        'password'=>array
        (
            'testlength'=>8
        ),
        'password-confirm'=>array
        (
            'testequalto'=>$postData['password-confirm']
        ),
        'policy'=>array
        (
            'testchecked'=>array()
        )
    );

以下是我迄今为止验证数据的方法。它可以工作,但是我想把它变成一个类来简化项目中的代码。

    foreach($postData as $key => $value)
    {
        if(!array_key_exists($key,$ruleSet))
        {
            $errors[] = "The field `$key` is not part of the form. Only send actual form data.";
            break;
        }

        $slice = array($key=>$ruleSet[$key]);
        foreach($slice as $rules => $rule)
        {
            foreach($rule as $rls => $r)
            {
                $r = array_merge((array)$value,(array)$r);
                $errors[] = sprintf(call_user_func_array($rls,$r),$key);
            }
        }
    }
    if(count($errors)>0) return implode(';;',array_filter($errors,'strlen'));

2 个答案:

答案 0 :(得分:0)

如果要调用的方法,则必须创建一个实例(使用new)或在声明方法static时静态调用它们。

在这两种方式中,您必须告诉call_user_func_array()您没有在全局范围内调用函数,而是从类中调用函数。

call_user_func_array(array('ruleValidator', $rls), $r)

然后声明函数static:

public static function testlength($string,$threshold) {

}

new

$slice = array($key=>$ruleSet[$key]);
$callbackClass = new ruleValidator();
foreach($slice as $rules => $rule)

/** ... */

call_user_func_array(array($callbackClass, $rls), $r)

答案 1 :(得分:0)

感谢@Deadooshka为我提供了解决方案。

call_user_func_array("ruleValidator::$rls", $r)