PHP source Ext/mysql Extension Part _php tutorial

Source: Internet
Author: User
Tags sprintf
I have written an external module extension, now start to see the PHP source in the MySQL extension, it can be integrated into the PHP internal, so should be considered as built-in extension.
This extension requires some of the interfaces provided by the MySQL database, so you need to install MySQL and be able to determine the location of the mysql.h.
The location of the extension is generally under php-source-code/ext/mysql.
Under Linux, the main documents to note are: CONFIG.M4, PHP_MYSQL.C, Php_mysql_structs.h.
PS: This directory has tags files, so you can use the various features of ctags, directly find functions, macro definitions and so on.
Ps:linux under MySQL start sudo mysql-dir/bin/mysqld_safe &
Then there will be two processes running:
Copy CodeThe 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

----------------------------------------------
Here 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 are finally used to perform core functions using Php_mysql_do_query_general.
First look at the trace pattern:
if (Mysg (Trace_mode)) {...}
There are configurations in php.ini:
Mysql.trace_mode = Off
If the configuration is open, the sentence in if is executed, and if the sentence being executed is a SELECT, it is preceded by a explain to analyze the performance of the SQL sentence.
Then look at the difference between Mysql_use_result and Mysql_store_result:
As you can see, mysql_query uses the Mysql_store_result function, and Mysql_unbuffered_query is Mysql_use_result.
Reference article (http://school.cnd8.com/mysql/jiaocheng/25143_8.htm), and summarized as follows:
Mysql_store_result queries and obtains all the result sets, which are saved on the client and ready for use by the client, so that the memory and performance requirements for the client are large.
Mysql_use_result query only, and the result gets a delay. Equivalent to maintaining a result set on the front end of the service.
When the Mysql_store_result is called and the result is obtained using mysql_fetch_row, the result is obtained directly from the client, and if NULL is returned, there is no result.
When the Mysql_use_result is called and the result is obtained using mysql_fetch_row, the result is obtained from the front end of the service, and if it is returned as NULL, it may be a useless result or a network connection error.
Because the result set is maintained in different places, the results of Mysql_store_result can provide more processing functions, such as arbitrary seek, total fetch, and non-sequential access. And the result set of Mysql_use_result is not possible.
In addition, because the Mysql_use_result result set is maintained on the server side, it puts forward a requirement that the client must call Mysql_fetch_row for each row in the result set, otherwise the remaining records in the result set become part of the next query result set. And an "Out of sync" error occurs.
So why use Mysql_use_result? Look at this situation:
MySQL and mysqldump default, use Mysql_store_result, but if you specify the--quick option, use Mysql_use_result.
That means Mysql_use_result has an advantage in terms of efficiency?
Look at the Help manual for MySQL:
-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's help manual:
-Q,--quick Don ' t buffer query, dump directly to stdout.
So when I'm not fully aware of why quick corresponds to Mysql_use_result, let's figure out when not to use Mysql_use_result. Because the Mysql_use_result result set is maintained on the server side, if the client program may be suspended, do not use it. If there is too much action between the rows and rows of the result set, do not use it. That is, if the query is finished, not immediately run out of results, free off, then do not use Mysql_use_result.
To try the results, write the following test code:
Copy CodeThe 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 does not show the results for the first time, but 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
To modify the test code:
Copy CodeThe 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);
}
}

Results of using unbuffered:
:!time./test.php
Real 1m10.220s
User 0m17.853s
SYS 0m9.541s
Results of using mysql_query:
:!time./test.php
Real 1m11.191s
User 0m19.297s
SYS 0m10.133s
Looks like the time difference is not big.
2. Some resource-related macro definitions
Copy CodeThe 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); \
}

What we return by the Mysql_connect function is actually a link ID (resource (4) of type (MySQL link)), through Zend_fetch_resource and ZEND_FETCH_RESOURCE2 macros, can be mapped to the corresponding MySQL resource up. Both macros call the Zend_fetch_resource method, so let's look at the method below.
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);
Where MySQL saves the valid resources returned, Php_mysql_conn * Defines the type of the return resource, Mysql_link, the ID corresponds to passed_id and default_id (because many function calls do not pass in the specific conn, is to use the default value), "Mysql-link" is Resource_type_name,le_link, Le_plink is Zend_fetch_resource ... section, they are the values of the static int type.
As can be seen by Zend_fetch_resource, the resource (4) of type (MySQL link) value.lval contains the ID of the long type. If default_id is-1, then it is the ID passed in passed_id, otherwise use default_id as the ID, using Zend_list_find to find its corresponding resources.
After looking at several functions, the extension is the encapsulation of the C interface provided by MySQL. But the package is very normative 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 PHP functions that may be useful for error checking:
Copy CodeThe 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
Copy CodeThe 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;

http://www.bkjia.com/PHPjc/320292.html www.bkjia.com true http://www.bkjia.com/PHPjc/320292.html techarticle I have written an external module extension, now start to see the PHP source in the MySQL extension, it can be integrated into the PHP internal, so should be considered as built-in extension. The extension needs to use ...

  • 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.