>  기사  >  PHP 프레임워크  >  ThinkPHP 캐시 소스 코드 심층 분석

ThinkPHP 캐시 소스 코드 심층 분석

咔咔
咔咔원래의
2021-01-18 22:46:261829검색
"

캐시는 프로젝트가 일정 기간 실행된 후 사용되는 기능입니다. 이 글에서는 프레임워크의 캐시에 대해 심층적으로 분석하겠습니다

"

서문

프로젝트에서 캐시는 꼭 필요한 기능입니다. 사용자 수가 많을 경우 캐시를 꼭 캐시해두어야 하는데, 데이터베이스를 직접 확인해보면 사용자 경험에 너무 안 좋습니다.

그러면 어떤 상황에서 캐싱을 사용해야 할까요!

  • 웨이보 핫검색 등 핫한 이벤트
  • 구성 항목 등 자주 업데이트되지 않는 데이터
  • 블로그 플랫폼 순위 목록
  • 소셜 플랫폼 관심 목록 팬 목록 등

The 위에서 언급한 애플리케이션 시나리오는 프레임워크의 캐시를 참조하지 않습니다. 일반적으로 프레임워크의 캐시는 캐시 수준에서 사용되지 않습니다.

일반적으로 사용되는 것은 redis, memcache 및 기타 NoSQL입니다.

하지만 오늘의 주요 논의는 프레임워크에서의 캐싱이므로 프레임워크의 캐싱이 만능이라고 생각하지 말고 여전히 프로젝트의 실제 상황에 따라 다릅니다.

1. 캐시 설정 및 소스 코드 분석 실행 과정

먼저 다음 사례를 구현하고 캐시 클래스를 도입해야 합니다

ThinkPHP 캐시 소스 코드 심층 분석
데모 사례

캐시는 어떻게 실행되나요?

코드만Cache::set이제 어떻게 작동하는지 아시나요? 카카를 모르신다면 제가 자세히 가르쳐 드리겠습니다.

우리 모두는 프레임워크의 항목 파일이 index.php이고 항목 파일에 base.php라는 파일이 도입되어 있다는 것을 알고 있습니다.

ThinkPHP 캐시 소스 코드 심층 분석
입력 파일

base.php 파일에 가보시면 클래스 라이브러리 별칭 등록 방법을 보실 수 있으며, 등록 방법은 프레임워크 실행 과정 부분에서 자세히 설명되어 있습니다. 돌아가서 더 자세히 알아보세요.

ThinkPHP 캐시 소스 코드 심층 분석
클래스 라이브러리 별칭 등록

그래서 코드는 프레임워크의 핵심인 Facade 클래스에서 실행됩니다. 이 클래스에는 존재하지 않는 정적 메서드가 있을 때 이 메서드가 실행됩니다. 라고 불리는.

ThinkPHP 캐시 소스 코드 심층 분석
Facade의 핵심 클래스

그러면 이 검증을 어떻게 해야 할까요? 이렇게만 말하면 안 되잖아요, 그렇죠?

그런 다음 코드는 Facade 인스턴스를 생성하는 메서드로 이동합니다. 우리가 수행하는 테스트는 이 클래스의 값을 인쇄하는 것입니다.

ThinkPHP 캐시 소스 코드 심층 분석
Create Facade 인스턴스 생성

이 캐시를 몇 번 실행했는지에 관계없이 인쇄 결과에 이 값이 존재한다는 것을 확실히 알 수 있으므로 Kaka의 진술을 검증하는 또 다른 서투른 방법입니다.

ThinkPHP 캐시 소스 코드 심층 분석
인쇄된 테스트 값

여기에는 모두가 알아야 할 아주 작은 세부 사항이 있습니다. 바로 static 사용에 관한 것입니다.

static에 대한 팁

먼저 캐시 클래스가 이 Facade 파사드 클래스를 상속하세요

ThinkPHP 캐시 소스 코드 심층 분석
클래스 상속

파사드 클래스에 static이 사용되고, 최종 반환되는 클래스는 캐시 클래스인 Facade 클래스를 상속받은 클래스입니다

ThinkPHP 캐시 소스 코드 심층 분석
Facade 클래스 데모

정적으로

