Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-如何使函数等待并返回另一个函数值_Php_Xml_Function_Loops_Children - Fatal编程技术网

PHP-如何使函数等待并返回另一个函数值

PHP-如何使函数等待并返回另一个函数值,php,xml,function,loops,children,Php,Xml,Function,Loops,Children,所以我有一些XML,我需要遍历子对象来找到一个child值。问题在于实际的循环。我所知道的方法是生成一个函数,如果有子函数,使用相同的函数并循环遍历子函数,然后重复第四次 我的问题是,函数似乎并没有在返回我的值之前等待“子函数”完成 有更好的方法吗?我知道有回调,但我不确定如何在这里实现它 示例XML <?xml version="1.0" standalone="yes"?> <pages> <page> <title>P

所以我有一些XML,我需要遍历子对象来找到一个child值。问题在于实际的循环。我所知道的方法是生成一个函数,如果有子函数,使用相同的函数并循环遍历子函数,然后重复第四次

我的问题是,函数似乎并没有在返回我的值之前等待“子函数”完成

有更好的方法吗?我知道有回调,但我不确定如何在这里实现它

示例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>
正在输出:
子页面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';}