【问题标题】:Validating POST data class验证 POST 数据类
【发布时间】:2017-08-28 04:06:34
【问题描述】:

这是question I asked earlier 的扩展,由于使用eval(),被认为是不安全的做法。所以我采用了另一种方法,但我遇到了问题。我不知道如何将其转换为类。当我尝试使用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'));

【问题讨论】:

  • 你没有 new 语句来初始化类,并且你没有标记方法 static 在不构造的情况下调用它们。
  • 谢谢,但这不是我要问的。我知道我没有初始化。问题是我得到了Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'testlength' not found or invalid function name,但不仅仅是testlength,而是所有的验证方法。这就是我想要帮助理解或翻译代码以在课堂上工作的内容。
  • 转储你所有的$rls 里面有什么?
  • @Cirshiss 是的,这是您要解决的问题。你没有可调用的类,因为你没有new 他们,他们也不是static
  • call_user_func_array("ruleValidator::$rls", $r)

标签: php validation class


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    当你想调用一个类的方法时,你必须创建一个实例(使用new)或者在声明方法static时静态调用它们。

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

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

    然后将函数声明为静态:

    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)
    

    【讨论】:

    • 我进行了更改public static 并添加了$callbackClass = new ruleValidator(); 行并更改了回调call_user_func_array(array($callbackClass, $rls), $r) 这导致:​​Fatal error: Uncaught ArgumentCountError: Too few arguments to function ruleValidator::testequalto(), 1 passed on line 33 and exactly 2 expected Stack trace: #0 php_class_validator.php(33): ruleValidator-&gt;testequalto('testtesty') #1 php_class_validator.php(167): ruleValidator-&gt;validateData(Array, Array) #2 {main} thrown in php_class_validator.php on line 72
    • @Cirshiss 当你使用new 创建一个新实例时,方法不应该是static。当您使用:: 静态调用该类时,它应该具有static 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 2012-02-15
    • 2012-11-19
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多