2010-07-01 79 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) { 
    // ... 
} 

雖然最有可能,我寧願鮑爾泰克的解決方案。