PHP source Ext/mysql Extended part of the _php skills

Source: Internet
Author: User
Tags data structures php source code sprintf stmt

I've written an external module extension and now look at the MySQL extensions in the PHP source code that can be integrated into PHP, so it should be a built-in extension.
The extension needs to use 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 be noted are: Config.m4, PHP_MYSQL.C, Php_mysql_structs.h.
PS: The directory has tags files, so you can use the various characteristics of ctags, directly find functions, macro definitions.
Ps:linux under MySQL startup sudo mysql-dir/bin/mysqld_safe &
There will be two processes running:

Copy Code code 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 extensions provide functions mysql_query and Mysql_unbuffered_query finally use php_mysql_do_query_general to perform core functions.
First look at the trace mode:
if (Mysg (Trace_mode)) {...}
There are configurations in the 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 is using the Mysql_store_result function, and mysql_unbuffered_query is using Mysql_use_result.
The reference article (http://school.cnd8.com/mysql/jiaocheng/25143_8.htm) is summarized as follows:
Mysql_store_result queries and gets all the result sets, which are stored on the client and ready for client use, so that the client's memory and performance requirements are greater.
Mysql_use_result queries only, and results are delayed. It is equivalent to maintaining a result set at the front end of the service.
When Mysql_store_result is called, the result is obtained directly from the client when using Mysql_fetch_row to obtain results, and if returned null, there is no result.
When the Mysql_use_result is called, the results are obtained from the service front end, and if returned to NULL, the result may be useless, or it may be a network connection error.
Because of the different maintenance places of the result set, the results of Mysql_store_result can provide more processing functions, such as arbitrary seek, total number, and non sequential access. The Mysql_use_result result set is not available.
In addition, because the Mysql_use_result result set is maintained on the server side, it makes 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 the Mysql_use_result? Look at the situation:
MySQL and mysqldump default, use Mysql_store_result, but if you specify the--quick option, use Mysql_use_result.
Does that indicate that 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 don't fully understand why quick corresponds to Mysql_use_result, first figure out when not to use Mysql_use_result bar. 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 of the result set and the rows, do not use it. That is, if the query finished, not immediately use the results, free off, then do not use Mysql_use_result.
To try the effect, write the following test code:
Copy Code code 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 first result, but PHP will report notice:
PHP notice:mysql_unbuffered_query (): Function called without-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 Code code 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 Code code 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 resources 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 holds the returned valid resources, Php_mysql_conn * Defines the type of return resource, Mysql_link, IDs are corresponding to passed_id and default_id (because many function calls, do not pass to 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 values of the static int type.
As can be seen by Zend_fetch_resource, the resource (4) of type (MySQL link) contains a long ID in the value.lval. If default_id is-1, then the ID passed in with passed_id, or use default_id as the ID, using Zend_list_find to find its corresponding resources.
After looking at a few functions, in fact, the extension is the MySQL provided by the C interface package. But the package is very standard and stable!
If you want to know more, it still depends on the source code of MySQL. Several important data structures are attached below.
-----------------------------------------
Some PHP functions that may be useful for error checking:
Copy Code code 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 the MySQL source code
Copy Code code 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];
/*
The Set if 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-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 the result set of the 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;

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.