我在访问 php.ini 中的数组时遇到问题。
$path = "['a']['b']['c']";
$value = $array.$path;
在上面的代码中,我有一个名为 $array 的多维数组。
$path
是我从数据库中获得的动态值。
现在我想使用 $path 从 $array 中检索值,但我做不到。
$value = $array.$path
还给我
Array['a']['b']['c']
而不是价值。
我希望我已经正确解释了我的问题。
你有两个选择。首先(邪恶)如果使用eval()
函数 - 即将您的字符串解释为code。
其次是解析你的路径。那将是:
//$path = "['a']['b']['c']";
preg_match_all("/\['(.*?)'\]/", $path, $rgMatches);
$rgResult = $array;
foreach($rgMatches[1] as $sPath)
{
$rgResult=$rgResult[$sPath];
}
Kohana 框架“ Arr”类 (API)有一个方法 ( Arr::path
),它执行与您所请求的类似的操作。它只需要一个数组和一个路径(带有.
分隔符)并在找到时返回值。您可以修改此方法以满足您的需要。
public static function path($array, $path, $default = NULL, $delimiter = NULL)
{
if ( ! Arr::is_array($array))
{
// This is not an array!
return $default;
}
if (is_array($path))
{
// The path has already been separated into keys
$keys = $path;
}
else
{
if (array_key_exists($path, $array))
{
// No need to do extra processing
return $array[$path];
}
if ($delimiter === NULL)
{
// Use the default delimiter
$delimiter = Arr::$delimiter;
}
// Remove starting delimiters and spaces
$path = ltrim($path, "{$delimiter} ");
// Remove ending delimiters, spaces, and wildcards
$path = rtrim($path, "{$delimiter} *");
// Split the keys by delimiter
$keys = explode($delimiter, $path);
}
do
{
$key = array_shift($keys);
if (ctype_digit($key))
{
// Make the key an integer
$key = (int) $key;
}
if (isset($array[$key]))
{
if ($keys)
{
if (Arr::is_array($array[$key]))
{
// Dig down into the next part of the path
$array = $array[$key];
}
else
{
// Unable to dig deeper
break;
}
}
else
{
// Found the path requested
return $array[$key];
}
}
elseif ($key === '*')
{
// Handle wildcards
$values = array();
foreach ($array as $arr)
{
if ($value = Arr::path($arr, implode('.', $keys)))
{
$values[] = $value;
}
}
if ($values)
{
// Found the values requested
return $values;
}
else
{
// Unable to dig deeper
break;
}
}
else
{
// Unable to dig deeper
break;
}
}
while ($keys);
// Unable to find the value requested
return $default;
}
我希望找到一个优雅的嵌套数组访问解决方案,而不会引发未定义的索引错误,这篇文章在谷歌上很受欢迎。我参加聚会迟到了,但我想为未来的访客权衡一下。
一个简单的isset($array['a']['b']['c']
可以安全地检查嵌套值,但您需要提前知道要访问的元素。我喜欢用点表示法来访问多维数组,所以我自己写了一个类。它确实需要 PHP 5.6。
此类解析以点表示法编写的字符串路径,并安全地访问数组或类数组对象的嵌套值(实现 ArrayAccess)。如果未设置,它将返回值或 NULL。
use ArrayAccess;
class SafeArrayGetter implements \JsonSerializable {
/**
* @var array
*/
private $data;
/**
* SafeArrayGetter constructor.
*
* @param array $data
*/
public function __construct( array $data )
{
$this->data = $data;
}
/**
* @param array $target
* @param array ...$indices
*
* @return array|mixed|null
*/
protected function safeGet( array $target, ...$indices )
{
$movingTarget = $target;
foreach ( $indices as $index )
{
$isArray = is_array( $movingTarget ) || $movingTarget instanceof ArrayAccess;
if ( ! $isArray || ! isset( $movingTarget[ $index ] ) ) return NULL;
$movingTarget = $movingTarget[ $index ];
}
return $movingTarget;
}
/**
* @param array ...$keys
*
* @return array|mixed|null
*/
public function getKeys( ...$keys )
{
return static::safeGet( $this->data, ...$keys );
}
/**
* <p>Access nested array index values by providing a dot notation access string.</p>
* <p>Example: $safeArrayGetter->get('customer.paymentInfo.ccToken') ==
* $array['customer']['paymentInfo']['ccToken']</p>
*
* @param $accessString
*
* @return array|mixed|null
*/
public function get( $accessString )
{
$keys = $this->parseDotNotation( $accessString );
return $this->getKeys( ...$keys );
}
/**
* @param $string
*
* @return array
*/
protected function parseDotNotation( $string )
{
return explode( '.', strval( $string ) );
}
/**
* @return array
*/
public function toArray()
{
return $this->data;
}
/**
* @param int $options
* @param int $depth
*
* @return string
*/
public function toJson( $options = 0, $depth = 512 )
{
return json_encode( $this, $options, $depth );
}
/**
* @param array $data
*
* @return static
*/
public static function newFromArray( array $data )
{
return new static( $data );
}
/**
* @param \stdClass $data
*
* @return static
*/
public static function newFromObject( \stdClass $data )
{
return new static( json_decode( json_encode( $data ), TRUE ) );
}
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return array data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
function jsonSerialize()
{
return $this->toArray();
}
}