한 문장으로 요약할 수 있습니다. 상속된 경우 하위 클래스가 기본적으로 호출되고, 그렇지 않으면 자체 호출됩니다.

따라서 static::getFacadeClass()여기에도 실행된 하위 클래스의 메서드가 있습니다.

좋아, 잠시 막간을 시작하고 본론으로 들어가겠습니다.

그래서 코드는 thinkphp/library/ think/Cache.php이 파일은 핵심 클래스 라이브러리의 위치입니다. thinkphp/library/think/Cache.php这个文件,也就是核心类库的位置。

在这个方法你是找不到set方法的,所以代码将会执行到__call方法,这个方法当调用不存在的方法时则会触发的方法。

ThinkPHP 캐시 소스 코드 심층 분석
ThinkPHP 캐시 소스 코드 심층 분석

ThinkPHP 캐시 소스 코드 심층 분석

根据执行流程我们将会看到init这个方法ThinkPHP 캐시 소스 코드 심층 분석(这里需要注意,第一次并不是在这里进行执行的,而是ThinkPHP 캐시 소스 코드 심층 분석,当ThinkPHP 캐시 소스 코드 심층 분석执行完后会把值存放在handler这个属性,第二次通过call方法进来之后就直接返回了,而不会在进行一次执行,这里一定要注意)

ThinkPHP 캐시 소스 코드 심층 분석
ThinkPHP 캐시 소스 코드 심층 분석

在这里我们进行打印一次$options

이 메소드에서는 set 메소드를 찾을 수 없으므로 존재하지 않는 메소드가 호출될 때 트리거되는 __call 메소드에 대한 코드가 실행됩니다.
ThinkPHP 캐시 소스 코드 심층 분석cached class
cached class

자동으로 초기화된 캐시

실행 과정에 따르면 init 메소드가 캐시를 자동으로 초기화하는 것을 볼 수 있습니다(여기서 처음 실행되는 것은 여기서가 아니라 make 메소드라는 점에 유의해야 합니다. make 메소드가 실행되면, 에 값이 저장됩니다. 두 번째 호출 메소드를 통해 입력하면 핸들러 속성이 바로 반환되며 다시 실행되지 않습니다. 여기서 주의하세요)

🎜자동 초기화 캐시🎜캐시를 자동으로 초기화합니다🎜🎜🎜여기에서는$options이 값입니다. 🎜🎜🎜🎜결과 인쇄🎜🎜🎜🎜$options 매개변수에 값이 있는 이유를 토론하세요🎜🎜🎜컨테이너에 대한 지식은 여기 Kaka로 오세요. 🎜
ThinkPHP 캐시 소스 코드 심층 분석
make method

Cache 생성시 Facade 인스턴스를 생성할 때, 이 과정에서 아래 그림의 동그라미 부분을 주목하시고, 800번 본 make 메소드를 실행해 주세요.

ThinkPHP 캐시 소스 코드 심층 분석
Facade 인스턴스 생성

make 메소드에 왔을 때 동그라미 친 부분을 보시면 됩니다

ThinkPHP 캐시 소스 코드 심층 분석第二次执行的位置
make 메소드가 두 번째로 실행되는 위치

그런 다음 invokeClass 메소드를 입력하고, 이 메서드는 리플렉션 실행 클래스의 인스턴스화를 호출하면 종속성 주입을 지원합니다.

이 방법에서는 Cache의 make 메소드가 리플렉션을 통해 실행됩니다.

调用反射执行类的实例化 支持依赖注入
반사 실행 클래스의 인스턴스화를 호출하고 종속성 주입을 지원합니다

그래서 Cache 클래스의 make 메소드가 실행됩니다. 이 메소드는 이 클래스를 인스턴스화하고 생성자를 실행합니다.

缓存类的ThinkPHP 캐시 소스 코드 심층 분석
캐시 클래스의 make 메소드

생성자로 오시면 make 메소드에서 얻은 캐시 구성 파일의 구성 항목이 자동으로 초기화하는 부분인 init 메소드로 전달되는 것을 보실 수 있습니다. 은닉처.

ThinkPHP 캐시 소스 코드 심층 분석
Constructor

