switch(ZEND_NUM_ARGS()) {///zend_num_args是输入参数的个数 case 0: /* defaults */ break; case 1: { if (zend_get_parameters_ex(1, &z_host)==FAILURE) { MYSQL_DO_CONNECT_RETURN_FALSE(); } } break; case 2: { if (zend_get_parameters_ex(2, &z_host, &z_user)==FAILURE) { MYSQL_DO_CONNECT_RETURN_FALSE(); } convert_to_string_ex(z_user); user = Z_STRVAL_PP(z_user); } break; case 3: { if (zend_get_parameters_ex(3, &z_host, &z_user, &z_passwd) == FAILURE) { MYSQL_DO_CONNECT_RETURN_FALSE(); } convert_to_string_ex(z_user); convert_to_string_ex(z_passwd); user = Z_STRVAL_PP(z_user); passwd = Z_STRVAL_PP(z_passwd); } break; case 4: { if (!persistent) { if (zend_get_parameters_ex(4, &z_host, &z_user, &z_passwd, &z_new_link) == FAILURE) { MYSQL_DO_CONNECT_RETURN_FALSE(); } convert_to_string_ex(z_user); convert_to_string_ex(z_passwd); convert_to_boolean_ex(z_new_link); user = Z_STRVAL_PP(z_user); passwd = Z_STRVAL_PP(z_passwd); new_link = Z_BVAL_PP(z_new_link); } else { if (zend_get_parameters_ex(4, &z_host, &z_user, &z_passwd, &z_client_flags) == FAILURE) { MYSQL_DO_CONNECT_RETURN_FALSE(); } convert_to_string_ex(z_user); convert_to_string_ex(z_passwd); convert_to_long_ex(z_client_flags); user = Z_STRVAL_PP(z_user); passwd = Z_STRVAL_PP(z_passwd); client_flags = Z_LVAL_PP(z_client_flags); } } break; case 5: { if (zend_get_parameters_ex(5, &z_host, &z_user, &z_passwd, &z_new_link, &z_client_flags) == FAILURE) { MYSQL_DO_CONNECT_RETURN_FALSE(); } convert_to_string_ex(z_user); convert_to_string_ex(z_passwd); convert_to_boolean_ex(z_new_link); convert_to_long_ex(z_client_flags); user = Z_STRVAL_PP(z_user); passwd = Z_STRVAL_PP(z_passwd); new_link = Z_BVAL_PP(z_new_link); client_flags = Z_LVAL_PP(z_client_flags); } break; default: WRONG_PARAM_COUNT; break; } /* disable local infile option for open_basedir */ if (PG(open_basedir) && strlen(PG(open_basedir)) && (client_flags & CLIENT_LOCAL_FILES)) { client_flags ^= CLIENT_LOCAL_FILES; } if (z_host) { SEPARATE_ZVAL(z_host); /* We may modify z_host if it contains a port, separate */ convert_to_string_ex(z_host); host_and_port = Z_STRVAL_PP(z_host); if (z_user) { convert_to_string_ex(z_user); user = Z_STRVAL_PP(z_user); if (z_passwd) { convert_to_string_ex(z_passwd); passwd = Z_STRVAL_PP(z_passwd); } } } hashed_details_length = sizeof("mysql___")-1 + strlen(SAFE_STRING(host_and_port))+strlen(SAFE_STRING(user))+strlen(SAFE_STRING(passwd)); hashed_details = (char *) emalloc(hashed_details_length+1); sprintf(hashed_details, "mysql_%s_%s_%s", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd)); } /* We cannot use mysql_port anymore in windows, need to use * mysql_real_connect() to set the port. */ if (host_and_port && (tmp=strchr(host_and_port, ':'))) { host = estrndup(host_and_port, tmp-host_and_port); free_host = 1; tmp++; if (tmp[0] != '/') { port = atoi(tmp); if ((tmp=strchr(tmp, ':'))) { tmp++; socket=tmp; } } else { socket = tmp; } } else { host = host_and_port; port = MySG(default_port); }#if MYSQL_VERSION_ID < 32200 mysql_port = port; #endif
if (!MySG(allow_persistent)) { persistent=0; } if (persistent) { list_entry *le; /* try to find if we already have this link in our persistent list */ if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */ list_entry new_le; if (MySG(max_links)!=-1 && MySG(num_links)>=MySG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links)); efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } if (MySG(max_persistent)!=-1 && MySG(num_persistent)>=MySG(max_persistent)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent)); efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } /* create the link */ mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn)); mysql->active_result_id = 0; #if MYSQL_VERSION_ID > 32199 /* this lets us set the port number */ mysql_init(&mysql->conn); if (connect_timeout != -1) mysql_options(&mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); if (mysql_real_connect(&mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) { #else if (mysql_connect(&mysql->conn, host, user, passwd)==NULL) { #endif /* Populate connect error globals so that the error functions can read them */ if (MySG(connect_error)!=NULL) efree(MySG(connect_error)); MySG(connect_error)=estrdup(mysql_error(&mysql->conn)); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error)); #if defined(HAVE_MYSQL_ERRNO) MySG(connect_errno)=mysql_errno(&mysql->conn); #endif free(mysql); efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } /* hash it up */ Z_TYPE(new_le) = le_plink; new_le.ptr = mysql; if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) { free(mysql); efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } MySG(num_persistent)++; MySG(num_links)++; } else { /* The link is in our list of persistent connections */ if (Z_TYPE_P(le) != le_plink) { MYSQL_DO_CONNECT_RETURN_FALSE(); } /* ensure that the link did not die */ #if MYSQL_VERSION_ID > 32230 /* Use mysql_ping to ensure link is alive (and to reconnect if needed) */ if (mysql_ping(le->ptr)) { #else /* Use mysql_stat() to check if server is alive */ handler=signal(SIGPIPE, SIG_IGN); #if defined(HAVE_MYSQL_ERRNO) && defined(CR_SERVER_GONE_ERROR) mysql_stat(le->ptr); if (mysql_errno(&((php_mysql_conn *) le->ptr)->conn) == CR_SERVER_GONE_ERROR) { #else if (!strcasecmp(mysql_stat(le->ptr), "mysql server has gone away")) { /* the link died */ #endif signal(SIGPIPE, handler); #endif /* end mysql_ping */ #if MYSQL_VERSION_ID > 32199 /* this lets us set the port number */ if (mysql_real_connect(le->ptr, host, user, passwd, NULL, port, socket, client_flags)==NULL) { #else if (mysql_connect(le->ptr, host, user, passwd)==NULL) { #endif php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect"); zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1); efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } } #if MYSQL_VERSION_ID < 32231 signal(SIGPIPE, handler); #endif mysql = (php_mysql_conn *) le->ptr; } ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink); } else { /* non persistent */ list_entry *index_ptr, new_index_ptr;
/* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual mysql link sits. * if it doesn't, open a new mysql link, add it to the resource list, * and add a pointer to it with hashed_details as the key. */ if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) { int type; long link; void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) { MYSQL_DO_CONNECT_RETURN_FALSE(); } link = (long) index_ptr->ptr; ptr = zend_list_find(link,&type); /* check if the link is still there */ if (ptr && (type==le_link || type==le_plink)) { zend_list_addref(link); Z_LVAL_P(return_value) = link; php_mysql_set_default_link(link TSRMLS_CC); Z_TYPE_P(return_value) = IS_RESOURCE; efree(hashed_details); MYSQL_DO_CONNECT_CLEANUP(); return; } else { zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1); } } if (MySG(max_links)!=-1 && MySG(num_links)>=MySG(max_links)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links)); efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn)); mysql->active_result_id = 0; #if MYSQL_VERSION_ID > 32199 /* this lets us set the port number */ mysql_init(&mysql->conn); if (connect_timeout != -1) mysql_options(&mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); if (mysql_real_connect(&mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) { #else if (mysql_connect(&mysql->conn, host, user, passwd)==NULL) { #endif /* Populate connect error globals so that the error functions can read them */ if (MySG(connect_error)!=NULL) efree(MySG(connect_error)); MySG(connect_error)=estrdup(mysql_error(&mysql->conn)); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error)); #if defined(HAVE_MYSQL_ERRNO) MySG(connect_errno)=mysql_errno(&mysql->conn); #endif efree(hashed_details); efree(mysql); MYSQL_DO_CONNECT_RETURN_FALSE(); } /* add it to the list */ ZEND_REGISTER_RESOURCE(return_value, mysql, le_link); /* add it to the hash */ new_index_ptr.ptr = (void *) Z_LVAL_P(return_value); Z_TYPE(new_index_ptr) = le_index_ptr; if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) { efree(hashed_details); MYSQL_DO_CONNECT_RETURN_FALSE(); } MySG(num_links)++; } efree(hashed_details); php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC); MYSQL_DO_CONNECT_CLEANUP(); }
php连接mysql的时候是怎么连接的?据说pconnect的连接是可重用的啊?我想知道如何扩展php使得以实现类似于pconnect的效果,但是不是连接数据库,而是通过socket连接另外的后台!
我担心没有思路看不懂源码!
连接socket后不关闭就是所谓的永久连接,直到网络中断。
但php不具有线程的概念,所以此路不通。
但我估计你的系统应该不会出现这种情况,如果这种情况存在的话,我也只能劝你
改用其他的实现方式。
其次php的socket功能官方的说法都是试验性的(不过我一直在用,效果还不错,:)),
而且我不了解你的产品的结构和功用,所以具体的实现还要你自己把握。其实换个角度来思考一下,换主动为被动,由服务器来拒绝socket连接。
php做socket客户端到无所谓,不过如果保持长连接就太浪费资源了,apache是基于进程的,每一个php连接都要开一个进程,且还一直保持??太可怕了!
重新设计吧!
php的生命期就是他的执行期,执行结束所有变量都被销毁。原来我们曾想写一个php的module,所有的请求都通过这个module来实现。
但最终被我们摒弃了,改用web service来实现(虽然只是soap1.1),socket只用来传输控制命令。
{
char *user=NULL, *passwd=NULL, *host_and_port=NULL, *socket=NULL, *tmp=NULL, *host=NULL;
char *hashed_details=NULL;
int hashed_details_length, port = MYSQL_PORT;
int client_flags = 0;
php_mysql_conn *mysql=NULL;
#if MYSQL_VERSION_ID <= 32230
void (*handler) (int);
#endif
zval **z_host=NULL, **z_user=NULL, **z_passwd=NULL, **z_new_link=NULL, **z_client_flags=NULL;
zend_bool free_host=0, new_link=0;
long connect_timeout;
connect_timeout = MySG(connect_timeout); socket = MySG(default_socket); if (MySG(default_port) < 0) {
#if !defined(PHP_WIN32) && !defined(NETWARE)
struct servent *serv_ptr;
char *env;
MySG(default_port) = MYSQL_PORT;
if ((serv_ptr = getservbyname("mysql", "tcp"))) {
MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);
}
if ((env = getenv("MYSQL_TCP_PORT"))) {
MySG(default_port) = (uint) atoi(env);
}
#else
MySG(default_port) = MYSQL_PORT;
#endif
}
if (PG(sql_safe_mode)) {
if (ZEND_NUM_ARGS()>0) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
}
host_and_port=passwd=NULL;
user=php_get_current_user();
hashed_details_length = strlen(user)+5+3;///why +5+3
hashed_details = (char *) emalloc(hashed_details_length+1);
sprintf(hashed_details, "mysql__%s_", user);
client_flags = CLIENT_INTERACTIVE;///宏的意思 ?
} else {
host_and_port = MySG(default_host);
user = MySG(default_user);
passwd = MySG(default_password);
switch(ZEND_NUM_ARGS()) {///zend_num_args是输入参数的个数
case 0: /* defaults */
break;
case 1: {
if (zend_get_parameters_ex(1, &z_host)==FAILURE) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
}
break;
case 2: {
if (zend_get_parameters_ex(2, &z_host, &z_user)==FAILURE) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
convert_to_string_ex(z_user);
user = Z_STRVAL_PP(z_user);
}
break;
case 3: {
if (zend_get_parameters_ex(3, &z_host, &z_user, &z_passwd) == FAILURE) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
convert_to_string_ex(z_user);
convert_to_string_ex(z_passwd);
user = Z_STRVAL_PP(z_user);
passwd = Z_STRVAL_PP(z_passwd);
}
break;
case 4: {
if (!persistent) {
if (zend_get_parameters_ex(4, &z_host, &z_user, &z_passwd, &z_new_link) == FAILURE) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
convert_to_string_ex(z_user);
convert_to_string_ex(z_passwd);
convert_to_boolean_ex(z_new_link);
user = Z_STRVAL_PP(z_user);
passwd = Z_STRVAL_PP(z_passwd);
new_link = Z_BVAL_PP(z_new_link);
}
else {
if (zend_get_parameters_ex(4, &z_host, &z_user, &z_passwd, &z_client_flags) == FAILURE) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
convert_to_string_ex(z_user);
convert_to_string_ex(z_passwd);
convert_to_long_ex(z_client_flags);
user = Z_STRVAL_PP(z_user);
passwd = Z_STRVAL_PP(z_passwd);
client_flags = Z_LVAL_PP(z_client_flags);
}
}
break;
case 5: {
if (zend_get_parameters_ex(5, &z_host, &z_user, &z_passwd, &z_new_link, &z_client_flags) == FAILURE) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
convert_to_string_ex(z_user);
convert_to_string_ex(z_passwd);
convert_to_boolean_ex(z_new_link);
convert_to_long_ex(z_client_flags);
user = Z_STRVAL_PP(z_user);
passwd = Z_STRVAL_PP(z_passwd);
new_link = Z_BVAL_PP(z_new_link);
client_flags = Z_LVAL_PP(z_client_flags);
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
/* disable local infile option for open_basedir */
if (PG(open_basedir) && strlen(PG(open_basedir)) && (client_flags & CLIENT_LOCAL_FILES)) {
client_flags ^= CLIENT_LOCAL_FILES;
} if (z_host) {
SEPARATE_ZVAL(z_host); /* We may modify z_host if it contains a port, separate */
convert_to_string_ex(z_host);
host_and_port = Z_STRVAL_PP(z_host);
if (z_user) {
convert_to_string_ex(z_user);
user = Z_STRVAL_PP(z_user);
if (z_passwd) {
convert_to_string_ex(z_passwd);
passwd = Z_STRVAL_PP(z_passwd);
}
}
} hashed_details_length = sizeof("mysql___")-1 + strlen(SAFE_STRING(host_and_port))+strlen(SAFE_STRING(user))+strlen(SAFE_STRING(passwd));
hashed_details = (char *) emalloc(hashed_details_length+1);
sprintf(hashed_details, "mysql_%s_%s_%s", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd));
} /* We cannot use mysql_port anymore in windows, need to use
* mysql_real_connect() to set the port.
*/
if (host_and_port && (tmp=strchr(host_and_port, ':'))) {
host = estrndup(host_and_port, tmp-host_and_port);
free_host = 1;
tmp++;
if (tmp[0] != '/') {
port = atoi(tmp);
if ((tmp=strchr(tmp, ':'))) {
tmp++;
socket=tmp;
}
} else {
socket = tmp;
}
} else {
host = host_and_port;
port = MySG(default_port);
}#if MYSQL_VERSION_ID < 32200
mysql_port = port;
#endif
persistent=0;
}
if (persistent) {
list_entry *le; /* try to find if we already have this link in our persistent list */
if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */
list_entry new_le; if (MySG(max_links)!=-1 && MySG(num_links)>=MySG(max_links)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
}
if (MySG(max_persistent)!=-1 && MySG(num_persistent)>=MySG(max_persistent)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent));
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
}
/* create the link */
mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
mysql->active_result_id = 0;
#if MYSQL_VERSION_ID > 32199 /* this lets us set the port number */
mysql_init(&mysql->conn); if (connect_timeout != -1)
mysql_options(&mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); if (mysql_real_connect(&mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) {
#else
if (mysql_connect(&mysql->conn, host, user, passwd)==NULL) {
#endif
/* Populate connect error globals so that the error functions can read them */
if (MySG(connect_error)!=NULL) efree(MySG(connect_error));
MySG(connect_error)=estrdup(mysql_error(&mysql->conn));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
#if defined(HAVE_MYSQL_ERRNO)
MySG(connect_errno)=mysql_errno(&mysql->conn);
#endif
free(mysql);
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
} /* hash it up */
Z_TYPE(new_le) = le_plink;
new_le.ptr = mysql;
if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {
free(mysql);
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
}
MySG(num_persistent)++;
MySG(num_links)++;
} else { /* The link is in our list of persistent connections */
if (Z_TYPE_P(le) != le_plink) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
/* ensure that the link did not die */
#if MYSQL_VERSION_ID > 32230 /* Use mysql_ping to ensure link is alive (and to reconnect if needed) */
if (mysql_ping(le->ptr)) {
#else /* Use mysql_stat() to check if server is alive */
handler=signal(SIGPIPE, SIG_IGN);
#if defined(HAVE_MYSQL_ERRNO) && defined(CR_SERVER_GONE_ERROR)
mysql_stat(le->ptr);
if (mysql_errno(&((php_mysql_conn *) le->ptr)->conn) == CR_SERVER_GONE_ERROR) {
#else
if (!strcasecmp(mysql_stat(le->ptr), "mysql server has gone away")) { /* the link died */
#endif
signal(SIGPIPE, handler);
#endif /* end mysql_ping */
#if MYSQL_VERSION_ID > 32199 /* this lets us set the port number */
if (mysql_real_connect(le->ptr, host, user, passwd, NULL, port, socket, client_flags)==NULL) {
#else
if (mysql_connect(le->ptr, host, user, passwd)==NULL) {
#endif
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
}
}
#if MYSQL_VERSION_ID < 32231
signal(SIGPIPE, handler);
#endif
mysql = (php_mysql_conn *) le->ptr;
}
ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
} else { /* non persistent */
list_entry *index_ptr, new_index_ptr;
/* first we check the hash for the hashed_details key. if it exists,
* it should point us to the right offset where the actual mysql link sits.
* if it doesn't, open a new mysql link, add it to the resource list,
* and add a pointer to it with hashed_details as the key.
*/
if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
int type;
long link;
void *ptr; if (Z_TYPE_P(index_ptr) != le_index_ptr) {
MYSQL_DO_CONNECT_RETURN_FALSE();
}
link = (long) index_ptr->ptr;
ptr = zend_list_find(link,&type); /* check if the link is still there */
if (ptr && (type==le_link || type==le_plink)) {
zend_list_addref(link);
Z_LVAL_P(return_value) = link;
php_mysql_set_default_link(link TSRMLS_CC);
Z_TYPE_P(return_value) = IS_RESOURCE;
efree(hashed_details);
MYSQL_DO_CONNECT_CLEANUP();
return;
} else {
zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1);
}
}
if (MySG(max_links)!=-1 && MySG(num_links)>=MySG(max_links)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
} mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn));
mysql->active_result_id = 0;
#if MYSQL_VERSION_ID > 32199 /* this lets us set the port number */
mysql_init(&mysql->conn); if (connect_timeout != -1)
mysql_options(&mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout); if (mysql_real_connect(&mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) {
#else
if (mysql_connect(&mysql->conn, host, user, passwd)==NULL) {
#endif
/* Populate connect error globals so that the error functions can read them */
if (MySG(connect_error)!=NULL) efree(MySG(connect_error));
MySG(connect_error)=estrdup(mysql_error(&mysql->conn));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
#if defined(HAVE_MYSQL_ERRNO)
MySG(connect_errno)=mysql_errno(&mysql->conn);
#endif
efree(hashed_details);
efree(mysql);
MYSQL_DO_CONNECT_RETURN_FALSE();
} /* add it to the list */
ZEND_REGISTER_RESOURCE(return_value, mysql, le_link); /* add it to the hash */
new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
Z_TYPE(new_index_ptr) = le_index_ptr;
if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) {
efree(hashed_details);
MYSQL_DO_CONNECT_RETURN_FALSE();
}
MySG(num_links)++;
} efree(hashed_details);
php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
MYSQL_DO_CONNECT_CLEANUP();
}
据说这段代码中实现了我所说的类似的功能,我对zend_api不熟,看了一下,如果传说是真的话。
EG(regular_list)///我猜想这个东西应该就是那个存储句柄的容器吧?
////////////////////////////////////////////////////////////////////////////////
if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) ///这一段是在已经创建好的池中找句柄吗?