我正在使用Laravel
并且正在尝试编写一个接受参数$ art的工匠命令,然后需要将其转换为数组。例如:
// An example of a value that is being passed in from the CLI and stored as $content
$content = "['div']['div'][0]['h2']['a']";
为了澄清,$content
然后作为函数参数传入,其中它将用于从实际结果集中提取值。换句话说,我收到来自API的响应,$content
是我需要从响应中提取的值的路径。例如,实现的硬编码版本如下:
$result = $report['div']['div'][0]['h2']['a'];
现在,$result
包含我需要处理的值。但是,我正在努力使这个动态,所以每次添加新的数据源来检查报告时我都不会重复自己。目前,我有4个函数,每个函数都有到所需结果的硬编码路径;我的目标是使它能够传入包含所需值路径的参数并重构我的代码,因此我只有一个函数接受值的路径作为参数。
我希望澄清最终目标,以及为什么我只引用键,而不是值。
无论如何,回到手头的问题。我尝试了以下不同的变体:
// Attempting to parse the string into an array
$arr = explode("]", trim(str_replace("[","",$content), "]"));
这导致以下数组:
array (size=5)
0 => string ''div'' (length=5)
1 => string ''div'' (length=5)
2 => string '0' (length=1)
3 => string ''h2'' (length=4)
4 => string ''a'' (length=3)
但是,我需要的是将数组格式化如下:
$array = ['div']['div'][0]['h2']['a']
我尝试对foreach($array as $element)
$arr
进行array_push
并为每个元素执行$arr
,但这会产生与$content
相同的输出。
如何循环遍历字符串并将其解析为数组?另外,我需要0作为索引保留,而不是类型转换为字符串。最后一点,[
的值每次都会完全不同,所以我需要它非常灵活。唯一保持不变的部分是]
,private function yql_check_website($url, $xpath, $content) {
require_once('../vendor/OAuth.php');
$statement = "select * from html where url='{$url}' and xpath='{$xpath}' ";
$cc_key = $this->key;
$cc_secret = $this->secret;
$url = "http://query.yahooapis.com/v1/public/yql";
$args = array();
$args["q"] = $statement;
$args["format"] = "json";
$consumer = new OAuthConsumer($cc_key, $cc_secret);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL,"GET", $url, $args);
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
$url = sprintf("%s?%s", $url, OAuthUtil::build_http_query($args));
$url .= "&env=store://datatables.org/alltableswithkeys";
$ch = curl_init();
$headers = array($request->to_header());
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$rsp = curl_exec($ch);
$report = json_decode($rsp, true);
// Dynamically inspect the $report object for the xpath content
$result = $report . $content;
unset($report);
return $result;
}
将始终封装密钥。
我很想知道其他人如何解决这个看似微不足道的问题(我已经花了几年的时间从编程开始,显然已经忘记了比我更愿意承认的事情;))。老实说,我认为str_replace和explode将为我提供我期待的结果......
但是,在重新阅读php.net/explode文档后,它总是将每个元素转换为字符串(从而覆盖我的0索引),而我不知道如何将其转换为嵌套数组,而是一个简单的扁平阵列。
我期待着您的建议和见解。感谢。
编辑:
包括使用参数的函数,以帮助提供更清晰的信息。
$report['div']['div'][0]['h2']['a']
因此,$ report包含整个API响应,但我唯一需要的是$content
中提供的内容(对于此示例,至少,每个报告的路径都不同,我是刮)。所以,我试图将命令行参数转换为数组的原因是,它可以在上面的代码中使用,其中{{1}}被调用,以便导航API的响应并从中返回值分割。
我希望这更有意义。而且,如果有更好的方法来实现这个目标,请随意提及它。我可能采取了错误的做法......
答案 0 :(得分:1)
Laravel有一些数组访问方法,可以提供对数组的“点”访问,包括array_get。方法原型如下所示:
function array_get(array $array, string $key, mixed $default = null)
所以,在你的情况下,你可以写:
$results = array_get($report, "div.div.0.h2.a");
答案 1 :(得分:0)
你可以在这里使用preg_match_all ..
$content = "['div']['div'][0]['h2']['a']";
$expression = /\['([a-zA-Z0-9]+)\']/;
$results = preg_match_all( $expression, $content, $matches );
print_r( $matches );
如果你必须让阵列像你所说的那样,你可以做这样的事情(对于初学者来说 - 这虽然有点丑陋......)
// array( ['div']['div'][0]['h2']['a']
// visualizing...
// array( 'div' => array ( 'div' => 'array( "0" => array( "h2" => array( "a") ) ) ) );
function createDepth( $source, $currentKey, $nextDepth = null ) {
if( !is_array( $nextDepth ) ) {
$source[] = array( $currentKey => $nextDepth );
} else {
$nextKey = array_shift( $nextDepth );
$source[] = createDepth( array( $currentKey => array() ), $nextKey, $nextDepth );
}
return source;
}
// Edit: doh, unset the first key..
unset( $matches[0] );
// Continue from here.
$currentKey = array_shift( $matches );
$holder = array();
$final = createDepth( $holder, $currentKey, $matches);
print_r( $final );
注意:上述所有内容均未经测试......
答案 2 :(得分:0)
这是你想要的吗?
$str = "['div']['div'][0]['h2']['a']";
$str = preg_split('/]\[/', substr(str_replace("'", "", $str), 1, -1));
print_r($str);
Array (
[0] => div
[1] => div
[2] => 0
[3] => h2
[4] => a
)