search
HomeBackend DevelopmentPHP TutorialPHP source code ext/mysql extension_PHP tutorial
PHP source code ext/mysql extension_PHP tutorialJul 21, 2016 pm 03:45 PM
extmysqlphpexternalstartExpandmoduleSource codeNowlookpart

I have written an external module extension, and now I am starting to look at the mysql extension in the PHP source code. It can be integrated into PHP, so it should be regarded as a built-in extension.
This extension needs to use some interfaces provided by the mysql database, so mysql needs to be installed and the location of mysql.h needs to be determined.
The location of this extension is generally under PHP-source-code/ext/mysql.
Under Linux, the main files to pay attention to are: config.m4, php_mysql.c, php_mysql_structs.h.
ps: There are tags files in this directory, so you can use the various features of ctags to directly find functions, macro definitions, etc.
ps: After starting mysql under Linux sudo mysql-dir/bin/mysqld_safe &
, there will be two processes running:

Copy code The code is as follows:

root 5297 0.0 0.0 5920 1416 pts/5 S 11:08 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe
mysql 5320 1.4 1.1 202728 23796 pts/5 Sl 11:08 1:47 /usr/local/mysql/libexec/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/var --user=mysql -- pid-file=/usr/local/mysql/var/tj1clnxweb0004.pid --skip-external-locking --port=3306 --socket=/tmp/mysql.sock

--- ------------------------------------------------
Record the reading below first Some details in the process:
1. php_mysql_do_query_general function
The functions mysql_query and mysql_unbuffered_query provided by this extension will ultimately use php_mysql_do_query_general to perform core functions.
First look at the trace mode:
if (MySG(trace_mode)) { .... }
There is configuration in php.ini:
mysql.trace_mode = Off
And if configured is open, then the sentence in the if will be executed, and if the executed sentence is select, explain will be added in front to analyze the performance of the sql sentence.
Then take a look at the difference between mysql_use_result and mysql_store_result:
As you can see, mysql_query uses the mysql_store_result function, while mysql_unbuffered_query uses mysql_use_result.
Refer to the article (http://school.cnd8.com/mysql/jiaocheng/25143_8.htm) and summarize it as follows:
mysql_store_result queries and obtains all result sets, saves them on the client, and prepares them for the client Use, which requires greater memory and performance on the client.
mysql_use_result only queries, but delays getting the results. It is equivalent to maintaining a result set on the service front end.
After calling mysql_store_result and using mysql_fetch_row to obtain the result, the result is obtained directly from the client. If the return value is NULL, there is no result.
When mysql_use_result is called and the result is obtained using mysql_fetch_row, the result is obtained from the service front end. If the result is NULL, the result may be useless or there may be a network connection error or other reasons.
Due to the different maintenance places of the result set, the results of mysql_store_result can provide more processing functions, such as arbitrary seek, get the total number, non-sequential access, etc. The result set of mysql_use_result cannot be used.
In addition, since the result set of mysql_use_result is maintained on the server side, it puts forward a requirement: the client must call mysql_fetch_row for each row in the result set. Otherwise, the remaining records in the result set will become the next query result. part of the set, and an "out of sync" error occurs.
So, why do you still need to use mysql_use_result? Take a look at this situation:
mysql and mysqldump use mysql_store_result by default, but if the --quick option is specified, mysql_use_result is used.
That means mysql_use_result has an advantage in efficiency?
Look at the mysql help manual:
-q, --quick Don't cache result, print it row by row. This may slow
down the server if the output is suspended. Doesn't use
history file.
Mysqldump help manual:
-q, --quick Don't buffer query, dump directly to stdout.
Then I haven’t fully understood why quick corresponds to mysql_use_result. When doing this, first figure out when not to use mysql_use_result. Since the result set of mysql_use_result is maintained on the server side, do not use it if the client program may hang. Don't use it if there are too many operations between rows in the result set. In other words, if the query is completed and the results are not used up immediately and freed, then don't use mysql_use_result.
In order to try the effect, I wrote the following test code:
Copy the code The code is as follows:

$sql = sprintf ("select * from pet;");
$result = mysql_unbuffered_query($sql, $conn);
$rows = mysql_fetch_row($result);
var_dump($rows);
$ sql = sprintf("select * from shop");
$result = mysql_unbuffered_query($sql, $conn);
$rows = mysql_fetch_row($result);
var_dump($rows);

The result of the execution is that the second fetch will not display the first result, but PHP will report a notice:
PHP Notice: mysql_unbuffered_query(): Function called without first fetching all rows from a previous unbuffered query in /home/yicheng/test-all/mysqltest/test.php on line 28
Modify the test code:
Copy the code The code is as follows:

$i = 1000000;
while($i--){
$sql = sprintf("select * from pet;");
$result = mysql_query($sql, $conn);
#$result = mysql_unbuffered_query($sql, $conn);
while($rows = mysql_fetch_row($result)){

}
if ($result) {
mysql_free_result($result);
}
}

The result of using unbuffered:
:!time ./test.php
real 1m10.220s
user 0m17.853s
sys 0m9.541s
Result of using mysql_query:
:!time ./test.php
real 1m11.191s
user 0m19.297s
sys 0m10.133s
It seems that the time difference is not big
2. Some resource-related macro definitions
Copy the code The code is as follows:

#define ZEND_VERIFY_RESOURCE(rsrc)
if (!rsrc) {
RETURN_FALSE;
}
#define ZEND_FETCH_RESOURCE(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type)
rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC, default_id, resource_type_name, NULL, 1, resource_type);
ZEND_VERIFY_RESOURCE(rsrc);
#define ZEND_FETCH_RESOURCE2(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_ type1 , resource_type2)
rsrc = (rsrc_type) zend_fetch_resource(passed_id TSRMLS_CC, default_id, resource_type_name, NULL, 2, resource_type1, resource_type2);
ZEND_VERIFY_RESOURCE(rsrc);
#define ZEND_REGISTER_RESOURCE(rsrc_result, rsrc_point er, rsrc_type)
zend_register_resource(rsrc_result, rsrc_pointer, rsrc_type);
#define ZEND_GET_RESOURCE_TYPE_ID(le_id, le_type_name)
if (le_id == 0) {
le_id = zend_fetch_list_dtor_id(le_type_name);
}

