PHP - 如何让一个函数等待并且 return 另一个函数值
PHP - How do I make a function wait and return another functions value
所以我有一些 XML 我需要遍历 children 来找到 childs 值。问题是实际的循环。我知道的方法是制作一个函数,如果有 child,使用相同的函数并循环遍历 children - 如此循环第四次。
我的问题是函数似乎没有在等待 "child function" 完成后返回我的值。
有更好的方法吗?我知道有回调,但我不确定如何在这里实现它
例子XML
<?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>
例子PHP
$page = "Child Page2";
echo "The ID of " . $page . " is " . a($page);
function a ($title) {
$xml = simplexml_load_file("pages.xml") or die("Failed.");
return b ($xml[0], $title);
}
function b ($pages, $title) {
$val;
foreach ($pages as $page) {
if($page->title == $title) {
$val = $page->id;
break;
} else if ($page->children->children() > 0){
$val = b($page->children->children(), $title);
}
}
return $val;
}
正在输出:The ID of Child Page2 is
现在我知道 XML 在这个例子中并不完美,但它只是一个占位符,所以你明白我想做什么。我在 XML 上使用 SimpleXML 如果有任何帮助的话
解决方案
问题是,如果 b();
在第一个分支返回,但仍需要检查 children 的其他分支,则整个返回 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;
}
如果不需要,我不会在这里使用 XML。这是一个使用数组的粗略示例,但它适用于您要执行的操作。如果这对你有用,请告诉我。如果你喜欢对象表示法,你可以把数组变成一个对象,或者使用 类 (首选)。
我认为您可以仅使用 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 模式说明:
// Search following pattern no matter where it is
page/title <page> with child <title> with
[text()="'.$title.'"] node value = $text
/.. select parent node
终于找到问题了。问题是因为我有很多分支(许多 parents 和 children),一旦我的循环通过第一个分支但什么也没找到,它 returned null
到也 returned 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;
}
在我发表评论的地方,你可以看到最后的 return 被迫等待 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';}
如果每个标题只能有一个实例,这是最简单的方法..
如果我误解了你,并且每次搜索可能会有多个结果,那么此方法只会 return 它找到的第一个匹配项的 ID。
所以我有一些 XML 我需要遍历 children 来找到 childs 值。问题是实际的循环。我知道的方法是制作一个函数,如果有 child,使用相同的函数并循环遍历 children - 如此循环第四次。
我的问题是函数似乎没有在等待 "child function" 完成后返回我的值。
有更好的方法吗?我知道有回调,但我不确定如何在这里实现它
例子XML
<?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>
例子PHP
$page = "Child Page2";
echo "The ID of " . $page . " is " . a($page);
function a ($title) {
$xml = simplexml_load_file("pages.xml") or die("Failed.");
return b ($xml[0], $title);
}
function b ($pages, $title) {
$val;
foreach ($pages as $page) {
if($page->title == $title) {
$val = $page->id;
break;
} else if ($page->children->children() > 0){
$val = b($page->children->children(), $title);
}
}
return $val;
}
正在输出:The ID of Child Page2 is
现在我知道 XML 在这个例子中并不完美,但它只是一个占位符,所以你明白我想做什么。我在 XML 上使用 SimpleXML 如果有任何帮助的话
解决方案
问题是,如果 b();
在第一个分支返回,但仍需要检查 children 的其他分支,则整个返回 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;
}
如果不需要,我不会在这里使用 XML。这是一个使用数组的粗略示例,但它适用于您要执行的操作。如果这对你有用,请告诉我。如果你喜欢对象表示法,你可以把数组变成一个对象,或者使用 类 (首选)。
我认为您可以仅使用 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 模式说明:
// Search following pattern no matter where it is
page/title <page> with child <title> with
[text()="'.$title.'"] node value = $text
/.. select parent node
终于找到问题了。问题是因为我有很多分支(许多 parents 和 children),一旦我的循环通过第一个分支但什么也没找到,它 returned null
到也 returned 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;
}
在我发表评论的地方,你可以看到最后的 return 被迫等待 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';}
如果每个标题只能有一个实例,这是最简单的方法..
如果我误解了你,并且每次搜索可能会有多个结果,那么此方法只会 return 它找到的第一个匹配项的 ID。