zend-framework - 如何过滤/验证 bool 值?

标签 zend-framework zend-validate zend-filter

我刚刚读了一篇关于 Quality Assurance for PHP Projects 的精彩演示。米开朗基罗·范·达姆 (Michelangelo van Dam) 又名 DragonBe。在他的演示中,他使用 Zend-Framework 作为示例,我对它有基本的熟悉。

因为我想提高自己,所以我从单元测试开始,尽管我觉得问题出在ZF方面。

问题:

每当我分配 bool 值 false 时,都会使用给定的代码工件Zend_Filter 或 Zend_Validator 将其更改为 null 。我不明白为什么会出现这种情况。

请参阅底部的更新以获取更新的代码和测试

首先进行测试

public function goodData() {
  return array(
    array('DU-IT', 'Sample Description', true, false),
    array('Mercüß', 'bla"ß"trager', false, true),
    array('Mia123', '728 Tage im Jahr', false, false)
  );
}

/**
 * @dataProvider goodData()
 */
public function testModelAcceptsValidData($name, $description, $flag_active, $flag_deleted)
{
  $data = array(
    'id'            => 0,
    'name'          => $name,
    'description'   => $description,
    'flag_active'   => $flag_active,
    'flag_deleted'  => $flag_deleted
  );

  try {
    $this->_model->populate($data);
  } catch (Zend_Exception $e) {
    $this->fail('Unexpected Exception: '.$e->getMessage());
  }

  $this->assertSame($data, $this->_model->toArray());
}

模型

public function __construct($props = null)
{
  // Set Filters
  $this->_filters = array(
    'id'            => array('Int'),
    'name'          => array('StringTrim', 'StripTags'),
    'description'   => array('StringTrim', 'StripTags'),
    'flag_active'   => array(new Zend_Filter_Boolean()),
    'flag_deleted'  => array(new Zend_Filter_Boolean())
  );

  // Set Validators
  $this->_validators = array(
    'id'            => array('Int'),
    'name'          => array(new Zend_Validate_StringLength(array('min'=>4, 'max'=>50))),
    'description'   => array(new Zend_Validate_StringLength(array('max'=>5000))),
    'flag_active'   => array(new Zend_Validate_InArray(array(true, false))),
    'flag_deleted'  => array(new Zend_Validate_InArray(array(true, false)))
  );

  // Set Properties
  if (!is_null($props)) {
    $this->populate($props);
  }
}

public function setFlagActive($arg)
{
  $input = new Zend_Filter_Input($this->_filters, $this->_validators);
  $input->setData(array('flag_active'=>$arg));
  if (!$input->isValid('flag_active')) {
    throw new Zend_Exception('Invalid FLAG_ACTIVE provided'. gettype($input->flag_active));
  }
  $this->_flag_active = (bool) $input->flag_active;
  return $this;
}

就模型而言,我尝试将验证器留给 flag_activeflag_deleted空,但这并没有改变我的结果。 phpunit的错误信息还是一样:

Unexpected Exception: Invalid FLAG_ACTIVE providedNULL

虽然 NULL 是变量的类型,但每当我传递 false 时作为通过数据提供者 goodData() 的标志参数(同样的情况也发生在 badData 上)。

我的猜测是这与 Zend_Filter 有关,但我就是无法弄清楚这一点。非常感谢提示!

更新 由于德鲁给出了一些提示,我进一步测试了一些,但问题仍然存在。我已将更新的类和单元测试粘贴到 Pastebin 上,以提高可读性。

PHPUnit 给出以下错误:You must give a non-empty value for field 'flag_active' flag_deleted 也是如此。一半测试的第二个错误是 <null> does not match expected type "boolean" 。我被困住了。无论我使用过滤器还是 inArrayValidator(array(0=>true,1=>false)) 它都不会改变任何事情:\

最佳答案

如果您检查 $input->getMessages() 的内容,它应该提供一些关于为什么该特定值无效的解释。

当您使用 Zend_Filter_Input 时,任何未通过验证的值将无法通过其名称神奇地访问(例如 $input->flag_active)。如果未通过验证步骤,该值将始终为 NULL

某些过滤器在某些情况下几乎可以保证验证(即带有 Int 验证器的 Int 过滤器),因为过滤器将过滤数据并为验证器返回有效值。通过 Int 过滤器传递 hello 返回 0,即使原始输入数据也可以使用简单的 Int 验证器进行验证无效。

您最有可能在异常中获得空值的原因是该值因未验证而不可用;因此,请检查输入消息以获取有关原因的任何提示。

编辑:

我认为您遇到的问题是 Zend_Filter_Input 默认情况下不允许空值。因此,如果进入过滤器的值为 falseNULL,则会导致过滤器出现错误。

查看此代码:

    <?php

    // set up a boolean validator and inarray validator like you have
    $filters    = array('test' => array(new Zend_Filter_Boolean()));
    $validators = array('test' => array(new Zend_Validate_InArray(array(true, false))));

    // set up the input filter with default options
    $input      = new Zend_Filter_Input($filters, $validators);

    // our "input" value which is (bool)false
    $test       = false;

    $input->setData(array('test' => $test));

    // run through input filter using default values
    // should throw error about a non-empty value
    if (!$input->isValid('test')) {
        echo "Test is not valid.  <br />Original Value: ";
        var_dump($test);
        echo "<br />";
        print_r($input->getMessages());
    } else {
        echo "Test is valid.<br />Original Value: ";
        var_dump($test);
        echo "<br />Value now: ";
        var_dump($input->test);
    }

    // now allowing empty values...
    echo "<hr />\n";

    // tell Zend_Filter_Input to allow empty values on input
    $options = array(Zend_Filter_Input::ALLOW_EMPTY => true);

    // set up new input filter with option
    $input   = new Zend_Filter_Input($filters, $validators, null, $options);

    $input->setData(array('test' => $test));

    // run through input filter allowing empty values
    // this should NOT throw an error
    if (!$input->isValid('test')) {
        echo "Test is not valid.  <br />Original Value: ";
        var_dump($test);
        echo "<br />";
        print_r($input->getMessages());
    } else {
        echo "Test is valid.<br />Original Value: ";
        var_dump($test);
        echo "<br />Value now: ";
        var_dump($input->test);
    }

所以问题似乎是 Zend_Filter_Input 不喜欢空值,除非您指定一个选项。因此,除非将 Zend_Filter_Input::ALLOW_EMPTY 设置为 true,否则向过滤器发送有效 (false) 值会导致错误。

关于zend-framework - 如何过滤/验证 bool 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11136008/

相关文章:

php - 使用别名加入 Zend Framework

internet-explorer - Zend Framework - Internet Explorer - phpsessid cookie 问题

php - 需要指导以开始使用 Zend ACL

正则表达式一个点或一个下划线验证器

php - Zend_Form 和 Zend_Filter

php - 没有 Zend Forms 的 Zend Form 验证和过滤

Phpunit 错误 - 断言节点失败,表示为

doctrine-orm - ZF2 inputfilter 主义 NoObjectExists 编辑对象不验证

php - 验证 Zend Form Multiselect 中的选项数量

php - 如何在 Zend Framework 2 和 Zend Filter 中以 Zip 格式压缩上传的文件