2010-07-31 6 views
0

다차원, 연관 배열의 인덱스로 객체를 검색하는 재귀 함수가 있습니다.PHP : 연관 배열에서 참조로 객체 제거

$settings = array(
'title' => new XCPreferenceShortText('title'), 
'html' => new XCPreferenceLongText('html'), 
'_blog' => array(
    '_blog' => new XCPreferenceHeading('blog'), 
    'acceptcomments' => new XCPreferenceBoolean('acceptcomments'), 
    'per_page' => new XCPreferenceNumberSet('per_page') 
), 
'_publishing' => array(
    '_publishing' => new XCPreferenceHeading('publishing'), 
    'published' => new XCPreferenceBoolean('published'), 
    'publishon' => new XCPreferenceDate('publishon'), 
) 
); 

이 코드는 배열을 통과 때마다 is_array($value) 반환 사실, 그것은 전체를 재귀.

function &find($idx, $pref_array = false) { 

    if ($pref_array === false) 
     $pref_array = &$this->preferences; 

    foreach ($pref_array as $key => $data) { 
     if (is_array($data)) { 
      $res = $this->find($idx, $data); 
      if ($res !== false) 
       return $res; 
     } 
     else if ($key == $idx) 
      return $pref_array[$idx]; 
    } 

    return false; 
} 

이 함수는 발견 (및 그 결과에 대한 참조 인 경우) 주어진 키에 연관된 객체 -하지만 변수에 리턴 값/레퍼런스를 저장하고 VAR가 null로 설정된 경우,이 영향을주지 않는다 "원래"배열의 실제 요소에. 호출에 상점에게 참조를 만들 불충분 참조로 함수가 반환을 말하는

$value = &find($idx); 
$value = null; 
//just to be safe, in case you re-use $value later on 
unset($value); 

:

답변

0

Artefacto가 제안한대로 함수 호출이 향상되었지만 함수가 여전히 재귀에 의해 검색된 요소에 대한 참조를 반환하지 않았습니다.

실수는 재귀 호출 자체입니다. 당신이 나를 위해 작동 조정 된 버전 이하를 찾을 것입니다 : $data로 잘못 전에

foreach ($pref_array as $key => $data) { 
     if (is_array($data)) { 
      $res = &$this->find($idx, &$pref_array[$key]); 
      if ($res !== false) 
       return $res; 
     } 
     else if ($key == $idx) { 
      return $pref_array[$idx]; 
     } 
    } 

&$this->find($idx, $data); 호출을 실제로 대한 참조 없었다. 배열에 대한 참조를 얻으려면 배열을 가져와 변수 ($pref_array)를 참조해야했습니다.

고마워요.

1

는이 같은 함수를 호출해야합니다.

그런데 RecursiveArrayIterator이라는 이터레이터가 있다는 것을 알고 있어야합니다.

+0

(다시 귀찮게합니다.) 나는 그렇게 생각하지 않습니다 ... 이것은 발견 된 객체에 대한 배열의 참조를 지우지 않고,'find'가 반환 될 때 생성 된 새로운 참조 만 있습니다. 아니면 그렇습니까? – MvanGeest

+0

@Mvan 글쎄, 당신은 그것을 테스트 할 수 있습니다 : http://codepad.viper-7.com/ISR2lq 개체 대신 지금 NULL입니다. – Artefacto

+0

@ban 질문을 읽어보십시오. OP가 원하는 모든 것은 배열의 값을 'NULL'로 바꾸는 것입니다. 그는 배열 요소를 설정 해제하고 싶지 않습니다. 실제로'$ value = null;은'$ value'가 프록시 객체 일 때 매우 특정한 상황에서 객체를 NULL로 대체하지 않을 수도 있습니다. 나는이 경우에 그것이 매우 관련이 있다고 생각하지 않는다. – Artefacto