PHP-如何使函数等待并返回另一个函数值
所以我有一些XML,我需要遍历子对象来找到一个child值。问题在于实际的循环。我所知道的方法是生成一个函数,如果有子函数,使用相同的函数并循环遍历子函数,然后重复第四次 我的问题是,函数似乎并没有在返回我的值之前等待“子函数”完成 有更好的方法吗?我知道有回调,但我不确定如何在这里实现它 示例XMLPHP-如何使函数等待并返回另一个函数值,php,xml,function,loops,children,Php,Xml,Function,Loops,Children,所以我有一些XML,我需要遍历子对象来找到一个child值。问题在于实际的循环。我所知道的方法是生成一个函数,如果有子函数,使用相同的函数并循环遍历子函数,然后重复第四次 我的问题是,函数似乎并没有在返回我的值之前等待“子函数”完成 有更好的方法吗?我知道有回调,但我不确定如何在这里实现它 示例XML <?xml version="1.0" standalone="yes"?> <pages> <page> <title>P
<?xml version="1.0" standalone="yes"?>
<pages>
<page>
<title>Parent Page1</title>
<id>0</id>
<children>
<page>
<title>Child Page1</title>
<id>1</id>
<children/>
</page>
</children>
</page>
<page>
<title>Parent Page2</title>
<id>2</id>
<children>
<page>
<title>Child Page2</title>
<id>3</id>
<children/>
</page>
</children>
</page>
</pages>
正在输出:子页面2的ID为
现在我知道XML在这个例子中并不完美,但它只是一个占位符,所以您可以理解我要做的事情。我在XML上使用SimpleXML,如果这有任何帮助的话
解决方案
问题是如果b()
在第一个分支中返回,但仍然需要检查子级的其他分支,整个过程返回null
,或者根本没有返回任何内容
我下面的解决方案可行,但与Swayze的答案一致,因为它更短、更有效(保存变量)尝试以下方法:
<?php
$page = "Child Page";
echo "The ID of " . $page . " is " . a($page);
function a($title) {
$pages = [
[
'title' => 'Parent Page',
'id' => 0,
'children' => [
[
'title' => 'Child Page',
'id' => 1,
'children' => []
]
]
]
];
return b($pages, $title);
}
function b($pages, $title) {
foreach ($pages as $page) {
if ($page['title'] == $title) {
$val = $page['id'];
} else if (count($page['children']) > 0) {
$val = b($page['children'], $title);
}
}
return $val;
}
我认为您可以使用xPath简化工作:
function b( $xml, $title )
{
$val = Null;
$pattern = '//page/title[text()="'.$title.'"]/..';
if( $found = $xml->xpath( $pattern ) ) $val = $found[0]->id;
return $val;
}
您还可以对其进行修改,以便最终有多个相同的标题:
function b( $xml, $title )
{
$val = array();
$pattern = '//page/title[text()="'.$title.'"]/..';
foreach( $xml->xpath( $pattern ) as $node )
{
$val[] = $found[0]->id;
}
return $val;
}
xPath模式解释:
//搜索以下模式,无论其位于何处
带有子级的页面/标题
[text()=“.”.$title.“]节点值=$text
/.. 选择父节点
我终于找到了问题所在。问题是,因为我有很多分支(很多父母都有孩子),一旦我的循环通过了第一个分支,却什么也没有找到,它就将null
返回到函数,该函数也将null
返回到开始处
我可以通过添加一个简单的if($received!=null)
来解决这个问题,如下所示
function b ($pages, $title) {
$val;
foreach ($pages as $page) {
if($page->title == $title) {
$val = $page->id;
break;
} else if ($page->children->children() > 0){
$received = b($page->children->children(), $title);
if ($received != null) { // Important
$val = $received;
}
}
}
return $val;
}
在我放置注释的地方,您可以看到最终返回是被迫等待foreach的其余部分,而不仅仅是使用它接收到的第一个null
function b ($pages, $title){
foreach ($pages as $page){
if($page->title == $title){
// returns id regardless of how many loops in you are
return $page->id;}
else if ($page->children->children() > 0){
// call function if it has children
return b ($page->children->children(), $title);}}
// if nothing is found
return 'no results';}
如果每个标题只能有一个实例,这是最简单的方法
如果我误解了您的意思,并且每次搜索可能会有多个结果,那么此方法将只返回找到的第一个匹配项的id。您是否可以将您的$pages
变量包括在内,忘记将$pages
更改为$xml
使用xml字符串有什么原因吗?不能对字符串执行foreach
。此外,您不需要声明$val;在函数b的顶部,我需要一种保存信息的方法,这似乎是我所知道的最好的选择,但只是将它使用simpleXML进行成像,所以它可以作为一个数组进行正确的输出,我只是想解释一下我正在使用的XML标记(家长和孩子)是的,这正是我想要做的。我添加了几个额外的子函数,它仍然有效,打破了我的理论,即如果调用了另一个函数,返回的函数实际上会等待。PHP函数是同步运行的,所以不会遇到这个问题。另外,如果我回答了你的问题,你能记下我的答案吗?谢谢你,伙计!哦,好的,谢谢你的回答,这意味着我的代码还有其他问题!谢谢你的帮助!就像我说的,这不是有效的代码,这是一个示例,向您展示了XML是如何布局的。我正在使用SimpleXML。我发布的代码运行良好。。试一试,你遇到的问题是,当你发现结果时,你需要打破这个循环。很抱歉,我的代码中也有这个,我只是忘了将它添加到我的示例中。我可以看到你的编辑,但这样行吗?您对b()的调用没有保存到任何变量,因此即使它确实找到了一些东西,它也不会丢失吗?啊,我错过了“return$page->id”这比我保存为variable好得多,而且可能比我保存为variable快得多如果您只查找一个结果,则不需要通过函数循环不断传递$val。。它过于复杂和不必要。。。您只需在找到值时返回该值,或者在完成后返回未找到的值。但是,如果我需要从多个分支的子级中找到单个值,那么我需要继续在父级及其子级之间循环,或者有更好的方法或这样做吗?您仍然可以循环并搜索所有子级,即使它是多维的,也不会传递变量。我将编辑我的原始答案,向您展示我的意思。有趣的是,我将研究代码,并可能在稍后将其改编为我的代码
function b ($pages, $title){
foreach ($pages as $page){
if($page->title == $title){
// returns id regardless of how many loops in you are
return $page->id;}
else if ($page->children->children() > 0){
// call function if it has children
return b ($page->children->children(), $title);}}
// if nothing is found
return 'no results';}