📄 php_mysql.c
字号:
php_info_print_table_row(2, "MYSQL_SOCKET", MYSQL_UNIX_ADDR); php_info_print_table_row(2, "MYSQL_INCLUDE", PHP_MYSQL_INCLUDE); php_info_print_table_row(2, "MYSQL_LIBS", PHP_MYSQL_LIBS);#endif php_info_print_table_end(); DISPLAY_INI_ENTRIES();}/* }}} *//* {{{ php_mysql_do_connect */#define MYSQL_DO_CONNECT_CLEANUP() \ if (free_host) { \ efree(host); \ }#define MYSQL_DO_CONNECT_RETURN_FALSE() \ MYSQL_DO_CONNECT_CLEANUP(); \ RETURN_FALSE;static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent){ 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 (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; 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()) { 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_get_default_link */static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS){ if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */ ht = 0; php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } return MySG(default_link);}/* }}} *//* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]]) Opens a connection to a MySQL Server */PHP_FUNCTION(mysql_connect){ php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]]) Opens a persistent connection to a MySQL Server */PHP_FUNCTION(mysql_pconnect){ php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto bool mysql_close([int link_identifier]) Close a MySQL connection */PHP_FUNCTION(mysql_close){ zval **mysql_link=NULL; int id; php_mysql_conn *mysql; switch (ZEND_NUM_ARGS()) { case 0: id = MySG(default_link); break; case 1: if (zend_get_parameters_ex(1, &mysql_link)==FAILURE) { RETURN_FALSE; } id = -1; break; default: WRONG_PARAM_COUNT; break; } ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); if (id==-1) { /* explicit resource number */ PHPMY_UNBUFFERED_QUERY_CHECK(); zend_list_delete(Z_RESVAL_PP(mysql_link)); } if (id!=-1 || (mysql_link && Z_RESVAL_PP(mysql_link)==MySG(default_link))) { PHPMY_UNBUFFERED_QUERY_CHECK(); zend_list_delete(MySG(default_link)); MySG(default_link) = -1; } RETURN_TRUE;}/* }}} *//* {{{ proto bool mysql_select_db(string database_name [, int link_identifier]) Selects a MySQL database */PHP_FUNCTION(mysql_select_db){ zval **db, **mysql_link; int id; php_mysql_conn *mysql; switch(ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &db)==FAILURE) { RETURN_FALSE; } id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU); CHECK_LINK(id); break; case 2: if (zend_get_parameters_ex(2, &db, &mysql_link)==FAILURE) { RETURN_FALSE; } id = -1; break; default: WRONG_PARAM_COUNT; break; } ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink); convert_to_string_ex(db); if (php_mysql_select_db(mysql, Z_STRVAL_PP(db) TSRMLS_CC)) { RETURN_TRUE; } else { RETURN_FALSE; }}/* }}} */#ifdef HAVE_GETINFO_FUNCS/* {{{ proto string mysql_get_client_info(void) Returns a string that represents the client library version */PHP_FUNCTION(mysql_get_client_info){ if (ZEND_NUM_ARGS() != 0) { WRONG_PARAM_COUNT; } RETURN_STRING((char *)mysql_get_client_info(),1); }/* }}} *//* {{{ proto string mysql_get_host_info([int link_identifier]) Returns a string describing the type of connection in use, including the server host name */PHP_FUNCTION(mysql_get_host_info)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -