根据关键字数组取值(其中包含特殊关键字*)
@param string $keys 关键字
@param array $values 值
@param null $default 默认
@param string $link 关键字的连接符
@return string|array
963279
public static function getChildWithStar($keys, array $values, $default = null, $link = '.') {
		$keys = explode($link, $keys, 2);
		$results = null;
		if ($keys[0] === '*') {
			$results = $values;
		} else {
			$results = array_key_exists($keys[0], $values) ? $values[$keys[0]] : $default;
		}
		if (count($keys) == 1) {
			return $results;
		}
		return self::getChildWithStar($keys[1], $results, $default, $link);
	}
700413
protected function prepareLink(string &$link = null): void
	{
		if ($link !== null) {
			if (Strings::endsWith($link, ':default')) {
				$link = substr($link, 0, -7);
			}
			$pos = strrpos($link, ':');
			if ($pos !== strlen($link)) {
				$link = substr($link, 0, $pos + 1);
			}
		}
	}
614700
public static function doteToArr($key = '', &$arr = [], $default = null)
    {
        if (!strpos($key, '.')) {
            return isset($arr[$key]) ? $arr[$key] : $default;
        }

        // 获取多维数组
        $key = explode('.', $key);
        $tmp = null;
        foreach ($key as $k) {
            if (is_null($tmp)) {
                if (isset($arr[$k])) {
                    $tmp = $arr[$k];
                } else {
                    return $default;
                }
            } else {
                if (isset($tmp[$k])) {
                    $tmp = $tmp[$k];
                } else {
                    return $default;
                }
            }
        }
        return $tmp;
    }
972513
public function getMultiple($keys, $default = null)
    {
        return coollect($keys)->map(function ($key) {
            return $this->get($key);
        });
    }
35334
public static function getString(
        array $params,
        string $key,
        $default = null
    ) {
        if (self::has($params, $key)) {
            return (string)$params[$key];
        }

        return $default;
    }
1266213
private static function _getValue($params, $keys, $keysCount, &$ancestorExist, $keyPrefix = '', &$cachedKeyValues = null)
    {
        $keyPath = $keyPrefix;
        $siblings = $params;
        $value = $params;

        if ($keysCount > 1) {
            // 查询缓存
            if ($cachedKeyValues !== null) {

                // todo 如果没有*号, 没必要重新合成路径
                $prefix = $keyPrefix;
                for ($i = 0; $i < $keysCount - 1; $i++) {
                    $key = $keys[$i];
                    if ($prefix === '')
                        $prefix = $key;
                    else if (is_integer($key) || $key === '*')
                        $prefix .= "[$key]";
                    else
                        $prefix .= ".$key";
                }

//                if (array_key_exists($prefix, $cachedKeyValues)) {
//                    echo "\n命中: key=$prefix" . ", value=" . $cachedKeyValues[$prefix] . "\n";
//                }
            }
        }

        for ($n = 0; $n < $keysCount; $n++) {
            $siblings = $value;
            $keyPrefix = $keyPath;

            $key = $keys[$n];
            if ($key === '*') {
                self::validateArr($siblings, null, $keyPrefix);
                $c = count($siblings);
                if ($c > 0) {
                    $subKeys = array_slice($keys, $n + 1);
                    $subKeysCount = $keysCount - $n - 1;

                    if ($subKeysCount) // *号后面还有keys
                    {
                        $values = [];
                        $ancestorExist = false;
                        for ($i = 0; $i < $c; $i++) {
                            $element = $siblings[$i];
                            $keyPath = $keyPrefix . "[$i]";
                            $aAncestorExist = false;
                            $aValue = self::_getValue($element, $subKeys, $subKeysCount, $aAncestorExist, $keyPath, $cachedKeyValues);
                            if ($aAncestorExist) {
                                $values[] = $aValue;
                                $ancestorExist = true;
                            }
//                            self::_validate($element, $subKeys, $subKeysCount, $validator, $keyPath, $ignoreRequired, $cachedKeyValues);
                        }
                    } else // *号是最后一级
                    {
                        $values = $siblings;

                        // todo 缓存数组本身的没什么用, 因为提取不到.
                        if ($cachedKeyValues !== null && $keyPrefix) {
                            $cachedKeyValues[$keyPrefix] = $siblings;
//                            echo "\n缓存: keyPrefix=$keyPrefix, key=$keyPath" . ", value=$siblings\n";
                        }
                    }
                    return $values;
                } else // 'items[*]' => 'Required' 要求items至少有1个元素, 但上面的循环不检测items==[]的情况
                    $value = null; // 这里是针对$value==[]这种情况的特殊处理
            } else {
                if (is_integer($key))
                    self::validateArr($siblings, null, $keyPrefix);
                else
                    self::validateObj($siblings, null, $keyPrefix);
                $value = @$siblings[$key];
            }

            if ($keyPrefix === '')
                $keyPath = $key;
            else if (is_integer($key) || $key === '*')
                $keyPath = $keyPrefix . "[$key]";
            else
                $keyPath = "$keyPrefix.$key";

            if ($value === null) {
                $n++;
                break;
            }
        }

        // 到这里$n表示当前的$value是第几层. 取值在[1, $keysCount]之间, 也就是说 $n 只可能小于或等于$keysCount
        if ($n == $keysCount) {
            $ancestorExist = true;
        } else {
            $ancestorExist = false;
            if ($cachedKeyValues !== null) {
                for (; $n < $keysCount; $n++) {
                    $keyPrefix = $keyPath;

                    $key = $keys[$n];

                    if ($keyPrefix === '')
                        $keyPath = $key;
                    else if (is_integer($key) || $key === '*')
                        $keyPath = $keyPrefix . "[$key]";
                    else
                        $keyPath = "$keyPrefix.$key";
                }
                $siblings = null;
            }
        }
        if ($cachedKeyValues !== null && $keyPrefix) {
            $cachedKeyValues[$keyPrefix] = $siblings; // 将父级数据缓存起来
//            echo "\n缓存: keyPrefix=$keyPrefix, key=$keyPath" . ", value=$siblings\n";
        }
        return $value;
    }
