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

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

问题描述:

所以我有一些XML我需要循环通过孩子找到一个孩子的价值。问题是实际的循环。我知道的方式是制作一个功能,如果有一个孩子,使用相同的功能,并循环通过孩子 - 再次,第四。PHP - 我如何使一个函数等待并返回另一个函数值

我的问题是,它看起来好像该函数正在等待“子函数”在返回我​​的值之前完成。

有没有更好的方法来做到这一点?我知道有回调,但我不确定我怎么会在这里实现它

示例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在这个例子中并不完美,但它只是一个pl aceholder让你明白我想要做什么。我使用的SimpleXML的XML如果以任何方式

解决方案

的问题是,如果返回的第一个分支b();,但是仍然需要检查孩子的其他分支,整个事情帮助返回null或完全没有。

我的解决方案低下来的作品,但去与斯韦兹的答案,因为它是更短,更有效(保存保存变量)

+1

请问您可以包括您的'$ pages'变量 –

+0

有没有抱歉,忘记从'$ pages'更改为'$ xml' –

+0

是否有任何理由使用XML字符串?你不能在一个字符串上“foreach”。另外,你不需要声明$ val;在函数b的顶部。 –

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。

+0

就像我说这不是工作代码,它是一个例子,向你展示XML是如何布局的 我正在使用SimpleXML –

+0

我发布的代码工作正常..试试吧,你遇到的问题是因为你需要打破循环,当你找到结果 – Swayze

+0

对不起,关于这一点,我也在我的代码中,我只是忘了把它添加到我的例子 –

试试这个:

<?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不需要。这是一个使用数组的简单例子,但它适用于你想要做的事情。让我知道这是否适合你。如果您喜欢对象符号,您可以将数组转换为对象,或使用类(首选)。

+0

是的,这正是我想要做的。我添加了一些额外的孩子,它仍然有效,破坏了我的理论,即一个返回函数实际上会等待另一个函数被调用。 –

+0

是的,PHP函数是同步运行的,所以你不会遇到这个问题。另外,如果我回答了你的问题,你能标记我的答案吗?谢啦! –

+0

哦,好的,谢谢你的回答,这意味着我的代码还有其他错误!感谢你的帮助! –

我想你可以使用XPath简化工作:

您还可以修改只是为了最终有一个以上相同的标题:

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 
+0

有趣的是,我将研究代码,并可能稍后在 –

我终于找到了问题。问题是因为我有很多分支(许多父母和孩子),一旦我的循环已经通过第一个分支并且什么都没找到,它就返回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收到

+0

的代码中调整它,如果你只是寻找一个结果,你不需要通过函数循环传递$ val ..它的过度复杂和不必要.. 。您只需在找到该值时返回值,或者返回在完成后找不到值。 – Swayze

+0

但是,如果我需要从多个儿童分支中找到单个值,那么我需要继续循环通过父母和他们的孩子 或者有没有更好的方法或做到这一点? –

+0

你仍然可以遍历并搜索所有的孩子,即使它是多维的,也不会传递变量。 我会编辑我的原始答案,向你展示我的意思。 – Swayze