여기서 init 메소드가 캐시를 자동으로 초기화하는 것을 볼 수 있습니다. 첫 번째 실행은 컨테이너가 인스턴스화될 때 실행되므로 $options에는 값이 있습니다. $options才会存在值。

接下来将顺着这个流程进行ThinkPHP 캐시 소스 코드 심층 분석也就是代码$this->handler = $this->connect($options);这块的内容。

这个方法就很简单了,就是使用了之前一直讲解的工厂模式实现的加载不同类型的缓存方式。

然后会把返回的对象存放在以$optionsmd5为下标的缓存实例属性$instance

다음으로 이 프로세스에 따라 $this->handler = $this->connect($options);이 블록의 내용입니다. 🎜🎜이 방법은 매우 간단합니다. 앞서 설명한 팩토리 패턴을 사용하여 다양한 유형의 캐시를 로드합니다. 🎜🎜그런 다음 반환된 개체는 $options md5는 아래 첨자가 붙은 캐시 인스턴스 속성입니다.<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba (27,31,35,.05); 글꼴 계열: 연산자 Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all;">$instance 내부입니다. 🎜<figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201120232141758.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbmdrYW5nNw==,size_16,color_FFFFFF,t_70#pic_center" alt="ThinkPHP 캐시 소스 코드 심층 분석" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">캐시에 연결</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">최종 코드는 캐시의 __call 메소드로 반환되며 클래스는 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">object(thinkcachedriverFile)方法为set

ThinkPHP 캐시 소스 코드 심층 분석
존재하지 않는 메소드가 호출되면 실행됩니다

그런 다음 실행 프로세스는 아래 위치에 와서 Cache

ThinkPHP 캐시 소스 코드 심층 분석
Write Cache

Get file name

이 방법에서 이해해야 할 주요 사항 중 하나는 특정 파일 이름을 가져온 다음 저장하는 방법입니다. 캐시의 데이터.

이 이름 값은 wechat이 설정해야 할 값입니다.

ThinkPHP 캐시 소스 코드 심층 분석
변수의 저장 파일 이름을 가져옵니다

그런 다음 getCacheKey로 이동하여 변수의 저장 파일 이름을 가져옵니다.

이 방법의 첫 번째 단계는 해싱을 통해 유형과 캐시 값을 암호화하는 것입니다. 이러한 옵션은 이 클래스에서 선언되며 여기에서 명확해야 합니다.

옵션 변수는 프레임워크에서 광범위하게 사용되므로 혼동하지 않도록 주의하세요.

이 방법에서 이해해야 할 것은 파일 이름이 어떻게 결정되는지입니다.

ThinkPHP 캐시 소스 코드 심층 분석
파일 이름을 얻으려면

이 옵션의 값을 확인하려면 이 클래스의 시작 부분으로 이동해야 합니다. 이 클래스에서는 위 그림에 사용된 암호화 유형이 hash_type임을 알 수 있습니다. md5

ThinkPHP 캐시 소스 코드 심층 분석
파일 값에 대한 캐싱에 대해

그런 다음 생성자로 이동하면 경로 설정을 볼 수 있습니다

ThinkPHP 캐시 소스 코드 심층 분석
캐시된 파일의 경로를 가져옵니다

다음 줄을Container::get('app')볼 수 있습니다. 위 그림의 코드에서는 이 코드 줄이 사용됩니다. 컨테이너에서도 make 메소드가 실행됩니다. 이 make 메소드는 컨테이너에서 매우 중요한 역할을 하므로 잘 이해해야 합니다.

그리고 혹시 보셨는지 모르겠지만 아래에 init 메소드가 있다는 작은 세부 사항이 있습니다. 이 메소드가 무엇을 하는지 살펴보겠습니다.

이 방법으로 오시면, 획득한 캐시 파일의 경로에 따라 바로 파일이 생성되는 것을 보실 수 있습니다.

ThinkPHP 캐시 소스 코드 심층 분석
초기화 확인

이때 생성된 파일을 확인하면 파일이 생성된 것을 확인할 수 있습니다.

ThinkPHP 캐시 소스 코드 심층 분석
캐시 파일의 경로

