위 디렉터리에서 Kaka는 쿼리를 사례 데모로 사용합니다. 다소 어려울 수 있습니다.
이 섹션의 사례는 프레임워크에서 일반적으로 사용하는 데이터베이스 쿼리 방법을 사용하여 쿼리됩니다.
위 그림에서 가장 일반적으로 사용되는 쿼리 방법이 사용되는 것을 볼 수 있습니다. 다음으로 이 사례 집합을 자세히 분석합니다.
Db 클래스의 __callStatic
메소드에도 동일한 코드가 나옵니다. 이 메소드는 선언되지 않은 정적 메소드를 호출할 때 실행됩니다.
이 메서드는 __call 메서드와 다릅니다. __call 메서드는 존재하지 않는 메서드를 호출할 때 호출됩니다. 둘 사이의 차이점에 유의하세요.
위 그림의 메서드에 대해 static::connect()
는 결국 object(thinkdbQuery)
이 객체는 내부 프로세스의 실행을 참조할 수 있습니다. 두 번째 디렉토리의 내용. static::connect()
执行最后会返回 object(thinkdbQuery)
这个对象,至于内部流程的执行可以参考第二目录的内容。
所以执行流程会来到thinkphp/library/think/db/Query.php
这个类的table
方法。
参数就是table中传递的数据库表名tp_test
thinkphp/library/think/db/Query.php
테이블
메소드. 매개변수는 tabletp_test
.
위 그림에 제공된 코드에 따라 통과된 테이블 이름이 3번 심사됩니다.
전달된 문자열에 따르면, 위의 세 가지 판단 중 어느 것도 사실이 아니므로 다음 프로세스가 실행됩니다.
table 메소드에서는 전달된 테이블 이름을 options
속성에 저장하는 것이 최종 실행 과정임을 알 수 있습니다.
하고 마지막으로 thinkdbQuery 개체
이 개체가 반환됩니다. thinkdbQuery Object
这个对象进行返回。
where方法解析
table方法分析完成后会紧接着执行where方法,同样还是在类thinkphp/library/think/db/Query.php
thinkphp/library/think/db/Query.php
🎜🎜🎜🎜위 그림에서 이 클래스의 메서드를 볼 수 있습니다func_get_args
, 이 메소드는 함수 매개변수 목록이 포함된 배열을 반환합니다. func_get_args
,这个方法会返回一个包含函数参数列表的数组。
这个方法平时都是跟call_user_func_array
同时使用,之前咔咔也使用这俩个方法进行过一次案例实验。
然后会使用函数array_shift
删除数组中的第一个元素(red),并返回被删除元素的值。
下图第一个结果为func_get_args
这个方法获取出来的数据,第二组结果为array_shift
call_user_func_array
를 동시에 사용했는데, 카카도 이 두 가지 방법을 사용해 이전에 사례 실험을 진행한 적이 있다. 🎜🎜그런 다음 함수가 사용됩니다. array_shift
배열의 첫 번째 요소(빨간색)를 삭제하고 삭제된 요소의 값을 반환합니다. 🎜🎜아래 그림의 첫 번째 결과는 func_get_args
이 방법으로 얻은 데이터, 두 번째 결과 세트는 array_shift
이 메소드가 반환한 결과입니다. 🎜더 나은 이해를 위해 두 결과 세트에서 반환된 값을 비교할 수 있습니다.array_shift
사용 시나리오. array_shift
的使用场景。
紧接着会进行分析查询表达式,也就是方法parseWhereExp
parseWhereExp
가 수행합니다. 이 메서드에서 주목해야 할 한 가지는 전달되는 두 개의 매개 변수입니다. 매개변수 1은 쿼리 로직이고, 매개변수 2는 케이스 사용 시 전달되는 매개변수입니다.
🎜🎜🎜코드의 첫 번째 줄에서는 지식 포인트instanceof
. instanceof
。
instanceof
可以判断某个对象是否是某个类的实例,判断一个对象是否实现了某个接口。
关于这个的使用案例在文章ThinkPHP源码解析之控制器
这一文中做了详细的说明。
根据学习instanceof
는 객체가 특정 클래스의 인스턴스인지, 객체가 특정 인터페이스를 구현하는지 여부를 확인할 수 있습니다. <p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb></p>이에 대한 사용 사례는 <code style="box-sizing: border-box; 글꼴 크기: 14px; 글꼴-가족: " operator mono consolas monaco menlo monospace overflow-wrap : rgba break>ThinkPHP 소스 코드 분석 컨트롤러
는 이 문서에서 자세히 설명합니다. 학습 기반 instanceof
함수는 첫 번째 판단이 실행되지 않음을 분명히 합니다.
위 그림대로 먼저 쿼리 로직의 모든 기호를 소문자로 변환
그런 다음 판단하세요$field instanceof Where
전달된 매개변수가 Where 클래스의 인스턴스인지 여부. $field instanceof Where
传递过来的参数是否为Where类的实例。
最后一个判断就是$field instanceof Expression
$field instanceof Expression
이전 단계와 동일한 기능이 판단됩니다. 그래서 코드의 최종 실행 로직은 아래 그림에서 동그라미 친 부분입니다.
사례 중 where에 전달된 매개 변수는 배열이라는 점을 기억하세요. 🎜매개변수를 where('t_id',1)
는 is_string($field)
의 프로세스이며, 이 프로세스는 모든 사람에게 맡겨져 있으며 Kaka는 이를 분석하지 않습니다. where('t_id',1)
则就会走is_string($field)
的这个流程,这个流程就交给大家了,咔咔就不去解析。
这里咔咔还是使用数组作为参数进行解析,那么代码依然会执行本类的parseArrayWhereItems
这个方法
在这个方法中先需要知道key
会返回什么,从当前内部指针位置返回元素键名。
所以代码会去执行if语句的判断,根据上边的所有判断都不符合所以会执行这段代码$where[] = [$key, is_array($val) ? 'IN' : '=', $val];
parseArrayWhereItems
이 방법🎜🎜🎜이 방법에서는 먼저key
는 현재 내부 포인터 위치에서 요소 키 이름을 반환합니다. 🎜🎜그래서 코드는 if문의 판단을 실행하게 됩니다. 위의 모든 판단에 따르면 일관성이 없으므로 이 코드가 실행됩니다. $where[] = [$key, is_array($val) ? 'IN' : '=' , $val];🎜<p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb>이 코드는 루프 배열의 값이 배열인지 여부를 결정합니다. 배열이면 in이고 그렇지 않으면 =입니다. 값이 1이므로 배열의 두 번째 값은 =입니다. </p>
<p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb>그럼 아래 그림에 출력된 데이터가 어디에 있는지 최종값이 나옵니다. </p>
<p><img src="https://img.php.cn/upload/image/303/557/279/1610338373356051.png" title="1610338373356051.png" alt="ThinkPHP의 Db 클래스 라이브러리는 커넥터, 쿼리 및 SQL 생성기와 함께 사용됩니다."></p>
<figure style="box-sizing: border-box; margin: 10px 0px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif font-size: letter-spacing: white-space: normal word-spacing: background-color: rgb><figcaption style="box-sizing: border-box; margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;">where에서 반환되는 값 </figcaption></figure><p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb> where는 비어 있지 않으므로 아래 표시된 위치까지 코드 실행 과정이 실행되고, 최종적으로 이 클래스의 인스턴스가 반환됩니다. </p>
<p><img src="https://img.php.cn/upload/image/607/906/494/1610338367967444.png" title="1610338367967444.png" alt="ThinkPHP의 Db 클래스 라이브러리는 커넥터, 쿼리 및 SQL 생성기와 함께 사용됩니다."></p>
<figure style="box-sizing: border-box; margin: 10px 0px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-radius: 16px; overflow: hidden; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif font-size: letter-spacing: white-space: normal word-spacing: background-color: rgb><figcaption style="box-sizing: border-box; margin-top: 5px; text-align: center; color: rgb(136, 136, 136); font-size: 12px;"> 옵션 속성에 쿼리 매개변수를 저장합니다. </figcaption></figure><p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb><span style="box-sizing: border-box; font-weight: 700; color: rgb(248, 57, 41);">find() 실행 프로세스 </span></p>
<p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb>그런 다음 코드는 여전히 이 클래스의 find 메소드를 실행하여 단일 레코드를 찾습니다. </p>
<p style="box-sizing: border-box; margin-top: 0.8em; margin-bottom: 0.8em; font-size: 16px; padding-top: 8px; padding-bottom: 8px; line-height: 1.75; color: rgb(53, 53, 53); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, " pingfang sc cambria cochin georgia times new roman serif letter-spacing: white-space: normal word-spacing: background-color: rgb>find에 매개변수가 전달되지 않으므로 코드는 <code style="box-sizing: border-box;font-size: 14px;font-family: " operator mono consolas monaco menlo monospace rgb word-break: break-all>$this->parseOptions();
분석 표현식(쿼리 또는 쓰기 작업에 사용할 수 있음)$this->parseOptions();
分析表达式(可用于查询或者写入操作)
就目前写的案例而言,这段看似很长的代码大家好好看看都可以看明白,最终依然是返回当前的所有参数。
以下就是返回的所以结果
真正的查询数据是这块代码$result = $this->connection->find($this);
,这段代码会执行到文件thinkphp/library/think/db/Connection.php
🎜 🎜다음 모든 결과가 반환됩니다 🎜
🎜$result = $this->connection->find($this);
, 이 코드는 thinkphp/library/think/db/Connection.php
🎜
이 코드를 보면 프레임워크에서 데이터 조각을 쿼리할 때 기본적으로 1이라는 제한을 추가하는 것을 알 수 있습니다. 이렇게 추가하는 이유는 SQL 최적화에 대한 지식을 확인해야 합니다.
여기서는 SQL 문 생성에 관한 내용입니다.
구체적인 구현 과정은 추후 기회가 된다면 각 방법에 대한 심층 분석을 별도로 진행할 예정이며, 이때는 주로 코드 분석에 중점을 둘 예정입니다.
최종 반환 결과는 다음과 같습니다
위는 커넥터, 쿼리어, 제너레이터와 결합하여 Db에서 구현한 데이터베이스 쿼리 기능에 대한 내용입니다.
지금까지는 Db 시나리오 분석이었습니다. 다음으로 Kaka는 모델에 대한 간단한 분석을 진행하겠습니다.
이 방법을 사용하여 결과를 인쇄해 보겠습니다.
위의 그림을 보면 프레임워크에서 최종적으로 생성된 SQL 문임을 알 수 있습니다. 그러면 Kaka가 이 SQL 문이 어떻게 생성되는지 설명하도록 안내합니다.
아래 사진은 이번 시연 사례를 보여주는데, 아래 사진에서 동그라미 친 부분이 바로 이 부분입니다.
위 그림에서 원으로 표시된 영역에서 코드를 추적하면 thinkphp/library/think/Db.php
, 이 클래스의 __callStatic 메소드를 실행합니다. 이 메소드는 예, 위에서도 여러 번 언급되었습니다. thinkphp/library/think/Db.php
,并且会去执行本类的__callStatic方法,这个方法就不在进行解释了,在上文和之前也已经提到过多次了。
并且返回结果也不去做声明了,上文也提到了,这里只需要知道最终返回结果为返回 object(thinkdbQuery)
根据上图的返回结果可以知道最终回去调用object(thinkdbQuery)
这个类的getLastSql
객체 반환(thinkdbQuery)
🎜🎜🎜🎜🎜선언되지 않은 정적 메소드가 호출되면 실행됩니다🎜🎜🎜에 따르면 위 그림의 반환 결과를 보면 결국 object(thinkdbQuery)
getLastSql
이 방법🎜이 방법에 따르면 최신 쿼리의 sql문이 얻어지는 것을 알 수 있습니다.
여기서 connection
속성이 무엇인지에 대해 몇 가지 질문이 있을 것입니다. 여기에 간단한 분석이 있습니다.
이 속성의 선언은 일반적으로 이 클래스의 생성자 또는 상위 클래스의 생성자에서 선언됩니다. 이는 소스 코드를 읽을 때의 작은 팁이기도 합니다.
그러므로 먼저 이 클래스의 생성자를 살펴봐야 합니다.
위 그림에서 볼 수 있듯이 여기서는 종속성 주입을 사용하므로 연결
은 개체이며 프레임워크의 소위 커넥터이기도 합니다. Connection
就是一个对象,并且也是框架中所谓的连接器。
所以说这个Connection
对象就是下图打印出来的。
根据上图得知使用的类文件应该就是thinkdbconnectorMysql
那么就会执行这个类里边的getLastSql
Connection
객체는 아래와 같이 출력됩니다.
🎜🎜커넥터의 객체 출력 결과🎜🎜🎜위 그림에 따르면 사용되는 클래스 파일은 thinkdbconnectorMysql
getLastSql
메소드. 🎜🎜하지만 이 수업을 실행해 보면 이 수업에는 그런 방법이 전혀 없다는 것을 알게 될 것입니다. 🎜
위 그림의 상속 관계에 따르면 이 메소드가 thinkphp/library/think/db/Connection.php
이 클래스 파일에 있음을 알 수 있습니다.
아래 그림은 이 메서드의 실행 과정을 보여줍니다. 두 개의 매개 변수가 있는 것을 볼 수 있지만 여전히 혼란스럽고 그것이 무엇인지 모르겠습니다.
코드 추적에 따라 위 그림에 나타나는 두 가지 매개 변수에 대해 간략하게 설명하겠습니다
queryStr
当前SQL指令$this->queryStr
当前SQL指令$this->bind
绑定参数追踪$this->queryStr这个属性值
走到这里估计有点蒙了吧!对于这个值有点确定不了了,指定不是靠打印可以获取到结果的。
当然还有另一种办法就是进行debug来断点调试。
但是既然咔咔带大家看源码呢!就不会用上边的俩种方式,会直接从源码中找到蛛丝马迹。
根据咔咔上边给提供的案例,执行的最后一步就是find方法,这个方法也是在thinkphp/library/think/db/Connection.php
$this->bind
绑定参数追踪$this->queryStr这个属性值🎜
설정할 수 없습니다. 。🎜
当然还有另一种办法就是进行debug来断点调试。🎜
但是既然咔咔带大家看源码呢! 🎜
根据咔咔上边给提供的案例, 执行的最后一步就是find방법, 这个方法也是에서thinkphp/library/think/db/Connection.php
这个类里边,寻找单条记录。🎜
그럼 이 방법으로 조금 검색해보겠습니다. 여기 카카가 동그라미로 표시되어 있는데, 아래 사진에서 카카로 동그라미 친 곳이 바로 여기입니다.
위 그림에서 Kaka가 제공한 코드 설명에 따르면 첫 번째 매개변수는 생성된 SQL 문입니다. 이 방법을 계속해서 살펴보겠습니다. 이 클래스에는 여전히 thinkphp/library/think/ db/Connection.php
이 파일은 쿼리
방법. thinkphp/library/think/db/Connection.php
这个文件中实现query
方法。
在这个方法中一眼就可以看见对于这个queryStr
queryStr
속성의 설정은 이 속성에 직접 값을 할당하는 것인데, 이는 이 속성의 값이 이전 SQL 문에서 생성된 SQL 문임을 의미합니다. 🎜그래서 이getLastSql
은 이 명령문 이전에 실행된 SQL 문을 가져오며, 가장 최근에 실행된 SQL 문만 가져올 수 있습니다. getLastSql
获取的就是在这个语句之前执行的SQL语句,也只能获取出最近执行的那个SQL语句。
以上就是关于getLastSql
getLastSql
의 구현 원리 중 여기서 주목해야 할 것은 SQL 생성인데, 조금 복잡합니다. 어떤 방법을 사용하더라도 모든 방법을 실행할 필요는 없으며 위에서 분석한 방법이기도 하며 매우 간단합니다.
마지막으로 getLastSql
을 사용하여 마지막으로 실행된 SQL 문 쿼리를 가져옵니다. 여기서 주요 구현 원칙은 Db 클래스가 데이터베이스를 작동할 때 find 메서드를 사용하든 선택 메서드를 사용하든 결국 다음으로 이동한다는 것입니다. 한 가지 방법은 쿼리 방법입니다. getLastSql
来获取最后一次执行的SQL语句查询,这里的实现原理主要就是在Db类操作数据库时,不管是使用find方法还是select方法最终都会走向一个方法那就是query方法。
同样在这个方法中存在一个属性值queryStr
,也就是在这个时候将SQL语句赋值进去的,然后在使用getLastSql
这个方法使用queryStr和bind
queryStr
즉, 이때 SQL 문을 할당한 다음 getLastSql
이 방법은 queryStr 및 바인딩
속성이 SQL을 접합하고 마지막으로 SQL 문이 반환됩니다. 배움의 끈기, 블로그의 끈기, 공유의 끈기는 카카가 창립 이래 늘 지켜온 신념입니다. 거대 인터넷에 올라온 카카의 글이 조금이나마 도움이 되었으면 좋겠습니다. 저는 카카입니다. 다음에 만나요.🎜
위 내용은 ThinkPHP의 Db 클래스 라이브러리는 커넥터, 쿼리 및 SQL 생성기와 함께 사용됩니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!