2014-01-10 2 views
3

클래스 자체에 새 인스턴스를 반환하는 메서드가 있습니다. 동일한 값으로 새로운 객체를 반복해서 선언하지 않고도 단일 객체를 사용할 수 있습니다. 왜 클래스를 확장하거나 다른 것을 확장하지 않는지 궁금해하는 사람들에게는 내 인생을 더 편하게 만들어 주며 매력처럼 작동하지만 최종 목표는 모든 것을 한 줄로 제거하는 것입니다. 예개체의 인스턴스를 모두 설정 해제합니다. PHP

:

$foo = new myClass('name1','ab','cd'); 
$bar = $foo->duplicate(); 

//duplicate() saves the new object in itself in an array: 
array_push($this->instance,new myClass('name1','ab','cd')); 
//and returns a pointer to the saved instance. 
return end($this->instance); 

$foo$bar 이제 동일한 방법과 가치를 공유하지만, 그 값은 개별적으로 변형 될 수있다. 내가 자동으로 해제 PHP됩니다 unset($foo)을 만든 첫 번째 클래스를 설정 해제하는 경우 여기

$foo->changeName('newName'); 

$bar->changeName('newName2'); 

내 질문은, 다른 인스턴스는 ($bar) 또는 가비지 컬렉터는 결국 그들을 제거 할 것인가?

$ foo를 불안정하게 테스트하여 $ foo를 호출 할 때 오류가 발생하지만 $ bar를 호출 할 때 오류가 발생합니다.

내가하려는 것은 해당 클래스의 모든 인스턴스를 한 번에 설정 해제하는 것입니다.

감사합니다. 내가 여기에 PHP 레퍼런스에서 이해하는 것과

+2

오브젝트의 '콜렉션'을 결정적으로 파기하려면 일종의 실제 콜렉션에 해당 콜렉션을 유지하고 한 번에 모두 루프에서 '해제'하십시오. –

답변

3

자동 정리?

아니요, PHP가 아키텍처를 알지 못합니다. "캐스케이드 (cascade)"객체는 제거되지 않으며 독립적 인 객체이며 더 많은 경우 다른 스코프에 속할 수 있습니다.간단한 코드 : 그런데

class Test 
{ 
    protected $id = null; 
    protected $uniqid = null; 

    public function __construct($id) 
    { 
     $this->id = $id;//user-passed variable 
     $this->uniqid = uniqid();//internal: to identify instance 
    } 

    public function getCopy() 
    { 
     return new self($this->id); 
    } 

    public function getIdentity() 
    { 
     return $this->uniqid; 
    } 
} 

$foo = new Test(3); 
$bar = $foo->getCopy(); 
var_dump($foo->getIdentity());//valid 

unset($foo); 
//still valid: bar has nothing to do with foo 
var_dump($bar->getIdentity()); 

, 당신은 PHP에서 clone (즉, 그러나, 분명히, 개체 복제가 발생합니다)

간단한 방법

가장 간단한 방법을 사용하여 복사하는 문제를 해결하려면 $GLOBALS을 반복하고 instanceof으로 확인하십시오. 즉

//static since doesn't belong to any instance: 
public static function cleanup() 
{ 
    foreach($GLOBALS as $name=>$var) 
    { 
     if($var instanceof self) 
     { 
     unset($GLOBALS[$name]); 
     } 
    } 
} 

- 그리고

$foo = new Test(3); 
$bar = $foo->getCopy(); 
var_dump($foo->getIdentity(), $bar->getIdentity());//valid 
Test::cleanup(); 
//2 x notice: 
var_dump($foo, $bar); 

주 (그것은 모든 청소 것, 즉 "아이"역학과 아무 상관이 : 내부 함수/메소드 범위는 영향을받지 않습니다이 심각한 약점이있다 전역 범위의 인스턴스 - 어느 인스턴스에서 복사했는지에 상관없이).

일반적인 경우의 뜻 하지

샘플은 일반적인 경우에 물건을한다. 왜? 당신이 홀더 클래스해야합니다 상상해 :

