>PHP 프레임워크 >ThinkPHP >ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

咔咔
咔咔원래의
2020-12-29 11:31:491689검색
"

이 기사에서는 컨트롤러를 입문서로 인스턴스화한 다음 ArrayAccess와 인스턴스를 반환하기 위해 매직 액세스를 직접 실행하는 것의 차이점을 분석합니다

"

머리말

위에서 특별한 세부 사항은 라우팅에 대한 설명이 제공되며, 애플리케이션 초기화 및 구문 분석부터 경로 스케줄링이 경로 감지로 돌아올 때까지 시작됩니다.

경로 탐지를 통해 얻은 값은 아래와 같으며, 이는 경로 스케줄링을 통해 최종적으로 반환되는 값입니다.

사용된 라우팅 규칙은 Route::get('hello/:name', 'index/index/:name');

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

입니다.

위 그림에서 볼 수 있듯이 디스패치c에 중요한 데이터가 저장되어 있습니다. 다음으로 컨트롤러에 대해 자세히 설명하겠습니다.

가장 먼저 설명할 것은 경로 감지가 완료된 후 수행되는 인스턴스화 컨트롤러 작업입니다.

1. 인스턴스화 컨트롤러

먼저 인스턴스화 컨트롤러를 실행하는 방법을 살펴보겠습니다!

먼저 항목 파일에서 코드를 실행해야 한다는 점은 의심의 여지가 없습니다. 여기서 컨테이너는 App 인스턴스를 반환하는 데 사용된 다음 App 클래스의 run 메서드가 호출됩니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

이 들어옵니다. 이 방법에서도 위에서 방금 구문 분석한 경로입니다.

따라서 감지 경로가 실행된 후 인스턴스화된 컨트롤러가 실행됩니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

라우팅 감지가 완료된 후 반환되는 내용은 thinkroutedispatchModule Object这个类,并且这个类赋值给了变量$dispatch

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

여기에서 사용되는 미들웨어의 코드를 살펴보세요. . 이 빠른 코드에서는 여전히 클로저가 사용됩니다. 클로저의 개념이 명확하지 않은 경우 기본으로 돌아가야 합니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

위 사진에서 동그라미 친 부분은 $dispatch->run()이 코드는 다음에 구문 분석됩니다. $dispatch->run()这块代码,接下来就要对这块代码进行解析了。

在检测路由最终的返回值可以知道其实这个方法是在thinkroutedispatchModule这个类中。

接着就需要对这个类中的run方法进行解析了,这个方法也就是执行路由调度。

在这个方法中不管是获取路由参数还是检测路由、数据自动验证都不会执行(是按照咔咔上文给的路由地址为案例)。

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

所以根据上图代码就会执行到$data = $this->exec();

라우트의 최종 반환 값을 확인한 후 이 메서드가 실제로 thinkroutedispatchModule이 클래스에 있습니다. 🎜🎜그런 다음 이 수업에서 라우팅 스케줄링을 수행하는 실행 방법을 분석해야 합니다. 🎜🎜이 방법에서는 라우팅 매개변수 획득, 라우팅 감지, 자동 데이터 확인이 실행되지 않습니다(위에 제공된 라우팅 주소가 예로 사용됨). 🎜

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP🎜 🎜🎜라우팅 스케줄링 실행🎜🎜🎜그래서 위 코드에 따르면 $data = $this->exec();여기. 🎜

이 방법을 추적하면 아래 그림과 같은 추상 클래스가 존재하게 됩니다. 여기서 알아야 할 것은 추상 클래스입니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

추상 클래스 설명

  • 추상 클래스는 인스턴스화할 수 없습니다.
  • 추상 메서드가 있는 클래스는 추상 클래스여야 합니다.
  • 요약 메서드는 함수 본문을 가질 수 없습니다. 즉, 추상 함수 fun();
  • 추상 클래스의 비추상 메서드는 하위 클래스에서 호출할 수 있습니다.
  • 비추상 하위 클래스는 추상 클래스를 상속하며 하위 클래스는 상위 클래스를 구현해야 합니다. 모든 추상 메서드
  • 추상 하위 클래스는 상위 클래스의 추상 메서드를 상속하지 않고 추상 클래스를 상속합니다.
  • 위 그림의 원리에 따르면
이 클래스는 추상 클래스입니다.

Dispatch그래서 두 가지 상황이 발생합니다. 하나는 추상 클래스가 상위 클래스의 추상 메서드를 상속하지 않고 추상 클래스를 상속한다는 것입니다.

다른 하나는 추상이 아닌 하위 클래스가 추상 클래스를 상속하고 하위 클래스가 상위 클래스의 모든 추상 메서드를 구현해야 한다는 것입니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

Dispatch를 상속받은 사람을 찾는 방법

이번에 Dispatch의 하위 클래스를 찾는 방법에 대한 질문이 있습니다.

