In the above directory, Kaka uses query as a case demonstration , this use is not recommended in the framework, because it will be difficult to maintain.
The case in this section will be queried using the database query method commonly used by the framework.
In the picture above, you can see that the most commonly used query methods are used. Next, we will Conduct a detailed analysis of this set of cases.
The same code will come to the __callStatic
method of the Db class. This method is executed when calling an undeclared static method.
This method is different from the __call method. The __call method calls a method that does not exist. You must pay attention to the difference between the two.
For the method in the above picture, static::connect()
will eventually return object(think \db\Query)
This object, as for the execution of the internal process, you can refer to the contents of the second directory.
So the execution process will come to the table
method of thinkphp/library/think/db/Query.php
this class.
The parameter is the database table name passed in tabletp_test
.
According to the code provided in the above figure, the passed table name will be judged three times.
According to the passed string, the above three judgments are not established, so the following process will be executed.
In the table method, you can see that the final execution process is to store the passed table name in the attribute options
.
and finally return the think\db\Query Object
object.
where method analysis
After the table method analysis is completed The where method will be executed immediately, also in the class thinkphp/library/think/db/Query.php
In the above figure, you can see a method func_get_args
in this class. This method will return an array containing a function parameter list. .
This method is usually used together with call_user_func_array
. Kaka also used these two methods to conduct a case experiment before.
Then the function array_shift
will be used to delete the first element (red) in the array and return the value of the deleted element.
The first result in the figure below is the data obtained by func_get_args
, and the second set of results is the result returned by array_shift
.
The values returned by the two sets of results can be compared to better understand the usage scenarios of array_shift
.
Then the query expression will be analyzed, which is the method parseWhereExp
Things to do.
One thing that needs to be noted in this method is the two parameters passed over.
Parameter one is the query logic, and parameter two is the parameter passed in when using the case.
In the first line of the code, we need to learn a knowledge pointinstanceof
.
instanceof
You can determine whether an object is an instance of a certain class and whether an object implements a certain interface.
The use case for this is explained in detail in the article ThinkPHP Source Code Analysis Controller
.
According to the function of learning instanceof
, we can clearly understand that the first judgment will not be executed.
Continue to study the following execution process, and conduct a simple analysis of the code according to the boxes circled by Kaka.
According to the above figure, all the symbols of the query logic will be converted to lowercase
Then make a judgment$field instanceof Where
Whether the parameter passed is an instance of the Where class.
The last judgment is $field instanceof Expression
It has the same function as the previous step.
So the final execution logic of the code is the part circled in the picture below.
Remember that the parameter passed to where during the case is an array.
If you change the parameter to where('t_id',1)
, you will follow the process of is_string($field)
. This process is left to everyone, click Click will not be analyzed.
Here Kaka still uses arrays as parameters for parsing, then the code will still execute the parseArrayWhereItems
method of this class
In this method, you first need to know what key
will return, and return the element key name from the current internal pointer position.
So the code will execute the judgment of the if statement. According to all the above judgments, it is not consistent, so this code will be executed. $where[] = [$key, is_array($val) ? 'IN ' : '=', $val];
This code will determine whether the value of the loop array is an array. If it is an array, it is in, otherwise it is =. Since value is 1, the second value of the array is =.
Then the final value of where is the data printed in the figure below.
Since where is not empty, the code execution process will be executed to the position in the figure below, and finally Return an instance of this class.
find() execution process
Then the code will still execute the find method of this class to find a single record.
Since no parameters are passed in find, the code will be executed to $this->parseOptions();
Analysis expression (can be used for query or write operations)
As far as the current case is concerned, you can understand this seemingly long code if you take a good look at it. In the end, it still returns all the current parameters.
The following are the returned results
The real query data is this code$result = $this->connection->find($this); , this code will be executed to the file
thinkphp/library/think/db/Connection.php
You can see from this code that when querying a piece of data, the framework adds a limit of 1 by default. As for why it is added like this, you need to check the knowledge of SQL optimization.
This is about the generation of sql statements. You will understand it if you look at the code carefully. Kaka What is analyzed is just a brief understanding of the execution process and specific code.
As for the specific implementation process, if there is an opportunity, Kaka will conduct an in-depth analysis of each method separately in the later stage. At that time, it will mainly focus on the analysis of the code.
The final return result is as follows
The above is about the database query function implemented by Db in combination with connectors, queryers, and generators.
So far, this is the analysis of the Db scene. Next, Kaka will conduct a simple analysis of the Model.
It’s still the previous case, let’s use this method to print the result to see what it is.
When you see the picture above, you will know that it is the SQL statement finally generated by the framework, then the next step is I will take you to discuss how this SQL statement is generated.
The picture below shows the case of this demonstration, which is the area circled in the picture below.
Code tracing from the area circled in the picture above will lead to the file thinkphp/library/think/Db. php
, and will execute the __callStatic method of this class. This method will not be explained. It has been mentioned many times above and before.
And the return result does not need to be declared. As mentioned above, you only need to know that the final return result is return object(think\db\Query)
According to the return result in the above figure, we can know that we will eventually call object(think\ db\Query)
This class’sgetLastSql
This method
According to this method, you can know that the sql statement of the latest query is obtained.
There will be some doubts here, about the attributeconnection
What exactly is it? Here is a brief analysis.
The declaration of this kind of attribute is generally declared in the constructor of this class or the constructor of the parent class. This is also a little tip when reading the source code.
So we first need to take a look at the constructor of this class.
As you can see from the above figure, dependency injection is used here, so Connection
is an object, and it is also the so-called connector.
So this Connection
object is printed as shown below.
According to the above figure, we know that the class file used should bethink\db \connector\Mysql
Then the getLastSql
method in this class will be executed.
But when you come to execute this class, you will find that there is no such method in this class at all.
According to the inheritance relationship in the above figure, we know that this method is in thinkphp/library/think/db /Connection.php
Inside this class file.
The picture below shows the execution process of this method. You can see that there are two parameters, but I am still confused about what these two parameters are.
According to the code tracking, we first briefly analyze the two parameters that appear in the picture above. instruction of
$this->queryStr
Current SQL command$this->bind
Binding ParametersTrack the attribute value of $this->queryStr
I’m probably a little confused when I get here! I'm a little unsure about this value, and the result can't be obtained by printing.
Of course there is another way to debug breakpoint debugging.
But since Kaka shows everyone the source code! You won't use the two methods above, you will find clues directly from the source code.
According to the case provided by Kaka, the last step of execution is the find method. This method is also in the class thinkphp/library/think/db/Connection.php
to find a single Record.
Then we will search a little bit in this method. Kaka has been circled here for everyone, which is the place circled by Kaka in the picture below.
According to the code comments given by Kaka in the picture above, the first parameter is the generated SQL statement. Continue to follow this method and take a look. At this time, this method will still implement the query
method in the file thinkphp/library/think/db/Connection.php
of this class.
In this method, you can see at a glance that the setting of the queryStr
attribute is directly assigned to this attribute, which means that the value of this attribute is the SQL generated by the previous SQL statement. statement.
So this getLastSql
obtains the SQL statement executed before this statement, and can only obtain the most recently executed That SQL statement.
The above is about the implementation principle of getLastSql
. What needs to be noted here is the generation of SQL, which is a bit complicated.
Up to this point, we are done with the analysis of the operation scenarios of the Db class in the database and the combination of connectors, queryers, and generators. It ends here.
Here Kaka mainly uses two cases for execution, the first is the native case, and the second is the frame-encapsulated case.
These two cases were used to conduct in-depth analysis of the source code, but there are many implementation methods in the document. For other methods, you only need to follow the tips given by Kaka and then analyze them bit by bit.
There is no need to execute all methods. No matter which method is used, it is the method analyzed above, which is also very simple.
Finally, I demonstrated how to use getLastSql
to obtain the last executed SQL statement query. The implementation principle here is mainly to use the find method or select when operating the database in the Db class. Methods will eventually lead to one method, which is the query method.
There is also an attribute value queryStr
in this method, that is, the SQL statement is assigned at this time, and then the getLastSql
method is used ## The #queryStr and bind attributes are splicing the SQL, and finally return the SQL statement.
Persistence in learning, persistence in blogging, and persistence in sharing are the beliefs that Kaka has always adhered to since its beginning. I hope that Kaka’s articles on the huge Internet can bring you a little bit of help. I’m Kaka, see you next time.
The above is the detailed content of ThinkPHP's Db class library is used in conjunction with connectors, queries, and sql generators. For more information, please follow other related articles on the PHP Chinese website!