마지막으로 file_put_contents 함수를 사용하여 방금 얻은 캐시 파일 저장 위치에 데이터를 저장합니다

ThinkPHP 캐시 소스 코드 심층 분석
캐시 파일에 데이터를 씁니다

데이터베이스 저장 형태는 아래와 같이

ThinkPHP 캐시 소스 코드 심층 분석
데이터 저장 형식

여기까지 프레임워크 캐시 설정은 끝났습니다. 사실 이 경우에는 Kaka에서 사용하는 파일 형식은 Redis와 동일합니다. 또는 다른 사람.

2. 캐시 캐시 획득의 실행 과정 및 소스 코드 분석

캐시 설정의 소스 코드 분석을 배웠으니, 캐시 획득의 소스 코드 분석도 간략하게 이해해야 합니다.

동일한 시연 사례는 이전과 동일합니다. set을 get으로 바꾸면 됩니다

ThinkPHP 캐시 소스 코드 심층 분석
데모 사례

캐시를 설정하는 과정은 동일합니다. 먼저 파사드 클래스로 와서 해당 캐시 인스턴스를 생성합니다

ThinkPHP 캐시 소스 코드 심층 분석
파사드 클래스가 캐시 인스턴스를 생성합니다

Facade 클래스가 캐시 클래스를 생성한 후 캐시 클래스 파일이 나옵니다thinkphp/library/think/Cache.php

이 파일에서 __call 메소드가 여전히 사용되는 것을 볼 수 있습니다. 이 메소드는 존재하지 않는 메소드를 호출하여 실행됩니다.

ThinkPHP 캐시 소스 코드 심층 분석
캐시된 파일

그 다음에는 init 메소드에 대해 설명하겠습니다. 이 메소드는 캐시 값을 설정할 때 자세히 설명했습니다.

실행 프로세스에 따르면 init 메소드가 자동으로 캐시를 초기화하는 것을 볼 수 있습니다(여기서 처음 실행되는 것은 여기서가 아니라 make 메소드라는 점에 유의해야 합니다. make 메소드가 실행되면 값은 handler Attribute에 저장되는데, 두 번째 호출 메소드를 통해 들어오면 다시 실행하지 않고 바로 반환됩니다. 여기서 주의하셔야 합니다.)

여기서 캐시의 make 메소드가 먼저 실행되는 이유는 캐시 때문입니다. 클래스 인스턴스가 컨테이너에 생성됩니다. 이때 클래스에 make 메소드가 있는지 여부를 make 메소드에서 판단하여 존재하는 경우 먼저 실행합니다.

ThinkPHP 캐시 소스 코드 심층 분석
캐시 자동 초기화

그래서 캐시 클래스thinkphp/library/think/cache/driver/File.php이 클래스의 get 메소드return call_user_func_array([$this->init(), $method], $args);这块代码会去执行thinkphp/library/think/cache/driver/File.php这个类的get方法

ThinkPHP 캐시 소스 코드 심층 분석
ThinkPHP 캐시 소스 코드 심층 분석

在这个类中你可以看到一个在设置缓存值时花了好久解析的一个方法getCacheKey

캐시 읽기

Read Cache

