将"this.that.other"之类的点语法转换为PHP中的多维数组

Bry*_*tts 33 php parsing

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

s1.t1.column.1 = size:33%
Run Code Online (Sandbox Code Playgroud)

会是一样的

$source['s1']['t1']['column']['1'] = 'size:33%';
Run Code Online (Sandbox Code Playgroud)

ale*_*lex 42

试试这个号码......

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

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

    $arr = $value;
}
Run Code Online (Sandbox Code Playgroud)

键盘

它将遍历键(.默认分隔)以获取最终属性,然后对值进行赋值.

如果某些键不存在,则会创建它们.

  • 作为记录,这将是补充变体:http://stackoverflow.com/a/10424516/1388892 (2认同)
  • 这个功能有一个bug.由于"while"评估,如果路径中有0,它将打破循环:abc.0.bac.1将仅生成:$ arr ['abc'].要修复,只需将第一行替换为while()...到foreach循环.此外,向它添加第四个参数$ separator将使它对不同的情况更有用(例如,当你有下划线或破折号时):function assignArrayByPath(&$ arr,$ path,$ value,$ separator ='.'){ $ keys = explode($ separator,$ path); foreach($ keys AS $ key){$ arr =&$ arr [$ key]; } $ arr = $ value; } (2认同)

pha*_*est 20

仅供参考在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;
}
Run Code Online (Sandbox Code Playgroud)

这很简单

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

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

// ['products' => ['desk' => ['price' => 200]]]
Run Code Online (Sandbox Code Playgroud)

您可以在文档中查看它

如果您需要使用点表示法来获取数据,则该过程会稍长一些,但是在一个平台上提供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;
}
Run Code Online (Sandbox Code Playgroud)

如你所见,它使用两个子方法,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;
}
Run Code Online (Sandbox Code Playgroud)

/**
 * 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);
}
Run Code Online (Sandbox Code Playgroud)

它最后使用的东西,但你可以跳过它,就是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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Erk*_*ren 6

您可以使用此函数将点表示法数组转换为多维数组。

function flattenToMultiDimensional(array $array, $delimiter = '.')
{
    $result = [];
    foreach ($array as $notations => $value) {
        // extract keys
        $keys = explode($delimiter, $notations);
        // reverse keys for assignments
        $keys = array_reverse($keys);

        // set initial value
        $lastVal = $value;
        foreach ($keys as $key) {
            // wrap value with key over each iteration
            $lastVal = [
                $key => $lastVal
            ];
        }
        
        // merge result
        $result = array_merge_recursive($result, $lastVal);
    }

    return $result;
}
Run Code Online (Sandbox Code Playgroud)

例子:

$array = [
    'test.example.key' => 'value'
];

print_r(flattenToMultiDimensional($array));
Run Code Online (Sandbox Code Playgroud)

输出:

Array
(
    [test] => Array
        (
            [example] => Array
                (
                    [key] => value
                )

        )

)
Run Code Online (Sandbox Code Playgroud)