2009-08-14 3 views
2

PHP 변수에 대한 모든 변경 사항을 추적하려고합니다. 변수는 객체 또는 배열이 될 수 있습니다. 이 객체가 객체 캐시를 사용하여 스토리지에 유지됩니다PHP 개체 속성 변경 내용 추적

$object = array('a', 'b'); 

:

예를 들어 그것은 뭔가 것 같습니다. PHP 스크립트가 다시 실행될 때.

그래서 두 번째 스크립트가 실행되거나 다른 스크립트가 실행되어 해당 개체가 수정 될 때 스크립트를 실행 한 후에 수정 사항을 추적 할 수 있습니다.

예를 들면 :

$object[] = 'c'; 

나는 'C'는 객체에 추가되었는지 알고 싶습니다.

이제 실제 코드는 다음과 같은 :

$storage = new Storage(); 
$storage->object = array('a', 'b'); 

초 부하 :

$storage = new Storage(); 

var_dump($storage->object); // array('a', 'b') 

$storage->object[] = 'c'; 

내가 알고 싶은 것은 'C'는 그렇게> $ 스토리지 기반으로 개체를 추진 한 것입니다 클래스 "저장소"나는 그 값을 영구 저장소로 설정할 수 있습니다.

몇 가지 방법을 시도해 봤지만 단점이 있습니다.

1) 객체의 변경을 추적 "저장 가능"클래스 내의 모든 오브젝트를 감싸

"저장 가능"클래스 단지 속성과 실제 데이터 객체를 저장하고 __get() 및 __set 제공() 메소드를 사용하여 액세스하십시오. 개체의 멤버/속성이 수정되거나 추가되면 "저장 가능"클래스가이를 기록합니다. 속성에 액세스 할 때 Storable 클래스의 __get()은 다른 Storable 클래스로 래핑 된 속성을 반환하므로 변경 내용이 각 새 수준에서 재귀 적으로 추적됩니다.

문제는 개체가 더 이상 원시 데이터 형식이 아니므로 배열에서 배열 함수를 실행할 수 없다는 것입니다.

예 :

$storage = new Storage(); 

var_dump($storage->object); // array('a', 'b') 

array_push($storage->object, 'c'); // fails 

그래서 대신에 우리가 저장 가능한 방법으로 이러한 배열 기능을 구현해야 할 것이다.

예 :

$storage = new Storage(); 

var_dump($storage->object); // array('a', 'b') 

$storage->object->push('c'); 

이 모두 훌륭하지만 너무 변화를 추적하는 동안은 어떻게 든 내가 개발하고 있어요 라이브러리에 오버 헤드를 줄이기 위해 기본 기능을 사용하기 위해 가능하면 알고 싶습니다 모든 변경 사항을 영구 저장소에 추가 할 수 있습니다.

2)의 이동을 추적 잊어, 그냥 전체 개체 구조

이 실제로 할 수있는 (객체 캐시에 저장된 객체와 동기화 프로그램에서 개체를 유지하는 간단한 방법입니다 업데이트 다른 컴퓨터에서).

그러나 인덱스가 1000 개인 배열과 같은 전체 구조는 단일 인덱스가 변경 될 때 객체 캐시에 대한 소켓을 통해 보내야한다는 것을 의미합니다.

3) 개체를 복제하고, 그대로 복제 개체를 유지하는 개체의 거울을 로컬

나도 해봤하십시오. 그런 다음 모든 처리가 PHP 스크립트에 의해 완료되면 복제를 수정 된 객체와 재귀 적으로 비교하고 변경된 속성을 다시 객체 캐시에 제출하십시오.

그러나이 방법을 사용하려면 전체 개체를 다운로드해야합니다. 개체가 복제되기 때문에 개체가 두 배의 메모리를 차지해야합니다.


나는 꽤 모호하지만, 상당히 복잡한 코드가 있음을 알고 있습니다. 누구든지 코드를보고 싶으면 공개하거나 공개 SVN 저장소에 올려 놓을 수 있습니다. 프로젝트는 오픈 소스이지만 공개 저장소를 아직 설정하지 않았습니다.

답변

1

'개체'는 실제로 배열이므로 기능을 추가 할 수 없습니다. 클래스 메소드로 캡슐화하려는 아이디어가 올바른 접근법입니다. 이 단계에서 적절한 디자인에 대한 성능에 대해 걱정하는 것은 무의미하고 잘못된 것입니다.이 방법으로 인해 발생하는 오버 헤드는 전체 응용 프로그램 성능에 중요하지 않을 수 있습니다.

ArrayObject과 같은 SPL 배열 클래스를 조사해야합니다. 그것들은 완전한 배열과 같은 인터페이스를 제공하며 쉽게 확장 할 수 있습니다.

+0

감사합니다. 내가 오버 헤드를 말했을 때 나는 코드 작성과 성능의 양을 의미했습니다. 나는 그것이 잘못되었다고 생각한다. 나는 단지 최소한의 일을하려는 게으른 프로그래머 일 뿐이다. 나는 Array 인터페이스가 갈 길이 될 것이라고 생각한다. – bucabay

+0

@bucabay, 최소한의 작업으로 코드 작성에 문제는 없습니다. –

1

모든 정직함에서 나는 당신이하고있는 일을 재고 할 것입니다. 당신은 PHP를 그렇지 않은 것으로 바꾸려고합니다. 이것은 Java와 C#에서 볼 수있는 ORM의 종류입니다. PHP가 아니기 때문에 기본적으로 일시적입니다 (memcache/APC/etc를 제외한 모든 것을 의미하는 각 요청마다 다시 작성됩니다). 이는 정교한 개체 캐싱 및 변경 내용 추적에 대한 오해입니다. 말했다되고 그건

, 당신이 할 수있는 유일한 방법은 __get(), __set()__isset() 과부하 및 ArrayAccess를 구현하는 일에 모든 것을 감싸입니다.

+0

이것은 실제로 memcache 및 APC를 비롯한 개체 캐시에 대한 인터페이스입니다. 나는 PHP의 일시적인 특성이 여기에 이득이라고 믿는다. – bucabay

+0

ArrayAccess를 구현하면 모든 배열 함수 (예 : array_pop()를 사용할 수 있습니까? – bucabay

+0

__get 및 __set에 대해 +1 – Josh