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

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

咔咔
咔咔원래의
2020-12-04 12:49:35139검색
"

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

"

머리말

에서 위 기사에서 라우팅에 대해 설명합니다. 특별 세부 설명도 애플리케이션 초기화 및 분석부터 경로 스케줄링이 경로 감지로 돌아올 때까지 시작됩니다.

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

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

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
인쇄된 장소
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
라우팅 감지 결과

위 그림에서 볼 수 있듯이, 중요한 데이터는 디스패치c에 저장되고 이후 제어가 이루어지게 됩니다. 장치에 대해 자세히 설명되어 있습니다.

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

1. 인스턴스화 컨트롤러

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

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

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

이 실행 응용 프로그램으로 들어옵니다. 이 방법에서는 위에서 방금 구문 분석한 경로도 사용됩니다.

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

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
애플리케이션 실행

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

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

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

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

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

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

接着就需要对这个类中的run方法进行解析了,这个方法也就是ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP。

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

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

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

경로의 최종 반환 값을 감지한 후 이 메서드가 실제로 thinkroutedispatchModule이 클래스에 있습니다.

그런 다음 이 수업에서 라우팅 스케줄링을 수행하는 실행 방법을 분석해야 합니다.
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP이 방법에서는 라우팅 매개변수 획득, 라우팅 감지, 자동 데이터 확인이 모두 실행되지 않습니다(위의 Kaka가 예시로 제공한 라우팅 주소를 기반으로 함).
라우팅 스케줄링 실행
라우팅 스케줄링 실행

그래서 위 코드에 따르면 $data = $this->exec();여기.

🎜이 방법을 추적하면 아래 그림과 같은 추상 클래스가 존재하게 됩니다. 여기서 알아야 할 것은 추상 클래스입니다. 🎜🎜🎜🎜추상 클래스🎜🎜🎜🎜추상 클래스 설명🎜🎜
  • 추상 클래스는 인스턴스화할 수 없습니다.
  • 추상 메서드가 있는 클래스는 추상 클래스여야 합니다. 클래스는 추상 수정되어야 합니다.
  • 추상 메서드는 함수 본문을 가질 수 없습니다.
  • 추상 클래스의 비추상 메서드는 하위 클래스에서 호출할 수 있습니다.
  • 비추상 하위 클래스는 추상 클래스를 상속하며, 하위 클래스는 상위 클래스의 모든 추상 메서드를 구현해야 합니다.
  • 추상 하위 클래스는 상속 없이 추상 클래스를 상속합니다. 상위 클래스의 추상 메서드

는 위 그림의 원리에 따라 볼 수 있습니다Dispatch이 클래스는 추상 클래스입니다. Dispatch这个类是ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP。

所以就会有俩种情况, 一种是ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP继承ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP,无需继承父类的抽象方法。

另一种是非抽象子类继承ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP,子类必须实现父类的所有抽象方法。

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

怎么去找谁继承了Dispatch

这个时候是不是有一个疑问就是怎么去找Dispatch的子类。

在这个图中可以看到本类Dispatch,但是还有一个dispatch这个目录。

根据ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP返回的数据可以轻而易举的就知道是thinkphp/library/think/route/dispatch/Module.php

그래서 두 가지 상황이 발생합니다. 하나는 추상 클래스가 상위 클래스의 추상 메서드를 상속하지 않고 추상 클래스를 상속한다는 것입니다. 🎜🎜다른 하나는 추상이 아닌 하위 클래스가 추상 클래스를 상속하고 하위 클래스가 상위 클래스의 모든 추상 메서드를 구현해야 한다는 것입니다. 🎜
추상 클래스
추상 클래스
🎜찾는 방법 Dispatch는 누가 상속받나요?🎜🎜이때 Dispatch의 서브클래스를 어떻게 찾는지에 대한 질문이 있습니다. 🎜🎜이 사진에서 이런 종류의 Dispatch를 볼 수 있는데, Dispatch 디렉토리도 있습니다. 🎜🎜경로 감지에서 반환된 데이터에 따르면 thinkphp/library/think/route/dispatch/Module.php이 클래스입니다. 🎜
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
하위 카테고리를 찾는 중

thinkphp/ library/think/route/dispatch/Module.php보기exec 메소드. thinkphp/library/think/route/dispatch/Module.php查看exec方法。

那么接下来的任务就是对这个方法进行深入的解读了。

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

先看第一行代码$this->app['hook']->listen('module_init');,在这里使用了容器ArrayAccess用数组的形式访问对象,然后执行的ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP__get,当访问不存在的属性时会去执行make方法。

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

그럼 다음 작업은 이 방법에 대한 심층적인 설명을 제공하는 것입니다.
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP인스턴스화된 컨트롤러
컨트롤러 인스턴스화

먼저 코드의 첫 번째 줄을 보세요.$this->app['hook']->listen('module_init');, 여기서 컨테이너 ArrayAccess는 배열에 액세스합니다. 존재하지 않는 속성에 액세스하면 make 메소드가 실행됩니다.

🎜편집기를 사용하여 이 앱을 추적하면 ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
상속 클래스

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

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
존재하지 않는 속성에 액세스할 때 매직 메서드가 실행됩니다

따라서 이 블록의 매개변수가 후크로 전달되고 후크의 인스턴스가 반환되는 방법은 에서 설명합니다. 컨테이너 섹션이 자세히 나와 있으니 살펴보세요!

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

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

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);返回behaviorLoadBehavior的实例

