PHP source code ext/mysql extension part _ PHP Tutorial

Source: Internet
Author: User
Extmysql extension of PHP source code. I have written an external module extension. now I am looking at the mysql extension in the PHP source code. it can be integrated into PHP, so it should be a built-in extension. I have written an external module extension for this extension. now I start to look at the mysql extension in the PHP source code. it can be integrated into PHP, so it should be a built-in extension.
This extension requires some interfaces provided by the mysql database. Therefore, you need to install mysql and determine the location of mysql. h.
The extension is generally located in PHP-source-code/ext/mysql.
In linux, pay attention to the following files: config. m4, php_mysql.c, and php_mysql_structs.h.
Ps: The Directory contains a tags file. Therefore, you can use the features of ctags to directly find functions and macro definitions.
Ps: start sudo mysql-dir/bin/mysqld_safe in mysql in linux &
Two processes will run later:

The code is as follows:


Root 5297 0.0 0.0 5920 1416 pts/5 S/bin/sh/usr/local/mysql/bin/mysqld_safe
Mysql 5320 1.4 1.1 202728 23796 pts/5 Sl/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


----------------------------------------------
The following are some details of the reading process:
1. php_mysql_do_query_general function
The functions mysql_query and mysql_unbuffered_query provided by this extension use php_mysql_do_query_general to execute core functions.
First, let's look at the trace mode:
If (MySG (trace_mode )){....}
Configuration in php. ini:
Mysql. trace_mode = Off
If the configuration is enabled, then the sentence in if will be executed. if the sentence to be executed is select, the explain statement will be added in front to analyze the performance of the SQL sentence.
Then let's take a look at the differences between mysql_use_result and mysql_store_result:
We can see that 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 as follows:
Mysql_store_result: query and obtain all the result sets and save them on the client for use by the client. in this way, the memory and performance of the client are high.
Mysql_use_result is only queried, but the result is delayed. As a result, a result set is maintained at the service front end.
When mysql_store_result is called and mysql_fetch_row is used to obtain the result, the result is obtained directly from the client. if the returned result is NULL, no result is returned.
When mysql_use_result is called and mysql_fetch_row is used to obtain the result, the result is obtained from the service front-end. if the returned result is NULL, the result may be useless or due to network connection errors.
Because the maintenance of the result set is different, the results of mysql_store_result can provide more processing functions, such as any seek, the total number of retrieved results, and unordered access. The result set of mysql_use_result cannot be used.
In addition, because the result set of mysql_use_result is maintained on the server side, the client must call mysql_fetch_row for each row in the result set. otherwise, the remaining records in the result set will become part of the next query result set, and an "out-of-sync" error occurs.
So why does mysql_use_result need to be used? Check this situation:
Mysql and mysqldump are short of time and use mysql_store_result. However, if the -- quick option is specified, mysql_use_result is used.
Does mysql_use_result have an advantage in efficiency?
See 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 suincluded. Doesn't use
History file.
Mysqldump help manual:
-Q, -- quick Don't buffer query, dump directly to stdout.
So when I don't fully understand why quick corresponds to mysql_use_result, I should first understand when to use mysql_use_result. Because the result set of mysql_use_result is maintained on the server side, do not use it if the client program may be suspended. If there are too many operations between rows in the result set, do not use it. That is to say, if the query is complete, instead of immediately using the results, free off, then do not use mysql_use_result.
To try the effect, write the following test 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 execution result is that the first result is not displayed for the second fetch, but the php will report 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:

The code is as follows:


USD 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 );
}
}


Unbuffered result:
:! Time./test. php
Real 1m10. 220 s
User 0m17. 853 s
Sys 0m9. 541 s
Result of mysql_query:
:! Time./test. php
Real 1m11. 191 s
User 0m19. 297 s
Sys 0m10. 133 s
It seems that there is little difference in time.
2. some macro definitions related to resources

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_pointer, 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 );\
}


The mysql_connect function returns 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_RESOURCE2 (mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink );
Mysql saves the returned valid resources. php_mysql_conn * defines the type of the returned resource. mysql_link and id correspond to passed_id and default_id respectively (because many function calls do not input specific conn, is to use the default value), "MySQL-Link" is resource_type_name, le_link, le_plink is zend_fetch_resource... which are static int type values.
As shown in zend_fetch_resource, the value. lval of resource (4) of type (mysql link) contains the long type id. If default_id is-1, it is the id passed in with passed_id. otherwise, default_id is used as the id and zend_list_find is used to find the corresponding resource.
After reading several functions, the extension is actually the encapsulation of the c interface provided by mysql. But the encapsulation is very standard and stable!
For more information, see the source code of MYSQL. The following are some important data structures.
-----------------------------------------
Some php functions that may be useful for troubleshooting:

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 struct in MYSQL source 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
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 * shortts;/* 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 *,
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;

Bytes. This extension needs to be used...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.