이 사진에서 이런 종류의 Dispatch를 볼 수 있는데, Dispatch 디렉토리도 있습니다.

경로 감지에서 반환된 데이터에 따르면 thinkphp/library/think/route/dispatch/Module.php이 클래스입니다. thinkphp/library/think/route/dispatch/Module.php这个类。

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

来到thinkphp/library/think/route/dispatch/Module.php查看exec

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP🎜🎜🎜 하위 클래스를 찾는 중 🎜🎜🎜은 thinkphp/library/ think/route/dispatch/Module.php보기exec 메소드. 🎜

그럼 다음 작업은 이 방법에 대한 심층적인 설명을 제공하는 것입니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

코드의 첫 번째 줄을 먼저 살펴보세요$this->app['hook']->listen('module_init');, 여기서 컨테이너 ArrayAccess는 배열 형식의 객체에 액세스하는 데 사용됩니다. 그런 다음 마법을 실행합니다. __get 메서드는 존재하지 않는 속성에 액세스할 때 make 메서드를 실행합니다. $this->app['hook']->listen('module_init');,在这里使用了容器ArrayAccess用数组的形式访问对象,然后执行的魔术方法__get,当访问不存在的属性时会去执行make方法。

使用编辑器追踪这个app会到thinkphp/library/think/route/Dispatch.php

편집기를 사용하여 이 앱을 추적하면 thinkphp/ library/think/route/Dispatch.php 클래스에서 이 클래스의 생성자에서 App 인스턴스가 app 속성에 할당된 것을 볼 수 있습니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그런 다음 App 클래스에 오면 Container 클래스에서 상속된 것을 볼 수 있습니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

🎜

존재하지 않는 속성에 액세스하려면 돌아가서 컨테이너의 __get 매직 메서드를 실행하세요.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

따라서 이 블록의 매개변수가 후크에 전달되고 후크의 인스턴스가 반환되는 방법이 설명됩니다. 컨테이너 섹션에서 매우 자세하게 확인하실 수 있습니다!

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그런 다음 후크의 청취 메소드가 실행되어 태그의 동작을 모니터링합니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

이때, 애플리케이션 동작 확장 정의 파일에 오면 모듈에 대해 이 매개변수가 초기화된 것을 볼 수 있는데, 이 값이 비어 있기 때문입니다.

위 그림에서는 실행되지 않으므로 간단한 테스트를 위해 이 파라미터에 애플리케이션 초기화 값을 넣어줍니다.

이 클래스는 Facade 클래스를 최적화하는 실행 후크입니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그러면 코드는 $results[$key] = $this->execTag($name, $tag, $params);여기. $results[$key] = $this->execTag($name, $tag, $params);这里来。

参数说明

  • $name = string(22) "behaviorLoadBehavior"
  • $tag = module_init

接着通过正则对传过来的参数进行处理,最终返回moduleInit

然后通过$obj = Container::get($class);

매개변수 설명🎜
  • $name = string(22) "behaviorLoadBehavior"
  • $tag = module_init
🎜그런 다음 전달된 매개변수는 정규 표현식을 통해 처리되고 마지막으로 moduleInit가 반환됩니다🎜🎜그 다음 By$obj = 컨테이너::get($class) ;behaviorLoadBehavior🎜의 인스턴스를 반환합니다.

마지막으로 통과했습니다is_callable이 기능이 사용됩니다. 확인을 위해 클래스의 메서드가 메서드 배열 형식으로 호출될 수 있는지 여부를 감지합니다. 이 메서드는 나중에 구문 분석할 개체로 별도의 기사를 작성합니다. 여기서는 false를 반환한다는 점만 알면 됩니다. is_callable这个函数进行验证,检测类里边的方法是否可以被调用,方法数组格式,这个方法后期咔咔单独写一篇文章作为对象来解析,这里只需要知道会返回false即可。

然后会把本类的$portal这个值赋值给$method,这个值就是run。

最后通过$result = $this->app->invoke($call, [$params]);这行代码,这行代码的底部执行就是通过反射机制实现的。

最后这段代码会返回NULL。

实例化控制器

接下来就是进行实例化控制器,调用的方法是$this->app->controller()

그런 다음 $portal code> <code style="font-size: 14px; Overflow-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0px 2px; background-color: rgba(27, 31 , 35, 0.05); 글꼴 계열: " operator mono consolas monaco menlo monospace word-break: break-all color: rgb>$method 실행됩니다. 🎜🎜마지막으로 $result = $this-> app->invoke($call, [$params]);이 코드 줄, 이 코드 줄의 하단 실행은 리플렉션 메커니즘을 통해 구현됩니다. 🎜🎜마지막 코드는 NULL을 반환합니다. 🎜🎜컨트롤러 인스턴스화🎜🎜다음 단계는 컨트롤러를 인스턴스화하는 것입니다.$this->app->controller()🎜