最终通过is_callable这个函数进行验证,检测类里边的方法是否可以被调用,方法数组格式,这个方法后期咔咔单独写一篇文章作为对象来解析,这里只需要知道会返回false即可。

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

最后通过$result = $this->app->invoke($call, [$params]);

매개변수 설명

    $name = string(22) "behaviorLoadBehavior"
  • $tag = module_init
그 다음 전달된 매개변수는 정규식을 통해 처리되고 마지막으로 moduleInit가 반환됩니다

그런 다음 $obj = Container::get($class);behaviorLoadBehavior

의 인스턴스를 반환합니다.is_callable이 함수는 클래스의 메소드를 호출할 수 있는지 확인합니다. 배열 형식을 사용하면 Kaka는 구문 분석할 개체로 별도의 기사를 작성합니다. 여기서는 false가 반환된다는 점만 알면 됩니다. 🎜🎜그런 다음 $portal이 값은 $method, 값은 달리다. 🎜🎜마지막으로 $result = $this->app ->invoke($call, [$params]);이 코드 줄, 이 코드 줄의 하단 실행은 리플렉션 메커니즘을 통해 구현됩니다. 🎜🎜마지막 코드는 NULL을 반환합니다. 🎜🎜🎜인스턴스화된 컨트롤러🎜🎜

다음 단계는 컨트롤러를 인스턴스화하는 것입니다. 호출 방법은 $this->app->controller()

这里需要注意的是list这个函数,这个函数的后边会返回一个数组,然后list中的俩个变量会分别为索引0和1。

判断也会去执行第一个,同样会执行到容器类的make方法,这个方法会直接返回appindexcontrollerIndex

여기서 주목해야 할 것은 목록 함수입니다. 이 함수 다음에 배열이 반환되고 목록의 두 변수가 반환됩니다. 인덱스 0과 1.
实例化(分层)控制器 格式:[模块名/]控制器名판정은 첫 번째 것도 실행하고 컨테이너 클래스의 make 메소드도 실행합니다. 이 메소드는 appindexcontrollerIndex이 클래스의 인스턴스입니다.

인스턴스화(계층형) 컨트롤러 형식: [모듈 이름/] 컨트롤러 이름 2. ArrayAccess와 인스턴스 반환에 대한 매직 액세스 직접 실행의 차이점에 대해

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

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

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

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP이 사례는 주로 ArrayAccess 클래스를 구현하기 위해 이전에 시연되었습니다.

이미 작성한 테스트 방법입니다

그리고 컨트롤러에 와서 사용하게 되면 먼저 인스턴스화를 시켜줍니다. 이전에 구현한 사례는 다음과 같습니다. 🎜🎜하지만 이번에 구현해야 할 케이스는 아래 사진에 구현된 것이 아닙니다. 🎜
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
컨트롤러 사용하기

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

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

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

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

Summary

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

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

프레임워크 실제 사례

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

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

먼저 인쇄 시 이 앱의 값을 살펴보겠습니다. thinkApp 개체개체. thinkApp Object对象。

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

thinkApp Object这个对象去访问request时,因为app属性就没有这个request

인쇄된 앱 값
인쇄된 앱 값ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
thinkApp 개체
액세스할 개체request, 왜냐하면 앱 속성에 이 request, 그리고 앱 클래스가 컨테이너 클래스를 상속하기 때문에 따라서 컨테이너 클래스로 이동하여 아래 표시된 메서드를 실행합니다.

이 메소드를 실행하세요ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP返回实例对象
그러면 __get 메소드가 실행되고, make 메소드가 실행되어 해당 인스턴스를 반환하게 됩니다.

🎜이 메소드를 실행하면 인스턴스 객체를 반환합니다🎜🎜🎜이때에도 여전히 의문점이 있다면 왜 실행된다고 하는데 그냥 실행하는 걸까요! 🎜

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

이 위치에 임의의 값을 인쇄하세요.

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

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

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

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
여기에 그림 설명 삽입
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
결과 인쇄

ArrayAccess의 사용은 여기서 끝입니다. 이것도 이전 내용을 기반으로 한 자세한 설명입니다. __get 메서드가 어떤 상황에서 실행되는지 자세히 알아보세요.

__get 메소드 자세한 설명

이 경우 아래 사진을 참고해주세요$this->hook.

ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
애플리케이션 초기화

같은 이유로 이것을 먼저 디버깅해 보겠습니다$this의 값은 무엇입니까. $this是什么值。

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

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

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

所以说当系统访问$this->hook

이 값은 이 클래스에 있으므로 인쇄할 필요가 없습니다.
ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP결과 인쇄
결과 인쇄

클래스의 속성 액세스가 쉬워야 합니다. $this->가 됩니다.

그래서 시스템이 $this->hook 이때 App 클래스에는 Hook 속성이 없으므로 컨테이너 클래스의 매직 메소드가 실행됩니다. ArrayAccess와 직접 매직 액세스 반환 인스턴스의 차이점에 대해 ThinkPHP
Magic method

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

🎜🎜🎜 클래스 인스턴스 만들기 🎜🎜🎜🎜 요약 🎜🎜

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

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

app['request']를 만나면 ArrayAccess가 실행된 후 offsetGet이 실행됩니다

  • __get은 클래스의 속성이 존재하지 않을 때 실행됩니다
  • ArrayAccess가 인스턴스화됩니다. 클래스가 배열 형식으로 액세스될 때 이 메서드가 존재하지 않으면 실행됩니다. offsetGet

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

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