class Holder 
{ 
    protected $obj = null; 

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

    public function getData() 
    { 
     return $this->obj; 
    } 
} 

을 당신은 여기에 인스턴스를 전달합니다 : - 그래서

$foo = new Test(3); 
$bar = $foo->getCopy(); 
$baz = new Holder($bar); 

을 다음 일반적인 경우에이 간단한 상황을 처리 할 기회가없는거야 . 그리고 더 복잡한 상황에서 당신은 또한 붙어있을 것입니다.

무엇을할까요?

나는 이것을 할 필요가있을 때 명시 적으로 객체를 파괴하라.. 암시 적 unset은 부작용이며, 비록 당신이 그것을 어떻게 든 유지할지라도 (Observer 패턴 + 일부 글로벌 레지스트리를 상상할 수 있습니다) - 이것은 끔찍한 부작용이되어 코드에 대한 가독성을 떨어 뜨립니다. 그리고 위의 코드에서 $GLOBALS을 사용하는 코드도 마찬가지입니다. 어떤 경우에도 그런 식으로 행동하지 않는 것이 좋습니다.

+0

고마워요, 이것은 매우 유용하고 잘 설명, 빠른 질문, 내가 지금까지 한 일을 계속하고 싶기 때문에, 그렇지 않으면 이해합니다. 이런 식으로 가능하지 않습니다 : 패스 참조 또는 포인터를 반환하면 어떻게됩니까? & $ this-> 인스턴스? 분명히 이것이 작동한다면 Holder ($ bar)는 에러를 반환 할 것이지만, 우리가하는 일을주의 깊게 알고 생각하는 것이 좋습니다. 감사! – multimediaxp

+0

클래스/함수 내부에서 무슨 일이 벌어지는 지 확신 할 수 없기 때문에 여전히 신뢰할 수 없습니다. 어떻게 든 데이터를 복사 할 수 있습니까? (예를 들어'clone '을 통해). 흔히 당신은 __loose__를 추적 할 것입니다 - 그건 확실합니다 –

+0

그것은 작동하지 않았습니다, 당신이 옳았습니다! 감사! – multimediaxp

0

: 그들이 궁극적으로하지 않기 때문에 자동으로 다른 모든 인스턴스를 파괴하지 않을 것이다 주요 인스턴스를 파괴

http://www.php.net/manual/en/features.gc.refcounting-basics.php

같은 'zval'을 가리 킵니다.

그러나 가비지 수집은 더 이상 참조되지 않으면 결국 모든 인스턴스를 파괴합니다. 귀하의 예제에서 $ bar는 여전히 두 번째 인스턴스를 참조하기 때문에 파손되지 않습니다.

  1. 이 참조를 추가하면 새로운 개체를 만드는 개체
  2. 마다의 모든 인스턴스를 참조하는 정적 배열을 사용하여 동시에 그들 모두를 설정 해제하려는 경우 당신이 무엇을 할 수 있는지

    하나이 배열 및 해제를 순환 한 클래스

  3. 사용 정적 unsetAll 함수()의 정적 인 배열이 객체에 모든 인스턴스
+0

모든 인스턴스가 주 개체에 저장되고 저장된 인스턴스에 대한 포인터를 반환한다는 사실을 잊어 버렸습니다. – multimediaxp

+0

다음 제안 된 솔루션을 잘 작동합니다. –

+0

주 객체를 불안정하게 만든 후 새 인스턴스를 호출 할 때 오류가 발생하지 않는다는 것을 전에 언급했듯이 확실하지 않습니다. 내 질문 좀 봐 더 구체적인 코드 예제를 추가했습니다. 감사! – multimediaxp

0

코드 아래를보십시오 모든 PHP 개체를 지 웁니다.

public function clearAllVars() 
    { 
     $vars = get_object_vars($this); 
     foreach($vars as $key => $val) 
     { 
     $this->$key = null; 
     } 
    } 
} 
관련 문제