2012-05-02 1 views
1

나는 어디에서나 보았고 대답을 찾을 수없는 것처럼 보입니다. PHP에서 재귀 객체를 사용하는 것이 안전하거나 좋은 방법인지 궁금합니다.PHP 객체로 재귀 적 속성을 설정하는 것이 안전합니까?

<?php 
     $bar = new User(); 
     $bar->database->doSomethingForUser(); 
    ?> 

나 '... ... 포함하는 객체에 대한 참조를 사용하여 속성을 포함하는 다른 개체의 속성으로

<?php 

    class User 
    { 
     public $database; 

     public function __construct() { 
      $this->database = new Database($this); 
     } 
    } 

    Class Database 
    { 
     private $user; 

     public function __construct(User $user) { 
      $this->user = $user; 
     } 

     public function doSomethingForUser() { 
      // Call db or get info for this user 
     } 
    } 

를 객체를 생성 한 후 다음과 같이 사용하려면 array_multisort (특히 "PHP 치명적인 오류 : 중첩 수준이 너무 깊음 - 재귀 종속성"과 같은 특정 함수를 사용하여 문제가 발생했음을 알게되었습니다.) 객체 배열을 정렬하려고 할 때 var_dump를 사용하면 일부가 표시됩니다. 반복적 인 속성 ...

어떤 도움도 감사합니다 iated

+0

당신이하고있는 일을 알고 있고 그 문제를 해결하는 방법을 아는 것이 안전합니다. 분명히 array_multisort를 사용할 경우 순환 참조를 사용하지 않습니다. – gcochard

+0

그게 내가 좀 혼란스러워하는 곳이라고 생각해. 원형 참조를 포함하는 객체의 배열을 정렬하려고 할 때 어떻게 처리 할 것 인가? –

+0

간단합니다. 모든 단계를 거치지 않아도된다고 가정하면 최상위 배열을 정렬하면됩니다. 재귀 적으로 정렬 할 필요가 없습니다. 두 객체를 정확하게 비교하는 비교 함수와 함께'usort'와 같은 것을 사용하십시오. – cHao

답변

4

PHP 5.3 이전에는 문제가 발생할 수있었습니다. PHP는 참조 횟수를 계산하는 데 사용되며 순환 참조는 객체가 GCed를 유지하지 못하도록합니다.

5.3에서 알맞은 가비지 컬렉터가 구현되었으므로이 점은별로 중요하지 않습니다. 그러나 함수가 가능성을 인식하지 못하고이를 처리 할 준비가되어 있으면 객체 그래프를 가로 지르는 모든 함수에 이러한 객체를 전달하면 무한 재귀가 발생할 수 있습니다. (I는 var_dump이 상당히 재귀를 처리하는 생각하지만, 반복적으로 정렬 같은 객체는 아마 문제가 모든 종류의 원인이됩니다.) database 개인이기 때문에 bar->database->any_method()가 작동하지 않습니다

0

참고.

PHP에서 객체에 대한 재귀 적 참조를 만들 때 실제로는 꽤 좋습니다. 단지 기존 참조를 사용하고 분명히 더 많은 메모리를 생성하지 않습니다. 이 경우 결정적이지 않은 재귀 수준을 만들지는 않습니다.이 개체는 단지 하나의 개체 집합이므로 이러한 개체를 많이 만들지 않는 한 오버플로가 발생하지 않을 것입니다 (다른 이유 일 수 있습니다) . 당신이 Uservar_dump을 할 경우

, 당신은 볼 수 있습니다 :

object(User)#1 (1) { 
    ["database:private"]=> 
    object(Database)#2 (1) { 
    ["user:private"]=> 
    object(User)#1 (1) { 
     ["database:private"]=> 
     object(Database)#2 (1) { 
     ["user:private"]=> 
     *RECURSION* 
     } 
    } 
    } 
} 

을 ... PHP는 재귀를 통지 있도록.

나는 을 물어야 할 것입니다. 왜이 경우에 그렇게 할 수 있습니까?

+0

그래, 내가 민간 형식을 만들었다는 것을 깨달았다. .... 어쨌든 필자는 사용자 메서드에서 데이터베이스 메서드를 분리하려고 했으므로 사용자 개체를 만들 때마다 모든 메서드가 들어있는 데이터베이스 개체가 포함되어있다. 특정 사용자에 대한 데이터 검색 처리 –

관련 문제