处理丢失的数组偏移量

时间:2010-07-01 16:28:58

标签: php

考虑以下代码:

$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
}

在进入$ test [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;
}

基本上是出于风格上的原因。

7 个答案:

答案 0 :(得分:6)

有趣。

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

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

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

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

答案 1 :(得分: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
}

答案 2 :(得分:0)

为什么使用$ param1,$ param2而不是直接使用Array作为参数,例如:

$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];
 }
}

答案 3 :(得分: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

答案 4 :(得分:0)

你真的应该选择Bartek的解决方案,但为了完整性,这里有一个,这可能更像你想要它:

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

但老实说:如果阵列的大小可以增加,你真的想每次都改变功能签名吗?享受我们的直播和传递阵列

如果它最多有3个条目,那么你可以使用上面的代码。

答案 5 :(得分: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
}

答案 6 :(得分:0)

通过call_user_func_array

进行此操作也很简单
foreach ($tests as $test) {
    call_user_func_array('test', $test);
}

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

虽然我很可能更喜欢Bartek的解决方案。