What we return from the mysql_connect function is actually a link id (resource(4) of type (mysql link)), which can be mapped to the corresponding mysql resource through the ZEND_FETCH_RESOURCE and ZEND_FETCH_RESOURCE2 macros. Both macros call the zend_fetch_resource method, so let's take a look at this method.
ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, char *resource_type_name, int *found_resource_type, int num_resource_types, ...)
For example, call the ZEND_FETCH_RESOURCE2 macro in the mysql_list_dbs function:
ZEND_FETCH_RES OURCE2(mysql , php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
where mysql saves the returned valid resources, php_mysql_conn * defines the type of returned resources, mysql_link, id correspond to passed_id and default_id respectively ( Because many function calls do not pass in the specific conn, they just use the default value), "MySQL-Link" is the resource_type_name, le_link, le_plink are the... parts of zend_fetch_resource, and they are both static int type values.
As can be seen from zend_fetch_resource, value.lval of resource(4) of type (mysql link) contains long type id. If default_id is -1, then the id passed in by passed_id is used, otherwise default_id is used as the id, and zend_list_find is used to find the corresponding resource.
After looking at a few functions, I realized that this extension is just an encapsulation of the c interface provided by mysql. But the packaging is very standardized and stable!
If you want to know more, you still have to look at the source code of MYSQL. Several important data structures are posted below.
----------------------------------------
Some questions about checking Error may be useful php functions:
Copy code The code is as follows:

error_reporting(E_ALL);
#var_dump( mysql_get_host_info($conn));
#var_dump(mysql_get_proto_info($conn));
#var_dump(mysql_get_server_info($conn));
#var_dump(mysql_stat($conn));
# var_dump(mysql_errno($conn));
#var_dump(mysql_error($conn));
#var_dump(mysql_info($conn));

------ ---------------------------------------------
Some useful structs in MYSQL source code
Copy code The code is as follows:

typedef struct st_mysql
{
NET net; /* Communication parameters */
gptr connector_fd; /* ConnectorFd for SSL */
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,*info;
char *db;
struct charset_info_st *charset;
MYSQL_FIELD *fields;
MEM_ROOT field_alloc;
my_ulonglong affected_rows;
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
my_ulonglong extra_info; /* Not used */
unsigned long thread_id; /* Id for connection in server */
unsigned long packet_length;
unsigned int port;
unsigned long client_flag,server_capabilities;
unsigned int protocol_version;
unsigned int field_count;
unsigned int server_status;
unsigned int server_language;
unsigned int warning_count;
struct st_mysql_options options;
enum mysql_status status;
my_bool free_me; /* If free in mysql_close */
my_bool reconnect; /* set to 1 if automatic reconnect */
/* session-wide random string */
char scramble[SCRAMBLE_LENGTH+1];
/*
Set if this is the original connection, not a master or a slave we have
added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()
*/
my_bool rpl_pivot;
/*
Pointers to the master, and the next slave connections, points to
itself if lone connection.
*/
struct st_mysql* master, *next_slave;
struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
/* needed for send/read/store/use result to work correctly with replication */
struct st_mysql* last_used_con;
LIST *stmts; /* list of all statements */
const struct st_mysql_methods *methods;
void *thd;
/*
Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
from mysql_stmt_close if close had to cancel result set of this object.
*/
my_bool *unbuffered_fetch_owner;
#if defined(EMBEDDED_LIBRARY) || defined(EMBEDDED_LIBRARY_COMPATIBLE) || MYSQL_VERSION_ID >= 50100
/* needed for embedded server - no net buffer to store the 'info' */
char *info_buffer;
#endif
} MYSQL;
typedef struct st_mysql_methods
{
my_bool (*read_query_result)(MYSQL *mysql);
my_bool (*advanced_command)(MYSQL *mysql,
enum enum_server_command command,
const char *header,
unsigned long header_length,
const char *arg,
unsigned long arg_length,
my_bool skip_check,
MYSQL_STMT *stmt);
MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
unsigned int fields);
MYSQL_RES * (*use_result)(MYSQL *mysql);
void (*fetch_lengths)(unsigned long *to,
MYSQL_ROW column, unsigned int field_count);
void (*flush_use_result)(MYSQL *mysql);
#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
int (*stmt_execute)(MYSQL_STMT *stmt);
int (*read_binary_rows)(MYSQL_STMT *stmt);
int (*unbuffered_fetch)(MYSQL *mysql, char **row);
void (*free_embedded_thd)(MYSQL *mysql);
const char *(*read_statistics)(MYSQL *mysql);
my_bool (*next_result)(MYSQL *mysql);
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
#endif
} MYSQL_METHODS;

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/320292.htmlTechArticle我写过一个外部模块扩展,现在开始看PHP源码中的mysql扩展,它是可以被集成到PHP内部的,所以应该算是内置的扩展了。 该扩展需要用到...
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace(" ","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.