转换点语法,如;“这个.那个.其他”;在PHP中实现多维数组
正如标题所暗示的,我正在尝试创建一个解析器,并试图找到将点名称空间中的内容转换为多维数组的最佳解决方案,以便转换点语法,如;“这个.那个.其他”;在PHP中实现多维数组,php,parsing,Php,Parsing,正如标题所暗示的,我正在尝试创建一个解析器,并试图找到将点名称空间中的内容转换为多维数组的最佳解决方案,以便 s1.t1.column.1 = size:33% 就跟 $source['s1']['t1']['column']['1'] = 'size:33%'; 试试这个号码 function assignArrayByPath(&$arr, $path, $value, $separator='.') { $keys = explode($separator, $path
s1.t1.column.1 = size:33%
就跟
$source['s1']['t1']['column']['1'] = 'size:33%';
试试这个号码
function assignArrayByPath(&$arr, $path, $value, $separator='.') {
$keys = explode($separator, $path);
foreach ($keys as $key) {
$arr = &$arr[$key];
}
$arr = $value;
}
它将循环通过键(默认情况下以
分隔)到达最终属性,然后对值进行赋值
如果某些键不存在,则会创建它们。我很确定您正在尝试这样做以存储一些配置数据或类似数据 我强烈建议您将此类文件保存为
.ini
,并使用函数将配置数据更改为多维数组。就这么简单
$confArray = parse_ini_file("filename.ini");
var_dump($confArray);
又快又脏
<?php
$input = 'one.two.three = four';
list($key, $value) = explode('=', $input);
foreach (explode('.', $key) as $keyName) {
if (false === isset($source)) {
$source = array();
$sourceRef = &$source;
}
$keyName = trim($keyName);
$sourceRef = &$sourceRef[$keyName];
}
$sourceRef = $value;
unset($sourceRef);
var_dump($source);
虽然pasrse_ini_file()也可以产生多维数组,但我将提供一个不同的解决方案
$conf = new Zend_COnfig_Ini("path/to/file.ini");
echo $conf -> one -> two -> three; // This is how easy it is to do so
//prints one.two.three
我在上找到了一个适合我的解决方案:因为我有一个基于.ini文件的数组,有不同的键,所以我做了一个很小的数组,为我工作
我的数组如下所示:
[resources.db.adapter] => PDO_MYSQL
[resources.db.params.host] => localhost
[resources.db.params.dbname] => qwer
[resources.db.params.username] => asdf
...
根据请求,这是我描述的为我工作的代码:
<?php
echo "remove the exit :-)"; exit;
$db_settings = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/website/var/config/app.ini');
echo "<pre>";
print_r($db_settings);
echo "</pre>";
$resources = array();
foreach ($db_settings as $path => $value) {
$ancestors = explode('.', $path);
set_nested_value($resources, $ancestors, $value);
}
echo "<pre>";
print_r($resources);
echo "</pre>";
/**
* Give it and array, and an array of parents, it will decent into the
* nested arrays and set the value.
*/
function set_nested_value(array &$arr, array $ancestors, $value) {
$current = &$arr;
foreach ($ancestors as $key) {
// To handle the original input, if an item is not an array,
// replace it with an array with the value as the first item.
if (!is_array($current)) {
$current = array( $current);
}
if (!array_key_exists($key, $current)) {
$current[$key] = array();
}
$current = &$current[$key];
}
$current = $value;
}
这是上述代码的结果:
$size = $username = $data->get('s1.t1.column.1');
仅供参考,在Laravel中,我们有一个array\u set()
helper函数,在这个函数中进行翻译
方法使用点表示法存储在数组中
/**
*使用“点”符号将数组项设置为给定值。
*
*如果没有为该方法提供键,则将替换整个数组。
*
*@param数组$array
*@param string$key
*@param混合$value
*@return数组
*/
公共静态函数集(&$array,$key,$value)
{
如果(为空($key)){
返回$array=$value;
}
$keys=分解('.',$key);
同时(计数($keys)>1){
$key=数组移位($key);
//如果键在此深度不存在,我们将创建一个空数组
//来保存下一个值,允许我们创建数组来保存final
//值在正确的深度。然后我们将继续挖掘数组。
如果(!isset($array[$key])| |!is_array($array[$key])){
$array[$key]=[];
}
$array=&$array[$key];
}
$array[array_shift($keys)]=$value;
返回$array;
}
这很简单
$array=['products'=>['desk'=>['price'=>100]];
数组_集($数组,'products.desk.price',200);
//['products'=>['desk'=>['price'=>200]]
你可以查一下
如果您需要使用点表示法获取数据,则该过程会稍微长一点,但由array\u get()
提供在一个盘子上,它转换为(实际上链接的源代码显示了所有与helper数组相关的类)
方法使用点表示法从数组中读取
/**
*使用“点”符号从数组中获取项。
*
*@param\ArrayAccess | array$array
*@param string$key
*@param混合$default
*@返回混合
*/
公共静态函数get($array,$key,$default=null)
{
如果(!static::accessible($array)){
返回值($default);
}
如果(为空($key)){
返回$array;
}
if(static::exists($array,$key)){
返回$array[$key];
}
if(strpos($key,'.')==false){
返回$array[$key]??值($default);
}
foreach(分解('.',$key)为$segment){
if(static::accessible($array)&&static::exists($array,$segment)){
$array=$array[$segment];
}否则{
返回值($default);
}
}
返回$array;
}
如您所见,它使用两个子方法,accessible()
和exists()
/**
*确定给定值是否可访问数组。
*
*@param混合$value
*@returnbool
*/
可访问的公共静态函数($value)
{
返回的是ArrayAccess的_数组($value)| |$value实例;
}
及
/**
*确定提供的数组中是否存在给定的密钥。
*
*@param\ArrayAccess | array$array
*@param string | int$key
*@returnbool
*/
存在公共静态函数($array,$key)
{
if($array instanceof ARRAYAACCESS){
返回$array->offsetExists($key);
}
返回数组\u key\u存在($key,$array);
}
它使用的最后一个东西,但您可能可以跳过它,是value()
,它是
如果(!function_存在('value')){
/**
*返回给定值的默认值。
*
*@param混合$value
*@返回混合
*/
函数值($value)
{
返回闭包的$value实例?$value():$value;
}
}
我建议使用
如果您不熟悉Composer的使用,请转到进行介绍,这样您就可以下载并自动加载该包,作为项目的依赖项
获得包后,可以将多维数组加载到数据对象中:
Array
(
[test] => Array
(
[example] => Array
(
[key] => value
)
)
)
并使用点符号访问值:
可以使用此函数将点符号arrray转换为多维数组
函数flattToMultidimensional(数组$array,$delimiter='))
{
$result=[];
foreach($array作为$notations=>$value){
//提取密钥
$keys=explode($delimiter,$notations);
//为作业反转键
$keys=数组_反转($keys);
//设定初始值
$lastVal=$value;
foreach($key作为$key){
//在每次迭代中使用键包装值
$lastVal=[
$key=>$lastVal
];
}
//合并结果
$result=array\u merge\u recursive($result$lastVal);
}
返回$result;
}
例如:
$array=[
'test.example.key'=>'值'
];
打印(平面到多维($array));
输出:
我不明白你为什么要重写
use Dflydev\DotAccessData\Data;
$data = new Data(array(
's1' => array(
't1' => array(
'column' => array(
'1' => 'size:33%',
),
),
),
);
$size = $username = $data->get('s1.t1.column.1');
Array
(
[test] => Array
(
[example] => Array
(
[key] => value
)
)
)