在 PHP 中将“this.that.other”等点语法转换为多维数组

2022-08-30 11:40:19

正如标题所暗示的那样,我正在尝试创建一个解析器,并试图找到将点命名空间中的东西转换为多维数组的最佳解决方案,以便

s1.t1.column.1 = size:33%

将与

$source['s1']['t1']['column']['1'] = 'size:33%';

答案 1

试试这个号码...

function assignArrayByPath(&$arr, $path, $value, $separator='.') {
    $keys = explode($separator, $path);

    foreach ($keys as $key) {
        $arr = &$arr[$key];
    }

    $arr = $value;
}

密码键盘

它将遍历键(默认为分隔符)以到达最终属性,然后对值进行赋值。.

如果某些密钥不存在,则会创建它们。


答案 2

仅供参考 在Laravel中,我们有一个助手函数,该函数在此函数中转换array_set()

使用点表示法存储在数组中的方法

/**
 * Set an array item to a given value using "dot" notation.
 *
 * If no key is given to the method, the entire array will be replaced.
 *
 * @param  array   $array
 * @param  string  $key
 * @param  mixed   $value
 * @return array
 */
public static function set(&$array, $key, $value)
{
    if (is_null($key)) {
        return $array = $value;
    }

    $keys = explode('.', $key);

    while (count($keys) > 1) {
        $key = array_shift($keys);

        // If the key doesn't exist at this depth, we will just create an empty array
        // to hold the next value, allowing us to create the arrays to hold final
        // values at the correct depth. Then we'll keep digging into the array.
        if (! isset($array[$key]) || ! is_array($array[$key])) {
            $array[$key] = [];
        }

        $array = &$array[$key];
    }

    $array[array_shift($keys)] = $value;

    return $array;
}

简单如下

$array = ['products' => ['desk' => ['price' => 100]]];

array_set($array, 'products.desk.price', 200);

// ['products' => ['desk' => ['price' => 200]]]

您可以在文档中查看

如果您需要使用点表示法获取数据,则该过程会稍长一些,但是在板上提供,该板转换为此函数(实际上链接的源会向您显示所有与帮助器数组相关的类)array_get()

使用点表示法从数组中读取的方法

/**
 * Get an item from an array using "dot" notation.
 *
 * @param  \ArrayAccess|array  $array
 * @param  string  $key
 * @param  mixed   $default
 * @return mixed
 */
public static function get($array, $key, $default = null)
{
    if (! static::accessible($array)) {
        return value($default);
    }
    if (is_null($key)) {
        return $array;
    }
    if (static::exists($array, $key)) {
        return $array[$key];
    }
    if (strpos($key, '.') === false) {
        return $array[$key] ?? value($default);
    }
    foreach (explode('.', $key) as $segment) {
        if (static::accessible($array) && static::exists($array, $segment)) {
            $array = $array[$segment];
        } else {
            return value($default);
        }
    }
    return $array;
}

如您所见,它使用两个子方法,并且accessible()exists()

/**
 * Determine whether the given value is array accessible.
 *
 * @param  mixed  $value
 * @return bool
 */
public static function accessible($value)
{
    return is_array($value) || $value instanceof ArrayAccess;
}

/**
 * Determine if the given key exists in the provided array.
 *
 * @param  \ArrayAccess|array  $array
 * @param  string|int  $key
 * @return bool
 */
public static function exists($array, $key)
{
    if ($array instanceof ArrayAccess) {
        return $array->offsetExists($key);
    }
    return array_key_exists($key, $array);
}

它使用的最后一件事,但你可能会跳过它,是哪个是value()

if (! function_exists('value')) {
    /**
     * Return the default value of the given value.
     *
     * @param  mixed  $value
     * @return mixed
     */
    function value($value)
    {
        return $value instanceof Closure ? $value() : $value;
    }
}

推荐