여기서 주목해야 할 것은 목록 함수입니다. 이 함수는 배열을 반환하고 목록의 두 변수는 각각 인덱스 0과 1이 됩니다.

판정은 첫 번째 것도 실행하고 컨테이너 클래스의 make 메소드도 실행합니다. 이 메소드는 이 클래스의 인스턴스를 appindexcontrollerIndex직접 반환합니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

2. ArrayAccess와 인스턴스 반환에 대한 매직 액세스 직접 실행의 차이점에 대해

몇몇 친구들은 이미 배웠습니다. ArrayAccess 및 매직 메소드 __get을 사용하는 방법.

이 두 곳에서 일부 모호한 부분이 있을 것으로 추정됩니다. 카카가 이 두 곳을 합쳐서 한번 분석해보겠습니다.

먼저 ArrayAccess의 사용에 대해 이야기합시다

이 사례는 주로 ArrayAccess 클래스를 구현하기 위해 이전에 시연되었습니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그러면 컨트롤러에 와서 먼저 인스턴스화를 시켜줍니다. 이전에 구현한 사례는 다음과 같습니다.

하지만 이번에 구현해야 하는 경우는 아래 사진에 구현된 것이 아닙니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

다음에는 아래 그림의 방법을 이용하여 배열을 이용하여 객체 속성에 직접 접근합니다.

위 그림을 보면 속성 제목이 kaka로 설정되어 있는 것을 볼 수 있는데, 이 경우 배열 형태로 바로 얻을 수 있습니다.

반환 결과가 kaka인 것을 확인하세요. 이는 객체의 속성이 배열 형식으로 직접 액세스된다는 의미입니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

요약

첫 번째 경우의 구현 과정에서 객체를 사용하여 배열 형태로 객체의 속성에 직접 접근하는 단계가 무시되었습니다.

보이는 것은 바로 얻을 수 있으니, 이 아이디어를 프레임워크에 넣어서 살펴보겠습니다.

프레임워크 실제 사례

이전 기사에서 분석한 경로에 다음 코드가 존재하므로 간단히 분석해 보겠습니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

먼저 thinkApp Object객체로 출력되는 이 앱의 가치를 살펴보겠습니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

thinkApp Object这个对象去访问request时,因为app属性就没有这个request이며, 앱 클래스가 컨테이너 클래스를 상속하므로 컨테이너 클래스로 이동하여 아래 그림의 메서드를 실행하게 됩니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그러면 __get 메소드가 실행되고, make 메소드가 실행되어 해당 인스턴스를 반환하게 됩니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

이때에도 여전히 궁금한 점이 있다면 실행된다고 하는데 왜 그냥 실행하는 걸까요!

다음으로 Kaka가 간단한 테스트를 통해 알아보겠습니다.

이 위치에 임의의 값을 인쇄합니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그런 다음 컨테이너 클래스의 ArrayAccess의 offsetGet 메소드로 이동하여 전달된 값을 인쇄합니다.

인쇄된 결과를 보면 매우 명확해질 것입니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

이것도 이전 내용을 기반으로 한 자세한 설명입니다. 다음 __get 메서드에 대한 자세한 설명을 제공합니다. 컨테이너에서 __get 메서드가 어떤 상황에서 실행되는지 확인하세요.

__get 메소드 사용에 대한 자세한 설명

这个案例请看下图中的这个$this ->후크$this->hook

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

同样的道理先来调试一下这个$this是什么值。

打印这个值都没什么必要,因为就是在本类中。

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

在类中属性的访问应该都会,就是直接使用$this->

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

初始化应用>
🎜同样的道理先来调试一下这个$this是什么值。🎜🎜打印这个值都没什么必要,因为就是재본类中。🎜

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP🎜

打印结果
🎜재类中属性访问应该都会,就是直接使用$this-> 即可。🎜

그래서 시스템이 $this->hookthis에 액세스하면 App 클래스에는 후크 속성이 없으므로 컨테이너 클래스의 매직 메서드가 실행됩니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

그런 다음 make 메소드를 실행하여 클래스의 인스턴스를 생성합니다.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP

요약

그래서 우리는 ArrayAccess와 __get 매직 메소드를 사용하고, 궁극적으로 실행된 make 메소드는 클래스의 인스턴스를 반환합니다.

this->config가 나타나면 실행되는 컨테이너의 __get 메서드입니다.

app['request']가 나타나면 ArrayAccess를 실행한 후 offsetGet을 실행하세요

  • __get은 클래스의 속성이 존재하지 않는 경우에 실행됩니다.
  • ArrayAccess는 인스턴스화된 클래스를 사용하여 배열 형태로 액세스할 때 실행됩니다. offsetGet이 메소드가 실행됩니다.
    추천 튜토리얼: "thinkphp"

위 내용은 ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.