이 글에서는 주로 PHP에서 가상 프록시를 통해 지연 로딩을 구현하는 방법을 소개합니다. 이제 참고할 만한 내용이 있어서 공유합니다.
기본 원칙은 가상 프록시를 통해 수행하는 것입니다. (가상 프록시) 자리 표시자, 프록시 개체의 멤버(메서드 또는 속성)에 액세스하면 로드가 트리거됩니다.
이것은 Martin의 "Enterprise Application Architecture Patterns"에서 배운 내용입니다. PHP 동적 언어의 특성을 지원하고 Java보다 훨씬 쉽게 지연 로딩(LazyLoad)을 구현할 수 있습니다. 기본 원칙은 가상 프록시(가상 프록시)를 자리 표시자로 사용하는 것입니다. 프록시 개체의 멤버(메서드 또는 속성)에 액세스하면 로딩이 트리거됩니다.
그러나 제가 구현한 버전에는 다음과 같은 제한 사항이 있습니다.
객체에만 적용할 수 있으며 배열과 같은 기본 데이터 유형을 프록시할 수 없습니다(ArrayObject와 같은 내장 객체로 캡슐화해야 함).
프록시된 후 다음을 사용하는 일부 인터페이스 구현 ArrayAccess의 인덱서 및 Itreator의 반복자와 같은 연산자 오버로드 속성은 유효하지 않을 수 있습니다. 이 프록시를 사용하여 컬렉션 유형의 지연 로딩을 처리하는 경우 외부 foreach 반복을 사용할 수 있도록 특수 처리를 위한 하위 클래스를 상속해야 합니다
// 测试 $v = new VirtualProxy(function(){ echo 'Now, Loading', "\n"; $a = new ArrayObject(range(1,100)); $a->abc = 'a'; // 实际使用中,这里调用的是 DataMapper 的 findXXX 方法 // 返回的是领域对象集合 return $a; }); // 代理对象直接当作原对象访问 // 而此时构造方法传入的 callback 函数才被调用 // 从而实现加载对象操作的延迟 echo $v->abc . $v->offsetGet(50);
Virtual Proxy
/** * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 * * @author tonyseek * */ class VirtualProxy { private $holder = null; private $loader = null; /** * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 * * @param Closure $loader 生成被代理对象的闭包函数 */ public function __construct(Closure $loader) { $this->loader = $loader; } /** * 代理成员方法的调用 * * @param string $method * @param array $arguments * @throws BadMethodCallException * @return mixed */ public function __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 mixed */ public function __get($property) { $this->check(); if (!isset($this->holder->$property)) { throw new ErrorException(); } return $this->holder->$property; } /** * 代理成员属性的赋值 * * @param string $property * @param mixed $value */ public function __set($property, $value) { $this->check(); $this->holder->$property = $value; } /** * 检查是否已经存在被代理对象,不存在则生成。 */ private function check() { if (null == $this->holder) { $loader = $this->loader; $this->holder = $loader(); } } }
위 내용은 모두의 학습에 도움이 되기를 바랍니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요!
관련 권장 사항:
php의 urlencode() URL 인코딩 기능 분석 정보
PHP를 사용하여 대규모 웹 사이트 트래픽 및 높은 동시성 문제를 해결하는 방법
의 2세트 구성 파일 및 매개변수 분석
위 내용은 PHP에서 가상 프록시를 통해 지연 로딩을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!