0

我有一个大型数据集,我正在检查其中的内容;我在创建数据的内部数组时进行此验证;为避免以后再次循环数组,我希望验证更改数组的内容。现在的问题是我通过 call_user_func 调用验证例程,这似乎给通过引用传递带来了一些问题。或者也许我做错了什么。

这是一个精简的示例:

public function index( )
{
    $arr = array( 
        array('a' => 'aap', 'n' => 'noot', 'm' => 'mies'), 
        array('a' => 'ding', 'b' => 'flof', 'c' => 'bips'), 
        array( 'd' => 'do', 'e' => 're', 'c' => 'mi') 
    );

    $func = array( $this, '_user_func' );

    $errors = 0;
    $new_arr = array();
    foreach ($arr as $key => &$value) {
        $new_arr[$key] = &$value; // Simulate production-code manipulation
        //if ( !$this->_do_callback($func, $new_arr[$key], $key) ) $errors++; // No exception but array not modified afterwards
        if ( !call_user_func( $func, $new_arr[$key], $key ) ) $errors++; // Exception: Parameter 1 to TestRef::user_func() expected to be a reference, value given
    }
    unset($value);
    var_dump($new_arr);
    print_r('Errors: '.$errors);
}

private function _do_callback( $func, array &$row, $row_id )
{
    if ( is_callable( $func ) )
    {
        return call_user_func( $func, $row, $row_id );
    }
    else
    {
        throw new Exception( "Error doing callback. Callback empty or not a callable function." );
    }
}

private function _user_func( &$arr, $index = 0 )
{
    // "Validation" routine
    foreach ($arr as $key => &$value) {
        if ($key == 'b') return FALSE; // Simulate validation error for error count
        $arr[$key] = 'replaced';
    }
    unset($value);
    //var_dump($arr); // Works!
    return TRUE;
}
4

3 回答 3

1

要么

尝试将您的 foreach 循环更改为:

foreach ($arr as $key => &$value) {
    $this->_do_callback($func, $value, $key); // No exception but array not modified afterwards
    //call_user_func( $func, $value, $key ); // Exception: Parameter 1 to TestRef::user_func() expected to be a reference, value given
}

unset($value); // avoid memory leak

或者

在调用之前将变量包装在数组中call_user_func

于 2012-09-10T10:49:30.120 回答
1

我认为您正在尝试重新定义现有的 php 函数,即 array_walk。特别是在您的情况下,您将需要array_walk_recursive

这是您的代码的重写(简化?)版本。

    public function index( )
    {
        $arr = array( 
            array('a' => 'aap', 'n' => 'noot', 'm' => 'mies'), 
            array('a' => 'ding', 'b' => 'flof', 'c' => 'bips'), 
            array( 'd' => 'do', 'e' => 're', 'c' => 'mi') 
        );

        $func = array( $this, '_user_func' );

        var_dump($arr); // BEFORE WALK
        array_walk_recursive($arr, $func);
        var_dump($arr); // AFTER WALK
    }

    /**
     *  Does something to a row from an array (notice the reference)
     */
    private function _user_func( &$rowValue, $rowIndex )
    {
            $rowValue = 'replaced';
    }

你可以在这里看到这个代码——> http://ideone.com/LcZKo

于 2012-09-10T11:06:48.903 回答
0

你有没有这样尝试过:?

foreach ($arr as $key => &$value) {
        $this->_do_callback($func, $value, $key); // No exception but array not modified afterwards
        //call_user_func( $func, $value, $key ); // Exception: Parameter 1 to TestRef::user_func() expected to be a reference, value given
    }
于 2012-09-10T10:42:12.353 回答