2

我刚刚阅读了Michelangelo van Dam aka DragonBe 的一篇关于 PHP 项目质量保证的精彩演讲。在他的演讲中,他以 Zend-Framework 为例,我在基本层面上对此很熟悉。

由于我想提高自己,我从单元测试开始,虽然我觉得问题出在 ZF 方面。

问题:

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_active留空flag_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)) 它都不会改变任何事情:\

4

1 回答 1

3

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

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

某些过滤器在某些情况下几乎可以保证验证(即带有 Int 验证器的 Int 过滤器),因为过滤器将过滤数据并为验证器返回有效值。即使原始输入数据无效hello,通过过滤Int器返回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 不喜欢空值,除非你指定一个选项。因此,将有效 ( false) 值发送到过滤器会导致错误,除非您设置Zend_Filter_Input::ALLOW_EMPTYtrue.

于 2012-06-25T20:11:46.583 回答