2016-04-03 134 views
-1

所以我有一些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的頂部。 –

回答

1
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

對不起,關於這一點,我也在我的代碼中,我只是忘了把它添加到我的例子 –

1

試試這個:

<?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

哦,好的,謝謝你的回答,這意味着我的代碼還有其他錯誤!感謝你的幫助! –

1

我想你可以使用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

有趣的是,我將研究代碼,並可能稍後在 –

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

相關問題