array_map并将2个参数传递给映射函数 - array_map():参数#3应该是一个数组

Lat*_*san 16 php laravel laravel-4

我有一个看起来像这样的抽象类:

abstract class Transformer {

    /**
     * Transform a collection of items
     *
     * @param array $items
     * @param bool $format
     * @return array
     */
    public function transformCollection(array $items, $format)
    {
        return array_map([$this, 'transform'], $items, $format);
    }

    /**
     * Transform a item
     *
     * @param array $item
     * @param bool $format
     * @return mixed
     */
    public abstract function transform(array $item, $format);

}
Run Code Online (Sandbox Code Playgroud)

然后我有以下实现它的类:

class ServiceLogTransformer extends Transformer {

    public function transform(array $service_log, $format = false)
    {
        return [
            'id'    => $service_log['id'],
            'date'  => $service_log['log_date'],
            'time'  => $service_log['log_time'],
            'type'  => ($format ? status_label($service_log['log_type']) : $service_log['log_type']),
            'entry' => $service_log['log_entry']
        ];
    }

}
Run Code Online (Sandbox Code Playgroud)

当这段代码运行时,我收到错误:

array_map():参数#3应该是一个数组

array_map在类中调用函数时,如何传递2个或更多参数?我检查了PHP文档,看起来这是允许的,但它不适用于我的Larave 4.2项目.

有任何想法吗?

Pet*_*ter 42

请始终阅读文档:

http://php.net/manual/en/function.array-map.php

array array_map ( callable $callback , array $array1 [, array $... ] )
Run Code Online (Sandbox Code Playgroud)

然而你通过bool $format作为参数

"在类中调用array_map函数时,如何传递2个或更多参数?

我会用use()语法创建匿名函数

public function transformCollection(array $items, $format)
{
    return array_map(function($item) use ($format) {
        return $this->transform($item, $format);
    }, $items);
}
Run Code Online (Sandbox Code Playgroud)


Sha*_*ill 7

大多数答案表明,带有use关键字的匿名函数是将附加参数传递给其他可调用对象的典型方式。

abstract class Transformer {
    public function transformCollection(array $items, $format)
    {
        return array_map(function($item) use ($format) {
            return $this->transform($item, $format);
        }, $items);
    }
}
Run Code Online (Sandbox Code Playgroud)

不过,最有可能的是,这种特殊情况更适合标准foreach循环array_map,因为它可能更高效且更易于阅读。这也将防止您的索引被重新编号,以及使用TraversableArrayAccess项目。

abstract class Transformer {
    public function transformCollection(array $items, $format)
    {
        foreach($items as $key => $item) {
           $items[$key] = $this->transform($item, $format);
        }
        return $items;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您真的,真的很想使用array_map匿名函数在您的环境中不起作用(即 PHP 5.3 之前的版本)并且您需要$format作为第二个参数传递,那么您将需要转换$format为具有相同长度为$items.

abstract class Transformer {
    public function transformCollection(array $items, $format)
    {
        // Fill an array of same length as $items with the $format argument.
        $format = array_fill(0, count($items), $format);
        return array_map([$this, 'transform'], $items, $format);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我最近意识到还有另一种选择,因为您正在使用实例来转换数据。它涉及存储$format到实例,可能使用 setter,如果它作为参数提供,则覆盖它。这样就可以通过使用$this->format.

abstract class Transformer {
    protected $format;

    public function setFormat($format)
    {
        $this->format = $format;
    }

    public function transformCollection(array $items, $format = null)
    {
        if (isset($format)) {
            $this->setFormat($format);
        }
        // ...
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)


ale*_*ell 6

您不能使用array_map将硬编码值传递给回调函数(currying函数式语言中通常称为或部分应用的函数).什么array_map需要的是阵列可变量的,所有这些都应该有元件的相同的量.每个数组的当前索引处的元素作为单独的参数传递给回调.所以,例如,如果你这样做:

$arr1 = [1, 2, 3, 4];
$arr2 = [2, 4, 6, 8];

$func = function ($a, $b) { return $a.'-'.$b; };


$arr3 = array_map($func, $arr1, $arr2);
Run Code Online (Sandbox Code Playgroud)

你得到这个:

['1-2', '2-4', '3-6', '4-8']
Run Code Online (Sandbox Code Playgroud)

希望这能解释它背后的想法 - 你传入的每个数组都会将第一个数组中当前位置的元素作为相关参数传递给回调函数.

所以,正如我所说,它不能用于将'静态'值传递给回调.但是,您可以通过动态定义匿名函数来自己完成此操作.在你的transformCollection方法中:

return array_map(function ($item) use ($format) {
    return $this->transform($item, $format);
}, $items);
Run Code Online (Sandbox Code Playgroud)