array_map () 等函数不支持传入实现 ArrayAccess 接口的对象,感觉不太方便

ArrayAccess (数组式访问)接口,是提供像访问数组一样访问对象的能力的接口,须实现以下方法:

ArrayAccess::offsetExists — 检查一个偏移位置是否存在
ArrayAccess::offsetGet — 获取一个偏移位置的值
ArrayAccess::offsetSet — 设置一个偏移位置的值
ArrayAccess::offsetUnset — 复位一个偏移位置的值

藉由实现该接口,可通过 $obj[$prop] 的方式访问对象属性(或容器元素)。
最近在写一个功能,为了兼容,本打算支持传入实现ArrayAccess接口的对象:

function concatWhereClause(
    string $keyword,
    bool $prefix = false,
    ...$fields
): string {
    $arg3 = func_get_arg(2);

    if (is_array($arg3) || $arg3 instanceof \ArrayAccess) {
        $fields = $arg3;
    }

    $keyword = $keyword . '%';
    if ($prefix) $keyword = '%' . $keyword;

    $keywordFields = array_map(function ($field) {
        return $field . ' LIKE ' . $keyword;
    }, $fields);

    $pinyinFields = array_map(function ($field) {
        return $field . '_pinyin LIKE ' . $keyword;
    }, $fields);

    $queryCondition = implode(' OR ', array_merge(
        $keywordFields,
        $pinyinFields
    ));

    return ' WHERE ' . $queryCondition;
}

结果传入实现ArrayAccess接口的对象的时候,报错了!

{"message": "array_map(): Argument #2 should be an array"}

这样子导致调用该方法时,若第三个参数不传入字段名字符串,则必须传入数组,不能传入实现ArrayAccess接口的对象,即必须要将对象转化为数组才行。
感觉数组式访问接口在这一点上做得还不是很完善。

Long2Ge
讨论数量: 2
long2ge

array_filter()、array_reduce()等函数同理。

4年前 评论
long2ge

@CismonX zend_array 这块我没深究过。
__toString() 魔术方法又是如何由最开始的只支持 echo 和 print 到可以在任何字符串环境生效呢?
以后 PHP 有没有可能会出现像 __toArray() 那样把对象当作数组调用时会被触发的魔术方法?

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!