2010-07-01 40 views
2

考虑下面的代码:处理缺阵偏移

$tests = array( 
array ("a", "b", "c"), array ("1", "2", "3"), array ("!", "@") 
); 

foreach ($tests as $test) 
test($test[0], $test[1], $test[2]); 

function test($param1, $param2, $param3) { 
// do whatever 
} 

这将没有任何问题的工作,直到它到达$测试[2],这当然没有在第三个元素阵列,这将导致PHP吐出:

Notice: Undefined offset: 2 

有没有办法来解决这个问题,除了:它得到一个笨拙

foreach ($tests as $test) { 
if (count($x) == 2) 
    test($test[0], $test[1]); 
else 
    test($test[0], $test[1], $test[2]); 
} 

function test($param1, $param2, $param3=null) { 
// do whatever 
} 

每个$ test数组的大小都变得越来越大。 或者我应该忽略通知?

编辑:这就是我真正想要做:

// wanted this: 
function validate() { 
    $pass = true; 
    $rules = array (array ('field1', '!=', 'banana'), 
      array('field2', 'notempty') 
    ); 

    for ($i=0; $i<count($rules) && $pass; $i++) 
     $pass = check($rules[$i][0], $rules[$i][1], $rules[$i][1]); 

    return $pass; 
} 

function check($field, $operator, $expected) { 
    $value = $this->getValue($field); 

    switch ($operator) { 
     case '!=': 
      $pass = ($value != $expected); 
      break; 

     case '==': 
      $pass = ($value == $expected); 
      break; 

     case 'empty': 
      $pass = empty($value); 
      break; 

     default: 
      $pass = !empty($value); 
      break; 
    } 

    return $pass; 
} 

//instead of 
function validate() { 
    $pass = true; 

    for ($i=0; $i<count($rules) && $pass; $i++) 
     $pass = check($rules[$i]); 

    return $pass; 
} 

function check($check) { 
    $value = $this->getValue($check[0]); 

    switch ($check[1]) { 
     case '!=': 
      $pass = ($value != $check[2]); 
      break; 

     case '==': 
      $pass = ($value == $check[2]); 
      break; 

     case 'empty': 
      $pass = empty($value); 
      break; 

     default: 
      $pass = !empty($value); 
      break; 
    } 

    return $pass; 
} 

基本上文体上。

+0

函数的必需参数应该是必需的,或者是完全可选的。为什么test()必须采用可变数量的参数?你有没有尝试过像传递一个单独的参数作为一个数组,像'test($ arr)',其中'$ arr'就像'Array('arg1','arg2','arg3_if_present')',那里有必要的工作?只是看起来需要重构。 – 2010-07-01 16:34:23

回答

6

有趣。

你为什么不juse做这样的事情?

foreach($tests as $test) { 
    test($test); 
} 

function test($test) { 
    // loop through $test to get all the values as you did originally 
} 

如果你有一个数组的动态大小,我不明白为什么你不能只是整个数组传递给函数而不是分开的论点。

+0

我现在正在与此相关,但我想要的是我最初的文体原因。 – quantumSoup 2010-07-01 16:38:11

+0

在上面编辑的文章中对此进行了解释 – quantumSoup 2010-07-01 16:48:40

0

用这个代替:

$tests = array( 
array ("a", "b", "c"), array ("1", "2", "3"), array ("!", "@") 
); 

foreach ($tests as $test) 
test($test); 

function test($test) 
{ 
    for($i=0; $i < count($test); $i++) 
    { 
     if (! isset($test[$i])) 
      $test[$i] = ''; 
    } 

// do whatever 
} 
0

你为什么要使用$参数1,$参数2并没有直接的参数,例如数组:

$tests = array( 
array('a', 'b', 'c'), 
array('1', '2', '3'), 
array('!', '@') 
); 

foreach ($tests as $test) 
{ 
test($test); 
} 

function test($params) 
{ 
$param1 = $params[0]; // Or use directly $params[index], than you need not to set it. 
} 

或者另一种方式(但这种方式是不是最好的方法,以上的方式是更好的;))

$tests = array( 
array('a', 'b', 'c'), 
array('1', '2', '3'), 
array('!', '@') 
); 

foreach ($tests as $test) 
{ 
test($test); 
} 

function test($params) 
{ 
for($i=0; $i<=count($params)-1; $i++) 
{ 
    $param$i = $params[$i]; 
} 
} 
0

如果问题的关键只是如何迭代多维数组,然后做

$iterator = new RecursiveIteratorIterator(
       new RecursiveArrayIterator($theArray) 
       RecursiveIteratorIterator::SELF_FIRST); 

foreach($iterator as $key => $val) { 
    echo "$key = $val \n" 
} 

如果你想知道如何通过可变数量的参数的函数,考虑

function throwItAtMe() 
{ 
    $args = func_get_args(); 
    print_r($args); 
} 
throwItAtMe(1,2,3,4,5, 'foo', 'bar', 'baz'); 

为了您的规则/断言简单地使用Strategy Pattern或有看看Specification pattern

0

你真的应该跟鲍尔泰克的解决方案去,但为了完整性这里是一个,也可能是更喜欢你想要的:

foreach ($tests as $test) { 
    test($test[0], $test[1], isset($test[2]) ? $test[2] : null); 
} 

但说实话:如果数组的大小可以增加,你真的每次都想更改函数签名?享受我们的生活吧通过阵列

如果它最多有3个条目,那么你会很满意上面的代码。

0
foreach($tests as $test) { 
    test($test); 
} 

function test($test) { 
    @list($field, $operator, $expected) = $test; 
    // if $test size is 2 then $expected will be NULL, @ is to suppress Notice, if you don't show notices you may ommit it 
} 
0

还有通过call_user_func_array丑陋但短期的方式做到这一点:

foreach ($tests as $test) { 
    call_user_func_array('test', $test); 
} 

function test($param1, $param2, $param3 = null) { 
    // ... 
} 

虽然最有可能,我宁愿鲍尔泰克的解决方案。