PHP讨论-将参数作为数组或“ Configuration”类传递

时间:2019-01-27 00:36:01

标签: php doctrine doctrine-odm

首先,如果这个问题不属于这里(并且有一个更好的地方),请告诉我。

第二,我问的是有关“代码质量”而不是“性能”的问题。

第三,这与PHP并没有真正的关系,但是由于每种语言都有其“良好实践”,因此我更愿意指定它。

最后,如果有类似的问题,对此感到抱歉,我没有找到。

现在是问题:

将方法参数设置为数组还是"Configuration"类更好吗?

例如,我正在使用Doctrine,在我的个人资料中,我经常有一个方法接受“条件”,而另一种方法prepareCriteria使用$criteria数组来构建{{1 }}。

在这种情况下,我使用数组的次数越多,我越想知道拥有一些QueryBuilder(或CriteriaBuilder或其他任何东西)来完全控制数组的类型是否会更好传递的参数,而不依赖于数组的简单字符串键。

您对此有何看法?

ps:我真的不知道什么样的标签可以适合这种问题。 我在举例说明时添加了CriteriaConfiguration,但是如果您可以使用更精确的标签,请告诉我。

1 个答案:

答案 0 :(得分:0)

PHP中的最佳实践可能是在生产系统上禁用断言时使用冗长的关联数组和字符串assertions,而在PHP 7甚至是期望中,零成本时开销很小。编写代码时很烦人,但在以后的代码审阅时可读,并且在开发时测试代码时也会发现错误。

仅显示一个示例:

php.ini

zend.assertions  = 1
assert.warning   = 1
assert.exception = 1
assert.bail      = 1

PHP

function foobar(array $config)
{    
  assert
  (
    (function($keys_allowed, $keys_expected)use($config)
    {
      // do not stop execution until all issues are output
      $opt_expt = assert_options(ASSERT_EXCEPTION, 0);
      $opt_bail = assert_options(ASSERT_BAIL     , 0);

      $ok = 1;

      $ok &= assert( empty( $diff = array_diff_key(array_fill_keys($keys_expected, 1), $config) ),
                     new AssertionError('Missing mandatory keys: (' . join(', ', array_keys($diff)) . ')'));

      $ok &= assert( empty( $diff = array_diff_key($config, $keys_allowed) ),
                     new AssertionError('Disallowed keys: (' . join(', ', array_keys($diff)) . ')'));

      $ok &= assert( empty( $diff = array_filter
                                    ( $config,
                                      function($v, $k)use($keys_allowed)
                                      {
                                        return isset($keys_allowed[$k]) && $keys_allowed[$k] !== gettype($v);
                                      },
                                      ARRAY_FILTER_USE_BOTH)
                                    ),
                     new AssertionError('Type error on items: (' . join(', ', array_keys($diff)) . ')'));

      //restore configured behaviour    
      assert_options(ASSERT_EXCEPTION, $opt_expt);
      assert_options(ASSERT_BAIL     , $opt_bail);
      return $ok;
    })
    (
      [ 'foo' => 'string', 'bar' => 'integer', 'baz' => 'boolean' ],   [ 'baz' ]
    )
    , new AssertionError('Arguments assertion in function `' . __FUNCTION__ . '` failed.')
  );


  // foobar function stuff
  echo 'Ok!', PHP_EOL;
}

// test
foobar(['foo' => '1',              'baz' => true                     ] );  // Ok!
foobar([              'bar' => 1 , 'baz' => true                     ] );  // Ok!


foobar(['foo' => 1  ,              'baz' => true                     ] );  // Warning: type ; Fatal error
foobar(['foo' => '1', 'bar' => 1                                     ] );  // Warning: missing ; Fatal error
foobar(['foo' => 1  , 'bar' => '1'               , 'forbidden' => 'x'] );  // Warnings: missing, disallowed, type ; Fatal error

外部断言引发致命错误,停止执行,而内部断言引发不间断警告。

您可以将使用过的变量作为附加参数,轻松地将匿名函数转换为命名函数。