📄 mysqli_api.c
字号:
/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...]) U Bind variables to a prepared statement for result storage */PHP_FUNCTION(mysqli_stmt_bind_result){ zval ***args; int argc = ZEND_NUM_ARGS(); int start = 1; ulong rc; MY_STMT *stmt; zval *mysql_stmt; if (getThis()) { start = 0; } if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); if (argc < (getThis() ? 1 : 2)) { WRONG_PARAM_COUNT; } args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); if (zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } if ((argc - start) != mysql_stmt_field_count(stmt->stmt)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement"); efree(args); RETURN_FALSE; } rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC); efree(args); RETURN_BOOL(!rc);}/* }}} *//* {{{ proto bool mysqli_change_user(object link, string user, string password, string database) U Change logged-in user of the active connection */PHP_FUNCTION(mysqli_change_user){ MY_MYSQL *mysql; zval *mysql_link = NULL; char *user, *password, *dbname; int user_len, password_len, dbname_len; ulong rc; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&s&s&", &mysql_link, mysqli_link_class_entry, &user, &user_len, UG(utf8_conv), &password, &password_len, UG(utf8_conv), &dbname, &dbname_len, UG(utf8_conv)) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); rc = mysql_change_user(mysql->mysql, user, password, dbname); MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); if (rc) { RETURN_FALSE; } RETURN_TRUE;}/* }}} *//* {{{ proto string mysqli_character_set_name(object link) U Returns the name of the character set used for this connection */PHP_FUNCTION(mysqli_character_set_name){ MY_MYSQL *mysql; zval *mysql_link; char *csname; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);#if !defined(HAVE_MYSQLND) csname = (char *)mysql_character_set_name(mysql->mysql);#else csname = mysql->mysql->charset->name;#endif RETURN_UTF8_STRING(csname, ZSTR_DUPLICATE);}/* }}} *//* {{{ proto bool mysqli_close(object link) U Close connection */PHP_FUNCTION(mysqli_close){ zval *mysql_link; MY_MYSQL *mysql; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED); php_clear_mysql(mysql); if (!mysql->persistent) { mysqli_close(mysql->mysql, MYSQLI_CLOSE_EXPLICIT); } MYSQLI_CLEAR_RESOURCE(&mysql_link); efree(mysql); RETURN_TRUE;}/* }}} *//* {{{ proto bool mysqli_commit(object link) U Commit outstanding actions and close transaction */PHP_FUNCTION(mysqli_commit){ MY_MYSQL *mysql; zval *mysql_link; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); if (mysql_commit(mysql->mysql)) { RETURN_FALSE; } RETURN_TRUE;}/* }}} *//* {{{ proto bool mysqli_data_seek(object result, int offset) U Move internal result pointer */PHP_FUNCTION(mysqli_data_seek){ MYSQL_RES *result; zval *mysql_result; long offset; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered(result)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT"); RETURN_FALSE; } if (offset < 0 || offset >= mysql_num_rows(result)) { RETURN_FALSE; } mysql_data_seek(result, offset); RETURN_TRUE;}/* }}} *//* {{{ proto void mysqli_debug(string debug) U*/#if !defined(HAVE_MYSQLND)PHP_FUNCTION(mysqli_debug){ char *debug; int debug_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", &debug, &debug_len, UG(utf8_conv)) == FAILURE) { return; } mysql_debug(debug); RETURN_TRUE;}#endif/* }}} *//* {{{ proto bool mysqli_dump_debug_info(object link) U*/PHP_FUNCTION(mysqli_dump_debug_info){ MY_MYSQL *mysql; zval *mysql_link; ulong rc; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); rc = mysql_dump_debug_info(mysql->mysql); if (rc) { RETURN_FALSE; } RETURN_TRUE; }/* }}} *//* {{{ proto int mysqli_errno(object link) U Returns the numerical value of the error message from previous MySQL operation */PHP_FUNCTION(mysqli_errno){ MY_MYSQL *mysql; zval *mysql_link; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); RETURN_LONG(mysql_errno(mysql->mysql));}/* }}} *//* {{{ proto string mysqli_error(object link) U Returns the text of the error message from previous MySQL operation */PHP_FUNCTION(mysqli_error) { MY_MYSQL *mysql; zval *mysql_link; char *strerr; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID); strerr = (char *)mysql_error(mysql->mysql); RETURN_UTF8_STRING(strerr, ZSTR_DUPLICATE);}/* }}} *//* {{{ proto bool mysqli_stmt_execute(object stmt) U Execute a prepared statement */PHP_FUNCTION(mysqli_stmt_execute){ MY_STMT *stmt; zval *mysql_stmt; unsigned int i; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); i = 0;#ifndef HAVE_MYSQLND for (; i < stmt->param.var_cnt; i++) { if (stmt->param.vars[i]) { if ( !(stmt->param.is_null[i] = (stmt->param.vars[i]->type == IS_NULL)) ) { switch (stmt->stmt->params[i].buffer_type) { case MYSQL_TYPE_VAR_STRING: if (UG(unicode) && Z_TYPE_P(stmt->param.vars[i]) == IS_UNICODE) { zend_unicode_to_string(UG(utf8_conv), (char **)&stmt->stmt->params[i].buffer, (int *)&stmt->stmt->params[i].buffer_length, Z_USTRVAL_PP(&stmt->param.vars[i]), Z_USTRLEN_PP(&stmt->param.vars[i]) TSRMLS_CC); } else { if (Z_TYPE_P(stmt->param.vars[i]) != IS_STRING) { convert_to_string_ex(&stmt->param.vars[i]); } stmt->stmt->params[i].buffer = Z_STRVAL_PP(&stmt->param.vars[i]); stmt->stmt->params[i].buffer_length = Z_STRLEN_PP(&stmt->param.vars[i]); } break; case MYSQL_TYPE_DOUBLE: convert_to_double_ex(&stmt->param.vars[i]); stmt->stmt->params[i].buffer = (gptr)&Z_LVAL_PP(&stmt->param.vars[i]); break; case MYSQL_TYPE_LONG: convert_to_long_ex(&stmt->param.vars[i]); stmt->stmt->params[i].buffer = (gptr)&Z_LVAL_PP(&stmt->param.vars[i]); break; default: break; } } } }#endif if (mysql_stmt_execute(stmt->stmt)) { MYSQLI_REPORT_STMT_ERROR(stmt->stmt); RETVAL_FALSE; } else { RETVAL_TRUE; } if (MyG(report_mode) & MYSQLI_REPORT_INDEX) { php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC); }#ifndef HAVE_MYSQLND /* free converted utf8 strings */ if (UG(unicode)) { for (i = 0; i < stmt->param.var_cnt; i++) { if (stmt->stmt->params[i].buffer_type == MYSQL_TYPE_VAR_STRING && Z_TYPE_P(stmt->param.vars[i]) == IS_UNICODE) { efree(stmt->stmt->params[i].buffer); } } }#endif}/* }}} *//* {{{ mixed mysqli_stmt_fetch_libmysql */#if !defined(HAVE_MYSQLND)void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS){ MY_STMT *stmt; zval *mysql_stmt; unsigned int i; ulong ret; unsigned int uval; my_ulonglong llval; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) { return; } MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID); /* reset buffers */ for (i = 0; i < stmt->result.var_cnt; i++) { if (stmt->result.buf[i].type == IS_STRING) { memset(stmt->result.buf[i].val, 0, stmt->result.buf[i].buflen); } } ret = mysql_stmt_fetch(stmt->stmt);#ifdef MYSQL_DATA_TRUNCATED if (!ret || ret == MYSQL_DATA_TRUNCATED) {#else if (!ret) {#endif for (i = 0; i < stmt->result.var_cnt; i++) { /* QQ: Isn't it quite better to call zval_dtor(). What if the user has assigned a resource, or an array to the bound variable? We are going to leak probably. zval_dtor() will handle also Unicode/Non-unicode mode. */ /* Even if the string is of length zero there is one byte alloced so efree() in all cases */ if (Z_TYPE_P(stmt->result.vars[i]) == IS_STRING) { efree(stmt->result.vars[i]->value.str.val); } if (Z_TYPE_P(stmt->result.vars[i]) == IS_UNICODE) { USTR_FREE(stmt->result.vars[i]->value.ustr.val); } if (!stmt->result.is_null[i]) { switch (stmt->result.buf[i].type) { case IS_LONG: if ((stmt->stmt->fields[i].type == MYSQL_TYPE_LONG) && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)) { /* unsigned int (11) */ uval= *(unsigned int *) stmt->result.buf[i].val; if (uval > INT_MAX) { char *tmp, *p; int j=10; tmp= emalloc(11); p= &tmp[9]; do { *p-- = (uval % 10) + 48; uval = uval / 10; } while (--j > 0); tmp[10]= '\0'; /* unsigned int > INT_MAX is 10 digits - ALWAYS */ ZVAL_UTF8_STRINGL(stmt->result.vars[i], tmp, 10, 0); if (UG(unicode)) { efree(tmp); } break; } } if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) { ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val); } else { ZVAL_LONG(stmt->result.vars[i], *(int *)stmt->result.buf[i].val); } break; case IS_DOUBLE: ZVAL_DOUBLE(stmt->result.vars[i], *(double *)stmt->result.buf[i].val); break; case IS_STRING: if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG) { my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0; llval= *(my_ulonglong *) stmt->result.buf[i].val;#if SIZEOF_LONG==8 if (uns && llval > 9223372036854775807L) {#elif SIZEOF_LONG==4 if ((uns && llval > L64(2147483647)) || (!uns && (( L64(2147483647) < (my_longlong) llval) || (L64(-2147483648) > (my_longlong) llval)))) {#endif char tmp[22]; /* even though lval is declared as unsigned, the value * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must * use MYSQLI_LL_SPEC. */ sprintf((char *)&tmp, (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval); ZVAL_UTF8_STRING(stmt->result.vars[i], tmp, ZSTR_DUPLICATE); } else { ZVAL_LONG(stmt->result.vars[i], llval); } }#if MYSQL_VERSION_ID > 50002 else if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) { llval = *(my_ulonglong *)stmt->result.buf[i].val; ZVAL_LONG(stmt->result.vars[i], llval); }#endif else { ZVAL_UTF8_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->result.buf[i].buflen, ZSTR_DUPLICATE); } break; default: break; } } else { ZVAL_NULL(stmt->result.vars[i]); } } } else { MYSQLI_REPORT_STMT_ERROR(stmt->stmt); } switch (ret) { case 0:#ifdef MYSQL_DATA_TRUNCATED /* according to SQL standard truncation (e.g. loss of precision is not an error) - for detecting possible truncation you have to check mysqli_stmt_warning */ case MYSQL_DATA_TRUNCATED:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -