2011-12-16 2 views
0

일부 개체의 목록이 있다고 가정 해보십시오. 이러한 객체는 기본 클래스를 확장하는 다양한 클래스의 인스턴스입니다. 이제 이러한 개체를 데이터베이스에 저장하고 싶습니다.다이내믹 클래스 인스턴스 : 우수 사례?

추가 요구 사항으로 기본 클래스를 확장하는 클래스의 수는 상당히 클 수 있습니다. 더 나은 방법으로 그런 것을 할 수있는 사례를

<?php 
class Page { 
    abstract public function foo($args); 
} 

class ChartPage : Page{ 
    public function foo($args){ 
     var_dump($args); 
    } 
} 

// other classes like ChartPage would be defined here 

// fetched row from a MySQL database 
$row = array("id" => 21, "title" => "Test", "class" => "ChartPage", "args" => "{}"); 
$object = new $row['class']; 
$object->foo($row['args']); 
?> 

있습니다 그것은 데이터베이스에서 문자열로 클래스 이름을 저장하고 그런 식으로 가져올하는 것이 좋습니다

인가?

답변

1

당신은 직렬화/역 직렬화 사용하기 위해 기본적으로 PHP에서 사용할 수있는 당신의 자신의 기능을 작성하기위한 특별한 이유가없는 한 :

당신은 읽을 수를 PHP의 객체 직렬화에 대한 자세한 내용은 다음 링크를 참조하십시오.

는 직렬화 된 데이터는 PHP의 당신이 JSON 또는 XML 같은 직렬화의 또 다른 방법을 선택할 수 밖에 것들을 공유하는 경우. 그러나 나중에 PHP를 통해 액세스하기 위해 객체를 저장하는 문제라면 표준 직렬화 방법만으로는 충분하지 않습니다.


식별자의 일부 종류는 직렬화 된 데이터로 저장해야합니다, 당신은 객체가 정말 종류를 확인하기 위해, 그렇지 않으면 불가능하다.

확실히 직렬화 된 데이터의 키가 가장 일치하는 개체 유형을 검색하는 데 사용되는 역 직렬화 방법을 보았습니다. 그러나 이것이 100 % 정확하지 않기 때문에 권장 할만한 것이 아닙니다. 사례. 당신의 예제 코드에서


나는 Page::foo 새 클래스를 건물 공장으로 사용되는 것으로 가정한다.

데이터를 직렬화/직렬화 해제하고 객체의 모든 데이터를 저장하려는 독자적인 방법을 작성하려는 경우 Page을 상속받은 클래스에 강제로 팩토리를 구현하지 않아도됩니다.

Page 또한 객체에 포함 된 키/값 쌍을 반복하여 임의의 클래스를 직렬화하는 통일 된 방법을 사용할 수 있습니다. 이 접근법에는 약간의 문제가 있습니다.

상속 된 개체가 다소 복잡한 구성원 (예 : 사용자 정의 클래스 등의 기본 개체가 아닌 개체) 인 경우 정확하게 저장하지 않을 수 있습니다.

예를 들어, 객체에 활성 mysql 연결이있는 경우 직렬화 된 데이터에 연결 자체를 어떻게 저장할 것이므로 이러한 연결을 다시 열기 위해 자격 증명을 저장하기를 원할 것입니다.

다시 소켓 연결과 관련된 파일 설명자를 저장하고 항상 백그라운드에서 실행중인 상상의 MySQLKeepConnAlive 객체를 사용하여 열어 두는 것은 멋지지만 종종 필요한 경우가 많습니다.

아무튼; 만약 내가 당신이라면 기본 객체에서 사용할 수있는 직렬화/직렬화를위한 기본 메소드를 작성할 것입니다. 상속 된 유형이 복잡한 경우 개발자가이 메소드를 대체하고 자신의 메소드를 제공해야합니다.

데이터 구조를 사용하여 아래에 설명 된 개체를 저장 하겠지만 이전에 설명한 것과 멀리 떨어져 있지 않습니다. '__PAYLOAD'에는 객체의 멤버가 포함되고 다른 값은 기본 클래스에 정의되어야합니다.

'__PAYLOAD'는 서로 다른 클래스의 두 인스턴스에 대해 동일하게 보이지 않지만 특정 ID 및 유형의 객체를로드하고 객체에 대한 기본 정보를 찾는 통일 된 방법이 있습니다.

물론 "기본"입력란을 아래에 추가 할 수 있습니다. 이는 내가 생각하는 것의 예일뿐입니다.

$serialized_data = array (
    '__TITLE': 'Test', 
    '__TYPE': 'CharPage', 
    '__ID':   21, 
    '__PAYLOAD': array (
    'member_1' => 'foobar', 
    'member_2' => 'barbaz', 
    'member_3' => 'bazbir' 
) 
);