865316
public function hasOne($link, $defaults = [])
    {
        if (!is_array($defaults)) {
            $defaults = ['model' => $defaults ?: 'Model_'.$link];
        }

        $defaults['join'] = $this;

        return $this->owner->hasOne($link, $defaults);
    }
1168106
protected function linksForJson($uri, $links, $arrayLinkRels)
    {
        $data = array();
        if (!is_null($uri)) {
            $data['self'] = array('href' => $uri);
        }
        foreach ($links as $rel => $links) {
            if (count($links) === 1 && $rel !== 'curies' && !in_array($rel, $arrayLinkRels)) {
                $data[$rel] = array('href' => $links[0]->getUri());
                foreach ($links[0]->getAttributes() as $attribute => $value) {
                    $data[$rel][$attribute] = $value;
                }
            } else {
                $data[$rel] = array();
                foreach ($links as $link) {
                    $item = array('href' => $link->getUri());
                    foreach ($link->getAttributes() as $attribute => $value) {
                        $item[$attribute] = $value;
                    }
                    $data[$rel][] = $item;
                }
            }
        }

        return $data;
    }
793261
public static function choicesIsset(array $values, array $choices)
    {
        self::notEmpty($values, null, null);

        foreach ($choices as $choice) {

            self::keyIsset($values, $choice, null, null);
        }
    }
1002396
function get($key, $default = null)
    {
        $index = array_search($key, $this->keys);

        if ($index !== false) {
            return $this->values[$index];
        } else {
            return $default;
        }
    }
1328496
private function renderView($links)
	{
		$defaults = $this->defaults;

		return View::make($this->view, compact('links', 'defaults'))->render();
	}
724222
public function value($key, $default = null)
    {
        return array_key_exists($key, $this->values)
            ? $this->values[$key]
            : $default;
    }
579896
public static function createFromValues(array $values)
    {
        if (\array_key_exists('keys', $values) && \is_array($values['keys'])) {
            return JWKSet::createFromKeyData($values);
        }

        return JWK::create($values);
    }
410537
public static function getChildByArray(array $keys, array $values, $default = null) {
		switch (count($keys)) {
			case 0:
				return $values;
			case 1:
				return array_key_exists($keys[0], $values) ? $values[$keys[0]] : $default;
			case 2:
				return isset($values[$keys[0]][$keys[1]]) ? $values[$keys[0]][$keys[1]] : $default;
			case 3:
				return isset($values[$keys[0]][$keys[1]][$keys[2]]) ? $values[$keys[0]][$keys[1]][$keys[2]] : $default;
			case 4:
				return isset($values[$keys[0]][$keys[1]][$keys[2]][$keys[3]]) ? $values[$keys[0]][$keys[1]][$keys[2]][$keys[3]] : $default;
			default:
				return isset($values[$keys[0]]) ? self::getChildByArray(array_slice($keys, 1), $values[$keys[0]], $default) : $default;
		}
	}
308880
public function getConfigValue($keys, $default = null)
    {
        $value = $this->_config;
        foreach ((array) $keys as $key) {
            if (isset($value[$key])) {
                $value = $value[$key];
            } else {
                return $default;
            }
        }

        return $value;
    }
1226102
public function getMultiple($keys, $default = null) : array
    {
        if (!is_array($keys) && !is_object($keys)) {
            throw new \TypeError('Arg keys type[' . Utils::getType($keys) . '] is not array|object.');
        }
        $values = [];
        foreach ($keys as $k) {
            $values[$k] = $this->get($k, $default);
        }
        return $values;
    }
456493
protected function buildLinks($links, array $linksOptions = [])
    {
        return array_map(function ($link) use ($linksOptions) {
            return $this->Html->link($link[0], $link[1], $linksOptions);
        }, $links);
    }