이 클래스에서는 시간이 오래 걸리는 A 메소드를 볼 수 있습니다. 캐시 값 설정 시 구문 분석 시간getCacheKey <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201122192916199.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbmdrYW5nNw==,size_16,color_FFFFFF,t_70#pic_center" alt="ThinkPHP 캐시 소스 코드 심층 분석" style="max-width:90%">이 방법에서 sbustr은 주로 값의 스탠자를 암호화하는 데 사용됩니다. 처음 두 값은 디렉터리이고 나머지 문자는 파일 이름입니다. <figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;"></figcaption>그런 다음 파일 이름을 반환합니다. </figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"></p>🎜변수의 저장 파일 이름을 가져옵니다🎜🎜🎜그런 다음 file_get_contents를 사용하여 파일 내용을 가져옵니다🎜<figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201122193753936.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbmdrYW5nNw==,size_16,color_FFFFFF,t_70#pic_center" alt="ThinkPHP 캐시 소스 코드 심층 분석" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">파일 내용을 읽어보세요</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">그러면 여기에 만료된 삭제된 캐시 파일이 있습니다. </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">프레임워크의 만료 정책은 만료 시간을 설정하면 캐시가 만료된 후 바로 삭제되지 않고, 다시 액세스한 후에 삭제된다는 것입니다. </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">이 전략은 redis에서 지연 삭제입니다. 지연 삭제를 사용하면 데이터가 만료될 때 자동으로 삭제되지 않습니다. 그러면 삭제 방법은 다음에 키 값을 얻을 때 판단하는 것입니다. 만료되었습니다. 만료된 경우 삭제하세요. </p> <figure data-tool="mdnice编辑器" style="margin: 0; margin-top: 10px; margin-bottom: 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden;"><img src="https://img-blog.csdnimg.cn/20201122193909511.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZhbmdrYW5nNw==,size_16,color_FFFFFF,t_70#pic_center" alt="ThinkPHP 캐시 소스 코드 심층 분석" style="max-width:90%"><figcaption style="margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">만료된 전나무 캐시 파일</figcaption></figure><p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">지금까지 캐시 획득 실행 프로세스는 소스 코드 파싱을 통해 완료되었습니다. 실제로 대부분의 콘텐츠는 획득 시 파싱되었습니다. </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">그렇다면 우리가 여전히 캐시된 데이터를 얻는 것에 대해 이야기하는 이유는 여기서 설명할 것이 있기 때문입니다. </p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px; margin-bottom: 15px; padding: 0px; color: black; border-top: 2px solid rgb(248, 57, 41); text-align: center; font-size: 1.3em;"> <span class="prefix" style="display: none;"></span><span class="content" style="display: inline-block; font-weight: normal; background: rgb(248, 57, 41); color: #ffffff; padding: 3px 10px 1px; border-radius: 0 0 13px 13px;"> 3. 데이터 압축 </span><span class="suffix"></span> </h1> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;"> 캐시 설정 시 캐시된 값을 <code style="font-size: 14px; word-wrap: break-word) 파일에 쓰는 기능이 있습니다. ; 패딩: 2px 4px; 테두리 반경: 0 2px; 배경색: rgba(27,31,35,.05); 글꼴 계열: 연산자 Mono, Consolas, Menlo, word- break : break-all; color: rgb(271, 93, 108);">gzcompressgzcompress

然而在获取缓存值的时候从文件将数据读出时又遇到的一个函数gzuncompress

그러나 캐시 값을 가져올 때 파일에서 데이터를 읽을 때 다른 함수가 발생합니다gzuncompress

사실 캐시 설정부터 가져오기까지 압축된 데이터가 설정되고 압축이 풀린 데이터가 얻어지는 함수를 보면 알 수 있습니다. 🎜

PHP에는 두 가지 다른 압축 함수가 있습니다. gzdeflate、gzencode,同样的解压函数也是对应的gzinflate gzdecode

이러한 함수는 모두 압축 함수이지만 기본 구현은 다릅니다.

gzcompress는 ZLIB 형식을 사용합니다.

gzdeflate는 순수 DEFLATE 형식을 사용합니다.

gzencode는 GZIP 형식을 사용합니다.

위 내용은 데이터 압축 및 압축 해제에 대한 일부 지식입니다.

4. 요약

이 섹션에서 Kaka는 프레임워크의 캐싱 처리 결과를 안내합니다.

사실 Kaka는 프레임워크의 캐시 응답 시간이 1/3로 단축되어야 한다는 것을 이전에 테스트한 적이 있습니다. 물론 이 역시 데이터 크기에 따라 다릅니다.

이걸로 PHP 프레임워크의 소스코드 해석이 끝났습니다ThinkPHP. 나중에 시간이 나면 언급되지 않은 내용도 좀 해석해보겠습니다.

마지막으로 소스 코드를 읽는 것은 정말 피곤합니다.

배움에 대한 끈기, 블로그에 대한 끈기, 공유에 대한 끈기는 Kaka가 경력 이후부터 항상 지켜온 신념입니다. Kaka의 Nuoda 인터넷 기사가 여러분에게 조금이나마 도움이 되기를 바랍니다. , 다음호

을 참조하세요.

위 내용은 ThinkPHP 캐시 소스 코드 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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