summaryrefslogtreecommitdiff
path: root/ext/mysqli
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mysqli')
-rw-r--r--ext/mysqli/config.m437
-rw-r--r--ext/mysqli/config.w3238
-rw-r--r--ext/mysqli/mysqli.c356
-rw-r--r--ext/mysqli/mysqli_api.c1043
-rw-r--r--ext/mysqli/mysqli_driver.c16
-rw-r--r--ext/mysqli/mysqli_embedded.c2
-rw-r--r--ext/mysqli/mysqli_exception.c2
-rw-r--r--ext/mysqli/mysqli_fe.c71
-rw-r--r--ext/mysqli/mysqli_libmysql.h36
-rw-r--r--ext/mysqli/mysqli_mysqlnd.h41
-rw-r--r--ext/mysqli/mysqli_nonapi.c429
-rw-r--r--ext/mysqli/mysqli_prop.c19
-rw-r--r--ext/mysqli/mysqli_repl.c2
-rw-r--r--ext/mysqli/mysqli_report.c9
-rw-r--r--ext/mysqli/mysqli_warning.c162
-rw-r--r--ext/mysqli/php_mysqli.h343
-rw-r--r--ext/mysqli/php_mysqli_structs.h396
17 files changed, 2027 insertions, 975 deletions
diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4
index 19bc252bb0..7302e66c42 100644
--- a/ext/mysqli/config.m4
+++ b/ext/mysqli/config.m4
@@ -3,18 +3,17 @@ dnl $Id$
dnl config.m4 for extension mysqli
PHP_ARG_WITH(mysqli, for MySQLi support,
-[ --with-mysqli[=FILE] Include MySQLi support. FILE is the optional pathname
- to mysql_config [mysql_config]])
+[ --with-mysqli[=FILE] Include MySQLi support. FILE is the optional pathname to mysql_config [mysql_config].
+ If mysqlnd is passed as FILE, the MySQL native driver will be used])
PHP_ARG_ENABLE(embedded_mysqli, whether to enable embedded MySQLi support,
[ --enable-embedded-mysqli MYSQLi: Enable embedded support], no, no)
-if test "$PHP_MYSQLI" != "no"; then
+if test "$PHP_MYSQLI" = "mysqlnd"; then
+ dnl This needs to be set in any extension which wishes to use mysqlnd
+ PHP_MYSQLND_ENABLED=yes
-dnl there are no mysql libs currently bundled with PHP.. --Jani
-dnl if test "$PHP_MYSQL" = "yes"; then
-dnl AC_MSG_ERROR([--with-mysql (using bundled libs) can not be used together with --with-mysqli.])
-dnl fi
+elif test "$PHP_MYSQLI" != "no"; then
if test "$PHP_MYSQLI" = "yes"; then
MYSQL_CONFIG=`$php_shtool path mysql_config`
@@ -26,6 +25,8 @@ dnl fi
if test "$PHP_EMBEDDED_MYSQLI" = "yes"; then
AC_DEFINE(HAVE_EMBEDDED_MYSQLI, 1, [embedded MySQL support enabled])
MYSQL_LIB_CFG='--libmysqld-libs'
+ dnl mysqlnd doesn't support embedded, so we have to add some extra stuff
+ mysqli_extra_sources="mysqli_embedded.c"
elif test "$enable_maintainer_zts" = "yes"; then
MYSQL_LIB_CFG='--libs_r'
MYSQL_LIB_NAME='mysqlclient_r'
@@ -48,17 +49,29 @@ dnl fi
[
PHP_EVAL_INCLINE($MYSQLI_INCLINE)
PHP_EVAL_LIBLINE($MYSQLI_LIBLINE, MYSQLI_SHARED_LIBADD)
- AC_DEFINE(HAVE_MYSQLILIB,1,[ ])
- PHP_CHECK_LIBRARY($MYSQL_LIB_NAME, mysql_stmt_field_count,
+ AC_DEFINE(HAVE_MYSQLILIB, 1, [ ])
+ PHP_CHECK_LIBRARY($MYSQL_LIB_NAME, mysql_set_character_set,
[ ],[
- AC_MSG_ERROR([MySQLI doesn't support versions < 4.1.3 (for MySQL 4.1.x) and < 5.0.1 for (MySQL 5.0.x) anymore. Please update your libraries.])
- ],[$MYSQLI_LIBLINE])
+ AC_MSG_ERROR([MySQLI doesn't support versions < 4.1.13 (for MySQL 4.1.x) and < 5.0.7 for (MySQL 5.0.x) anymore. Please update your libraries.])
+ ],[$MYSQLI_LIBLINE])
],[
AC_MSG_ERROR([wrong mysql library version or lib not found. Check config.log for more information.])
],[
$MYSQLI_LIBLINE
])
- PHP_NEW_EXTENSION(mysqli, mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c mysqli_fe.c mysqli_report.c mysqli_repl.c mysqli_driver.c mysqli_warning.c mysqli_exception.c mysqli_embedded.c, $ext_shared)
+ mysqli_extra_sources="$mysqli_extra_sources mysqli_repl.c"
+fi
+
+dnl Build extension
+if test "$PHP_MYSQLI" != "no"; then
+ mysqli_sources="mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c \
+ mysqli_fe.c mysqli_report.c mysqli_driver.c mysqli_warning.c \
+ mysqli_exception.c $mysqli_extra_sources"
+ PHP_NEW_EXTENSION(mysqli, $mysqli_sources, $ext_shared)
PHP_SUBST(MYSQLI_SHARED_LIBADD)
+
+ if test "$PHP_MYSQLI" = "mysqlnd"; then
+ PHP_ADD_EXTENSION_DEP(mysqli, mysqlnd)
+ fi
fi
diff --git a/ext/mysqli/config.w32 b/ext/mysqli/config.w32
index 789112ea14..0f418f0cba 100644
--- a/ext/mysqli/config.w32
+++ b/ext/mysqli/config.w32
@@ -1,14 +1,42 @@
// $Id$
// vim:ft=javascript
+// Note: The extension name is "mysqli", you enable it with "--with-mysqli".
+// Passing value "mysqlnd" to it enables the bundled
+// client library to connect to the MySQL server, i.e. no external MySQL
+// client library is needed to perform the build.
+
ARG_WITH("mysqli", "MySQLi support", "no");
if (PHP_MYSQLI != "no") {
- if (CHECK_LIB("libmysql.lib", "mysqli", PHP_MYSQLI) &&
- CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_MYSQLI", PHP_MYSQLI + "\\include;" + PHP_PHP_BUILD + "\\include\\mysql;" + PHP_MYSQLI)) {
- EXTENSION("mysqli", "mysqli.c mysqli_api.c mysqli_prop.c mysqli_nonapi.c mysqli_fe.c mysqli_report.c mysqli_repl.c mysqli_driver.c mysqli_warning.c mysqli_exception.c mysqli_embedded.c");
- AC_DEFINE('HAVE_MYSQLILIB', 1, 'Have MySQLi library');
+ mysqli_source =
+ "mysqli.c " +
+ "mysqli_api.c " +
+ "mysqli_driver.c " +
+ "mysqli_embedded.c " +
+ "mysqli_exception.c " +
+ "mysqli_fe.c " +
+ "mysqli_nonapi.c " +
+ "mysqli_prop.c " +
+ "mysqli_report.c " +
+ "mysqli_warning.c";
+
+ if (PHP_MYSQLI != "mysqlnd") {
+ if (CHECK_LIB("libmysql.lib", "mysqli", PHP_MYSQLI) &&
+ CHECK_HEADER_ADD_INCLUDE("mysql.h", "CFLAGS_MYSQLI", PHP_MYSQLI +
+ "\\include;" + PHP_PHP_BUILD +
+ "\\include\\mysql;" + PHP_MYSQLI)) {
+ // No "mysqli_repl.c" when using "mysqlnd"
+ mysqli_extra_sources = "mysqli_repl.c";
+ EXTENSION("mysqli", mysqli_source + " " + mysqli_extra_sources);
+ AC_DEFINE('HAVE_MYSQLILIB', 1, 'Have MySQLi library');
+ } else {
+ WARNING("mysqli not enabled; libraries and headers not found");
+ }
} else {
- WARNING("mysqli not enabled; libraries and headers not found");
+ EXTENSION("mysqli", mysqli_source);
+ AC_DEFINE('HAVE_MYSQLND', 1, 'MySQLi with native driver support enabled');
+ AC_DEFINE('HAVE_MYSQLILIB', 1, 'Have MySQLi library');
+ ADD_EXTENSION_DEP('mysqli', 'mysqlnd', true);
}
}
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index ff4f206b7a..8de80f5e05 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -28,7 +28,7 @@
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
#include "zend_exceptions.h"
#define MYSQLI_STORE_RESULT 0
@@ -52,6 +52,12 @@ zend_class_entry *mysqli_driver_class_entry;
zend_class_entry *mysqli_warning_class_entry;
zend_class_entry *mysqli_exception_class_entry;
+#ifdef HAVE_MYSQLND
+MYSQLND_ZVAL_PCACHE *mysqli_mysqlnd_zval_cache;
+MYSQLND_QCACHE *mysqli_mysqlnd_qcache;
+#endif
+
+
extern void php_mysqli_connect(INTERNAL_FUNCTION_PARAMETERS);
typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC);
@@ -62,6 +68,63 @@ typedef struct _mysqli_prop_handler {
mysqli_write_t write_func;
} mysqli_prop_handler;
+static int le_pmysqli;
+
+static int php_mysqli_persistent_on_rshut(zend_rsrc_list_entry *le TSRMLS_DC)
+{
+ if (le->type == le_pmysqli) {
+ mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
+ HashPosition pos;
+ MYSQL **mysql;
+ ulong idx;
+ dtor_func_t pDestructor = plist->used_links.pDestructor;
+ plist->used_links.pDestructor = NULL; /* Don't call pDestructor now */
+
+ zend_hash_internal_pointer_reset_ex(&plist->used_links, &pos);
+ while (SUCCESS == zend_hash_get_current_data_ex(&plist->used_links, (void **)&mysql, &pos)) {
+ zend_hash_get_current_key_ex(&plist->used_links, NULL, NULL, &idx, FALSE, &pos);
+ /* Make it free */
+ zend_hash_next_index_insert(&plist->free_links, mysql, sizeof(MYSQL *), NULL);
+ /* First move forward */
+ zend_hash_move_forward_ex(&plist->used_links, &pos);
+ /* The delete, because del will free memory, but we need it's ->nextItem */
+ zend_hash_index_del(&plist->used_links, idx);
+ }
+
+ /* restore pDestructor, which should be php_mysqli_dtor_p_elements() */
+ plist->used_links.pDestructor = pDestructor;
+ }
+ return ZEND_HASH_APPLY_KEEP;
+}
+
+/* Destructor for mysqli entries in free_links/used_links */
+void php_mysqli_dtor_p_elements(void *data)
+{
+ MYSQL **mysql = (MYSQL **) data;
+ TSRMLS_FETCH();
+#if defined(HAVE_MYSQLND)
+ mysqlnd_end_psession(*mysql);
+#endif
+ mysqli_close(*mysql, MYSQLI_CLOSE_IMPLICIT);
+}
+
+ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor)
+{
+ if (rsrc->ptr) {
+ mysqli_plist_entry *plist = (mysqli_plist_entry *) rsrc->ptr;
+ zend_hash_destroy(&plist->free_links);
+ zend_hash_destroy(&plist->used_links);
+ free(plist);
+ }
+}
+
+
+int php_le_pmysqli(void)
+{
+ return le_pmysqli;
+}
+
+#ifndef HAVE_MYSQLND
/* {{{ php_free_stmt_bind_buffer */
void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
{
@@ -80,7 +143,7 @@ void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
if (bbuf.vars[i]) {
zval_ptr_dtor(&bbuf.vars[i]);
- }
+ }
}
if (bbuf.vars) {
@@ -100,30 +163,44 @@ void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
}
bbuf.var_cnt = 0;
- return;
}
/* }}} */
+#endif
/* {{{ php_clear_stmt_bind */
-void php_clear_stmt_bind(MY_STMT *stmt)
+void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC)
{
if (stmt->stmt) {
- mysql_stmt_close(stmt->stmt);
+ if (mysqli_stmt_close(stmt->stmt, TRUE)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error occured while closing statement");
+ return;
+ }
}
+ /*
+ mysqlnd keeps track of the binding and has freed its
+ structures in stmt_close() above
+ */
+#ifndef HAVE_MYSQLND
+ /* Clean param bind */
php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
+ /* Clean output bind */
php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);
+#endif
if (stmt->query) {
efree(stmt->query);
}
efree(stmt);
- return;
}
/* }}} */
/* {{{ php_clear_mysql */
void php_clear_mysql(MY_MYSQL *mysql) {
+ if (mysql->hash_key) {
+ efree(mysql->hash_key);
+ mysql->hash_key = NULL;
+ }
if (mysql->li_read) {
efree(Z_STRVAL_P(mysql->li_read));
FREE_ZVAL(mysql->li_read);
@@ -140,7 +217,7 @@ static void mysqli_objects_free_storage(void *object TSRMLS_DC)
mysqli_object *intern = (mysqli_object *)zo;
MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
- my_efree(my_res);
+ my_efree(my_res);
zend_object_std_dtor(&intern->zo TSRMLS_CC);
efree(intern);
}
@@ -157,7 +234,9 @@ static void mysqli_link_free_storage(void *object TSRMLS_DC)
if (my_res && my_res->ptr) {
MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr;
if (mysql->mysql) {
- mysql_close(mysql->mysql);
+ if (!mysql->persistent) {
+ mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
+ }
}
php_clear_mysql(mysql);
efree(mysql);
@@ -166,6 +245,13 @@ static void mysqli_link_free_storage(void *object TSRMLS_DC)
}
/* }}} */
+/* {{{ mysql_driver_free_storage */
+static void mysqli_driver_free_storage(void *object TSRMLS_DC)
+{
+ mysqli_objects_free_storage(object TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ mysqli_stmt_free_storage
*/
static void mysqli_stmt_free_storage(void *object TSRMLS_DC)
@@ -176,7 +262,7 @@ static void mysqli_stmt_free_storage(void *object TSRMLS_DC)
if (my_res && my_res->ptr) {
MY_STMT *stmt = (MY_STMT *)my_res->ptr;
- php_clear_stmt_bind(stmt);
+ php_clear_stmt_bind(stmt TSRMLS_CC);
}
mysqli_objects_free_storage(object TSRMLS_CC);
}
@@ -243,7 +329,7 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC)
ret = FAILURE;
obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
- if (member->type != IS_STRING) {
+ if (member->type != IS_STRING) {
tmp_member = *member;
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
@@ -256,7 +342,8 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC)
if (ret == SUCCESS) {
if (strcmp(obj->zo.ce->name, "mysqli_driver") &&
- (!obj->ptr || ((MYSQLI_RESOURCE *)(obj->ptr))->status < MYSQLI_STATUS_INITIALIZED)) {
+ (!obj->ptr || ((MYSQLI_RESOURCE *)(obj->ptr))->status < MYSQLI_STATUS_INITIALIZED))
+ {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name );
retval = EG(uninitialized_zval_ptr);
return(retval);
@@ -290,7 +377,7 @@ void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
zend_object_handlers *std_hnd;
int ret;
- if (member->type != IS_STRING) {
+ if (member->type != IS_STRING) {
tmp_member = *member;
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
@@ -333,7 +420,6 @@ void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli
static union _zend_function *php_mysqli_constructor_get(zval *object TSRMLS_DC)
{
- mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
zend_class_entry * ce = Z_OBJCE_P(object);
if (ce != mysqli_link_class_entry && ce != mysqli_stmt_class_entry &&
@@ -342,6 +428,7 @@ static union _zend_function *php_mysqli_constructor_get(zval *object TSRMLS_DC)
return zend_std_get_constructor(object TSRMLS_CC);
} else {
static zend_internal_function f;
+ mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC);
f.function_name = obj->zo.ce->name;
f.scope = obj->zo.ce;
@@ -361,7 +448,7 @@ static union _zend_function *php_mysqli_constructor_get(zval *object TSRMLS_DC)
} else if (obj->zo.ce == mysqli_warning_class_entry) {
f.handler = ZEND_MN(mysqli_warning___construct);
}
-
+
return (union _zend_function*)&f;
}
}
@@ -382,8 +469,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
intern->prop_handler = NULL;
mysqli_base_class = class_type;
- while (mysqli_base_class->type != ZEND_INTERNAL_CLASS && mysqli_base_class->parent != NULL)
- {
+ while (mysqli_base_class->type != ZEND_INTERNAL_CLASS && mysqli_base_class->parent != NULL) {
mysqli_base_class = mysqli_base_class->parent;
}
zend_hash_find(&classes, mysqli_base_class->name, mysqli_base_class->name_length + 1,
@@ -396,6 +482,8 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
/* link object */
if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) {
free_storage = mysqli_link_free_storage;
+ } else if (instanceof_function(class_type, mysqli_driver_class_entry TSRMLS_CC)) { /* driver object */
+ free_storage = mysqli_driver_free_storage;
} else if (instanceof_function(class_type, mysqli_stmt_class_entry TSRMLS_CC)) { /* stmt object */
free_storage = mysqli_stmt_free_storage;
} else if (instanceof_function(class_type, mysqli_result_class_entry TSRMLS_CC)) { /* result object */
@@ -412,17 +500,21 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
return retval;
}
/* }}} */
-
-/* {{{ mysqli_module_entry
- */
+
+
/* Dependancies */
-static const zend_module_dep mysqli_deps[] = {
+const static zend_module_dep mysqli_deps[] = {
#if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
ZEND_MOD_REQUIRED("spl")
#endif
+#if defined(HAVE_MYSQLND)
+ ZEND_MOD_REQUIRED("mysqlnd")
+#endif
{NULL, NULL, NULL}
};
+/* {{{ mysqli_module_entry
+ */
zend_module_entry mysqli_module_entry = {
#if ZEND_MODULE_API_NO >= 20050922
STANDARD_MODULE_HEADER_EX, NULL,
@@ -454,22 +546,33 @@ ZEND_GET_MODULE(mysqli)
*/
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY_EX("mysqli.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysqli_globals, mysqli_globals, display_link_numbers)
+ STD_PHP_INI_ENTRY_EX("mysqli.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_mysqli_globals, mysqli_globals, display_link_numbers)
+ STD_PHP_INI_BOOLEAN("mysqli.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_pw", NULL, PHP_INI_ALL, OnUpdateString, default_pw, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_port", "3306", PHP_INI_ALL, OnUpdateLong, default_port, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_ENTRY("mysqli.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysqli_globals, mysqli_globals)
STD_PHP_INI_BOOLEAN("mysqli.reconnect", "0", PHP_INI_SYSTEM, OnUpdateLong, reconnect, zend_mysqli_globals, mysqli_globals)
+ STD_PHP_INI_BOOLEAN("mysqli.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysqli_globals, mysqli_globals)
+#ifdef HAVE_MYSQLND
+ STD_PHP_INI_ENTRY("mysqli.cache_size", "2000", PHP_INI_SYSTEM, OnUpdateLong, cache_size, zend_mysqli_globals, mysqli_globals)
+#endif
PHP_INI_END()
-
/* }}} */
+
/* {{{ PHP_GINIT_FUNCTION
*/
static PHP_GINIT_FUNCTION(mysqli)
{
mysqli_globals->num_links = 0;
- mysqli_globals->max_links = 0;
+ mysqli_globals->num_active_persistent = 0;
+ mysqli_globals->num_inactive_persistent = 0;
+ mysqli_globals->max_links = -1;
+ mysqli_globals->max_links = -1;
+ mysqli_globals->max_persistent = -1;
+ mysqli_globals->allow_persistent = 1;
mysqli_globals->default_port = 0;
mysqli_globals->default_host = NULL;
mysqli_globals->default_user = NULL;
@@ -478,11 +581,16 @@ static PHP_GINIT_FUNCTION(mysqli)
mysqli_globals->reconnect = 0;
mysqli_globals->report_mode = 0;
mysqli_globals->report_ht = 0;
+ mysqli_globals->allow_local_infile = 1;
#ifdef HAVE_EMBEDDED_MYSQLI
mysqli_globals->embedded = 1;
#else
mysqli_globals->embedded = 0;
#endif
+#ifdef HAVE_MYSQLND
+ mysqli_globals->cache_size = 0;
+ mysqli_globals->mysqlnd_thd_zval_cache = NULL;
+#endif
}
/* }}} */
@@ -494,6 +602,16 @@ PHP_MINIT_FUNCTION(mysqli)
zend_object_handlers *std_hnd = zend_get_std_object_handlers();
REGISTER_INI_ENTRIES();
+#ifndef HAVE_MYSQLND
+#if MYSQL_VERSION_ID >= 40000
+ if (mysql_server_init(0, NULL, NULL)) {
+ return FAILURE;
+ }
+#endif
+#else
+ mysqli_mysqlnd_zval_cache = mysqlnd_palloc_init_cache(MyG(cache_size));
+ mysqli_mysqlnd_qcache = mysqlnd_qcache_init_cache();
+#endif
memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
mysqli_object_handlers.clone_obj = NULL;
@@ -504,6 +622,10 @@ PHP_MINIT_FUNCTION(mysqli)
zend_hash_init(&classes, 0, NULL, NULL, 1);
+ /* persistent connections */
+ le_pmysqli = zend_register_list_destructors_ex(NULL, php_mysqli_dtor,
+ "MySqli persistent connection", module_number);
+
INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods);
#ifdef HAVE_SPL
mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC);
@@ -552,6 +674,13 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT);
+#if defined(HAVE_MYSQLND)
+ REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_CMD_BUFFER_SIZE", MYSQLND_OPT_NET_CMD_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_OPT_NET_READ_BUFFER_SIZE", MYSQLND_OPT_NET_READ_BUFFER_SIZE, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MYSQLND_STRING_TO_INT_CONVERSION
+ REGISTER_LONG_CONSTANT("MYSQLI_OPT_INT_AND_YEAR_AS_INT", MYSQLND_OPT_INT_AND_YEAR_AS_INT, CONST_CS | CONST_PERSISTENT);
+#endif
/* mysqli_real_connect flags */
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
@@ -573,7 +702,7 @@ PHP_MINIT_FUNCTION(mysqli)
/* for mysqli_stmt_set_attr */
REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH", STMT_ATTR_UPDATE_MAX_LENGTH, CONST_CS | CONST_PERSISTENT);
-#if MYSQL_VERSION_ID > 50003
+#if MYSQL_VERSION_ID > 50003 || defined(HAVE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_CURSOR_TYPE", STMT_ATTR_CURSOR_TYPE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_NO_CURSOR", CURSOR_TYPE_NO_CURSOR, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_READ_ONLY", CURSOR_TYPE_READ_ONLY, CONST_CS | CONST_PERSISTENT);
@@ -581,7 +710,7 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_CURSOR_TYPE_SCROLLABLE", CURSOR_TYPE_SCROLLABLE, CONST_CS | CONST_PERSISTENT);
#endif
-#if MYSQL_VERSION_ID > 50007
+#if MYSQL_VERSION_ID > 50007 || defined(HAVE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_STMT_ATTR_PREFETCH_ROWS", STMT_ATTR_PREFETCH_ROWS, CONST_CS | CONST_PERSISTENT);
#endif
@@ -627,17 +756,19 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_TYPE_INTERVAL", FIELD_TYPE_INTERVAL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_TYPE_GEOMETRY", FIELD_TYPE_GEOMETRY, CONST_CS | CONST_PERSISTENT);
-#if MYSQL_VERSION_ID > 50002
+#if MYSQL_VERSION_ID > 50002 || defined(HAVE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_TYPE_NEWDECIMAL", FIELD_TYPE_NEWDECIMAL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_TYPE_BIT", FIELD_TYPE_BIT, CONST_CS | CONST_PERSISTENT);
#endif
-
+ REGISTER_LONG_CONSTANT("MYSQLI_SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, CONST_CS | CONST_PERSISTENT);
/* replication */
+#if !defined(HAVE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_RPL_MASTER", MYSQL_RPL_MASTER, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_RPL_SLAVE", MYSQL_RPL_SLAVE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_RPL_ADMIN", MYSQL_RPL_ADMIN, CONST_CS | CONST_PERSISTENT);
+#endif
/* bind support */
REGISTER_LONG_CONSTANT("MYSQLI_NO_DATA", MYSQL_NO_DATA, CONST_CS | CONST_PERSISTENT);
@@ -652,10 +783,6 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_REPORT_ALL", MYSQLI_REPORT_ALL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_REPORT_OFF", 0, CONST_CS | CONST_PERSISTENT);
- if (mysql_server_init(0, NULL, NULL)) {
- return FAILURE;
- }
-
return SUCCESS;
}
/* }}} */
@@ -664,15 +791,25 @@ PHP_MINIT_FUNCTION(mysqli)
*/
PHP_MSHUTDOWN_FUNCTION(mysqli)
{
+#ifndef HAVE_MYSQLND
+#if MYSQL_VERSION_ID >= 40000
#ifdef PHP_WIN32
unsigned long client_ver = mysql_get_client_version();
- /* Can't call mysql_server_end() multiple times prior to 5.0.42 on Windows */
- if ((client_ver > 50042 && client_ver < 50100) || client_ver > 50122) {
+ /*
+ Can't call mysql_server_end() multiple times prior to 5.0.42 on Windows.
+ PHP bug#41350 MySQL bug#25621
+ */
+ if ((client_ver >= 50042 && client_ver < 50100) || client_ver > 50122) {
mysql_server_end();
}
#else
mysql_server_end();
#endif
+#endif
+#else
+ mysqlnd_palloc_free_cache(mysqli_mysqlnd_zval_cache);
+ mysqlnd_qcache_free_cache_reference(&mysqli_mysqlnd_qcache);
+#endif
zend_hash_destroy(&mysqli_driver_properties);
zend_hash_destroy(&mysqli_result_properties);
@@ -690,13 +827,16 @@ PHP_MSHUTDOWN_FUNCTION(mysqli)
*/
PHP_RINIT_FUNCTION(mysqli)
{
-#ifdef ZTS
+#if !defined(HAVE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
if (mysql_thread_init()) {
return FAILURE;
}
#endif
MyG(error_msg) = NULL;
MyG(error_no) = 0;
+#ifdef HAVE_MYSQLND
+ MyG(mysqlnd_thd_zval_cache) = mysqlnd_palloc_rinit(mysqli_mysqlnd_zval_cache);
+#endif
return SUCCESS;
}
@@ -706,27 +846,55 @@ PHP_RINIT_FUNCTION(mysqli)
*/
PHP_RSHUTDOWN_FUNCTION(mysqli)
{
-#ifdef ZTS
+ /* check persistent connections, move used to free */
+ zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysqli_persistent_on_rshut TSRMLS_CC);
+
+#if !defined(HAVE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
mysql_thread_end();
#endif
if (MyG(error_msg)) {
efree(MyG(error_msg));
}
+#ifdef HAVE_MYSQLND
+ mysqlnd_palloc_rshutdown(MyG(mysqlnd_thd_zval_cache));
+#endif
return SUCCESS;
}
/* }}} */
+
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(mysqli)
{
+ char buf[32];
+
php_info_print_table_start();
php_info_print_table_header(2, "MysqlI Support", "enabled");
php_info_print_table_row(2, "Client API library version", mysql_get_client_info());
+ snprintf(buf, sizeof(buf), "%ld", MyG(num_active_persistent));
+ php_info_print_table_row(2, "Active Persistent Links", buf);
+ snprintf(buf, sizeof(buf), "%ld", MyG(num_inactive_persistent));
+ php_info_print_table_row(2, "Inactive Persistent Links", buf);
+ snprintf(buf, sizeof(buf), "%ld", MyG(num_links));
+ php_info_print_table_row(2, "Active Links", buf);
+#if !defined(HAVE_MYSQLND)
php_info_print_table_row(2, "Client API header version", MYSQL_SERVER_VERSION);
php_info_print_table_row(2, "MYSQLI_SOCKET", MYSQL_UNIX_ADDR);
-
-
+#else
+ {
+ zval values;
+
+ php_info_print_table_header(2, "Persistent cache", mysqli_mysqlnd_zval_cache? "enabled":"disabled");
+
+ if (mysqli_mysqlnd_zval_cache) {
+ /* Now report cache status */
+ mysqlnd_palloc_stats(mysqli_mysqlnd_zval_cache, &values);
+ mysqlnd_minfo_print_hash(&values);
+ zval_dtor(&values);
+ }
+ }
+#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
@@ -742,16 +910,16 @@ Parameters:
ZEND_FUNCTION(mysqli_stmt_construct)
{
MY_MYSQL *mysql;
- zval *mysql_link;
+ zval *mysql_link;
MY_STMT *stmt;
- MYSQLI_RESOURCE *mysqli_resource;
+ MYSQLI_RESOURCE *mysqli_resource;
char *statement;
- int stmt_len;
+ int statement_len;
switch (ZEND_NUM_ARGS())
{
case 1: /* mysql_stmt_init */
- if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
+ if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
@@ -761,15 +929,15 @@ ZEND_FUNCTION(mysqli_stmt_construct)
stmt->stmt = mysql_stmt_init(mysql->mysql);
break;
case 2:
- if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &stmt_len)==FAILURE) {
+ if (zend_parse_parameters(2 TSRMLS_CC, "Os", &mysql_link, mysqli_link_class_entry, &statement, &statement_len)==FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
-
+
if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
- mysql_stmt_prepare(stmt->stmt, statement, stmt_len);
+ mysql_stmt_prepare(stmt->stmt, statement, statement_len);
}
break;
default:
@@ -800,20 +968,24 @@ ZEND_FUNCTION(mysqli_result_construct)
MY_MYSQL *mysql;
MYSQL_RES *result;
zval *mysql_link;
- MYSQLI_RESOURCE *mysqli_resource;
+ MYSQLI_RESOURCE *mysqli_resource;
long resmode = MYSQLI_STORE_RESULT;
switch (ZEND_NUM_ARGS()) {
case 1:
- if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
+ if (zend_parse_parameters(1 TSRMLS_CC, "O", &mysql_link, mysqli_link_class_entry)==FAILURE) {
return;
}
- break;
+ break;
case 2:
- if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) {
+ if (zend_parse_parameters(2 TSRMLS_CC, "Ol", &mysql_link, mysqli_link_class_entry, &resmode)==FAILURE) {
return;
}
- break;
+ if (resmode != MYSQLI_USE_RESULT && resmode != MYSQLI_STORE_RESULT) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
+ RETURN_FALSE;
+ }
+ break;
default:
WRONG_PARAM_COUNT;
}
@@ -830,7 +1002,7 @@ ZEND_FUNCTION(mysqli_result_construct)
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)result;
mysqli_resource->status = MYSQLI_STATUS_VALID;
-
+
((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
}
@@ -843,12 +1015,14 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
MYSQL_RES *result;
zval *mysql_result;
long fetchtype;
+ zval *ctor_params = NULL;
+ zend_class_entry *ce = NULL;
+#if !defined(HAVE_MYSQLND)
unsigned int i;
MYSQL_FIELD *fields;
MYSQL_ROW row;
unsigned long *field_len;
- zval *ctor_params = NULL;
- zend_class_entry *ce = NULL;
+#endif
if (into_object) {
char *class_name;
@@ -882,11 +1056,12 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
}
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
- if ((fetchtype & MYSQLI_BOTH) == 0) {
+ if (fetchtype < MYSQLI_ASSOC || fetchtype > MYSQLI_BOTH) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH");
RETURN_FALSE;
}
+#if !defined(HAVE_MYSQLND)
if (!(row = mysql_fetch_row(result))) {
RETURN_NULL();
}
@@ -930,16 +1105,19 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
}
}
}
+#else
+ mysqlnd_fetch_into(result, MYSQLND_FETCH_ASSOC, return_value, MYSQLND_MYSQLI);
+#endif
- if (into_object) {
+ if (into_object && Z_TYPE_P(return_value) != IS_NULL) {
zval dataset = *return_value;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zval *retval_ptr;
-
+
object_and_properties_init(return_value, ce, NULL);
zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
-
+
if (ce->constructor) {
fci.size = sizeof(fci);
fci.function_table = &ce->function_table;
@@ -951,7 +1129,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
HashTable *ht = Z_ARRVAL_P(ctor_params);
Bucket *p;
-
+
fci.param_count = 0;
fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
p = ht->pListHead;
@@ -979,7 +1157,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
fcc.function_handler = ce->constructor;
fcc.calling_scope = EG(scope);
fcc.object_pp = &return_value;
-
+
if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
} else {
@@ -1009,6 +1187,8 @@ PHP_MYSQLI_API void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRML
}
/* }}} */
+#if !defined(HAVE_MYSQLND)
+
#define ALLOC_CALLBACK_ARGS(a, b, c)\
if (c) {\
a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
@@ -1029,7 +1209,7 @@ if (a) {\
#define LOCAL_INFILE_ERROR_MSG(source,dest)\
memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
-memcpy(source, dest, LOCAL_INFILE_ERROR_LEN-1);
+memcpy(source, dest, MIN(strlen(dest), LOCAL_INFILE_ERROR_LEN-1));
/* {{{ void php_set_local_infile_handler_default
*/
@@ -1037,7 +1217,10 @@ void php_set_local_infile_handler_default(MY_MYSQL *mysql) {
/* register internal callback functions */
mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
&php_local_infile_end, &php_local_infile_error, (void *)mysql);
- mysql->li_read = NULL;
+ if (mysql->li_read) {
+ zval_ptr_dtor(&mysql->li_read);
+ mysql->li_read = NULL;
+ }
}
/* }}} */
@@ -1047,7 +1230,7 @@ int php_local_infile_init(void **ptr, const char *filename, void *userdata)
{
mysqli_local_infile *data;
MY_MYSQL *mysql;
- php_stream_context *context = NULL;
+ php_stream_context *context = NULL;
TSRMLS_FETCH();
@@ -1086,7 +1269,7 @@ int php_local_infile_init(void **ptr, const char *filename, void *userdata)
int php_local_infile_read(void *ptr, char *buf, uint buf_len)
{
mysqli_local_infile *data;
- MY_MYSQL *mysql;
+ MY_MYSQL *mysql;
zval ***callback_args;
zval *retval;
zval *fp;
@@ -1101,9 +1284,7 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
/* default processing */
if (!mysql->li_read) {
- int count;
-
- count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
+ int count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
if (count < 0) {
LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2));
@@ -1113,21 +1294,21 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
}
ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
-
+
/* set parameters: filepointer, buffer, buffer_len, errormsg */
MAKE_STD_ZVAL(fp);
php_stream_to_zval(mysql->li_stream, fp);
callback_args[0] = &fp;
- ZVAL_STRING(*callback_args[1], "", 1);
- ZVAL_LONG(*callback_args[2], buf_len);
- ZVAL_STRING(*callback_args[3], "", 1);
+ ZVAL_STRING(*callback_args[1], "", 1);
+ ZVAL_LONG(*callback_args[2], buf_len);
+ ZVAL_STRING(*callback_args[3], "", 1);
if (call_user_function_ex(EG(function_table),
NULL,
mysql->li_read,
&retval,
- argc,
+ argc,
callback_args,
0,
NULL TSRMLS_CC) == SUCCESS) {
@@ -1136,22 +1317,36 @@ int php_local_infile_read(void *ptr, char *buf, uint buf_len)
zval_ptr_dtor(&retval);
if (rc > 0) {
- if (rc > buf_len) {
+ if (rc >= 0 && rc != Z_STRLEN_P(*callback_args[1])) {
+ LOCAL_INFILE_ERROR_MSG(data->error_msg,
+ "Mismatch between the return value of the callback and the content "
+ "length of the buffer.");
+ rc = -1;
+ } else if (rc > buf_len) {
/* check buffer overflow */
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "Read buffer too large");
+ LOCAL_INFILE_ERROR_MSG(data->error_msg, "Too much data returned");
rc = -1;
} else {
- memcpy(buf, Z_STRVAL_P(*callback_args[1]), rc);
+ memcpy(buf, Z_STRVAL_P(*callback_args[1]), MIN(rc, Z_STRLEN_P(*callback_args[1])));
}
- }
- if (rc < 0) {
+ } else if (rc < 0) {
LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
}
} else {
LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
rc = -1;
}
-
+ /*
+ If the (ab)user has closed the file handle we should
+ not try to use it anymore or even close it
+ */
+ if (!zend_rsrc_list_get_rsrc_type(Z_LVAL_P(fp) TSRMLS_CC)) {
+ LOCAL_INFILE_ERROR_MSG(data->error_msg, "File handle closed");
+ rc = -1;
+ /* Thus the end handler won't try to free already freed memory */
+ mysql->li_stream = NULL;
+ }
+
FREE_CALLBACK_ARGS(callback_args, 1, argc);
efree(fp);
return rc;
@@ -1167,7 +1362,7 @@ int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
if (data) {
strlcpy(error_msg, data->error_msg, error_msg_len);
return 2000;
- }
+ }
strlcpy(error_msg, ER(CR_OUT_OF_MEMORY), error_msg_len);
return CR_OUT_OF_MEMORY;
}
@@ -1175,10 +1370,10 @@ int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
/* {{{ php_local_infile_end
*/
-void php_local_infile_end(void *ptr)
+void php_local_infile_end(void *ptr)
{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
+ mysqli_local_infile *data;
+ MY_MYSQL *mysql;
TSRMLS_FETCH();
@@ -1193,9 +1388,10 @@ void php_local_infile_end(void *ptr)
php_stream_close(mysql->li_stream);
free(data);
- return;
+ return;
}
/* }}} */
+#endif
/*
* Local variables:
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index fd01ba9ffa..5e55be7d51 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -12,7 +12,9 @@
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: Georg Richter <georg@php.net> |
+ | Authors: Georg Richter <georg@php.net> |
+ | Andrey Hristov <andrey@php.net> |
+ | Ulf Wendel <uw@php.net> |
+----------------------------------------------------------------------+
$Id$
@@ -26,8 +28,9 @@
#include "php.h"
#include "php_ini.h"
+#include "php_globals.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
/* {{{ proto mixed mysqli_affected_rows(object link)
Get number of affected rows in previous MySQL operation */
@@ -51,16 +54,17 @@ PHP_FUNCTION(mysqli_affected_rows)
}
/* }}} */
+
/* {{{ proto bool mysqli_autocommit(object link, bool mode)
Turn auto commit on or of */
PHP_FUNCTION(mysqli_autocommit)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
- zend_bool automode;
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ zend_bool automode;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ob", &mysql_link, mysqli_link_class_entry, &automode) == FAILURE) {
- return;
+ return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
@@ -71,83 +75,38 @@ PHP_FUNCTION(mysqli_autocommit)
}
/* }}} */
-/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....])
- Bind variables to a prepared statement as parameters */
-PHP_FUNCTION(mysqli_stmt_bind_param)
+/* {{{ mysqli_stmt_bind_param_do_bind */
+#ifndef HAVE_MYSQLND
+static
+int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
+ zval ***args, unsigned int start, const char * const types TSRMLS_DC)
{
- zval ***args;
- int argc = ZEND_NUM_ARGS();
- int i;
- int num_vars;
- int start = 2;
- int ofs;
- MY_STMT *stmt;
- zval *mysql_stmt;
+ int i, ofs;
MYSQL_BIND *bind;
- char *types;
- int typelen;
unsigned long rc;
- /* calculate and check number of parameters */
- if (argc < 2) {
- /* there has to be at least one pair */
- WRONG_PARAM_COUNT;
- }
-
- if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry, &types, &typelen) == FAILURE) {
- return;
- }
-
- MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
-
- num_vars = argc - 1;
- if (getThis()) {
- start = 1;
- } else {
- /* ignore handle parameter in procedural interface*/
- --num_vars;
- }
-
- if (typelen != argc - start) {
- /* number of bind variables doesn't match number of elements in type definition string */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
- RETURN_FALSE;
- }
-
- if (typelen != stmt->stmt->param_count) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
- RETURN_FALSE;
- }
-
/* prevent leak if variables are already bound */
if (stmt->param.var_cnt) {
php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE);
}
- args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
-
- if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
- efree(args);
- WRONG_PARAM_COUNT;
- }
-
stmt->param.is_null = ecalloc(num_vars, sizeof(char));
- bind = (MYSQL_BIND *)ecalloc(num_vars, sizeof(MYSQL_BIND));
+ bind = (MYSQL_BIND *) ecalloc(num_vars, sizeof(MYSQL_BIND));
ofs = 0;
- for (i=start; i < argc; i++) {
+ for (i = start; i < argc; i++) {
/* set specified type */
switch (types[ofs]) {
case 'd': /* Double */
bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
- bind[ofs].buffer = (char*)&Z_DVAL_PP(args[i]);
+ bind[ofs].buffer = &Z_DVAL_PP(args[i]);
bind[ofs].is_null = &stmt->param.is_null[ofs];
break;
case 'i': /* Integer */
- bind[ofs].buffer_type = MYSQL_TYPE_LONG;
- bind[ofs].buffer = (char*)&Z_LVAL_PP(args[i]);
+ bind[ofs].buffer_type = (sizeof(long) > 4) ? MYSQL_TYPE_LONGLONG : MYSQL_TYPE_LONG;
+ bind[ofs].buffer = &Z_LVAL_PP(args[i]);
bind[ofs].is_null = &stmt->param.is_null[ofs];
break;
@@ -164,85 +123,162 @@ PHP_FUNCTION(mysqli_stmt_bind_param)
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[ofs], i+1);
- RETVAL_FALSE;
- goto end;
+ rc = 1;
+ goto end_1;
}
ofs++;
}
rc = mysql_stmt_bind_param(stmt->stmt, bind);
- MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
+end_1:
if (rc) {
- RETVAL_FALSE;
- goto end;
+ efree(stmt->param.is_null);
+ } else {
+ stmt->param.var_cnt = num_vars;
+ stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0);
+ for (i = 0; i < num_vars; i++) {
+ if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) {
+ ZVAL_ADDREF(*args[i+start]);
+ stmt->param.vars[i] = *args[i+start];
+ } else {
+ stmt->param.vars[i] = NULL;
+ }
+ }
}
+ efree(bind);
- stmt->param.var_cnt = num_vars;
- stmt->param.vars = (zval **)safe_emalloc(num_vars, sizeof(zval), 0);
- for (i = 0; i < num_vars; i++) {
- if (bind[i].buffer_type != MYSQL_TYPE_LONG_BLOB) {
- ZVAL_ADDREF(*args[i+start]);
- stmt->param.vars[i] = *args[i+start];
- } else {
- stmt->param.vars[i] = NULL;
+ return rc;
+}
+#else
+static
+int mysqli_stmt_bind_param_do_bind(MY_STMT *stmt, unsigned int argc, unsigned int num_vars,
+ zval ***args, unsigned int start, const char * const types TSRMLS_DC)
+{
+ int i;
+ MYSQLND_PARAM_BIND *params;
+ enum_func_status ret = FAIL;
+
+ /* If no params -> skip binding and return directly */
+ if (argc == start) {
+ return PASS;
+ }
+ params = emalloc((argc - start) * sizeof(MYSQLND_PARAM_BIND));
+ for (i = 0; i < (argc - start); i++) {
+ zend_uchar type;
+ switch (types[i]) {
+ case 'd': /* Double */
+ type = MYSQL_TYPE_DOUBLE;
+ break;
+ case 'i': /* Integer */
+#if SIZEOF_LONG==8
+ type = MYSQL_TYPE_LONGLONG;
+#elif SIZEOF_LONG==4
+ type = MYSQL_TYPE_LONG;
+#endif
+ break;
+ case 'b': /* Blob (send data) */
+ type = MYSQL_TYPE_LONG_BLOB;
+ break;
+ case 's': /* string */
+ type = MYSQL_TYPE_VAR_STRING;
+ break;
+ default:
+ /* We count parameters from 1 */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Undefined fieldtype %c (parameter %d)", types[i], i + start + 1);
+ ret = FAIL;
+ efree(params);
+ goto end;
}
+ params[i].zv = *(args[i + start]);
+ params[i].type = type;
}
- RETVAL_TRUE;
+ ret = mysqlnd_stmt_bind_param(stmt->stmt, params);
+
end:
- efree(args);
- efree(bind);
+ return ret;
}
+#endif
/* }}} */
-/* {{{ proto bool mysqli_stmt_bind_result(object stmt, mixed var, [,mixed, ...])
- Bind variables to a prepared statement for result storage */
-
-/* TODO:
- do_alloca, free_alloca
-*/
-
-PHP_FUNCTION(mysqli_stmt_bind_result)
+/* {{{ proto bool mysqli_stmt_bind_param(object stmt, string types, mixed variable [,mixed,....]) U
+ Bind variables to a prepared statement as parameters */
+PHP_FUNCTION(mysqli_stmt_bind_param)
{
- zval ***args;
- int argc = ZEND_NUM_ARGS();
- int i;
- int start = 1;
- int var_cnt;
- int ofs;
- long col_type;
- ulong rc;
- MY_STMT *stmt;
- zval *mysql_stmt;
- MYSQL_BIND *bind;
+ zval ***args;
+ int argc = ZEND_NUM_ARGS();
+ int num_vars;
+ int start = 2;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
+ char *types;
+ int types_len;
+ unsigned long rc;
- if (getThis()) {
- start = 0;
+ /* calculate and check number of parameters */
+ if (argc < 2) {
+ /* there has to be at least one pair */
+ WRONG_PARAM_COUNT;
}
- if (zend_parse_method_parameters((getThis()) ? 0:1 TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
+ if (zend_parse_method_parameters((getThis()) ? 1:2 TSRMLS_CC, getThis(), "Os", &mysql_stmt, mysqli_stmt_class_entry,
+ &types, &types_len) == FAILURE) {
return;
}
- MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
+ MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
- if (argc < (getThis() ? 1 : 2)) {
- WRONG_PARAM_COUNT;
+ num_vars = argc - 1;
+ if (getThis()) {
+ start = 1;
+ } else {
+ /* ignore handle parameter in procedural interface*/
+ --num_vars;
+ }
+ if (!types_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type or no types specified");
+ RETURN_FALSE;
+ }
+
+ if (types_len != argc - start) {
+ /* number of bind variables doesn't match number of elements in type definition string */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables");
+ RETURN_FALSE;
+ }
+
+ if (types_len != mysql_stmt_param_count(stmt->stmt)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement");
+ RETURN_FALSE;
}
args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
- efree(args);
- WRONG_PARAM_COUNT;
+ zend_wrong_param_count(TSRMLS_C);
+ rc = 1;
+ } else {
+ rc = mysqli_stmt_bind_param_do_bind(stmt, argc, num_vars, args, start, types TSRMLS_CC);
+ MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
}
- var_cnt = argc - start;
+ efree(args);
- if (var_cnt != 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;
- }
+ RETURN_BOOL(!rc);
+}
+/* }}} */
+
+/* {{{ mysqli_stmt_bind_result_do_bind */
+#ifndef HAVE_MYSQLND
+/* TODO:
+ do_alloca, free_alloca
+*/
+static int
+mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
+{
+ MYSQL_BIND *bind;
+ int i, ofs;
+ int var_cnt = argc - start;
+ long col_type;
+ ulong rc;
/* prevent leak if variables are already bound */
if (stmt->result.var_cnt) {
@@ -268,7 +304,7 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
convert_to_double_ex(args[i]);
stmt->result.buf[ofs].type = IS_DOUBLE;
stmt->result.buf[ofs].buflen = sizeof(double);
-
+
/* allocate buffer for double */
stmt->result.buf[ofs].val = (char *)emalloc(sizeof(double));
bind[ofs].buffer_type = MYSQL_TYPE_DOUBLE;
@@ -305,7 +341,7 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
break;
case MYSQL_TYPE_LONGLONG:
-#if MYSQL_VERSION_ID > 50002
+#if MYSQL_VERSION_ID > 50002 || defined(HAVE_MYSQLND)
case MYSQL_TYPE_BIT:
#endif
stmt->result.buf[ofs].type = IS_STRING;
@@ -324,8 +360,8 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_TIMESTAMP:
@@ -385,7 +421,6 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
}
/* Don't free stmt->result.is_null because is_null & buf are one block of memory */
efree(stmt->result.buf);
- RETVAL_FALSE;
} else {
stmt->result.var_cnt = var_cnt;
stmt->result.vars = (zval **)safe_emalloc((var_cnt), sizeof(zval), 0);
@@ -394,10 +429,69 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
ZVAL_ADDREF(*args[i]);
stmt->result.vars[ofs] = *args[i];
}
- RETVAL_TRUE;
}
- efree(args);
efree(bind);
+
+ return rc;
+}
+#else
+static int
+mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, unsigned int start TSRMLS_DC)
+{
+ unsigned int i;
+ MYSQLND_RESULT_BIND *params;
+
+ params = emalloc((argc - start) * sizeof(MYSQLND_RESULT_BIND));
+ for (i = 0; i < (argc - start); i++) {
+ params[i].zv = *(args[i + start]);
+ }
+ return mysqlnd_stmt_bind_result(stmt->stmt, params);
+}
+#endif
+/* }}} */
+
+/* {{{ 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;
+ }
+
+ 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");
+ RETURN_FALSE;
+ }
+
+ args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0);
+
+ if (zend_get_parameters_array_ex(argc, args) == FAILURE) {
+ efree(args);
+ WRONG_PARAM_COUNT;
+ }
+
+ rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc, start TSRMLS_CC);
+
+ efree(args);
+
+ RETURN_BOOL(!rc);
}
/* }}} */
@@ -406,9 +500,9 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
PHP_FUNCTION(mysqli_change_user)
{
MY_MYSQL *mysql;
- zval *mysql_link = NULL;
- char *user, *password, *dbname;
- int user_len, password_len, dbname_len;
+ 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(), "Osss", &mysql_link, mysqli_link_class_entry, &user, &user_len, &password, &password_len, &dbname, &dbname_len) == FAILURE) {
@@ -431,8 +525,8 @@ PHP_FUNCTION(mysqli_change_user)
Returns the name of the character set used for this connection */
PHP_FUNCTION(mysqli_character_set_name)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -440,7 +534,7 @@ PHP_FUNCTION(mysqli_character_set_name)
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
- RETURN_STRING((char *) mysql_character_set_name(mysql->mysql), 1);
+ RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1);
}
/* }}} */
@@ -448,8 +542,8 @@ PHP_FUNCTION(mysqli_character_set_name)
Close connection */
PHP_FUNCTION(mysqli_close)
{
- zval *mysql_link;
- MY_MYSQL *mysql;
+ 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;
@@ -457,11 +551,32 @@ PHP_FUNCTION(mysqli_close)
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);
- mysql_close(mysql->mysql);
- mysql->mysql = NULL;
+ if (!mysql->persistent) {
+ mysqli_close(mysql->mysql, MYSQLI_CLOSE_EXPLICIT);
+ mysql->mysql = NULL;
+ } else {
+ zend_rsrc_list_entry *le;
+ if (zend_hash_find(&EG(persistent_list), mysql->hash_key, strlen(mysql->hash_key) + 1, (void **)&le) == SUCCESS) {
+ if (Z_TYPE_P(le) == php_le_pmysqli()) {
+ mysqli_plist_entry *plist = (mysqli_plist_entry *) le->ptr;
+ dtor_func_t pDestructor = plist->used_links.pDestructor;
+
+ plist->used_links.pDestructor = NULL; /* Don't call pDestructor now */
+ zend_hash_index_del(&plist->used_links, mysql->hash_index);
+ plist->used_links.pDestructor = pDestructor; /* Restore the destructor */
+
+ zend_hash_next_index_insert(&plist->free_links, &mysql->mysql, sizeof(MYSQL *), NULL);
+ MyG(num_links)--;
+ MyG(num_active_persistent)--;
+ MyG(num_inactive_persistent)++;
+ }
+ }
+ }
+
php_clear_mysql(mysql);
+
+ MYSQLI_CLEAR_RESOURCE(&mysql_link);
efree(mysql);
- MYSQLI_CLEAR_RESOURCE(&mysql_link);
RETURN_TRUE;
}
/* }}} */
@@ -470,8 +585,8 @@ PHP_FUNCTION(mysqli_close)
Commit outstanding actions and close transaction */
PHP_FUNCTION(mysqli_commit)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -489,8 +604,8 @@ PHP_FUNCTION(mysqli_commit)
PHP_FUNCTION(mysqli_data_seek)
{
MYSQL_RES *result;
- zval *mysql_result;
- long offset;
+ 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;
@@ -498,13 +613,13 @@ PHP_FUNCTION(mysqli_data_seek)
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
- if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) {
+ 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 >= result->row_count) {
- RETURN_FALSE;
+ if (offset < 0 || offset >= mysql_num_rows(result)) {
+ RETURN_FALSE;
}
mysql_data_seek(result, offset);
@@ -512,12 +627,12 @@ PHP_FUNCTION(mysqli_data_seek)
}
/* }}} */
-/* {{{ proto void mysqli_debug(string debug)
+/* {{{ proto void mysqli_debug(string debug) U
*/
PHP_FUNCTION(mysqli_debug)
{
- char *debug;
- int debug_len;
+ char *debug;
+ int debug_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &debug, &debug_len) == FAILURE) {
return;
@@ -528,25 +643,20 @@ PHP_FUNCTION(mysqli_debug)
}
/* }}} */
+
/* {{{ proto bool mysqli_dump_debug_info(object link)
*/
PHP_FUNCTION(mysqli_dump_debug_info)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
- ulong rc;
+ 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);
- rc = mysql_dump_debug_info(mysql->mysql);
-
- if (rc) {
- RETURN_FALSE;
- }
- RETURN_TRUE;
+ RETURN_BOOL(!mysql_dump_debug_info(mysql->mysql))
}
/* }}} */
@@ -554,8 +664,8 @@ PHP_FUNCTION(mysqli_dump_debug_info)
Returns the numerical value of the error message from previous MySQL operation */
PHP_FUNCTION(mysqli_errno)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -569,8 +679,8 @@ PHP_FUNCTION(mysqli_errno)
Returns the text of the error message from previous MySQL operation */
PHP_FUNCTION(mysqli_error)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -584,16 +694,19 @@ PHP_FUNCTION(mysqli_error)
Execute a prepared statement */
PHP_FUNCTION(mysqli_stmt_execute)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
- unsigned int i;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
+#ifndef HAVE_MYSQLND
+ unsigned int i;
+#endif
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);
-
- for (i = 0; i < stmt->param.var_cnt; i++) {
+
+#ifndef HAVE_MYSQLND
+ for (i = 0; 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) {
@@ -604,40 +717,43 @@ PHP_FUNCTION(mysqli_stmt_execute)
break;
case MYSQL_TYPE_DOUBLE:
convert_to_double_ex(&stmt->param.vars[i]);
- stmt->stmt->params[i].buffer = (char*)&Z_LVAL_PP(&stmt->param.vars[i]);
+ stmt->stmt->params[i].buffer = &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 = (char*)&Z_LVAL_PP(&stmt->param.vars[i]);
+ stmt->stmt->params[i].buffer = &Z_LVAL_PP(&stmt->param.vars[i]);
break;
default:
break;
}
- }
+ }
}
}
+#endif
+
if (mysql_stmt_execute(stmt->stmt)) {
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
- RETURN_FALSE;
+ RETVAL_FALSE;
+ } else {
+ RETVAL_TRUE;
}
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
- php_mysqli_report_index(stmt->query, stmt->stmt->mysql->server_status TSRMLS_CC);
+ php_mysqli_report_index(stmt->query, mysqli_stmt_server_status(stmt->stmt) TSRMLS_CC);
}
-
- RETURN_TRUE;
}
/* }}} */
-/* {{{ proto mixed mysqli_stmt_fetch(object stmt)
+#ifndef HAVE_MYSQLND
+/* {{{ void mysqli_stmt_fetch_libmysql
Fetch results from a prepared statement into the bound variables */
-PHP_FUNCTION(mysqli_stmt_fetch)
+void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
- unsigned int i;
- ulong ret;
- unsigned int uval;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
+ unsigned int i;
+ ulong ret;
+ unsigned int uval;
my_ulonglong llval;
@@ -647,8 +763,6 @@ PHP_FUNCTION(mysqli_stmt_fetch)
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);
@@ -661,6 +775,11 @@ PHP_FUNCTION(mysqli_stmt_fetch)
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);
@@ -669,11 +788,11 @@ PHP_FUNCTION(mysqli_stmt_fetch)
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))
+ && (stmt->stmt->fields[i].flags & UNSIGNED_FLAG))
{
/* unsigned int (11) */
uval= *(unsigned int *) stmt->result.buf[i].val;
-
+#if SIZEOF_LONG==4
if (uval > INT_MAX) {
char *tmp, *p;
int j=10;
@@ -681,13 +800,14 @@ PHP_FUNCTION(mysqli_stmt_fetch)
p= &tmp[9];
do {
*p-- = (uval % 10) + 48;
- uval = uval / 10;
+ uval = uval / 10;
} while (--j > 0);
tmp[10]= '\0';
- /* unsigned int > INT_MAX is 10 digis - ALWAYS */
+ /* unsigned int > INT_MAX is 10 digits - ALWAYS */
ZVAL_STRINGL(stmt->result.vars[i], tmp, 10, 0);
break;
}
+#endif
}
if (stmt->stmt->fields[i].flags & UNSIGNED_FLAG) {
ZVAL_LONG(stmt->result.vars[i], *(unsigned int *)stmt->result.buf[i].val);
@@ -702,11 +822,12 @@ PHP_FUNCTION(mysqli_stmt_fetch)
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 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))))
+ (!uns && (( L64(2147483647) < (my_longlong) llval) ||
+ (L64(-2147483648) > (my_longlong) llval))))
{
#endif
char tmp[22];
@@ -719,7 +840,7 @@ PHP_FUNCTION(mysqli_stmt_fetch)
} 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;
@@ -728,19 +849,21 @@ PHP_FUNCTION(mysqli_stmt_fetch)
#endif
else {
#if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002
- if(ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
+ if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) {
/* result was truncated */
- ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->stmt->bind[i].buffer_length, 1);
+ ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val,
+ stmt->stmt->bind[i].buffer_length, 1);
} else {
#else
{
#endif
- ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, stmt->result.buf[i].buflen, 1);
+ ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val,
+ stmt->result.buf[i].buflen, 1);
}
}
break;
default:
- break;
+ break;
}
} else {
ZVAL_NULL(stmt->result.vars[i]);
@@ -770,14 +893,68 @@ PHP_FUNCTION(mysqli_stmt_fetch)
}
}
/* }}} */
+#else
+/* {{{ mixed mysqli_stmt_fetch_mysqlnd */
+void mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAMETERS)
+{
+ MY_STMT *stmt;
+ zval *mysql_stmt;
+ zend_bool fetched_anything;
+
+ 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);
+
+ if (FAIL == mysqlnd_stmt_fetch(stmt->stmt, &fetched_anything)) {
+ RETURN_BOOL(FALSE);
+ } else if (fetched_anything == TRUE) {
+ RETURN_BOOL(TRUE);
+ } else {
+ RETURN_NULL();
+ }
+}
+#endif
+/* }}} */
+
+
+/* {{{ proto mixed mysqli_stmt_fetch(object stmt) U
+ Fetch results from a prepared statement into the bound variables */
+PHP_FUNCTION(mysqli_stmt_fetch)
+{
+#if !defined(HAVE_MYSQLND)
+ mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+#else
+ mysqli_stmt_fetch_mysqlnd(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+#endif
+}
+/* }}} */
+
+/* {{{ php_add_field_properties */
+static void php_add_field_properties(zval *value, MYSQL_FIELD *field TSRMLS_DC)
+{
+ add_property_string(value, "name",(field->name ? field->name : ""), 1);
+ add_property_string(value, "orgname",(field->org_name ? field->org_name : ""), 1);
+ add_property_string(value, "table",(field->table ? field->table : ""), 1);
+ add_property_string(value, "orgtable",(field->org_table ? field->org_table : ""), 1);
+ add_property_string(value, "def",(field->def ? field->def : ""), 1);
+
+ add_property_long(value, "max_length", field->max_length);
+ add_property_long(value, "length", field->length);
+ add_property_long(value, "charsetnr", field->charsetnr);
+ add_property_long(value, "flags", field->flags);
+ add_property_long(value, "type", field->type);
+ add_property_long(value, "decimals", field->decimals);
+}
+/* }}} */
/* {{{ proto mixed mysqli_fetch_field (object result)
Get column information from a result and return as an object */
PHP_FUNCTION(mysqli_fetch_field)
{
- MYSQL_RES *result;
- zval *mysql_result;
- MYSQL_FIELD *field;
+ MYSQL_RES *result;
+ zval *mysql_result;
+ MYSQL_FIELD *field;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
return;
@@ -790,18 +967,7 @@ PHP_FUNCTION(mysqli_fetch_field)
}
object_init(return_value);
-
- add_property_string(return_value, "name",(field->name ? field->name : ""), 1);
- add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1);
- add_property_string(return_value, "table",(field->table ? field->table : ""), 1);
- add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1);
- add_property_string(return_value, "def",(field->def ? field->def : ""), 1);
- add_property_long(return_value, "max_length", field->max_length);
- add_property_long(return_value, "length", field->length);
- add_property_long(return_value, "charsetnr", field->charsetnr);
- add_property_long(return_value, "flags", field->flags);
- add_property_long(return_value, "type", field->type);
- add_property_long(return_value, "decimals", field->decimals);
+ php_add_field_properties(return_value, field TSRMLS_CC);
}
/* }}} */
@@ -810,9 +976,9 @@ PHP_FUNCTION(mysqli_fetch_field)
PHP_FUNCTION(mysqli_fetch_fields)
{
MYSQL_RES *result;
- zval *mysql_result;
+ zval *mysql_result;
MYSQL_FIELD *field;
- zval *obj;
+ zval *obj;
unsigned int i;
@@ -827,22 +993,10 @@ PHP_FUNCTION(mysqli_fetch_fields)
for (i = 0; i < mysql_num_fields(result); i++) {
field = mysql_fetch_field_direct(result, i);
-
MAKE_STD_ZVAL(obj);
object_init(obj);
- add_property_string(obj, "name",(field->name ? field->name : ""), 1);
- add_property_string(obj, "orgname",(field->org_name ? field->org_name : ""), 1);
- add_property_string(obj, "table",(field->table ? field->table : ""), 1);
- add_property_string(obj, "orgtable",(field->org_table ? field->org_table : ""), 1);
- add_property_string(obj, "def",(field->def ? field->def : ""), 1);
- add_property_long(obj, "max_length", field->max_length);
- add_property_long(obj, "length", field->length);
- add_property_long(obj, "charsetnr", field->charsetnr);
- add_property_long(obj, "flags", field->flags);
- add_property_long(obj, "type", field->type);
- add_property_long(obj, "decimals", field->decimals);
-
+ php_add_field_properties(obj, field TSRMLS_CC);
add_index_zval(return_value, i, obj);
}
}
@@ -854,8 +1008,8 @@ PHP_FUNCTION(mysqli_fetch_field_direct)
{
MYSQL_RES *result;
zval *mysql_result;
- MYSQL_FIELD *field;
- long offset;
+ MYSQL_FIELD *field;
+ long offset;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &offset) == FAILURE) {
return;
@@ -873,18 +1027,7 @@ PHP_FUNCTION(mysqli_fetch_field_direct)
}
object_init(return_value);
-
- add_property_string(return_value, "name",(field->name ? field->name : ""), 1);
- add_property_string(return_value, "orgname",(field->org_name ? field->org_name : ""), 1);
- add_property_string(return_value, "table",(field->table ? field->table : ""), 1);
- add_property_string(return_value, "orgtable",(field->org_table ? field->org_table : ""), 1);
- add_property_string(return_value, "def",(field->def ? field->def : ""), 1);
- add_property_long(return_value, "max_length", field->max_length);
- add_property_long(return_value, "length", field->length);
- add_property_long(return_value, "charsetnr", field->charsetnr);
- add_property_long(return_value, "flags", field->flags);
- add_property_long(return_value, "type", field->type);
- add_property_long(return_value, "decimals", field->decimals);
+ php_add_field_properties(return_value, field TSRMLS_CC);
}
/* }}} */
@@ -896,7 +1039,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)
zval *mysql_result;
unsigned int i;
unsigned long *ret;
-
+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
return;
}
@@ -910,7 +1053,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)
array_init(return_value);
for (i = 0; i < mysql_num_fields(result); i++) {
- add_index_long(return_value, i, ret[i]);
+ add_index_long(return_value, i, ret[i]);
}
}
/* }}} */
@@ -919,17 +1062,28 @@ PHP_FUNCTION(mysqli_fetch_lengths)
Get a result row as an enumerated array */
PHP_FUNCTION(mysqli_fetch_row)
{
+#if !defined(HAVE_MYSQLND)
php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_NUM, 0);
+#else
+ MYSQL_RES *result;
+ zval *mysql_result;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
+ mysqlnd_fetch_into(result, MYSQLND_FETCH_NUM, return_value, MYSQLND_MYSQLI);
+#endif
}
/* }}} */
/* {{{ proto int mysqli_field_count(object link)
Fetch the number of fields returned by the last query for the given link
*/
-PHP_FUNCTION(mysqli_field_count)
+PHP_FUNCTION(mysqli_field_count)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -958,7 +1112,7 @@ PHP_FUNCTION(mysqli_field_seek)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid field offset");
RETURN_FALSE;
}
-
+
mysql_field_seek(result, fieldnr);
RETURN_TRUE;
}
@@ -975,7 +1129,7 @@ PHP_FUNCTION(mysqli_field_tell)
return;
}
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
-
+
RETURN_LONG(mysql_field_tell(result));
}
/* }}} */
@@ -992,12 +1146,12 @@ PHP_FUNCTION(mysqli_free_result)
}
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
- mysql_free_result(result);
- MYSQLI_CLEAR_RESOURCE(&mysql_result);
+ mysqli_free_result(result, FALSE);
+ MYSQLI_CLEAR_RESOURCE(&mysql_result);
}
/* }}} */
-/* {{{ proto string mysqli_get_client_info(void)
+/* {{{ proto string mysqli_get_client_info(void)
Get MySQL client info */
PHP_FUNCTION(mysqli_get_client_info)
{
@@ -1005,7 +1159,7 @@ PHP_FUNCTION(mysqli_get_client_info)
}
/* }}} */
-/* {{{ proto int mysqli_get_client_version(void)
+/* {{{ proto int mysqli_get_client_version(void)
Get MySQL client info */
PHP_FUNCTION(mysqli_get_client_version)
{
@@ -1018,7 +1172,7 @@ PHP_FUNCTION(mysqli_get_client_version)
PHP_FUNCTION(mysqli_get_host_info)
{
MY_MYSQL *mysql;
- zval *mysql_link = NULL;
+ zval *mysql_link = NULL;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -1033,24 +1187,23 @@ PHP_FUNCTION(mysqli_get_host_info)
Get MySQL protocol information */
PHP_FUNCTION(mysqli_get_proto_info)
{
- MY_MYSQL *mysql;
- zval *mysql_link = NULL;
+ MY_MYSQL *mysql;
+ zval *mysql_link = NULL;
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_get_proto_info(mysql->mysql));
}
/* }}} */
-/* {{{ proto string mysqli_get_server_info(object link)
+/* {{{ proto string mysqli_get_server_info(object link)
Get MySQL server info */
PHP_FUNCTION(mysqli_get_server_info)
{
MY_MYSQL *mysql;
- zval *mysql_link = NULL;
+ zval *mysql_link = NULL;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -1083,14 +1236,16 @@ PHP_FUNCTION(mysqli_get_server_version)
PHP_FUNCTION(mysqli_info)
{
MY_MYSQL *mysql;
- zval *mysql_link = NULL;
+ zval *mysql_link = NULL;
+ const char *info;
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_STRING((mysql->mysql->info) ? mysql->mysql->info : "", 1);
+ info = mysql_info(mysql->mysql);
+ RETURN_STRING((info) ? (char *)info : "", 1);
}
/* }}} */
@@ -1101,7 +1256,12 @@ PHP_FUNCTION(mysqli_init)
MYSQLI_RESOURCE *mysqli_resource;
MY_MYSQL *mysql = (MY_MYSQL *)ecalloc(1, sizeof(MY_MYSQL));
- if (!(mysql->mysql = mysql_init(NULL))) {
+#if !defined(HAVE_MYSQLND)
+ if (!(mysql->mysql = mysql_init(NULL)))
+#else
+ if (!(mysql->mysql = mysql_init(FALSE)))
+#endif
+ {
efree(mysql);
RETURN_FALSE;
}
@@ -1123,8 +1283,8 @@ PHP_FUNCTION(mysqli_init)
PHP_FUNCTION(mysqli_insert_id)
{
MY_MYSQL *mysql;
- my_ulonglong rc;
- zval *mysql_link;
+ my_ulonglong rc;
+ zval *mysql_link;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -1139,15 +1299,20 @@ PHP_FUNCTION(mysqli_insert_id)
Kill a mysql process on the server */
PHP_FUNCTION(mysqli_kill)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
- long processid;
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ long processid;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
-
+
+ if (processid <= 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "processid should have positive value");
+ RETURN_FALSE;
+ }
+
if (mysql_kill(mysql->mysql, processid)) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
RETURN_FALSE;
@@ -1158,6 +1323,7 @@ PHP_FUNCTION(mysqli_kill)
/* {{{ proto void mysqli_set_local_infile_default(object link)
unsets user defined handler for load local infile command */
+#if !defined(HAVE_MYSQLND)
PHP_FUNCTION(mysqli_set_local_infile_default)
{
MY_MYSQL *mysql;
@@ -1182,7 +1348,7 @@ PHP_FUNCTION(mysqli_set_local_infile_default)
PHP_FUNCTION(mysqli_set_local_infile_handler)
{
MY_MYSQL *mysql;
- zval *mysql_link;
+ zval *mysql_link;
char *callback_name;
zval *callback_func;
@@ -1197,24 +1363,29 @@ PHP_FUNCTION(mysqli_set_local_infile_handler)
if (!zend_is_callable(callback_func, 0, &callback_name)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
efree(callback_name);
- RETURN_FALSE;
+ RETURN_FALSE;
}
efree(callback_name);
/* save callback function */
- ALLOC_ZVAL(mysql->li_read);
- ZVAL_STRING(mysql->li_read, callback_func->value.str.val, 1);
+ if (!mysql->li_read) {
+ MAKE_STD_ZVAL(mysql->li_read);
+ } else {
+ zval_dtor(mysql->li_read);
+ }
+ ZVAL_STRINGL(mysql->li_read, Z_STRVAL_P(callback_func), Z_STRLEN_P(callback_func), 1);
RETURN_TRUE;
}
+#endif
/* }}} */
/* {{{ proto bool mysqli_more_results(object link)
check if there any more query results from a multi query */
PHP_FUNCTION(mysqli_more_results)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -1228,14 +1399,20 @@ PHP_FUNCTION(mysqli_more_results)
/* {{{ proto bool mysqli_next_result(object link)
read next result from multi_query */
PHP_FUNCTION(mysqli_next_result) {
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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_more_results(mysql->mysql)) {
+ php_error_docref(NULL TSRMLS_CC, E_STRICT, "There is no next result set. "
+ "Please, call mysqli_more_results()/mysqli::more_results() to check "
+ "whether to call this function/method");
+ }
+
RETURN_BOOL(!mysql_next_result(mysql->mysql));
}
/* }}} */
@@ -1268,7 +1445,7 @@ PHP_FUNCTION(mysqli_num_rows)
}
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
- if (result->handle && result->handle->status == MYSQL_STATUS_USE_RESULT) {
+ if (mysqli_result_is_unbuffered(result)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT");
RETURN_LONG(0);
}
@@ -1281,12 +1458,12 @@ PHP_FUNCTION(mysqli_num_rows)
Set options */
PHP_FUNCTION(mysqli_options)
{
- MY_MYSQL *mysql;
- zval *mysql_link = NULL;
- zval *mysql_value;
- long mysql_option;
- unsigned int l_value;
- long ret;
+ MY_MYSQL *mysql;
+ zval *mysql_link = NULL;
+ zval *mysql_value;
+ long mysql_option;
+ unsigned int l_value;
+ long ret;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olz", &mysql_link, mysqli_link_class_entry, &mysql_option, &mysql_value) == FAILURE) {
return;
@@ -1311,7 +1488,7 @@ PHP_FUNCTION(mysqli_options)
}
RETURN_BOOL(!ret);
-}
+}
/* }}} */
@@ -1319,8 +1496,8 @@ PHP_FUNCTION(mysqli_options)
Ping a server connection or reconnect if there is no connection */
PHP_FUNCTION(mysqli_ping)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ MY_MYSQL *mysql;
+ zval *mysql_link;
long rc;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
@@ -1339,60 +1516,71 @@ PHP_FUNCTION(mysqli_ping)
PHP_FUNCTION(mysqli_prepare)
{
MY_MYSQL *mysql;
- MY_STMT *stmt;
+ MY_STMT *stmt;
char *query = NULL;
unsigned int query_len;
zval *mysql_link;
- MYSQLI_RESOURCE *mysqli_resource;
+ MYSQLI_RESOURCE *mysqli_resource;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os",&mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
+
+#if !defined(HAVE_MYSQLND)
if (mysql->mysql->status == MYSQL_STATUS_GET_RESULT) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "All data must be fetched before a new statement prepare takes place");
RETURN_FALSE;
}
+#endif
stmt = (MY_STMT *)ecalloc(1,sizeof(MY_STMT));
if ((stmt->stmt = mysql_stmt_init(mysql->mysql))) {
if (mysql_stmt_prepare(stmt->stmt, query, query_len)) {
- char last_error[MYSQL_ERRMSG_SIZE];
- char sqlstate[SQLSTATE_LENGTH+1];
+ /* mysql_stmt_close() clears errors, so we have to store them temporarily */
+#if !defined(HAVE_MYSQLND)
+ char last_error[MYSQL_ERRMSG_SIZE];
+ char sqlstate[SQLSTATE_LENGTH+1];
unsigned int last_errno;
- /* mysql_stmt_close clears errors, so we have to store them temporarily */
last_errno = stmt->stmt->last_errno;
memcpy(last_error, stmt->stmt->last_error, MYSQL_ERRMSG_SIZE);
memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1);
-
- mysql_stmt_close(stmt->stmt);
+#else
+ mysqlnd_error_info error_info = mysql->mysql->error_info;
+#endif
+ mysqli_stmt_close(stmt->stmt, FALSE);
stmt->stmt = NULL;
/* restore error messages */
+#if !defined(HAVE_MYSQLND)
mysql->mysql->net.last_errno = last_errno;
memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE);
memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1);
+#else
+ mysql->mysql->error_info = error_info;
+#endif
}
}
- /* don't joing to the previous if because it won't work if mysql_stmt_prepare_fails */
+
+ /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
+ /* Get performance boost if reporting is switched off */
+ if (stmt->stmt && query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
+ stmt->query = (char *)emalloc(query_len + 1);
+ memcpy(stmt->query, query, query_len);
+ stmt->query[query_len] = '\0';
+ }
+
+ /* don't join to the previous if because it won't work if mysql_stmt_prepare_fails */
if (!stmt->stmt) {
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
efree(stmt);
RETURN_FALSE;
}
-
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)stmt;
- /* don't initialize stmt->query with NULL, we ecalloc()-ed the memory */
- /* Get performance boost if reporting is switched off */
- if (query_len && (MyG(report_mode) & MYSQLI_REPORT_INDEX)) {
- stmt->query = (char *)emalloc(query_len + 1);
- memcpy(stmt->query, query, query_len);
- stmt->query[query_len] = '\0';
- }
/* change status */
mysqli_resource->status = MYSQLI_STATUS_VALID;
@@ -1404,10 +1592,10 @@ PHP_FUNCTION(mysqli_prepare)
Open a connection to a mysql server */
PHP_FUNCTION(mysqli_real_connect)
{
- MY_MYSQL *mysql;
- char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
- unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
- unsigned long port=0, flags=0;
+ MY_MYSQL *mysql;
+ char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
+ unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
+ unsigned long port=0, flags=0;
zval *mysql_link;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &mysql_link, mysqli_link_class_entry,
@@ -1419,37 +1607,38 @@ PHP_FUNCTION(mysqli_real_connect)
if (!socket_len) {
socket = NULL;
}
-
- /* TODO: safe mode handling */
- if (PG(sql_safe_mode)) {
- } else {
- if (!passwd) {
- passwd = MyG(default_pw);
- if (!username){
- username = MyG(default_user);
- if (!hostname) {
- hostname = MyG(default_host);
- }
- }
- }
+ if (!socket) {
+ socket = MyG(default_socket);
}
+ if (!passwd) {
+ passwd = MyG(default_pw);
+ passwd_len = strlen(passwd);
+ }
+ if (!username){
+ username = MyG(default_user);
+ }
+ if (!hostname) {
+ hostname = MyG(default_host);
+ }
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);
/* remove some insecure options */
flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */
- if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
- flags &= ~CLIENT_LOCAL_FILES;
- }
-
- if (!socket) {
- socket = MyG(default_socket);
+ if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
+ flags ^= CLIENT_LOCAL_FILES;
}
- if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,flags) == NULL) {
+#if !defined(HAVE_MYSQLND)
+ if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname ,port, socket ,flags) == NULL)
+#else
+ if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
+ port, socket, flags, MyG(mysqlnd_thd_zval_cache) TSRMLS_CC) == NULL)
+#endif
+ {
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
- php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC,
- "%s", mysql->mysql->net.last_error);
+ php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
+ "%s", mysql_error(mysql->mysql));
/* change status */
MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_INITIALIZED);
@@ -1458,10 +1647,14 @@ PHP_FUNCTION(mysqli_real_connect)
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *)mysql_error(mysql->mysql) TSRMLS_CC);
+#if !defined(HAVE_MYSQLND)
mysql->mysql->reconnect = MyG(reconnect);
/* set our own local_infile handler */
php_set_local_infile_handler_default(mysql);
+#endif
+
+ mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
/* change status */
MYSQLI_SET_STATUS(&mysql_link, MYSQLI_STATUS_VALID);
@@ -1477,7 +1670,7 @@ PHP_FUNCTION(mysqli_real_query)
MY_MYSQL *mysql;
zval *mysql_link;
char *query = NULL;
- unsigned int query_len;
+ unsigned int query_len;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
return;
@@ -1493,7 +1686,7 @@ PHP_FUNCTION(mysqli_real_query)
if (!mysql_field_count(mysql->mysql)) {
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
- php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
+ php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
}
}
@@ -1517,7 +1710,7 @@ PHP_FUNCTION(mysqli_real_escape_string) {
newstr = safe_emalloc(2, escapestr_len, 1);
newstr_len = mysql_real_escape_string(mysql->mysql, newstr, escapestr, escapestr_len);
newstr = erealloc(newstr, newstr_len + 1);
-
+
RETURN_STRINGL(newstr, newstr_len, 0);
}
/* }}} */
@@ -1527,7 +1720,7 @@ PHP_FUNCTION(mysqli_real_escape_string) {
PHP_FUNCTION(mysqli_rollback)
{
MY_MYSQL *mysql;
- zval *mysql_link;
+ zval *mysql_link;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -1546,12 +1739,11 @@ PHP_FUNCTION(mysqli_rollback)
PHP_FUNCTION(mysqli_stmt_send_long_data)
{
MY_STMT *stmt;
- zval *mysql_stmt;
+ zval *mysql_stmt;
char *data;
long param_nr;
int data_len;
-
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, &param_nr, &data, &data_len) == FAILURE) {
return;
}
@@ -1573,8 +1765,8 @@ PHP_FUNCTION(mysqli_stmt_send_long_data)
Return the number of rows affected in the last query for the given link */
PHP_FUNCTION(mysqli_stmt_affected_rows)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
my_ulonglong rc;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
@@ -1590,21 +1782,21 @@ PHP_FUNCTION(mysqli_stmt_affected_rows)
}
/* }}} */
-/* {{{ proto bool mysqli_stmt_close(object stmt)
+/* {{{ proto bool mysqli_stmt_close(object stmt)
Close statement */
PHP_FUNCTION(mysqli_stmt_close)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
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);
- mysql_stmt_close(stmt->stmt);
+ mysqli_stmt_close(stmt->stmt, FALSE);
stmt->stmt = NULL;
- php_clear_stmt_bind(stmt);
+ php_clear_stmt_bind(stmt TSRMLS_CC);
MYSQLI_CLEAR_RESOURCE(&mysql_stmt);
RETURN_TRUE;
}
@@ -1614,9 +1806,9 @@ PHP_FUNCTION(mysqli_stmt_close)
Move internal result pointer */
PHP_FUNCTION(mysqli_stmt_data_seek)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
- long offset;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
+ long offset;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) {
return;
@@ -1636,7 +1828,7 @@ PHP_FUNCTION(mysqli_stmt_data_seek)
Return the number of result columns for the given statement */
PHP_FUNCTION(mysqli_stmt_field_count)
{
- MY_STMT *stmt;
+ MY_STMT *stmt;
zval *mysql_stmt;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
@@ -1652,8 +1844,8 @@ PHP_FUNCTION(mysqli_stmt_field_count)
Free stored result memory for the given statement handle */
PHP_FUNCTION(mysqli_stmt_free_result)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
@@ -1669,9 +1861,9 @@ PHP_FUNCTION(mysqli_stmt_free_result)
Get the ID generated from the previous INSERT operation */
PHP_FUNCTION(mysqli_stmt_insert_id)
{
- MY_STMT *stmt;
- my_ulonglong rc;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ my_ulonglong rc;
+ zval *mysql_stmt;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
@@ -1682,13 +1874,13 @@ PHP_FUNCTION(mysqli_stmt_insert_id)
}
/* }}} */
-/* {{{ proto int mysqli_stmt_param_count(object stmt) {
+/* {{{ proto int mysqli_stmt_param_count(object stmt)
Return the number of parameter for the given statement */
PHP_FUNCTION(mysqli_stmt_param_count)
{
- MY_STMT *stmt;
+ MY_STMT *stmt;
zval *mysql_stmt;
-
+
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
}
@@ -1700,10 +1892,10 @@ PHP_FUNCTION(mysqli_stmt_param_count)
/* {{{ proto bool mysqli_stmt_reset(object stmt)
reset a prepared statement */
-PHP_FUNCTION(mysqli_stmt_reset)
+PHP_FUNCTION(mysqli_stmt_reset)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
@@ -1722,8 +1914,8 @@ PHP_FUNCTION(mysqli_stmt_reset)
Return the number of rows in statements result set */
PHP_FUNCTION(mysqli_stmt_num_rows)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
my_ulonglong rc;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
@@ -1737,27 +1929,25 @@ PHP_FUNCTION(mysqli_stmt_num_rows)
}
/* }}} */
-/* {{{ proto string mysqli_select_db(object link, string dbname)
+/* {{{ proto bool mysqli_select_db(object link, string dbname)
Select a MySQL database */
PHP_FUNCTION(mysqli_select_db)
{
MY_MYSQL *mysql;
- zval *mysql_link;
- char *dbname;
- int dbname_len;
-
+ zval *mysql_link;
+ char *dbname;
+ int dbname_len;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &dbname, &dbname_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
-
- if (!mysql_select_db(mysql->mysql, dbname)) {
- RETURN_TRUE;
+
+ if (mysql_select_db(mysql->mysql, dbname)) {
+ MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
+ RETURN_FALSE;
}
-
- MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
- RETURN_FALSE;
+ RETURN_TRUE;
}
/* }}} */
@@ -1765,8 +1955,8 @@ PHP_FUNCTION(mysqli_select_db)
Returns the SQLSTATE error from previous MySQL operation */
PHP_FUNCTION(mysqli_sqlstate)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -1776,21 +1966,22 @@ PHP_FUNCTION(mysqli_sqlstate)
}
/* }}} */
-/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher])
+/* {{{ proto bool mysqli_ssl_set(object link ,string key ,string cert ,string ca ,string capath ,string cipher]) U
*/
+#if !defined(HAVE_MYSQLND)
PHP_FUNCTION(mysqli_ssl_set)
{
MY_MYSQL *mysql;
- zval *mysql_link;
- char *ssl_parm[5];
+ zval *mysql_link;
+ char *ssl_parm[5];
int ssl_parm_len[5], i;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osssss", &mysql_link, mysqli_link_class_entry, &ssl_parm[0], &ssl_parm_len[0], &ssl_parm[1], &ssl_parm_len[1], &ssl_parm[2], &ssl_parm_len[2], &ssl_parm[3], &ssl_parm_len[3], &ssl_parm[4], &ssl_parm_len[4]) == FAILURE) {
return;
}
- MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_INITIALIZED);
+ MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
- for (i=0; i < 5; i++) {
+ for (i = 0; i < 5; i++) {
if (!ssl_parm_len[i]) {
ssl_parm[i] = NULL;
}
@@ -1800,25 +1991,37 @@ PHP_FUNCTION(mysqli_ssl_set)
RETURN_TRUE;
}
+#endif
/* }}} */
/* {{{ proto mixed mysqli_stat(object link)
Get current system status */
PHP_FUNCTION(mysqli_stat)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ MY_MYSQL *mysql;
+ zval *mysql_link;
char *stat;
+#if defined(HAVE_MYSQLND)
+ uint stat_len;
+#endif
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 ((stat = (char *)mysql_stat(mysql->mysql))) {
+#if !defined(HAVE_MYSQLND)
+ if ((stat = (char *)mysql_stat(mysql->mysql)))
+ {
RETURN_STRING(stat, 1);
+#else
+ if (mysqlnd_stat(mysql->mysql, &stat, &stat_len) == PASS)
+ {
+ RETURN_STRINGL(stat, stat_len, 0);
+#endif
+ } else {
+ RETURN_FALSE;
}
- RETURN_FALSE;
}
/* }}} */
@@ -1828,16 +2031,23 @@ PHP_FUNCTION(mysqli_stat)
PHP_FUNCTION(mysqli_stmt_attr_set)
{
MY_STMT *stmt;
- zval *mysql_stmt;
- ulong mode;
+ zval *mysql_stmt;
+ long mode_in;
+ ulong mode;
ulong attr;
int rc;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &mysql_stmt, "mysqli_stmt", MYSQLI_STATUS_VALID);
+ if (mode_in < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "mode should be non-negative, %ld passed", mode_in);
+ RETURN_FALSE;
+ }
+
+ mode = mode_in;
if ((rc = mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode))) {
RETURN_FALSE;
}
@@ -1850,8 +2060,8 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
PHP_FUNCTION(mysqli_stmt_attr_get)
{
MY_STMT *stmt;
- zval *mysql_stmt;
-#if MYSQL_VERSION_ID > 50099
+ zval *mysql_stmt;
+#if !defined(HAVE_MYSQLND) && MYSQL_VERSION_ID > 50099
my_bool value;
#else
ulong value = 0;
@@ -1876,7 +2086,7 @@ PHP_FUNCTION(mysqli_stmt_attr_get)
PHP_FUNCTION(mysqli_stmt_errno)
{
MY_STMT *stmt;
- zval *mysql_stmt;
+ zval *mysql_stmt;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
@@ -1909,9 +2119,9 @@ PHP_FUNCTION(mysqli_stmt_error)
PHP_FUNCTION(mysqli_stmt_init)
{
MY_MYSQL *mysql;
- MY_STMT *stmt;
+ MY_STMT *stmt;
zval *mysql_link;
- MYSQLI_RESOURCE *mysqli_resource;
+ MYSQLI_RESOURCE *mysqli_resource;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",&mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -1961,9 +2171,9 @@ PHP_FUNCTION(mysqli_stmt_prepare)
return result set from statement */
PHP_FUNCTION(mysqli_stmt_result_metadata)
{
- MY_STMT *stmt;
+ MY_STMT *stmt;
MYSQL_RES *result;
- zval *mysql_stmt;
+ zval *mysql_stmt;
MYSQLI_RESOURCE *mysqli_resource;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
@@ -1979,7 +2189,7 @@ PHP_FUNCTION(mysqli_stmt_result_metadata)
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)result;
mysqli_resource->status = MYSQLI_STATUS_VALID;
- MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
+ MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
}
/* }}} */
@@ -1987,32 +2197,37 @@ PHP_FUNCTION(mysqli_stmt_result_metadata)
*/
PHP_FUNCTION(mysqli_stmt_store_result)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
- int i=0;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
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);
- /*
- If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
- not the maximal length of the type (which is 16MB even for LONGBLOB) but
- the maximal length of the field in the result set. If he/she has quite big
- BLOB/TEXT columns after calling store_result() the memory usage of PHP will
- double - but this is a known problem of the simple MySQL API ;)
- */
- for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
- if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
- stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
- stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB))
- {
- my_bool tmp=1;
- mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
- break;
+#if !defined(HAVE_MYSQLND)
+ {
+ /*
+ If the user wants to store the data and we have BLOBs/TEXTs we try to allocate
+ not the maximal length of the type (which is 16MB even for LONGBLOB) but
+ the maximal length of the field in the result set. If he/she has quite big
+ BLOB/TEXT columns after calling store_result() the memory usage of PHP will
+ double - but this is a known problem of the simple MySQL API ;)
+ */
+ int i = 0;
+
+ for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) {
+ if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB ||
+ stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB ||
+ stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB))
+ {
+ my_bool tmp=1;
+ mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp);
+ break;
+ }
}
}
+#endif
if (mysql_stmt_store_result(stmt->stmt)){
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
@@ -2024,16 +2239,16 @@ PHP_FUNCTION(mysqli_stmt_store_result)
/* {{{ proto string mysqli_stmt_sqlstate(object stmt)
*/
-PHP_FUNCTION(mysqli_stmt_sqlstate)
+PHP_FUNCTION(mysqli_stmt_sqlstate)
{
- MY_STMT *stmt;
- zval *mysql_stmt;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
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);
-
+
RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1);
}
/* }}} */
@@ -2042,9 +2257,9 @@ PHP_FUNCTION(mysqli_stmt_sqlstate)
Buffer result set on client */
PHP_FUNCTION(mysqli_store_result)
{
- MY_MYSQL *mysql;
- MYSQL_RES *result;
- zval *mysql_link;
+ MY_MYSQL *mysql;
+ MYSQL_RES *result;
+ zval *mysql_link;
MYSQLI_RESOURCE *mysqli_resource;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
@@ -2057,22 +2272,23 @@ PHP_FUNCTION(mysqli_store_result)
RETURN_FALSE;
}
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
- php_mysqli_report_index("from previous query", mysql->mysql->server_status TSRMLS_CC);
+ php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)result;
mysqli_resource->status = MYSQLI_STATUS_VALID;
- MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
+ MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
}
/* }}} */
+
/* {{{ proto int mysqli_thread_id(object link)
Return the current thread ID */
PHP_FUNCTION(mysqli_thread_id)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
@@ -2089,17 +2305,16 @@ PHP_FUNCTION(mysqli_thread_safe)
{
RETURN_BOOL(mysql_thread_safe());
}
-
/* }}} */
/* {{{ proto mixed mysqli_use_result(object link)
Directly retrieve query results - do not buffer results on client side */
PHP_FUNCTION(mysqli_use_result)
{
- MY_MYSQL *mysql;
- MYSQL_RES *result;
- zval *mysql_link;
- MYSQLI_RESOURCE *mysqli_resource;
+ MY_MYSQL *mysql;
+ MYSQL_RES *result;
+ zval *mysql_link;
+ MYSQLI_RESOURCE *mysqli_resource;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -2112,12 +2327,12 @@ PHP_FUNCTION(mysqli_use_result)
}
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
- php_mysqli_report_index("from previous query", mysql->mysql->server_status TSRMLS_CC);
+ php_mysqli_report_index("from previous query", mysqli_server_status(mysql->mysql) TSRMLS_CC);
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)result;
mysqli_resource->status = MYSQLI_STATUS_VALID;
- MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
+ MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
}
/* }}} */
@@ -2125,8 +2340,8 @@ PHP_FUNCTION(mysqli_use_result)
Return number of warnings from the last query for the given link */
PHP_FUNCTION(mysqli_warning_count)
{
- MY_MYSQL *mysql;
- zval *mysql_link;
+ 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;
diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c
index 494c2a554b..e8a9f71806 100644
--- a/ext/mysqli/mysqli_driver.c
+++ b/ext/mysqli/mysqli_driver.c
@@ -25,7 +25,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
#include "zend_exceptions.h"
@@ -110,7 +110,7 @@ static int driver_client_version_read(mysqli_object *obj, zval **retval TSRMLS_D
static int driver_client_info_read(mysqli_object *obj, zval **retval TSRMLS_DC)
{
ALLOC_ZVAL(*retval);
- ZVAL_STRING(*retval, MYSQL_SERVER_VERSION, 1);
+ ZVAL_STRING(*retval, (char *)mysql_get_client_info(), 1);
return SUCCESS;
}
/* }}} */
@@ -130,9 +130,17 @@ MAP_PROPERTY_MYG_LONG_READ(driver_report_read, report_mode);
ZEND_FUNCTION(mysqli_driver_construct)
{
+#if G0
+ MYSQLI_RESOURCE *mysqli_resource;
+
+ mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
+ mysqli_resource->ptr = 1;
+ mysqli_resource->status = (ZEND_NUM_ARGS() == 1) ? MYSQLI_STATUS_INITIALIZED : MYSQLI_STATUS_VALID;
+ ((mysqli_object *) zend_object_store_get_object(getThis() TSRMLS_CC))->ptr = mysqli_resource;
+#endif
}
-mysqli_property_entry mysqli_driver_property_entries[] = {
+const mysqli_property_entry mysqli_driver_property_entries[] = {
{"client_info", driver_client_info_read, NULL},
{"client_version", driver_client_version_read, NULL},
{"driver_version", driver_driver_version_read, NULL},
@@ -145,8 +153,10 @@ mysqli_property_entry mysqli_driver_property_entries[] = {
/* {{{ mysqli_driver_methods[]
*/
const zend_function_entry mysqli_driver_methods[] = {
+#if defined(HAVE_EMBEDDED_MYSQLI)
PHP_FALIAS(embedded_server_start, mysqli_embedded_server_start, NULL)
PHP_FALIAS(embedded_server_end, mysqli_embedded_server_end, NULL)
+#endif
{NULL, NULL, NULL}
};
/* }}} */
diff --git a/ext/mysqli/mysqli_embedded.c b/ext/mysqli/mysqli_embedded.c
index 12affc87c2..328025af21 100644
--- a/ext/mysqli/mysqli_embedded.c
+++ b/ext/mysqli/mysqli_embedded.c
@@ -25,7 +25,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
/* {{{ proto bool mysqli_embedded_server_start(bool start, array arguments, array groups)
initialize and start embedded server */
diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c
index b6b1d8903e..7b8a1d63e1 100644
--- a/ext/mysqli/mysqli_exception.c
+++ b/ext/mysqli/mysqli_exception.c
@@ -25,7 +25,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
#include "zend_exceptions.h"
/* {{{ mysqli_exception_methods[]
diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c
index f82d31c405..623042e576 100644
--- a/ext/mysqli/mysqli_fe.c
+++ b/ext/mysqli/mysqli_fe.c
@@ -27,7 +27,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
static
@@ -61,14 +61,24 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_connect_errno, NULL)
PHP_FE(mysqli_connect_error, NULL)
PHP_FE(mysqli_data_seek, NULL)
+ PHP_FE(mysqli_dump_debug_info, NULL)
PHP_FE(mysqli_debug, NULL)
+#if !defined(HAVE_MYSQLND)
PHP_FE(mysqli_disable_reads_from_master, NULL)
PHP_FE(mysqli_disable_rpl_parse, NULL)
- PHP_FE(mysqli_dump_debug_info, NULL)
PHP_FE(mysqli_enable_reads_from_master, NULL)
PHP_FE(mysqli_enable_rpl_parse, NULL)
+ PHP_FE(mysqli_send_query, NULL)
+ PHP_FE(mysqli_slave_query, NULL)
+ PHP_FE(mysqli_master_query, NULL)
+ PHP_FE(mysqli_rpl_parse_enabled, NULL)
+ PHP_FE(mysqli_rpl_probe, NULL)
+ PHP_FE(mysqli_rpl_query_type, NULL)
+#endif
+#if defined(HAVE_EMBEDDED_MYSQLI)
PHP_FE(mysqli_embedded_server_end, NULL)
PHP_FE(mysqli_embedded_server_start, NULL)
+#endif
PHP_FE(mysqli_errno, NULL)
PHP_FE(mysqli_error, NULL)
PHP_FE(mysqli_stmt_execute, NULL)
@@ -77,14 +87,22 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_fetch_fields, NULL)
PHP_FE(mysqli_fetch_field_direct, NULL)
PHP_FE(mysqli_fetch_lengths, NULL)
+#ifdef HAVE_MYSQLND
+ PHP_FE(mysqli_fetch_all, NULL)
+#endif
PHP_FE(mysqli_fetch_array, NULL)
PHP_FE(mysqli_fetch_assoc, NULL)
- PHP_FE(mysqli_fetch_object, NULL)
+ PHP_FE(mysqli_fetch_object, NULL)
PHP_FE(mysqli_fetch_row, NULL)
PHP_FE(mysqli_field_count, NULL)
PHP_FE(mysqli_field_seek, NULL)
PHP_FE(mysqli_field_tell, NULL)
PHP_FE(mysqli_free_result, NULL)
+#if defined(HAVE_MYSQLND)
+ PHP_FE(mysqli_get_cache_stats, NULL)
+ PHP_FE(mysqli_get_connection_stats, NULL)
+ PHP_FE(mysqli_get_client_stats, NULL)
+#endif
#ifdef HAVE_MYSQLI_GET_CHARSET
PHP_FE(mysqli_get_charset, NULL)
#endif
@@ -99,9 +117,10 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_info, NULL)
PHP_FE(mysqli_insert_id, NULL)
PHP_FE(mysqli_kill, NULL)
+#if !defined(HAVE_MYSQLND)
PHP_FE(mysqli_set_local_infile_default, NULL)
PHP_FE(mysqli_set_local_infile_handler, NULL)
- PHP_FE(mysqli_master_query, NULL)
+#endif
PHP_FE(mysqli_more_results, NULL)
PHP_FE(mysqli_multi_query, NULL)
PHP_FE(mysqli_next_result, NULL)
@@ -116,9 +135,6 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_real_escape_string, NULL)
PHP_FE(mysqli_real_query, NULL)
PHP_FE(mysqli_rollback, NULL)
- PHP_FE(mysqli_rpl_parse_enabled, NULL)
- PHP_FE(mysqli_rpl_probe, NULL)
- PHP_FE(mysqli_rpl_query_type, NULL)
PHP_FE(mysqli_select_db, NULL)
#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FE(mysqli_set_charset, NULL)
@@ -134,14 +150,17 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_stmt_bind_result, second_arg_force_by_ref_rest)
PHP_FE(mysqli_stmt_fetch, NULL)
PHP_FE(mysqli_stmt_free_result, NULL)
+#if defined(HAVE_MYSQLND)
+ PHP_FE(mysqli_stmt_get_result, NULL)
+#endif
PHP_FE(mysqli_stmt_get_warnings, NULL)
PHP_FE(mysqli_stmt_insert_id, NULL)
PHP_FE(mysqli_stmt_reset, NULL)
PHP_FE(mysqli_stmt_param_count, NULL)
- PHP_FE(mysqli_send_query, NULL)
- PHP_FE(mysqli_slave_query, NULL)
PHP_FE(mysqli_sqlstate, NULL)
+#if !defined(HAVE_MYSQLND)
PHP_FE(mysqli_ssl_set, NULL)
+#endif
PHP_FE(mysqli_stat, NULL)
PHP_FE(mysqli_stmt_affected_rows, NULL)
PHP_FE(mysqli_stmt_close, NULL)
@@ -150,8 +169,8 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_stmt_error, NULL)
PHP_FE(mysqli_stmt_num_rows, NULL)
PHP_FE(mysqli_stmt_sqlstate, NULL)
- PHP_FE(mysqli_store_result, NULL)
PHP_FE(mysqli_stmt_store_result, NULL)
+ PHP_FE(mysqli_store_result, NULL)
PHP_FE(mysqli_thread_id, NULL)
PHP_FE(mysqli_thread_safe, NULL)
PHP_FE(mysqli_use_result, NULL)
@@ -184,23 +203,34 @@ const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(close,mysqli_close,NULL)
PHP_FALIAS(commit,mysqli_commit,NULL)
PHP_FALIAS(connect,mysqli_connect,NULL)
+ PHP_FALIAS(dump_debug_info,mysqli_dump_debug_info,NULL)
PHP_FALIAS(debug,mysqli_debug,NULL)
+#if !defined(HAVE_MYSQLND)
PHP_FALIAS(disable_reads_from_master,mysqli_disable_reads_from_master,NULL)
PHP_FALIAS(disable_rpl_parse,mysqli_disable_rpl_parse,NULL)
- PHP_FALIAS(dump_debug_info,mysqli_dump_debug_info,NULL)
PHP_FALIAS(enable_reads_from_master,mysqli_enable_reads_from_master,NULL)
PHP_FALIAS(enable_rpl_parse,mysqli_enable_rpl_parse,NULL)
+ PHP_FALIAS(rpl_parse_enabled,mysqli_rpl_parse_enabled,NULL)
+ PHP_FALIAS(rpl_probe,mysqli_rpl_probe,NULL)
+ PHP_FALIAS(rpl_query_type,mysqli_rpl_query_type,NULL)
+ PHP_FALIAS(master_query,mysqli_master_query,NULL)
+ PHP_FALIAS(slave_query,mysqli_slave_query,NULL)
+#endif
#ifdef HAVE_MYSQLI_GET_CHARSET
PHP_FALIAS(get_charset,mysqli_get_charset,NULL)
#endif
PHP_FALIAS(get_client_info,mysqli_get_client_info,NULL)
+#if defined(HAVE_MYSQLND)
+ PHP_FALIAS(get_connection_stats,mysqli_get_connection_stats,NULL)
+#endif
PHP_FALIAS(get_server_info,mysqli_get_server_info,NULL)
PHP_FALIAS(get_warnings, mysqli_get_warnings, NULL)
PHP_FALIAS(init,mysqli_init,NULL)
PHP_FALIAS(kill,mysqli_kill,NULL)
+#if !defined(HAVE_MYSQLND)
PHP_FALIAS(set_local_infile_default,mysqli_set_local_infile_default,NULL)
PHP_FALIAS(set_local_infile_handler,mysqli_set_local_infile_handler,NULL)
- PHP_FALIAS(master_query,mysqli_master_query,NULL)
+#endif
PHP_FALIAS(multi_query,mysqli_multi_query,NULL)
PHP_FALIAS(mysqli,mysqli_connect,NULL)
PHP_FALIAS(more_results,mysqli_more_results, NULL)
@@ -214,16 +244,14 @@ const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(escape_string, mysqli_real_escape_string,NULL)
PHP_FALIAS(real_query,mysqli_real_query,NULL)
PHP_FALIAS(rollback,mysqli_rollback,NULL)
- PHP_FALIAS(rpl_parse_enabled,mysqli_rpl_parse_enabled,NULL)
- PHP_FALIAS(rpl_probe,mysqli_rpl_probe,NULL)
- PHP_FALIAS(rpl_query_type,mysqli_rpl_query_type,NULL)
PHP_FALIAS(select_db,mysqli_select_db,NULL)
#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FALIAS(set_charset,mysqli_set_charset,NULL)
#endif
PHP_FALIAS(set_opt, mysqli_options,NULL)
- PHP_FALIAS(slave_query,mysqli_slave_query,NULL)
+#if !defined(HAVE_MYSQLND)
PHP_FALIAS(ssl_set,mysqli_ssl_set,NULL)
+#endif
PHP_FALIAS(stat,mysqli_stat,NULL)
PHP_FALIAS(stmt_init,mysqli_stmt_init, NULL)
PHP_FALIAS(store_result,mysqli_store_result,NULL)
@@ -238,18 +266,20 @@ const zend_function_entry mysqli_link_methods[] = {
* Every user visible function must have an entry in mysqli_result_functions[].
*/
const zend_function_entry mysqli_result_methods[] = {
- PHP_FALIAS(mysqli_result, mysqli_result_construct, NULL)
+ PHP_FALIAS(__construct, mysqli_result_construct, NULL)
PHP_FALIAS(close,mysqli_free_result,NULL)
PHP_FALIAS(free,mysqli_free_result,NULL)
PHP_FALIAS(data_seek,mysqli_data_seek,NULL)
PHP_FALIAS(fetch_field,mysqli_fetch_field,NULL)
PHP_FALIAS(fetch_fields,mysqli_fetch_fields,NULL)
PHP_FALIAS(fetch_field_direct,mysqli_fetch_field_direct,NULL)
+#if defined(HAVE_MYSQLND)
+ PHP_FALIAS(fetch_all,mysqli_fetch_all,NULL)
+#endif
PHP_FALIAS(fetch_array,mysqli_fetch_array,NULL)
PHP_FALIAS(fetch_assoc,mysqli_fetch_assoc,NULL)
PHP_FALIAS(fetch_object,mysqli_fetch_object,NULL)
PHP_FALIAS(fetch_row,mysqli_fetch_row,NULL)
- PHP_FALIAS(field_count,mysqli_field_count,NULL)
PHP_FALIAS(field_seek,mysqli_field_seek,NULL)
PHP_FALIAS(free_result,mysqli_free_result,NULL)
{NULL, NULL, NULL}
@@ -261,7 +291,7 @@ const zend_function_entry mysqli_result_methods[] = {
* Every user visible function must have an entry in mysqli_stmt_functions[].
*/
const zend_function_entry mysqli_stmt_methods[] = {
- PHP_FALIAS(mysqli_stmt, mysqli_stmt_construct, NULL)
+ PHP_FALIAS(__construct, mysqli_stmt_construct, NULL)
PHP_FALIAS(attr_get,mysqli_stmt_attr_get,NULL)
PHP_FALIAS(attr_set,mysqli_stmt_attr_set,NULL)
PHP_FALIAS(bind_param,mysqli_stmt_bind_param,second_arg_force_by_ref_rest)
@@ -279,6 +309,9 @@ const zend_function_entry mysqli_stmt_methods[] = {
PHP_FALIAS(reset,mysqli_stmt_reset,NULL)
PHP_FALIAS(prepare,mysqli_stmt_prepare, NULL)
PHP_FALIAS(store_result,mysqli_stmt_store_result,NULL)
+#if defined(HAVE_MYSQLND)
+ PHP_FALIAS(get_result,mysqli_stmt_get_result,NULL)
+#endif
{NULL, NULL, NULL}
};
/* }}} */
diff --git a/ext/mysqli/mysqli_libmysql.h b/ext/mysqli/mysqli_libmysql.h
new file mode 100644
index 0000000000..1ea1fc3bf4
--- /dev/null
+++ b/ext/mysqli/mysqli_libmysql.h
@@ -0,0 +1,36 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 6 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2007 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Georg Richter <georg@mysql.com> |
+ | Andrey Hristov <andrey@mysql.com> |
+ | Ulf Wendel <uwendel@mysql.com> |
+ +----------------------------------------------------------------------+
+
+*/
+
+/* These are unused */
+#define MYSQLI_CLOSE_EXPLICIT
+#define MYSQLI_CLOSE_IMPLICIT
+#define MYSQLI_CLOSE_DISCONNECTED
+#define MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE 200
+#define MYSQLND_OPT_INT_AND_YEAR_AS_INT 201
+
+#define mysqli_result_is_unbuffered(r) ((r)->handle && (r)->handle->status == MYSQL_STATUS_USE_RESULT)
+#define mysqli_server_status(c) (c)->server_status
+#define mysqli_stmt_warning_count(s) mysql_warning_count((s)->mysql)
+#define mysqli_stmt_server_status(s) (s)->mysql->server_status
+#define mysqli_stmt_get_connection(s) (s)->mysql
+#define mysqli_close(c, is_forced) mysql_close((c))
+#define mysqli_stmt_close(c, implicit) mysql_stmt_close((c))
+#define mysqli_free_result(r, is_forced) mysql_free_result((r))
diff --git a/ext/mysqli/mysqli_mysqlnd.h b/ext/mysqli/mysqli_mysqlnd.h
new file mode 100644
index 0000000000..27032f15c8
--- /dev/null
+++ b/ext/mysqli/mysqli_mysqlnd.h
@@ -0,0 +1,41 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 2006-2007 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Georg Richter <georg@mysql.com> |
+ | Andrey Hristov <andrey@mysql.com> |
+ | Ulf Wendel <uwendel@mysql.com> |
+ +----------------------------------------------------------------------+
+
+*/
+
+#ifndef MYSQLI_MYSQLND_H
+#define MYSQLI_MYSQLND_H
+
+#include "ext/mysqlnd/mysqlnd_libmysql_compat.h"
+
+/* Here comes non-libmysql API to have less ifdefs in mysqli*/
+#define MYSQLI_CLOSE_EXPLICIT MYSQLND_CLOSE_EXPLICIT
+#define MYSQLI_CLOSE_IMPLICIT MYSQLND_CLOSE_IMPLICIT
+#define MYSQLI_CLOSE_DISCONNECTED MYSQLND_CLOSE_DISCONNECTED
+
+#define mysqli_result_is_unbuffered(r) ((r)->unbuf)
+#define mysqli_server_status(c) (c)->upsert_status.server_status
+#define mysqli_stmt_warning_count(s) mysqlnd_stmt_warning_count((s))
+#define mysqli_stmt_server_status(s) (s)->upsert_status.server_status
+#define mysqli_stmt_get_connection(s) (s)->conn
+#define mysqli_close(c, how) mysqlnd_close((c), (how))
+#define mysqli_stmt_close(c, implicit) mysqlnd_stmt_close((c), (implicit))
+#define mysqli_free_result(r, implicit) mysqlnd_free_result((r), (implicit))
+
+#endif
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index 2f9ba5325b..918594ad76 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -12,7 +12,9 @@
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: Georg Richter <georg@php.net> |
+ | Authors: Georg Richter <georg@php.net> |
+ | Andrey Hristov <andrey@php.net> |
+ | Ulf Wendel <uw@php.net> |
+----------------------------------------------------------------------+
$Id$
@@ -27,46 +29,54 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
+
+#define SAFE_STR(a) ((a)?a:"")
+
/* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])
Open a connection to a mysql server */
PHP_FUNCTION(mysqli_connect)
{
- MY_MYSQL *mysql = NULL;
- MYSQLI_RESOURCE *mysqli_resource = NULL;
- zval *object = getThis();
- char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
- unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
- long port=0;
+ MY_MYSQL *mysql = NULL;
+ MYSQLI_RESOURCE *mysqli_resource = NULL;
+ zval *object = getThis();
+ char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
+ unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
+ zend_bool persistent = FALSE;
+ long port = 0;
+ uint hash_len;
+ char *hash_key = NULL;
+ zend_bool new_connection = FALSE;
+ zend_rsrc_list_entry *le;
+ mysqli_plist_entry *plist = NULL;
if (getThis() && !ZEND_NUM_ARGS()) {
RETURN_NULL();
}
+ hostname = username = dbname = passwd = socket = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len,
&passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
return;
}
- if (!socket_len) {
- socket = NULL;
+ if (!socket_len || !socket) {
+ socket = MyG(default_socket);
}
-
- /* TODO: safe mode handling */
- if (PG(sql_safe_mode)){
- } else {
- if (!passwd) {
- passwd = MyG(default_pw);
- if (!username){
- username = MyG(default_user);
- if (!hostname) {
- hostname = MyG(default_host);
- }
- }
- }
+
+ if (!passwd) {
+ passwd = MyG(default_pw);
+ passwd_len = strlen(SAFE_STR(passwd));
+ }
+ if (!username){
+ username = MyG(default_user);
+ }
+ if (!hostname || !hostname_len) {
+ hostname = MyG(default_host);
}
+
if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
mysqli_resource = ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr;
if (mysqli_resource && mysqli_resource->ptr &&
@@ -75,7 +85,7 @@ PHP_FUNCTION(mysqli_connect)
mysql = (MY_MYSQL*)mysqli_resource->ptr;
php_clear_mysql(mysql);
if (mysql->mysql) {
- mysql_close(mysql->mysql);
+ mysqli_close(mysql->mysql, MYSQLI_CLOSE_EXPLICIT);
mysql->mysql = NULL;
}
}
@@ -84,61 +94,194 @@ PHP_FUNCTION(mysqli_connect)
mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL));
}
+ if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) {
+ hostname += 2;
+ if (!MyG(allow_persistent)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Persistent connections are disabled. Downgrading to normal");
+ } else {
+ mysql->persistent = persistent = TRUE;
+
+ if (!strlen(hostname)) {
+ hostname = MyG(default_host);
+ }
+
+ hash_len = spprintf(&hash_key, 0, "mysqli_%s%ld%s%s%s", SAFE_STR(hostname),
+ port, SAFE_STR(username), SAFE_STR(dbname),
+ SAFE_STR(passwd));
+
+ /* check if we can reuse exisiting connection ... */
+ if (zend_hash_find(&EG(persistent_list), hash_key, hash_len + 1, (void **)&le) == SUCCESS) {
+ if (Z_TYPE_P(le) == php_le_pmysqli()) {
+ plist = (mysqli_plist_entry *) le->ptr;
+
+ do {
+ if (zend_hash_num_elements(&plist->free_links)) {
+ HashPosition pos;
+ MYSQL **free_mysql;
+ ulong idx;
+ dtor_func_t pDestructor = plist->free_links.pDestructor;
+
+ zend_hash_internal_pointer_reset_ex(&plist->free_links, &pos);
+ if (SUCCESS != zend_hash_get_current_data_ex(&plist->free_links,
+ (void **)&free_mysql, &pos)) {
+ break;
+ }
+ if (HASH_KEY_IS_LONG != zend_hash_get_current_key_ex(&plist->free_links, NULL,
+ NULL, &idx, FALSE, &pos)) {
+ break;
+ }
+ plist->free_links.pDestructor = NULL; /* Don't call pDestructor now */
+ if (SUCCESS != zend_hash_index_del(&plist->free_links, idx)) {
+ plist->used_links.pDestructor = pDestructor; /* Restore the destructor */
+ break;
+ }
+ plist->free_links.pDestructor = pDestructor; /* Restore the destructor */
+ mysql->mysql = *free_mysql;
+
+ MyG(num_inactive_persistent)--;
+ MyG(num_active_persistent)++;
+ /* reset variables */
+ /* todo: option for ping or change_user */
+#if G0
+ if (!mysql_change_user(mysql->mysql, username, passwd, dbname)) {
+#else
+ if (!mysql_ping(mysql->mysql)) {
+#endif
+#ifdef HAVE_MYSQLND
+ mysqlnd_restart_psession(mysql->mysql);
+#endif
+ idx = zend_hash_next_free_element(&plist->used_links);
+ if (SUCCESS != zend_hash_next_index_insert(&plist->used_links, &free_mysql,
+ sizeof(MYSQL *), NULL)) {
+ php_mysqli_dtor_p_elements(free_mysql);
+ MyG(num_links)--;
+ break;
+ }
+ mysql->hash_index = idx;
+ mysql->hash_key = hash_key;
+ goto end;
+ }
+ }
+ } while (0);
+ }
+ } else {
+ zend_rsrc_list_entry le;
+ le.type = php_le_pmysqli();
+ le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
+
+ zend_hash_init(&plist->free_links, MAX(2, MyG(max_persistent)), NULL, php_mysqli_dtor_p_elements, 1);
+ zend_hash_init(&plist->used_links, MAX(2, MyG(max_persistent)), NULL, php_mysqli_dtor_p_elements, 1);
+ zend_hash_update(&EG(persistent_list), hash_key, hash_len + 1, (void *)&le, sizeof(le), NULL);
+ }
+ }
+ }
+
+ if (MyG(max_links) != -1 && MyG(num_links) >= MyG(max_links)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MyG(num_links));
+ goto err;
+ }
+ if (persistent && MyG(max_persistent) != -1 &&
+ (MyG(num_active_persistent) + MyG(num_inactive_persistent))>= MyG(max_persistent))
+ {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)",
+ MyG(num_active_persistent) + MyG(num_inactive_persistent));
+ goto err;
+ }
+
+#if !defined(HAVE_MYSQLND)
if (!(mysql->mysql = mysql_init(NULL))) {
- efree(mysql);
- RETURN_FALSE;
+#else
+ if (!(mysql->mysql = mysqlnd_init(persistent))) {
+#endif
+ goto err;
}
+ new_connection = TRUE;
#ifdef HAVE_EMBEDDED_MYSQLI
- if (strcmp(hostname, ":embedded")) {
+ if (hostname_len) {
unsigned int external=1;
mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external);
} else {
- hostname[0] = '\0';
mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
}
#endif
- if (!socket) {
- socket = MyG(default_socket);
- }
-
- if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,CLIENT_MULTI_RESULTS) == NULL) {
+#if !defined(HAVE_MYSQLND)
+ if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, CLIENT_MULTI_RESULTS) == NULL)
+#else
+ if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
+ port, socket, CLIENT_MULTI_RESULTS, MyG(mysqlnd_thd_zval_cache) TSRMLS_CC) == NULL)
+#endif
+ {
/* Save error messages */
-
- php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC,
- "%s", mysql->mysql->net.last_error);
-
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
+ php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
+ "%s", mysql_error(mysql->mysql));
/* free mysql structure */
- mysql_close(mysql->mysql);
- efree(mysql);
- RETURN_FALSE;
+ mysqli_close(mysql->mysql, MYSQLI_CLOSE_DISCONNECTED);
+ goto err;
}
/* clear error */
php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
+#if !defined(HAVE_MYSQLND)
mysql->mysql->reconnect = MyG(reconnect);
/* set our own local_infile handler */
php_set_local_infile_handler_default(mysql);
+#endif
+
+ mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
+end:
if (!mysqli_resource) {
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = (void *)mysql;
}
mysqli_resource->status = MYSQLI_STATUS_VALID;
+ /* store persistent connection */
+ if (persistent && new_connection) {
+ /* save persistent connection */
+ ulong hash_index = zend_hash_next_free_element(&plist->used_links);
+ if (SUCCESS != zend_hash_next_index_insert(&plist->used_links, &mysql->mysql,
+ sizeof(MYSQL *), NULL)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't store persistent connection");
+ } else {
+ mysql->hash_index = hash_index;
+ }
+ MyG(num_active_persistent)++;
+ }
+
+ mysql->hash_key = hash_key;
+ MyG(num_links)++;
+
+#if !defined(HAVE_MYSQLND)
+ mysql->multi_query = 0;
+#else
+ mysql->multi_query = 1;
+#endif
+
+
if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
} else {
((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr = mysqli_resource;
}
+ return;
+
+err:
+ efree(mysql);
+ if (persistent) {
+ efree(hash_key);
+ }
+ RETVAL_FALSE;
}
/* }}} */
+
/* {{{ proto int mysqli_connect_errno(void)
Returns the numerical value of the error message from last connect command */
PHP_FUNCTION(mysqli_connect_errno)
@@ -159,11 +302,30 @@ PHP_FUNCTION(mysqli_connect_error)
}
/* }}} */
+
/* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype])
Fetch a result row as an associative array, a numeric array, or both */
PHP_FUNCTION(mysqli_fetch_array)
{
+#if !defined(HAVE_MYSQLND)
php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
+#else
+ MYSQL_RES *result;
+ zval *mysql_result;
+ long mode = MYSQLND_FETCH_BOTH;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
+
+ if (mode < MYSQLI_ASSOC || mode > MYSQLI_BOTH) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH");
+ RETURN_FALSE;
+ }
+
+ mysqlnd_fetch_into(result, mode, return_value, MYSQLND_MYSQLI);
+#endif
}
/* }}} */
@@ -171,20 +333,102 @@ PHP_FUNCTION(mysqli_fetch_array)
Fetch a result row as an associative array */
PHP_FUNCTION(mysqli_fetch_assoc)
{
+#if !defined(HAVE_MYSQLND)
php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
+#else
+ MYSQL_RES *result;
+ zval *mysql_result;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_result, mysqli_result_class_entry) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
+ mysqlnd_fetch_into(result, MYSQLND_FETCH_ASSOC, return_value, MYSQLND_MYSQLI);
+
+#endif
}
/* }}} */
+
+/* {{{ proto mixed mysqli_fetch_all (object result [,int resulttype])
+ Fetches all result rows as an associative array, a numeric array, or both */
+#if defined(HAVE_MYSQLND)
+PHP_FUNCTION(mysqli_fetch_all)
+{
+ MYSQL_RES *result;
+ zval *mysql_result;
+ long mode = MYSQLND_FETCH_NUM;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
+
+ if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, "
+ "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH");
+ RETURN_FALSE;
+ }
+
+ mysqlnd_fetch_all(result, mode, return_value);
+}
+/* }}} */
+
+
+/* {{{ proto array mysqli_cache_stats(void) U
+ Returns statistics about the zval cache */
+PHP_FUNCTION(mysqli_get_cache_stats)
+{
+ if (ZEND_NUM_ARGS()) {
+ WRONG_PARAM_COUNT;
+ }
+ mysqlnd_palloc_stats(mysqli_mysqlnd_zval_cache, return_value);
+}
+/* }}} */
+
+
+/* {{{ proto array mysqli_get_client_stats(void)
+ Returns statistics about the zval cache */
+PHP_FUNCTION(mysqli_get_client_stats)
+{
+ if (ZEND_NUM_ARGS()) {
+ WRONG_PARAM_COUNT;
+ }
+ mysqlnd_get_client_stats(return_value);
+}
+/* }}} */
+
+
+/* {{{ proto array mysqli_get_connection_stats(void)
+ Returns statistics about the zval cache */
+PHP_FUNCTION(mysqli_get_connection_stats)
+{
+ 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);
+
+ mysqlnd_get_connection_stats(mysql->mysql, return_value);
+}
+#endif
+/* }}} */
+
+
/* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
Fetch a result row as an object */
PHP_FUNCTION(mysqli_fetch_object)
{
php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
+/* todo: mysqlnd support */
}
/* }}} */
/* {{{ proto bool mysqli_multi_query(object link, string query)
- Binary-safe version of mysql_query() */
+ allows to execute multiple queries */
PHP_FUNCTION(mysqli_multi_query)
{
MY_MYSQL *mysql;
@@ -199,25 +443,30 @@ PHP_FUNCTION(mysqli_multi_query)
MYSQLI_ENABLE_MQ;
if (mysql_real_query(mysql->mysql, query, query_len)) {
+#ifndef HAVE_MYSQLND
char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
unsigned int s_errno;
- MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
-
/* we have to save error information, cause
MYSQLI_DISABLE_MQ will reset error information */
strcpy(s_error, mysql_error(mysql->mysql));
strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
s_errno = mysql_errno(mysql->mysql);
-
+#else
+ mysqlnd_error_info error_info = mysql->mysql->error_info;
+#endif
+ MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
MYSQLI_DISABLE_MQ;
+#ifndef HAVE_MYSQLND
/* restore error information */
strcpy(mysql->mysql->net.last_error, s_error);
strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
mysql->mysql->net.last_errno = s_errno;
-
+#else
+ mysql->mysql->error_info = error_info;
+#endif
RETURN_FALSE;
- }
+ }
RETURN_TRUE;
}
/* }}} */
@@ -258,7 +507,7 @@ PHP_FUNCTION(mysqli_query)
if (!mysql_field_count(mysql->mysql)) {
/* no result set - not a SELECT */
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
- php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
+ php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
}
RETURN_TRUE;
}
@@ -266,13 +515,13 @@ PHP_FUNCTION(mysqli_query)
result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql->mysql) : mysql_store_result(mysql->mysql);
if (!result) {
- php_mysqli_throw_sql_exception(mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC,
- "%s", mysql->mysql->net.last_error);
+ php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
+ "%s", mysql_error(mysql->mysql));
RETURN_FALSE;
}
if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
- php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
+ php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
@@ -282,6 +531,36 @@ PHP_FUNCTION(mysqli_query)
}
/* }}} */
+
+#if defined(HAVE_MYSQLND)
+/* {{{ proto object mysqli_stmt_get_result(object link) U
+ Buffer result set on client */
+PHP_FUNCTION(mysqli_stmt_get_result)
+{
+ MYSQL_RES *result;
+ MYSQLI_RESOURCE *mysqli_resource;
+ MY_STMT *stmt;
+ zval *mysql_stmt;
+
+ 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);
+
+ if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) {
+ MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
+ RETURN_FALSE;
+ }
+
+ mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
+ mysqli_resource->ptr = (void *)result;
+ mysqli_resource->status = MYSQLI_STATUS_VALID;
+ MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
+}
+/* }}} */
+#endif
+
+
/* {{{ proto object mysqli_get_warnings(object link) */
PHP_FUNCTION(mysqli_get_warnings)
{
@@ -296,12 +575,13 @@ PHP_FUNCTION(mysqli_get_warnings)
MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
if (mysql_warning_count(mysql->mysql)) {
- w = php_get_warnings(mysql->mysql);
+ w = php_get_warnings(mysql->mysql TSRMLS_CC);
} else {
RETURN_FALSE;
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = mysqli_resource->info = (void *)w;
+ mysqli_resource->status = MYSQLI_STATUS_VALID;
MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
}
/* }}} */
@@ -317,15 +597,16 @@ PHP_FUNCTION(mysqli_stmt_get_warnings)
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) {
return;
}
- MYSQLI_FETCH_RESOURCE(stmt, MY_STMT*, &stmt_link, "mysqli_stmt", 1);
+ MYSQLI_FETCH_RESOURCE(stmt, MY_STMT*, &stmt_link, "mysqli_stmt", MYSQLI_STATUS_VALID);
- if (mysql_warning_count(stmt->stmt->mysql)) {
- w = php_get_warnings(stmt->stmt->mysql);
+ if (mysqli_stmt_warning_count(stmt->stmt)) {
+ w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC);
} else {
RETURN_FALSE;
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
mysqli_resource->ptr = mysqli_resource->info = (void *)w;
+ mysqli_resource->status = MYSQLI_STATUS_VALID;
MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
}
/* }}} */
@@ -354,13 +635,19 @@ PHP_FUNCTION(mysqli_set_charset)
#endif
#ifdef HAVE_MYSQLI_GET_CHARSET
-/* {{{ proto object mysqli_get_charset(object link)
+/* {{{ proto object mysqli_get_charset(object link) U
returns a character set object */
PHP_FUNCTION(mysqli_get_charset)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ char *name = NULL, *collation = NULL, *dir = NULL;
+ uint minlength, maxlength, number, state;
+#if !defined(HAVE_MYSQLND)
MY_CHARSET_INFO cs;
+#else
+ const MYSQLND_CHARSET *cs;
+#endif
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
@@ -369,16 +656,32 @@ PHP_FUNCTION(mysqli_get_charset)
object_init(return_value);
+#if !defined(HAVE_MYSQLND)
mysql_get_character_set_info(mysql->mysql, &cs);
+ name = (char *)cs.csname;
+ collation = (char *)cs.name;
+ dir = (char *)cs.dir;
+ minlength = cs.mbminlen;
+ maxlength = cs.mbmaxlen;
+ number = cs.number;
+ state = cs.state;
+#else
+ cs = mysql->mysql->charset;
+ name = cs->name;
+ collation = cs->collation;
+ minlength = cs->char_minlen;
+ maxlength = cs->char_maxlen;
+ number = cs->nr;
+ state = 1; /* all charsets are compiled in */
+#endif
- add_property_string(return_value, "charset", (cs.name) ? (char *)cs.csname : "", 1);
- add_property_string(return_value, "collation",(cs.name) ? (char *)cs.name : "", 1);
- add_property_string(return_value, "comment", (cs.comment) ? (char *)cs.comment : "", 1);
- add_property_string(return_value, "dir", (cs.dir) ? (char *)cs.dir : "", 1);
- add_property_long(return_value, "min_length", cs.mbminlen);
- add_property_long(return_value, "max_length", cs.mbmaxlen);
- add_property_long(return_value, "number", cs.number);
- add_property_long(return_value, "state", cs.state);
+ add_property_string(return_value, "charset", (name) ? (char *)name : "", 1);
+ add_property_string(return_value, "collation",(collation) ? (char *)collation : "", 1);
+ add_property_string(return_value, "dir", (dir) ? (char *)dir : "", 1);
+ add_property_long(return_value, "min_length", minlength);
+ add_property_long(return_value, "max_length", maxlength);
+ add_property_long(return_value, "number", number);
+ add_property_long(return_value, "state", state);
}
/* }}} */
#endif
diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c
index fd0b8a21fa..fd8281b551 100644
--- a/ext/mysqli/mysqli_prop.c
+++ b/ext/mysqli/mysqli_prop.c
@@ -27,7 +27,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
#define CHECK_STATUS(value) \
if (((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \
@@ -221,24 +221,23 @@ static int result_type_read(mysqli_object *obj, zval **retval TSRMLS_DC)
static int result_lengths_read(mysqli_object *obj, zval **retval TSRMLS_DC)
{
MYSQL_RES *p;
+ ulong *ret;
ALLOC_ZVAL(*retval);
CHECK_STATUS(MYSQLI_STATUS_VALID);
p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
- if (!p || !p->field_count) {
+ if (!p || !p->field_count || !(ret = mysql_fetch_lengths(p)))
+ {
ZVAL_NULL(*retval);
} else {
ulong i;
- zval *l;
array_init(*retval);
for (i=0; i < p->field_count; i++) {
- MAKE_STD_ZVAL(l);
- ZVAL_LONG(l, p->lengths[i]);
- add_index_zval(*retval, i, l);
- }
+ add_index_long(*retval, i, ret[i]);
+ }
}
return SUCCESS;
}
@@ -312,7 +311,7 @@ MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_error_read, mysql_stmt_error, MYSQLI_GET_ST
MYSQLI_MAP_PROPERTY_FUNC_STRING(stmt_sqlstate_read, mysql_stmt_sqlstate, MYSQLI_GET_STMT(MYSQLI_STATUS_INITIALIZED));
/* }}} */
-mysqli_property_entry mysqli_link_property_entries[] = {
+const mysqli_property_entry mysqli_link_property_entries[] = {
{"affected_rows", link_affected_rows_read, NULL},
{"client_info", link_client_info_read, NULL},
{"client_version", link_client_version_read, NULL},
@@ -333,7 +332,7 @@ mysqli_property_entry mysqli_link_property_entries[] = {
{NULL, NULL, NULL}
};
-mysqli_property_entry mysqli_result_property_entries[] = {
+const mysqli_property_entry mysqli_result_property_entries[] = {
{"current_field", result_current_field_read, NULL},
{"field_count", result_field_count_read, NULL},
{"lengths", result_lengths_read, NULL},
@@ -342,7 +341,7 @@ mysqli_property_entry mysqli_result_property_entries[] = {
{NULL, NULL, NULL}
};
-mysqli_property_entry mysqli_stmt_property_entries[] = {
+const mysqli_property_entry mysqli_stmt_property_entries[] = {
{"affected_rows", stmt_affected_rows_read, NULL},
{"insert_id", stmt_insert_id_read, NULL},
{"num_rows", stmt_num_rows_read, NULL},
diff --git a/ext/mysqli/mysqli_repl.c b/ext/mysqli/mysqli_repl.c
index b12706fa6b..8096c0239a 100644
--- a/ext/mysqli/mysqli_repl.c
+++ b/ext/mysqli/mysqli_repl.c
@@ -27,7 +27,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
/* {{{ proto void mysqli_disable_reads_from_master(object link)
*/
diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c
index be6e857226..dae2f9242d 100644
--- a/ext/mysqli/mysqli_report.c
+++ b/ext/mysqli/mysqli_report.c
@@ -25,7 +25,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
/* {{{ proto bool mysqli_report(int flags)
sets report level */
@@ -45,13 +45,14 @@ PHP_FUNCTION(mysqli_report)
/* }}} */
/* {{{ void php_mysqli_report_error(char *sqlstate, int errorno, char *error) */
-void php_mysqli_report_error(char *sqlstate, int errorno, char *error TSRMLS_DC) {
- php_mysqli_throw_sql_exception(sqlstate, errorno TSRMLS_CC, "%s", error);
+void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC)
+{
+ php_mysqli_throw_sql_exception((char *)sqlstate, errorno TSRMLS_CC, "%s", error);
}
/* }}} */
/* {{{ void php_mysqli_report_index() */
-void php_mysqli_report_index(char *query, unsigned int status TSRMLS_DC) {
+void php_mysqli_report_index(const char *query, unsigned int status TSRMLS_DC) {
char index[15];
if (status & SERVER_QUERY_NO_GOOD_INDEX_USED) {
diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c
index 92dc8ce327..7b02d9117a 100644
--- a/ext/mysqli/mysqli_warning.c
+++ b/ext/mysqli/mysqli_warning.c
@@ -25,55 +25,144 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
-#include "php_mysqli.h"
+#include "php_mysqli_structs.h"
+
+/* Define these in the PHP5 tree to make merging easy process */
+#define ZSTR_DUPLICATE (1<<0)
+#define ZSTR_AUTOFREE (1<<1)
+
+#define ZVAL_UTF8_STRING(z, s, flags) ZVAL_STRING((z), (char*)(s), ((flags) & ZSTR_DUPLICATE))
+#define ZVAL_UTF8_STRINGL(z, s, l, flags) ZVAL_STRINGL((z), (char*)(s), (l), ((flags) & ZSTR_DUPLICATE))
+
/* {{{ void php_clear_warnings() */
void php_clear_warnings(MYSQLI_WARNING *w)
{
- MYSQLI_WARNING *n;
+ MYSQLI_WARNING *n;
while (w) {
n = w;
- efree(w->reason);
+ zval_dtor(&(w->reason));
+ zval_dtor(&(w->sqlstate));
w = w->next;
efree(n);
}
}
/* }}} */
+
+#ifndef HAVE_MYSQLND
/* {{{ MYSQLI_WARNING *php_new_warning */
-MYSQLI_WARNING *php_new_warning(char *reason, char *sqlstate, int errorno)
+static
+MYSQLI_WARNING *php_new_warning(const char *reason, int errorno TSRMLS_DC)
{
- MYSQLI_WARNING *w;
+ MYSQLI_WARNING *w;
w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING));
- w->reason = safe_estrdup(reason);
- if (sqlstate) {
- strcpy(w->sqlstate, sqlstate);
- } else {
- strcpy(w->sqlstate, "00000");
- }
+ ZVAL_UTF8_STRING(&(w->reason), reason, ZSTR_DUPLICATE);
+
+ ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1, ZSTR_DUPLICATE);
+
w->errorno = errorno;
return w;
}
/* }}} */
-/* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql) */
-MYSQLI_WARNING *php_get_warnings(MYSQL *mysql)
+
+/* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */
+MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC)
{
- MYSQLI_WARNING *w, *first = NULL, *prev = NULL;
+ MYSQLI_WARNING *w, *first = NULL, *prev = NULL;
MYSQL_RES *result;
MYSQL_ROW row;
- if (mysql_query(mysql, "SHOW WARNINGS")) {
+ if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) {
return NULL;
}
result = mysql_store_result(mysql);
+
while ((row = mysql_fetch_row(result))) {
- w = php_new_warning(row[2], "HY000", atoi(row[1]));
+ w = php_new_warning(row[2], atoi(row[1]) TSRMLS_CC);
+ if (!first) {
+ first = w;
+ }
+ if (prev) {
+ prev->next = w;
+ }
+ prev = w;
+ }
+ mysql_free_result(result);
+ return first;
+}
+/* }}} */
+#else
+/* {{{ MYSQLI_WARNING *php_new_warning */
+static
+MYSQLI_WARNING *php_new_warning(const zval *reason, int errorno TSRMLS_DC)
+{
+ MYSQLI_WARNING *w;
+
+ w = (MYSQLI_WARNING *)ecalloc(1, sizeof(MYSQLI_WARNING));
+
+ w->reason = *reason;
+ zval_copy_ctor(&(w->reason));
+
+ ZVAL_UTF8_STRINGL(&(w->reason), Z_STRVAL(w->reason), Z_STRLEN(w->reason), ZSTR_AUTOFREE);
+
+ ZVAL_UTF8_STRINGL(&(w->sqlstate), "HY000", sizeof("HY000") - 1, ZSTR_DUPLICATE);
+
+ w->errorno = errorno;
+
+ return w;
+}
+/* }}} */
+
+
+/* {{{ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC) */
+MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC)
+{
+ MYSQLI_WARNING *w, *first = NULL, *prev = NULL;
+ MYSQL_RES *result;
+ zval *row;
+
+ if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) {
+ return NULL;
+ }
+
+ result = mysql_use_result(mysql);
+
+ for (;;) {
+ zval **entry;
+ int errno;
+
+ MAKE_STD_ZVAL(row);
+ mysqlnd_fetch_into(result, MYSQLND_FETCH_NUM, row, MYSQLND_MYSQLI);
+ if (Z_TYPE_P(row) != IS_ARRAY) {
+ zval_ptr_dtor(&row);
+ break;
+ }
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(row));
+ /* 0. we don't care about the first */
+ zend_hash_move_forward(Z_ARRVAL_P(row));
+
+ /* 1. Here comes the error no */
+ zend_hash_get_current_data(Z_ARRVAL_P(row), (void **)&entry);
+ convert_to_long_ex(entry);
+ errno = Z_LVAL_PP(entry);
+ zend_hash_move_forward(Z_ARRVAL_P(row));
+
+ /* 2. Here comes the reason */
+ zend_hash_get_current_data(Z_ARRVAL_P(row), (void **)&entry);
+
+ w = php_new_warning(*entry, errno TSRMLS_CC);
+ /*
+ Don't destroy entry, because the row destroy will decrease
+ the refcounter. Decreased twice then mysqlnd_free_result()
+ will crash, because it will try to access already freed memory.
+ */
if (!first) {
first = w;
}
@@ -81,11 +170,16 @@ MYSQLI_WARNING *php_get_warnings(MYSQL *mysql)
prev->next = (void *)w;
}
prev = w;
+
+ zval_ptr_dtor(&row);
}
+
mysql_free_result(result);
return first;
}
/* }}} */
+#endif
+
/* {{{ bool mysqli_warning::next() */
PHP_METHOD(mysqli_warning, next)
@@ -112,7 +206,9 @@ PHP_METHOD(mysqli_warning, next)
}
/* }}} */
+
/* {{{ property mysqli_warning_message */
+static
int mysqli_warning_message(mysqli_object *obj, zval **retval TSRMLS_DC)
{
MYSQLI_WARNING *w;
@@ -122,17 +218,16 @@ int mysqli_warning_message(mysqli_object *obj, zval **retval TSRMLS_DC)
}
w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
- ALLOC_ZVAL(*retval);
- if (w->reason) {
- ZVAL_STRING(*retval, w->reason, 1);
- } else {
- ZVAL_NULL(*retval);
- }
+ MAKE_STD_ZVAL(*retval);
+ **retval = w->reason;
+ zval_copy_ctor(*retval);
return SUCCESS;
}
/* }}} */
+
/* {{{ property mysqli_warning_sqlstate */
+static
int mysqli_warning_sqlstate(mysqli_object *obj, zval **retval TSRMLS_DC)
{
MYSQLI_WARNING *w;
@@ -142,13 +237,16 @@ int mysqli_warning_sqlstate(mysqli_object *obj, zval **retval TSRMLS_DC)
}
w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
- ALLOC_ZVAL(*retval);
- ZVAL_STRING(*retval, w->sqlstate, 1);
+ MAKE_STD_ZVAL(*retval);
+ **retval = w->sqlstate;
+ zval_copy_ctor(*retval);
return SUCCESS;
}
/* }}} */
+
/* {{{ property mysqli_warning_error */
+static
int mysqli_warning_errno(mysqli_object *obj, zval **retval TSRMLS_DC)
{
MYSQLI_WARNING *w;
@@ -157,7 +255,7 @@ int mysqli_warning_errno(mysqli_object *obj, zval **retval TSRMLS_DC)
return FAILURE;
}
w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr;
- ALLOC_ZVAL(*retval);
+ MAKE_STD_ZVAL(*retval);
ZVAL_LONG(*retval, w->errorno);
return SUCCESS;
}
@@ -187,20 +285,22 @@ PHP_METHOD(mysqli_warning, __construct)
} else if (obj->zo.ce == mysqli_stmt_class_entry) {
MY_STMT *stmt;
MYSQLI_FETCH_RESOURCE(stmt, MY_STMT *, &z, "mysqli_stmt", MYSQLI_STATUS_VALID);
- hdl = stmt->stmt->mysql;
+ hdl = mysqli_stmt_get_connection(stmt->stmt);
} else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid class argument");
RETURN_FALSE;
}
if (mysql_warning_count(hdl)) {
- w = php_get_warnings(hdl);
+ w = php_get_warnings(hdl TSRMLS_CC);
} else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No warnings found");
RETURN_FALSE;
}
mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
- mysqli_resource->status = MYSQLI_STATUS_VALID;
mysqli_resource->ptr = mysqli_resource->info = (void *)w;
+ mysqli_resource->status = MYSQLI_STATUS_VALID;
if (!getThis() || !instanceof_function(Z_OBJCE_P(getThis()), mysqli_warning_class_entry TSRMLS_CC)) {
MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
@@ -211,18 +311,22 @@ PHP_METHOD(mysqli_warning, __construct)
}
/* }}} */
+/* {{{ mysqli_warning_methods */
const zend_function_entry mysqli_warning_methods[] = {
PHP_ME(mysqli_warning, __construct, NULL, ZEND_ACC_PROTECTED)
PHP_ME(mysqli_warning, next, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
+/* }}} */
-mysqli_property_entry mysqli_warning_property_entries[] = {
+/* {{{ mysqli_warning_property_entries */
+const mysqli_property_entry mysqli_warning_property_entries[] = {
{"message", mysqli_warning_message, NULL},
{"sqlstate", mysqli_warning_sqlstate, NULL},
{"errno", mysqli_warning_errno, NULL},
{NULL, NULL, NULL}
};
+/* }}} */
/*
* Local variables:
diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h
index 965bec7082..d166d00f52 100644
--- a/ext/mysqli/php_mysqli.h
+++ b/ext/mysqli/php_mysqli.h
@@ -12,299 +12,17 @@
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: Georg Richter <georg@php.net> |
+ | Authors: Georg Richter <georg@php.net> |
+ | Andrey Hristov <andrey@php.net> |
+ | Ulf Wendel <uw@php.net> |
+----------------------------------------------------------------------+
$Id$
*/
-/* A little hack to prevent build break, when mysql is used together with
- * c-client, which also defines LIST.
- */
-#ifdef LIST
-#undef LIST
-#endif
-
-#include <mysql.h>
-
-/* character set support */
-#if MYSQL_VERSION_ID > 50009
-#define HAVE_MYSQLI_GET_CHARSET
-#endif
-
-#if (MYSQL_VERSION_ID > 40112 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID > 50005
-#define HAVE_MYSQLI_SET_CHARSET
-#endif
-
-
-#include <errmsg.h>
-
#ifndef PHP_MYSQLI_H
#define PHP_MYSQLI_H
-#define MYSQLI_VERSION_ID 101009
-
-enum mysqli_status {
- MYSQLI_STATUS_UNKNOWN=0,
- MYSQLI_STATUS_CLEARED,
- MYSQLI_STATUS_INITIALIZED,
- MYSQLI_STATUS_VALID
-};
-
-typedef struct {
- ulong buflen;
- char *val;
- ulong type;
-} VAR_BUFFER;
-
-typedef struct {
- unsigned int var_cnt;
- VAR_BUFFER *buf;
- zval **vars;
- char *is_null;
-} BIND_BUFFER;
-
-typedef struct {
- MYSQL_STMT *stmt;
- BIND_BUFFER param;
- BIND_BUFFER result;
- char *query;
-} MY_STMT;
-
-typedef struct {
- MYSQL *mysql;
- zval *li_read;
- php_stream *li_stream;
- unsigned int multi_query;
-} MY_MYSQL;
-
-typedef struct {
- int mode;
- int socket;
- FILE *fp;
-} PROFILER;
-
-typedef struct {
- void *ptr; /* resource: (mysql, result, stmt) */
- void *info; /* additional buffer */
- enum mysqli_status status;
-} MYSQLI_RESOURCE;
-
-typedef struct _mysqli_object {
- zend_object zo;
- void *ptr;
- HashTable *prop_handler;
-} mysqli_object; /* extends zend_object */
-
-typedef struct {
- char *reason;
- char sqlstate[6];
- int errorno;
- void *next;
-} MYSQLI_WARNING;
-
-typedef struct _mysqli_property_entry {
- char *pname;
- int (*r_func)(mysqli_object *obj, zval **retval TSRMLS_DC);
- int (*w_func)(mysqli_object *obj, zval *value TSRMLS_DC);
-} mysqli_property_entry;
-
-typedef struct {
- char error_msg[LOCAL_INFILE_ERROR_LEN];
- void *userdata;
-} mysqli_local_infile;
-
-#define phpext_mysqli_ptr &mysqli_module_entry
-
-#ifdef PHP_WIN32
-#define PHP_MYSQLI_API __declspec(dllexport)
-#define MYSQLI_LLU_SPEC "%I64u"
-#define MYSQLI_LL_SPEC "%I64d"
-#else
-#define PHP_MYSQLI_API
-#define MYSQLI_LLU_SPEC "%llu"
-#define MYSQLI_LL_SPEC "%lld"
-#endif
-
-#ifdef ZTS
-#include "TSRM.h"
-#endif
-
-#define PHP_MYSQLI_EXPORT(__type) PHP_MYSQLI_API __type
-
-extern zend_module_entry mysqli_module_entry;
-extern const zend_function_entry mysqli_functions[];
-extern const zend_function_entry mysqli_link_methods[];
-extern const zend_function_entry mysqli_stmt_methods[];
-extern const zend_function_entry mysqli_result_methods[];
-extern const zend_function_entry mysqli_driver_methods[];
-extern const zend_function_entry mysqli_warning_methods[];
-extern const zend_function_entry mysqli_exception_methods[];
-
-extern mysqli_property_entry mysqli_link_property_entries[];
-extern mysqli_property_entry mysqli_result_property_entries[];
-extern mysqli_property_entry mysqli_stmt_property_entries[];
-extern mysqli_property_entry mysqli_driver_property_entries[];
-extern mysqli_property_entry mysqli_warning_property_entries[];
-
-extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);
-extern void php_clear_stmt_bind(MY_STMT *stmt);
-extern void php_clear_mysql(MY_MYSQL *);
-extern MYSQLI_WARNING *php_get_warnings(MYSQL *mysql);
-extern void php_clear_warnings(MYSQLI_WARNING *w);
-extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
-extern void php_mysqli_report_error(char *sqlstate, int errorno, char *error TSRMLS_DC);
-extern void php_mysqli_report_index(char *query, unsigned int status TSRMLS_DC);
-extern int php_local_infile_init(void **, const char *, void *);
-extern int php_local_infile_read(void *, char *, uint);
-extern void php_local_infile_end(void *);
-extern int php_local_infile_error(void *, char *, uint);
-extern void php_set_local_infile_handler_default(MY_MYSQL *);
-extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...);
-extern zend_class_entry *mysqli_link_class_entry;
-extern zend_class_entry *mysqli_stmt_class_entry;
-extern zend_class_entry *mysqli_result_class_entry;
-extern zend_class_entry *mysqli_driver_class_entry;
-extern zend_class_entry *mysqli_warning_class_entry;
-extern zend_class_entry *mysqli_exception_class_entry;
-
-#ifdef HAVE_SPL
-extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
-#endif
-
-PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRMLS_DC);
-
-#define MYSQLI_DISABLE_MQ if (mysql->multi_query) { \
- mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
- mysql->multi_query = 0; \
-}
-
-#define MYSQLI_ENABLE_MQ if (!mysql->multi_query) { \
- mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \
- mysql->multi_query = 1; \
-}
-
-#define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \
- zend_class_entry ce; \
- INIT_CLASS_ENTRY(ce, name,class_functions); \
- ce.create_object = mysqli_objects_new; \
- mysqli_entry = zend_register_internal_class(&ce TSRMLS_CC); \
-} \
-
-#define MYSQLI_REGISTER_RESOURCE_EX(__ptr, __zval) \
- ((mysqli_object *) zend_object_store_get_object(__zval TSRMLS_CC))->ptr = __ptr; \
-
-#define MYSQLI_RETURN_RESOURCE(__ptr, __ce) \
- Z_TYPE_P(return_value) = IS_OBJECT; \
- (return_value)->value.obj = mysqli_objects_new(__ce TSRMLS_CC); \
- MYSQLI_REGISTER_RESOURCE_EX(__ptr, return_value)
-
-#define MYSQLI_REGISTER_RESOURCE(__ptr, __ce) \
-{\
- zval *object = getThis();\
- if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {\
- object = return_value;\
- Z_TYPE_P(object) = IS_OBJECT;\
- (object)->value.obj = mysqli_objects_new(__ce TSRMLS_CC);\
- }\
- MYSQLI_REGISTER_RESOURCE_EX(__ptr, object)\
-}
-
-#define MYSQLI_FETCH_RESOURCE(__ptr, __type, __id, __name, __check) \
-{ \
- MYSQLI_RESOURCE *my_res; \
- mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\
- if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\
- RETURN_NULL();\
- }\
- __ptr = (__type)my_res->ptr; \
- if (__check && my_res->status < __check) { \
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \
- RETURN_NULL();\
- }\
-}
-
-#define MYSQLI_SET_STATUS(__id, __value) \
-{ \
- mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\
- ((MYSQLI_RESOURCE *)intern->ptr)->status = __value; \
-} \
-
-#define MYSQLI_CLEAR_RESOURCE(__id) \
-{ \
- mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\
- efree(intern->ptr); \
- intern->ptr = NULL; \
-}
-
-#define MYSQLI_RETURN_LONG_LONG(__val) \
-{ \
- if ((__val) < LONG_MAX) { \
- RETURN_LONG((long) (__val)); \
- } else { \
- char *ret; \
- /* always used with my_ulonglong -> %llu */ \
- int l = spprintf(&ret, 0, "%llu", (__val)); \
- RETURN_STRINGL(ret, l, 0); \
- } \
-}
-
-#define MYSQLI_ADD_PROPERTIES(a,b) \
-{ \
- int i = 0; \
- while (b[i].pname != NULL) { \
- mysqli_add_property(a, b[i].pname, (mysqli_read_t)b[i].r_func, (mysqli_write_t)b[i].w_func TSRMLS_CC); \
- i++; \
- }\
-}
-
-#if WIN32|WINNT
-#define SCLOSE(a) closesocket(a)
-#else
-#define SCLOSE(a) close(a)
-#endif
-
-#define MYSQLI_STORE_RESULT 0
-#define MYSQLI_USE_RESULT 1
-
-/* for mysqli_fetch_assoc */
-#define MYSQLI_ASSOC 1
-#define MYSQLI_NUM 2
-#define MYSQLI_BOTH 3
-
-/* for mysqli_bind_param */
-#define MYSQLI_BIND_INT 1
-#define MYSQLI_BIND_DOUBLE 2
-#define MYSQLI_BIND_STRING 3
-#define MYSQLI_BIND_SEND_DATA 4
-
-/* fetch types */
-#define FETCH_SIMPLE 1
-#define FETCH_RESULT 2
-
-/*** REPORT MODES ***/
-#define MYSQLI_REPORT_OFF 0
-#define MYSQLI_REPORT_ERROR 1
-#define MYSQLI_REPORT_STRICT 2
-#define MYSQLI_REPORT_INDEX 4
-#define MYSQLI_REPORT_CLOSE 8
-#define MYSQLI_REPORT_ALL 255
-
-#define MYSQLI_REPORT_MYSQL_ERROR(mysql) \
-if ((MyG(report_mode) & MYSQLI_REPORT_ERROR) && mysql->net.last_errno) { \
- php_mysqli_report_error(mysql->net.sqlstate, mysql->net.last_errno, mysql->net.last_error TSRMLS_CC); \
-}
-
-#define MYSQLI_REPORT_STMT_ERROR(stmt) \
-if ((MyG(report_mode) & MYSQLI_REPORT_ERROR) && stmt->last_errno) { \
- php_mysqli_report_error(stmt->sqlstate, stmt->last_errno, stmt->last_error TSRMLS_CC); \
-}
-
-PHP_MYSQLI_API void mysqli_register_link(zval *return_value, void *link TSRMLS_DC);
-PHP_MYSQLI_API void mysqli_register_stmt(zval *return_value, void *stmt TSRMLS_DC);
-PHP_MYSQLI_API void mysqli_register_result(zval *return_value, void *result TSRMLS_DC);
-PHP_MYSQLI_API void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRMLS_DC);
PHP_MINIT_FUNCTION(mysqli);
PHP_MSHUTDOWN_FUNCTION(mysqli);
@@ -317,9 +35,7 @@ PHP_FUNCTION(mysqli_affected_rows);
PHP_FUNCTION(mysqli_autocommit);
PHP_FUNCTION(mysqli_change_user);
PHP_FUNCTION(mysqli_character_set_name);
-#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FUNCTION(mysqli_set_charset);
-#endif
PHP_FUNCTION(mysqli_close);
PHP_FUNCTION(mysqli_commit);
PHP_FUNCTION(mysqli_connect);
@@ -334,6 +50,7 @@ PHP_FUNCTION(mysqli_enable_reads_from_master);
PHP_FUNCTION(mysqli_enable_rpl_parse);
PHP_FUNCTION(mysqli_errno);
PHP_FUNCTION(mysqli_error);
+PHP_FUNCTION(mysqli_fetch_all);
PHP_FUNCTION(mysqli_fetch_array);
PHP_FUNCTION(mysqli_fetch_assoc);
PHP_FUNCTION(mysqli_fetch_object);
@@ -346,9 +63,10 @@ PHP_FUNCTION(mysqli_field_count);
PHP_FUNCTION(mysqli_field_seek);
PHP_FUNCTION(mysqli_field_tell);
PHP_FUNCTION(mysqli_free_result);
-#ifdef HAVE_MYSQLI_GET_CHARSET
+PHP_FUNCTION(mysqli_get_cache_stats);
+PHP_FUNCTION(mysqli_get_client_stats);
+PHP_FUNCTION(mysqli_get_connection_stats);
PHP_FUNCTION(mysqli_get_charset);
-#endif
PHP_FUNCTION(mysqli_get_client_info);
PHP_FUNCTION(mysqli_get_client_version);
PHP_FUNCTION(mysqli_get_host_info);
@@ -408,6 +126,7 @@ PHP_FUNCTION(mysqli_stmt_data_seek);
PHP_FUNCTION(mysqli_stmt_errno);
PHP_FUNCTION(mysqli_stmt_error);
PHP_FUNCTION(mysqli_stmt_free_result);
+PHP_FUNCTION(mysqli_stmt_get_result);
PHP_FUNCTION(mysqli_stmt_get_warnings);
PHP_FUNCTION(mysqli_stmt_reset);
PHP_FUNCTION(mysqli_stmt_insert_id);
@@ -425,53 +144,11 @@ ZEND_FUNCTION(mysqli_result_construct);
ZEND_FUNCTION(mysqli_driver_construct);
ZEND_METHOD(mysqli_warning,__construct);
-ZEND_BEGIN_MODULE_GLOBALS(mysqli)
- long default_link;
- long num_links;
- long max_links;
- unsigned int default_port;
- char *default_host;
- char *default_user;
- char *default_socket;
- char *default_pw;
- int reconnect;
- int strict;
- long error_no;
- char *error_msg;
- int report_mode;
- HashTable *report_ht;
- unsigned int multi_query;
- unsigned int embedded;
-ZEND_END_MODULE_GLOBALS(mysqli)
-
-
-#define MYSQLI_PROPERTY(a) extern int a(mysqli_object *obj, zval **retval TSRMLS_DC)
-
-MYSQLI_PROPERTY(my_prop_link_host);
-
-#ifdef ZTS
-#define MyG(v) TSRMG(mysqli_globals_id, zend_mysqli_globals *, v)
-#else
-#define MyG(v) (mysqli_globals.v)
-#endif
-
-#define my_estrdup(x) (x) ? estrdup(x) : NULL
-#define my_efree(x) if (x) efree(x)
-
-#ifdef PHP_WIN32
-#define L64(x) x##i64
-typedef __int64 my_longlong;
-#else
-#define L64(x) x##LL
-typedef long long my_longlong;
-#endif
-
-
-ZEND_EXTERN_MODULE_GLOBALS(mysqli)
+#define phpext_mysqli_ptr &mysqli_module_entry
+extern zend_module_entry mysqli_module_entry;
#endif /* PHP_MYSQLI.H */
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h
new file mode 100644
index 0000000000..5c6e23f4f3
--- /dev/null
+++ b/ext/mysqli/php_mysqli_structs.h
@@ -0,0 +1,396 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2007 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Georg Richter <georg@php.net> |
+ +----------------------------------------------------------------------+
+
+ $Id$
+*/
+
+#ifndef PHP_MYSQLI_STRUCTS_H
+#define PHP_MYSQLI_STRUCTS_H
+
+/* A little hack to prevent build break, when mysql is used together with
+ * c-client, which also defines LIST.
+ */
+#ifdef LIST
+#undef LIST
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifdef HAVE_MYSQLND
+#include "ext/mysqlnd/mysqlnd.h"
+#include "ext/mysqli/mysqli_mysqlnd.h"
+#else
+#include <mysql.h>
+#include <errmsg.h>
+#include "ext/mysqli/mysqli_libmysql.h"
+#endif
+
+#include "php_mysqli.h"
+
+/* character set support */
+#if defined(MYSQLND_VERSION_ID) || MYSQL_VERSION_ID > 50009
+#define HAVE_MYSQLI_GET_CHARSET
+#endif
+
+#if defined(MYSQLND_VERSION_ID) || (MYSQL_VERSION_ID > 40112 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID > 50005
+#define HAVE_MYSQLI_SET_CHARSET
+#endif
+
+#define MYSQLI_VERSION_ID 101009
+
+enum mysqli_status {
+ MYSQLI_STATUS_UNKNOWN=0,
+ MYSQLI_STATUS_CLEARED,
+ MYSQLI_STATUS_INITIALIZED,
+ MYSQLI_STATUS_VALID
+};
+
+typedef struct {
+ ulong buflen;
+ char *val;
+ ulong type;
+} VAR_BUFFER;
+
+typedef struct {
+ unsigned int var_cnt;
+ VAR_BUFFER *buf;
+ zval **vars;
+ char *is_null;
+} BIND_BUFFER;
+
+typedef struct {
+ MYSQL_STMT *stmt;
+ BIND_BUFFER param;
+ BIND_BUFFER result;
+ char *query;
+} MY_STMT;
+
+typedef struct {
+ MYSQL *mysql;
+ char *hash_key;
+ zval *li_read;
+ php_stream *li_stream;
+ zend_bool persistent;
+ unsigned long hash_index; /* Used when persistent, hold the index in plist->used_links */
+ unsigned int multi_query;
+} MY_MYSQL;
+
+typedef struct {
+ int mode;
+ int socket;
+ FILE *fp;
+} PROFILER;
+
+typedef struct {
+ void *ptr; /* resource: (mysql, result, stmt) */
+ void *info; /* additional buffer */
+ enum mysqli_status status; /* object status */
+} MYSQLI_RESOURCE;
+
+typedef struct _mysqli_object {
+ zend_object zo;
+ void *ptr;
+ HashTable *prop_handler;
+} mysqli_object; /* extends zend_object */
+
+typedef struct st_mysqli_warning MYSQLI_WARNING;
+
+struct st_mysqli_warning {
+ zval reason;
+ zval sqlstate;
+ int errorno;
+ MYSQLI_WARNING *next;
+};
+
+typedef struct _mysqli_property_entry {
+ char *pname;
+ int (*r_func)(mysqli_object *obj, zval **retval TSRMLS_DC);
+ int (*w_func)(mysqli_object *obj, zval *value TSRMLS_DC);
+} mysqli_property_entry;
+
+#if !defined(HAVE_MYSQLND)
+typedef struct {
+ char error_msg[LOCAL_INFILE_ERROR_LEN];
+ void *userdata;
+} mysqli_local_infile;
+#endif
+
+typedef struct {
+ HashTable free_links;
+ HashTable used_links;
+} mysqli_plist_entry;
+
+#ifdef PHP_WIN32
+#define PHP_MYSQLI_API __declspec(dllexport)
+#define MYSQLI_LLU_SPEC "%I64u"
+#define MYSQLI_LL_SPEC "%I64d"
+#define L64(x) x##i64
+typedef __int64 my_longlong;
+#else
+#define PHP_MYSQLI_API
+#define MYSQLI_LLU_SPEC "%llu"
+#define MYSQLI_LL_SPEC "%lld"
+#define L64(x) x##LL
+typedef long long my_longlong;
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#define PHP_MYSQLI_EXPORT(__type) PHP_MYSQLI_API __type
+
+extern const zend_function_entry mysqli_functions[];
+extern const zend_function_entry mysqli_link_methods[];
+extern const zend_function_entry mysqli_stmt_methods[];
+extern const zend_function_entry mysqli_result_methods[];
+extern const zend_function_entry mysqli_driver_methods[];
+extern const zend_function_entry mysqli_warning_methods[];
+extern const zend_function_entry mysqli_exception_methods[];
+
+extern const mysqli_property_entry mysqli_link_property_entries[];
+extern const mysqli_property_entry mysqli_result_property_entries[];
+extern const mysqli_property_entry mysqli_stmt_property_entries[];
+extern const mysqli_property_entry mysqli_driver_property_entries[];
+extern const mysqli_property_entry mysqli_warning_property_entries[];
+
+#ifdef HAVE_MYSQLND
+extern MYSQLND_ZVAL_PCACHE *mysqli_mysqlnd_zval_cache;
+extern MYSQLND_QCACHE *mysqli_mysqlnd_qcache;
+#endif
+
+extern void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flag, int into_object);
+extern void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC);
+extern void php_clear_mysql(MY_MYSQL *);
+extern MYSQLI_WARNING *php_get_warnings(MYSQL *mysql TSRMLS_DC);
+extern void php_clear_warnings(MYSQLI_WARNING *w);
+extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
+extern void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC);
+extern void php_mysqli_report_index(const char *query, unsigned int status TSRMLS_DC);
+extern int php_local_infile_init(void **, const char *, void *);
+extern int php_local_infile_read(void *, char *, uint);
+extern void php_local_infile_end(void *);
+extern int php_local_infile_error(void *, char *, uint);
+extern void php_set_local_infile_handler_default(MY_MYSQL *);
+extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...);
+extern zend_class_entry *mysqli_link_class_entry;
+extern zend_class_entry *mysqli_stmt_class_entry;
+extern zend_class_entry *mysqli_result_class_entry;
+extern zend_class_entry *mysqli_driver_class_entry;
+extern zend_class_entry *mysqli_warning_class_entry;
+extern zend_class_entry *mysqli_exception_class_entry;
+extern int php_le_pmysqli(void);
+extern void php_mysqli_dtor_p_elements(void *data);
+
+#ifdef HAVE_SPL
+extern PHPAPI zend_class_entry *spl_ce_RuntimeException;
+#endif
+
+PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry * TSRMLS_DC);
+
+#define MYSQLI_DISABLE_MQ if (mysql->multi_query) { \
+ mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
+ mysql->multi_query = 0; \
+}
+
+#define MYSQLI_ENABLE_MQ if (!mysql->multi_query) { \
+ mysql_set_server_option(mysql->mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON); \
+ mysql->multi_query = 1; \
+}
+
+#define REGISTER_MYSQLI_CLASS_ENTRY(name, mysqli_entry, class_functions) { \
+ zend_class_entry ce; \
+ INIT_CLASS_ENTRY(ce, name,class_functions); \
+ ce.create_object = mysqli_objects_new; \
+ mysqli_entry = zend_register_internal_class(&ce TSRMLS_CC); \
+} \
+
+#define MYSQLI_REGISTER_RESOURCE_EX(__ptr, __zval) \
+ ((mysqli_object *) zend_object_store_get_object(__zval TSRMLS_CC))->ptr = __ptr;
+
+#define MYSQLI_RETURN_RESOURCE(__ptr, __ce) \
+ Z_TYPE_P(return_value) = IS_OBJECT; \
+ (return_value)->value.obj = mysqli_objects_new(__ce TSRMLS_CC); \
+ MYSQLI_REGISTER_RESOURCE_EX(__ptr, return_value)
+
+#define MYSQLI_REGISTER_RESOURCE(__ptr, __ce) \
+{\
+ zval *object = getThis();\
+ if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {\
+ object = return_value;\
+ Z_TYPE_P(object) = IS_OBJECT;\
+ (object)->value.obj = mysqli_objects_new(__ce TSRMLS_CC);\
+ }\
+ MYSQLI_REGISTER_RESOURCE_EX(__ptr, object)\
+}
+
+#define MYSQLI_FETCH_RESOURCE(__ptr, __type, __id, __name, __check) \
+{ \
+ MYSQLI_RESOURCE *my_res; \
+ mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\
+ if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", intern->zo.ce->name);\
+ RETURN_NULL();\
+ }\
+ __ptr = (__type)my_res->ptr; \
+ if (__check && my_res->status < __check) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid object or resource %s\n", intern->zo.ce->name); \
+ RETURN_NULL();\
+ }\
+}
+
+#define MYSQLI_SET_STATUS(__id, __value) \
+{ \
+ mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\
+ ((MYSQLI_RESOURCE *)intern->ptr)->status = __value; \
+} \
+
+#define MYSQLI_CLEAR_RESOURCE(__id) \
+{ \
+ mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*(__id) TSRMLS_CC);\
+ efree(intern->ptr); \
+ intern->ptr = NULL; \
+}
+
+#define MYSQLI_RETURN_LONG_LONG(__val) \
+{ \
+ if ((__val) < LONG_MAX) { \
+ RETURN_LONG((__val)); \
+ } else { \
+ char *ret; \
+ int l = spprintf(&ret, 0, "%llu", (__val)); \
+ RETURN_STRINGL(ret, l, 0); \
+ } \
+}
+
+#define MYSQLI_ADD_PROPERTIES(a,b) \
+{ \
+ int i = 0; \
+ while (b[i].pname != NULL) { \
+ mysqli_add_property(a, b[i].pname, (mysqli_read_t)b[i].r_func, (mysqli_write_t)b[i].w_func TSRMLS_CC); \
+ i++; \
+ }\
+}
+
+#if WIN32|WINNT
+#define SCLOSE(a) closesocket(a)
+#else
+#define SCLOSE(a) close(a)
+#endif
+
+#define MYSQLI_STORE_RESULT 0
+#define MYSQLI_USE_RESULT 1
+
+/* for mysqli_fetch_assoc */
+#define MYSQLI_ASSOC 1
+#define MYSQLI_NUM 2
+#define MYSQLI_BOTH 3
+
+/* for mysqli_bind_param */
+#define MYSQLI_BIND_INT 1
+#define MYSQLI_BIND_DOUBLE 2
+#define MYSQLI_BIND_STRING 3
+#define MYSQLI_BIND_SEND_DATA 4
+
+/* fetch types */
+#define FETCH_SIMPLE 1
+#define FETCH_RESULT 2
+
+/*** REPORT MODES ***/
+#define MYSQLI_REPORT_OFF 0
+#define MYSQLI_REPORT_ERROR 1
+#define MYSQLI_REPORT_STRICT 2
+#define MYSQLI_REPORT_INDEX 4
+#define MYSQLI_REPORT_CLOSE 8
+#define MYSQLI_REPORT_ALL 255
+
+#define MYSQLI_REPORT_MYSQL_ERROR(mysql) \
+if ((MyG(report_mode) & MYSQLI_REPORT_ERROR) && mysql_errno(mysql)) { \
+ php_mysqli_report_error(mysql_sqlstate(mysql), mysql_errno(mysql), mysql_error(mysql) TSRMLS_CC); \
+}
+
+#define MYSQLI_REPORT_STMT_ERROR(stmt) \
+if ((MyG(report_mode) & MYSQLI_REPORT_ERROR) && mysql_stmt_errno(stmt)) { \
+ php_mysqli_report_error(mysql_stmt_sqlstate(stmt), mysql_stmt_errno(stmt), mysql_stmt_error(stmt) TSRMLS_CC); \
+}
+
+PHP_MYSQLI_API void mysqli_register_link(zval *return_value, void *link TSRMLS_DC);
+PHP_MYSQLI_API void mysqli_register_stmt(zval *return_value, void *stmt TSRMLS_DC);
+PHP_MYSQLI_API void mysqli_register_result(zval *return_value, void *result TSRMLS_DC);
+PHP_MYSQLI_API void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRMLS_DC);
+
+ZEND_BEGIN_MODULE_GLOBALS(mysqli)
+ long default_link;
+ long num_links;
+ long max_links;
+ long num_active_persistent;
+ long num_inactive_persistent;
+ long max_persistent;
+ long allow_persistent;
+ long cache_size;
+ unsigned long default_port;
+ char *default_host;
+ char *default_user;
+ char *default_socket;
+ char *default_pw;
+ long reconnect;
+ long allow_local_infile;
+ long strict;
+ long error_no;
+ char *error_msg;
+ long report_mode;
+ HashTable *report_ht;
+ unsigned long multi_query;
+ unsigned long embedded;
+#ifdef HAVE_MYSQLND
+ MYSQLND_THD_ZVAL_PCACHE *mysqlnd_thd_zval_cache;
+#endif
+ZEND_END_MODULE_GLOBALS(mysqli)
+
+#define MYSQLI_PROPERTY(a) extern int a(mysqli_object *obj, zval **retval TSRMLS_DC)
+
+MYSQLI_PROPERTY(my_prop_link_host);
+
+#ifdef ZTS
+#define MyG(v) TSRMG(mysqli_globals_id, zend_mysqli_globals *, v)
+#else
+#define MyG(v) (mysqli_globals.v)
+#endif
+
+#define my_estrdup(x) (x) ? estrdup(x) : NULL
+#define my_efree(x) if (x) efree(x)
+
+ZEND_EXTERN_MODULE_GLOBALS(mysqli)
+
+#endif /* PHP_MYSQLI_STRUCTS.H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */