PHP에서 가상 프록시를 통한 지연 로딩 구현 코드

高洛峰
풀어 주다: 2023-03-01 11:16:01
원래의
897명이 탐색했습니다.

이것은 Martin의 "Enterprise Application Architecture Patterns"에서 배운 내용입니다. PHP 동적 언어의 특성을 돕고 Java보다 훨씬 쉽게 지연 로딩(LazyLoad)을 구현할 수 있습니다. 기본 원칙은 가상 프록시(가상 프록시)를 자리 표시자로 사용하는 것입니다. 프록시 개체의 멤버(메서드 또는 속성)에 액세스하면 로딩이 트리거됩니다.

그러나 제가 구현한 버전에는 제한 사항이 있습니다.

은 객체에만 적용 가능하며 배열과 같은 기본 데이터 유형을 프록시할 수 없습니다(ArrayObject와 같은 내장 객체로 캡슐화해야 함)
가 프록시됩니다. 그 후 ArrayAccess의 인덱서 및 Itreator의 반복자와 같은 연산자 오버로딩 속성이 있는 일부 인터페이스 구현이 유효하지 않게 되었습니다. 이 프록시를 사용하여 컬렉션 유형의 지연 로드를 처리하는 경우 특수에 대한 하위 클래스를 상속해야 합니다. 외부 foreach 반복
demo
코드 복사 코드는 다음과 같습니다.
// Test
$v = new VirtualProxy(function(){
echo 'Now, Loading', "n";
$a = new ArrayObject(range(1,100));
$a->abc = 'a'
// 실제 사용에서는 DataMapper의 findXXX 메소드가 호출됩니다.
// 반환되는 것은 도메인 개체의 모음입니다
return $a;
})
// 이때 프록시 개체는 원본 개체로 직접 액세스됩니다
// , 생성자에 전달된 콜백 함수는
// 객체 작업 로드 지연을 달성하기 위해
echo $v->abc $v->offsetGet(50); 가상 프록시
코드 복사 코드는 다음과 같습니다.
/**
* 가상 프록시, 멤버에 접근할 때만 대상 객체를 생성하는 클로저 함수가 호출됩니다.
*
* @author tonyseek
*
*/
class VirtualProxy
{
private $holder = null
private $loader = null; ;

/**
* 가상 프록시, 멤버에 접근할 때만 대상 객체를 생성하는 클로저 함수가 호출됩니다.
*
* @param Closure $loader는 프록시 객체의 클로저 기능을 생성합니다
* /
공용 함수 __construct(Closure $loader)
{
$this->loader = $loader
}

/**
* 프록시 멤버 메서드 호출
*
* @param string $method
* @param array $arguments
* @throws BadMethodCallException
* @return 혼합
*/
공개 함수 __call($method, array $arguments = null)
{
$this->check()

if (!method_exists($this->holder, $method) ) {
throw new BadMethodCallException()
}

return call_user_func_array(
array(&$this->holder , $method),
$arguments)
}

/**
* 프록시 멤버 속성 읽기
*
* @param string $property
* @throws ErrorException
* @return 혼합
*/
공용 함수 __get($property)
{
$this- >check();

if ( !isset($this->holder->$property)) {
throw new ErrorException(); return $this->holder->$property; }

/**
* 프록시 구성원 속성 할당
*
* @param string $property
* @param 혼합 $value
*/
공용 함수 __set($property, $value)
{
$this->check();

$this->holder->$property = $value
}

/**
* 프록시 객체가 이미 존재하는지 확인하고, 존재하지 않으면 생성합니다.
*/
비공개 함수 check()
{
if (null == $this->holder) {
$loader = $this->loader
$this->holder = $로더()
}
}
}

관련 라벨:
php
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