2012-05-22 2 views
4

클래스 클래스를 확장하는 Foo 클래스와 Bar 인스턴스를 가진 경우 Bar의 해당 인스턴스를 사용하여 'a'를 채 웁니다. Foo의 새로운 인스턴스?PHP에서 기본 클래스의 인스턴스에서 확장 클래스의 객체를 만듭니다.

본질적으로 Bar 만 검색 할 수 있지만 많은 추가 방법을 제공하므로 코드에서 Foo를 사용하고 싶습니다.

나는 몇 가지 해결책이 비슷한 질문을하는 것을 보았지만 모두 파이썬이나 C#으로 보였다.

Bar의 생성자에 들어간 데이터에 액세스 할 수 없어 ReflectionClass :: newInstanceArgs를 사용할 수 없습니다.

+0

Bar 인스턴스를 가져 와서 Foo 인스턴스를 채운 Foo 용 함수/생성자를 작성할 수 있습니까? – gunnx

+0

왜 이것을 수행 하시겠습니까? 교활한 일이 일어나고있는 것처럼 들리네. –

+0

PHP에서 사용자 지정 개체를 캐스팅 할 수 없다고 생각합니다. 아마도 [이 게시물] (http://stackoverflow.com/a/2232065/1028949)에서 유용한 정보를 찾을 수 있습니다. – Quantastical

답변

1

원하는대로 쉽게 할 수있는 기본 제공 방법이 없습니다. 이러한 클래스의 인터페이스는 약간 재 설계되어야합니다. 같은 아마 뭔가 :

<?php 
class Bar 
{ 
    ... 
} 

class Foo extends Bar 
{ 
    public static function fromBar(Bar $bar) 
    { 
     $foo = new self(); 
     ... (copy data here) ... 

     return $foo; 
    } 
} 

+0

감사합니다. 그래, 내 질문에 따라 그것을 할 수있을 것으로 기대하는 것이 합리적이지 않다는 것을 깨달으면, 나는 그 선을 따라 뭔가를 할 것이라고 생각한다. 아마도 '확장'을 버리고 Foo의 속성으로 Bar를 사용합니다. – petesiss

2

이 작업을 수행하는 데 권장되는 방법은 dependency injection입니다. Foo에 대한 생성자는 Bar의 인스턴스를 수락 할 수 있으며 Bar 개체에서 새 Foo 개체의 상태를로드하는 코드를 작성해야합니다.

PHP에 설명하는 것과 정확히 일치하는 기능이있는 경우 FooBar으로 확장 되어도 두 클래스가 여전히 매우 다를 수 있기 때문에 문제가 될 수 있습니다. PHP가 자동으로 한 클래스의 인스턴스를 다른 클래스의 인스턴스로 전환하는 방법을 알만큼 충분히 똑똑 할 수는 없습니다.

정확한 상황에서 아래의 (매우 해키 한) "해결책"은 귀하가 묘사 한 것을 할 수 있다고 말했습니다. 실제로 사용하지 않는 것이 좋습니다. 나는 주로 당신이 이것을하기 위해 이상한 재료에 의지해야한다는 것을 보여주고 싶었습니다.

function convertObject($object, $newClass) 
{ 
    return unserialize(
     preg_replace(
      '/^O\:\d+\:"[^"]+"/', 
      'O:'.strlen($newClass).':"'.$newClass.'"', 
      serialize($object) 
     ) 
    ); 
} 
+0

그래 ... 나는 convertObject를하지 않을 것이다. 나는이 경우에 우리가 객체를 가지고있는 기본 클래스의 속성이 확장 객체의 적합한 시작 상태라고 생각하는 것이 그렇게 마법 같은 것처럼 보이지 않는다고 생각합니다 .... 물론 항상 그런 것은 아닙니다. 바를 푸 (Foo)의 재산으로 삼으려고합니다. – petesiss

0

난 그냥 뭔가를 썼다는이 예는 전술의 핵심 드라이버 파일에 대한 추가 지원 패키지 (들)을해야 할 수 있습니다 사용자 정의 드라이버를 확장하는 기반으로. $ 아이에 대한 두 번째 위해서 var_dump()는 당신이 지금 말했다 특성이 앰퍼샌드 (&를) 앞에는 볼 수있는 점을 제외하고 $ 부모와 동일한 정보를 출력

// File: parent.php 

class parent_class() { 

    protected $_protected_object; // set in constructor 
    protected $_protected_var = "Something dynamic"; 

    public function __construct() { 
     // keep in mind that if you don't override this constructor, this will execute when extended 
    } 

    public function create_resource() { 
     $this->_protected_object = new SomeObjectInstance(); 
    } 

    public function child_class() { 

     static $child = null; 

     if (is_null($child)) { 

      $file = "child.php"; 

      if (!\file_exists($file)) { 
       throw new Exception("Couldn't load '$file', doesn't exist"); 
      } else { 

       require_once($file); 

       $child = new child_class(); 
       $child->__overload("_protected_object", $this->_protected_object)->__overload("_protected_var", $this->_protected_var); 

      } 

     } 

     return $child; 

    } 

} 

// File: child.php 

class child_class extends parent_class { 

    protected function __overload($index, &$value) { 

     $this->$index =& $value; 
     return $this; 

    } 

    public function __construct() { 
     // REMEMBER: if you don't declare this method, the parent's constructor will execute 
    } 

    public function extended_func() { 
     // code 
    } 

    public function etc() { 
     // code 
    } 

} 

// Code instantiating objects: 

$parent = new parent_class(); 
$parent->create_resource(); 

var_dump($parent); 

/** 
* Would output something like this: 
* 
* object(parent_class)#1 (2) { 
* ["_protected_object":protected]=> 
* object(SomeObjectInstance)#2 (*) { 
*  %OBJECT PROPERTIES% 
* } 
* ["_protected_var":protected]=> 
* string(17) "Something dynamic" 
* } 
*/ 

$child = $parent->child_class(); 

var_dump($child); 

/** 
* Would output something like this: 
* 
* object(child_class)#3 (2) { 
* ["_protected_object":protected]=> 
* &object(SomeObjectInstance)#2 (*) { 
*  %OBJECT PROPERTIES% 
* } 
* ["_protected_var":protected]=> 
* &string(17) "Something dynamic" 
* } 
*/ 

공지 사항, 지금은 참조가 있음을 나타내는. 따라서 두 속성과 관련하여 부모 클래스 인스턴스의 내용을 변경하면 자식 클래스 인스턴스에 반영됩니다.

관련 문제