PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/mysqli - mysqli_nonapi.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 439 475 92.4 %
Date: 2016-09-18 Functions: 30 30 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2016 The PHP Group                                |
       6             :   +----------------------------------------------------------------------+
       7             :   | This source file is subject to version 3.01 of the PHP license,      |
       8             :   | that is bundled with this package in the file LICENSE, and is        |
       9             :   | available through the world-wide-web at the following url:           |
      10             :   | http://www.php.net/license/3_01.txt                                  |
      11             :   | If you did not receive a copy of the PHP license and are unable to   |
      12             :   | obtain it through the world-wide-web, please send a note to          |
      13             :   | license@php.net so we can mail you a copy immediately.               |
      14             :   +----------------------------------------------------------------------+
      15             :   | Authors: Georg Richter <georg@php.net>                               |
      16             :   |          Andrey Hristov <andrey@php.net>                             |
      17             :   |          Ulf Wendel <uw@php.net>                                     |
      18             :   +----------------------------------------------------------------------+
      19             : 
      20             :   $Id$
      21             : */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include <signal.h>
      28             : 
      29             : #include "php.h"
      30             : #include "php_ini.h"
      31             : #include "ext/standard/info.h"
      32             : #include "zend_smart_str.h"
      33             : #include "php_mysqli_structs.h"
      34             : #include "mysqli_priv.h"
      35             : 
      36             : #define SAFE_STR(a) ((a)?a:"")
      37             : 
      38             : #ifndef zend_parse_parameters_none
      39             : #define zend_parse_parameters_none()    \
      40             :         zend_parse_parameters(ZEND_NUM_ARGS(), "")
      41             : #endif
      42             : 
      43             : /* {{{ php_mysqli_set_error
      44             :  */
      45        1201 : static void php_mysqli_set_error(zend_long mysql_errno, char *mysql_err)
      46             : {
      47        1201 :         MyG(error_no) = mysql_errno;
      48        1201 :         if (MyG(error_msg)) {
      49          17 :                 efree(MyG(error_msg));
      50             :         }
      51        1226 :         if(mysql_err && *mysql_err) {
      52          25 :                 MyG(error_msg) = estrdup(mysql_err);
      53             :         } else {
      54        1176 :                 MyG(error_msg) = NULL;
      55             :         }
      56        1201 : }
      57             : /* }}} */
      58             : 
      59        1283 : void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor) /* {{{ */
      60             : {
      61        1283 :         MY_MYSQL                        *mysql = NULL;
      62        1283 :         MYSQLI_RESOURCE         *mysqli_resource = NULL;
      63        2566 :         zval                            *object = getThis();
      64        1283 :         char                            *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
      65        1283 :         size_t                                  hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
      66        1283 :         zend_bool                       persistent = FALSE;
      67        1283 :         zend_long                               port = 0, flags = 0;
      68        1283 :         zend_string                     *hash_key = NULL;
      69        1283 :         zend_bool                       new_connection = FALSE;
      70             :         zend_resource           *le;
      71        1283 :         mysqli_plist_entry *plist = NULL;
      72        1283 :         zend_bool                       self_alloced = 0;
      73             : 
      74             : 
      75             : #if !defined(MYSQL_USE_MYSQLND)
      76        1283 :         if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
      77           0 :                 php_error_docref(NULL, E_WARNING,
      78             :                                                 "Headers and client library minor version mismatch. Headers:%d Library:%ld",
      79             :                                                 MYSQL_VERSION_ID, mysql_get_client_version());
      80             :         }
      81             : #endif
      82             : 
      83        2566 :         if (getThis() && !ZEND_NUM_ARGS() && in_ctor) {
      84          16 :                 php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, in_ctor);
      85          16 :                 return;
      86             :         }
      87        1267 :         hostname = username = dbname = passwd = socket = NULL;
      88             : 
      89        1267 :         if (!is_real_connect) {
      90        1120 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ssssls", &hostname, &hostname_len, &username, &username_len,
      91             :                                                                         &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
      92           1 :                         return;
      93             :                 }
      94             : 
      95        1119 :                 if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry)) {
      96          39 :                         mysqli_resource = (Z_MYSQLI_P(object))->ptr;
      97          39 :                         if (mysqli_resource && mysqli_resource->ptr) {
      98           7 :                                 mysql = (MY_MYSQL*) mysqli_resource->ptr;
      99             :                         }
     100             :                 }
     101        1119 :                 if (!mysql) {
     102        1112 :                         mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL));
     103        1112 :                         self_alloced = 1;
     104             :                 }
     105        1119 :                 flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
     106             :         } else {
     107             :                 /* We have flags too */
     108         294 :                 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|sssslsl", &object, mysqli_link_class_entry,
     109             :                                                                                 &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len,
     110             :                                                                                 &flags) == FAILURE) {
     111           8 :                         return;
     112             :                 }
     113             : 
     114         139 :                 mysqli_resource = (Z_MYSQLI_P(object))->ptr;
     115         139 :                 MYSQLI_FETCH_RESOURCE_CONN(mysql, object, MYSQLI_STATUS_INITIALIZED);
     116             : 
     117             :                 /* set some required options */
     118         138 :                 flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
     119             :                 /* remove some insecure options */
     120         138 :                 flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
     121             : #if !defined(MYSQLI_USE_MYSQLND)
     122             :                 if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
     123             :                         flags &= ~CLIENT_LOCAL_FILES;
     124             :                 }
     125             : #endif
     126             :         }
     127             : 
     128        1257 :         if (!socket_len || !socket) {
     129          46 :                 socket = MyG(default_socket);
     130             :         }
     131        1257 :         if (!port){
     132          37 :                 port = MyG(default_port);
     133             :         }
     134        1257 :         if (!passwd) {
     135          26 :                 passwd = MyG(default_pw);
     136          26 :                 passwd_len = strlen(SAFE_STR(passwd));
     137             :         }
     138        1257 :         if (!username){
     139          19 :                 username = MyG(default_user);
     140             :         }
     141        1257 :         if (!hostname || !hostname_len) {
     142          17 :                 hostname = MyG(default_host);
     143             :         }
     144             : 
     145        1402 :         if (mysql->mysql && mysqli_resource &&
     146         145 :                 (mysqli_resource->status > MYSQLI_STATUS_INITIALIZED))
     147             :         {
     148             :                 /* already connected, we should close the connection */
     149          13 :                 php_mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT, mysqli_resource->status);
     150             :         }
     151             : 
     152        1257 :         if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) {
     153          90 :                 hostname += 2;
     154          90 :                 if (!MyG(allow_persistent)) {
     155           0 :                         php_error_docref(NULL, E_WARNING, "Persistent connections are disabled. Downgrading to normal");
     156             :                 } else {
     157          90 :                         mysql->persistent = persistent = TRUE;
     158             : 
     159         270 :                         hash_key = strpprintf(0, "mysqli_%s_%s" ZEND_LONG_FMT "%s%s%s", SAFE_STR(hostname), SAFE_STR(socket),
     160         180 :                                                                 port, SAFE_STR(username), SAFE_STR(dbname),
     161          90 :                                                                 SAFE_STR(passwd));
     162             : 
     163          90 :                         mysql->hash_key = hash_key;
     164             : 
     165             :                         /* check if we can reuse exisiting connection ... */
     166          90 :                         if ((le = zend_hash_find_ptr(&EG(persistent_list), hash_key)) != NULL) {
     167          76 :                                 if (le->type == php_le_pmysqli()) {
     168          76 :                                         plist = (mysqli_plist_entry *) le->ptr;
     169             : 
     170             :                                         do {
     171          76 :                                                 if (zend_ptr_stack_num_elements(&plist->free_links)) {
     172         100 :                                                         mysql->mysql = zend_ptr_stack_pop(&plist->free_links);
     173             : 
     174          50 :                                                         MyG(num_inactive_persistent)--;
     175             :                                                         /* reset variables */
     176             : 
     177             : #ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT
     178          50 :                                                         if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname, passwd_len)) {
     179             : #else
     180             :                                                         if (!mysql_ping(mysql->mysql)) {
     181             : #endif
     182             : #ifdef MYSQLI_USE_MYSQLND
     183          49 :                                                                 mysqlnd_restart_psession(mysql->mysql);
     184             : #endif
     185          49 :                                                                 MyG(num_active_persistent)++;
     186          49 :                                                                 goto end;
     187             :                                                         } else {
     188           1 :                                                                 mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
     189           1 :                                                                 mysql->mysql = NULL;
     190             :                                                         }
     191             :                                                 }
     192             :                                         } while (0);
     193             :                                 }
     194             :                         } else {
     195             :                                 zend_resource le;
     196          14 :                                 le.type = php_le_pmysqli();
     197          14 :                                 le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
     198             : 
     199          14 :                                 zend_ptr_stack_init_ex(&plist->free_links, 1);
     200          14 :                                 zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(hash_key), ZSTR_LEN(hash_key), &le, sizeof(le));
     201             :                         }
     202             :                 }
     203             :         }
     204        1208 :         if (MyG(max_links) != -1 && MyG(num_links) >= MyG(max_links)) {
     205           5 :                 php_error_docref(NULL, E_WARNING, "Too many open links (" ZEND_LONG_FMT ")", MyG(num_links));
     206           5 :                 goto err;
     207             :         }
     208             : 
     209        1213 :         if (persistent && MyG(max_persistent) != -1 &&
     210          10 :                 (MyG(num_active_persistent) + MyG(num_inactive_persistent))>= MyG(max_persistent))
     211             :         {
     212           2 :                 php_error_docref(NULL, E_WARNING, "Too many open persistent links (" ZEND_LONG_FMT ")",
     213           2 :                                                                 MyG(num_active_persistent) + MyG(num_inactive_persistent));
     214           2 :                 goto err;
     215             :         }
     216        1201 :         if (!mysql->mysql) {
     217             : #if !defined(MYSQLI_USE_MYSQLND)
     218             :                 if (!(mysql->mysql = mysql_init(NULL))) {
     219             : #else
     220        1078 :                 if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent))) {
     221             : #endif
     222           0 :                         goto err;
     223             :                 }
     224        1078 :                 new_connection = TRUE;
     225             :         }
     226             : 
     227             : #ifdef HAVE_EMBEDDED_MYSQLI
     228             :         if (hostname_len) {
     229             :                 unsigned int external=1;
     230             :                 mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external);
     231             :         } else {
     232             :                 mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
     233             :         }
     234             : #endif
     235             : 
     236             : #if !defined(MYSQLI_USE_MYSQLND)
     237             :         /* BC for prior to bug fix #53425 */
     238             :         flags |= CLIENT_MULTI_RESULTS;
     239             : 
     240             :         if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL)
     241             : #else
     242        1201 :         if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
     243             :                                                 port, socket, flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA) == NULL)
     244             : #endif
     245             :         {
     246             :                 /* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
     247          29 :                 php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));
     248          58 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql),
     249          58 :                                                                                 "%s", mysql_error(mysql->mysql));
     250          29 :                 if (!is_real_connect) {
     251             :                         /* free mysql structure */
     252          18 :                         mysqli_close(mysql->mysql, MYSQLI_CLOSE_DISCONNECTED);
     253          18 :                         mysql->mysql = NULL;
     254             :                 }
     255          29 :                 goto err;
     256             :         }
     257             : 
     258             :         /* clear error */
     259        1172 :         php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));
     260             : 
     261             : #if !defined(MYSQLI_USE_MYSQLND)
     262             :         mysql->mysql->reconnect = MyG(reconnect);
     263             : #endif
     264             : 
     265        1172 :         mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
     266             : 
     267             : end:
     268        1221 :         if (!mysqli_resource) {
     269        1087 :                 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     270        1087 :                 mysqli_resource->ptr = (void *)mysql;
     271             :         }
     272        1221 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     273             : 
     274             :         /* store persistent connection */
     275        1221 :         if (persistent && (new_connection || is_real_connect)) {
     276          50 :                 MyG(num_active_persistent)++;
     277             :         }
     278             : 
     279        1221 :         MyG(num_links)++;
     280             : 
     281        1221 :         mysql->multi_query = 0;
     282             : 
     283        2280 :         if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry)) {
     284        1059 :                 MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
     285             :         } else {
     286         162 :                 (Z_MYSQLI_P(object))->ptr = mysqli_resource;
     287             :         }
     288        1221 :         if (!is_real_connect) {
     289        1094 :                 return;
     290             :         } else {
     291         127 :                 RETURN_TRUE;
     292             :         }
     293             : 
     294             : err:
     295          36 :         if (mysql->hash_key) {
     296           4 :                 zend_string_release(mysql->hash_key);
     297           4 :                 mysql->hash_key = NULL;
     298           4 :                 mysql->persistent = FALSE;
     299             :         }
     300          36 :         if (!is_real_connect && self_alloced) {
     301          25 :                 efree(mysql);
     302             :         }
     303          36 :         RETVAL_FALSE;
     304             : } /* }}} */
     305             : 
     306             : /* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])
     307             :    Open a connection to a mysql server */
     308        1094 : PHP_FUNCTION(mysqli_connect)
     309             : {
     310        1094 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, FALSE);
     311        1094 : }
     312             : /* }}} */
     313             : 
     314             : /* {{{ proto object mysqli_link_construct()
     315             :   */
     316          42 : PHP_FUNCTION(mysqli_link_construct)
     317             : {
     318          42 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, TRUE);
     319          42 : }
     320             : /* }}} */
     321             : 
     322             : /* {{{ proto int mysqli_connect_errno(void)
     323             :    Returns the numerical value of the error message from last connect command */
     324          26 : PHP_FUNCTION(mysqli_connect_errno)
     325             : {
     326          26 :         RETURN_LONG(MyG(error_no));
     327             : }
     328             : /* }}} */
     329             : 
     330             : /* {{{ proto string mysqli_connect_error(void)
     331             :    Returns the text of the error message from previous MySQL operation */
     332          18 : PHP_FUNCTION(mysqli_connect_error)
     333             : {
     334          18 :         if (MyG(error_msg)) {
     335          14 :                 RETURN_STRING(MyG(error_msg));
     336             :         } else {
     337          11 :                 RETURN_NULL();
     338             :         }
     339             : }
     340             : /* }}} */
     341             : 
     342             : /* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype])
     343             :    Fetch a result row as an associative array, a numeric array, or both */
     344       46640 : PHP_FUNCTION(mysqli_fetch_array)
     345             : {
     346       46640 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
     347       46640 : }
     348             : /* }}} */
     349             : 
     350             : /* {{{ proto mixed mysqli_fetch_assoc (object result)
     351             :    Fetch a result row as an associative array */
     352       18253 : PHP_FUNCTION(mysqli_fetch_assoc)
     353             : {
     354       18253 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
     355       18253 : }
     356             : /* }}} */
     357             : 
     358             : /* {{{ proto mixed mysqli_fetch_all (object result [,int resulttype])
     359             :    Fetches all result rows as an associative array, a numeric array, or both */
     360             : #if defined(MYSQLI_USE_MYSQLND)
     361         213 : PHP_FUNCTION(mysqli_fetch_all)
     362             : {
     363             :         MYSQL_RES       *result;
     364             :         zval            *mysql_result;
     365         213 :         zend_long               mode = MYSQLND_FETCH_NUM;
     366             : 
     367         426 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) {
     368           2 :                 return;
     369             :         }
     370         211 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
     371             : 
     372         211 :         if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) {
     373           2 :                 php_error_docref(NULL, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, "
     374             :                                  "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH");
     375           2 :                 RETURN_FALSE;
     376             :         }
     377             : 
     378         209 :         mysqlnd_fetch_all(result, mode, return_value);
     379             : }
     380             : /* }}} */
     381             : 
     382             : /* {{{ proto array mysqli_get_client_stats(void)
     383             :    Returns statistics about the zval cache */
     384          50 : PHP_FUNCTION(mysqli_get_client_stats)
     385             : {
     386          50 :         if (zend_parse_parameters_none() == FAILURE) {
     387           1 :                 return;
     388             :         }
     389          49 :         mysqlnd_get_client_stats(return_value);
     390             : }
     391             : /* }}} */
     392             : 
     393             : /* {{{ proto array mysqli_get_connection_stats(void)
     394             :    Returns statistics about the zval cache */
     395           7 : PHP_FUNCTION(mysqli_get_connection_stats)
     396             : {
     397             :         MY_MYSQL        *mysql;
     398             :         zval            *mysql_link;
     399             : 
     400          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
     401             :                                                                          &mysql_link, mysqli_link_class_entry) == FAILURE) {
     402           2 :                 return;
     403             :         }
     404           5 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     405             : 
     406           5 :         mysqlnd_get_connection_stats(mysql->mysql, return_value);
     407             : }
     408             : #endif
     409             : /* }}} */
     410             : 
     411             : /* {{{ proto mixed mysqli_error_list (object connection)
     412             :    Fetches all client errors */
     413           1 : PHP_FUNCTION(mysqli_error_list)
     414             : {
     415             :         MY_MYSQL        *mysql;
     416             :         zval            *mysql_link;
     417             : 
     418           2 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     419           0 :                 return;
     420             :         }
     421           1 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     422           1 :         array_init(return_value);
     423             : #if defined(MYSQLI_USE_MYSQLND)
     424           1 :         if (mysql->mysql->data->error_info->error_list) {
     425             :                 MYSQLND_ERROR_LIST_ELEMENT * message;
     426             :                 zend_llist_position pos;
     427           2 :                 for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos);
     428             :                          message;
     429           0 :                          message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos))
     430             :                 {
     431             :                         zval single_error;
     432           0 :                         array_init(&single_error);
     433           0 :                         add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
     434           0 :                         add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
     435           0 :                         add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
     436           0 :                         add_next_index_zval(return_value, &single_error);
     437             :                 }
     438             :         }
     439             : #else
     440             :         if (mysql_errno(mysql->mysql)) {
     441             :                 zval single_error;
     442             :                 array_init(&single_error);
     443             :                 add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
     444             :                 add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
     445             :                 add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
     446             :                 add_next_index_zval(return_value, &single_error);
     447             :         }
     448             : #endif
     449             : }
     450             : /* }}} */
     451             : 
     452             : /* {{{ proto string mysqli_stmt_error_list(object stmt)
     453             : */
     454           1 : PHP_FUNCTION(mysqli_stmt_error_list)
     455             : {
     456             :         MY_STMT *stmt;
     457             :         zval    *mysql_stmt;
     458             : 
     459           2 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     460           0 :                 return;
     461             :         }
     462           1 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
     463           1 :         array_init(return_value);
     464             : #if defined(MYSQLI_USE_MYSQLND)
     465           1 :         if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
     466             :                 MYSQLND_ERROR_LIST_ELEMENT * message;
     467             :                 zend_llist_position pos;
     468           2 :                 for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos);
     469             :                          message;
     470           0 :                          message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos))
     471             :                 {
     472             :                         zval single_error;
     473           0 :                         array_init(&single_error);
     474           0 :                         add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
     475           0 :                         add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
     476           0 :                         add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
     477           0 :                         add_next_index_zval(return_value, &single_error);
     478             :                 }
     479             :         }
     480             : #else
     481             :         if (mysql_stmt_errno(stmt->stmt)) {
     482             :                 zval single_error;
     483             :                 array_init(&single_error);
     484             :                 add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
     485             :                 add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
     486             :                 add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
     487             :                 add_next_index_zval(return_value, &single_error);
     488             :         }
     489             : #endif
     490             : }
     491             : /* }}} */
     492             : 
     493             : /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
     494             :    Fetch a result row as an object */
     495          30 : PHP_FUNCTION(mysqli_fetch_object)
     496             : {
     497          30 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
     498          28 : }
     499             : /* }}} */
     500             : 
     501             : /* {{{ proto bool mysqli_multi_query(object link, string query)
     502             :    allows to execute multiple queries  */
     503          28 : PHP_FUNCTION(mysqli_multi_query)
     504             : {
     505             :         MY_MYSQL        *mysql;
     506             :         zval            *mysql_link;
     507          28 :         char            *query = NULL;
     508             :         size_t          query_len;
     509             : 
     510          56 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
     511           2 :                 return;
     512             :         }
     513          26 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     514             : 
     515          25 :         MYSQLI_ENABLE_MQ;
     516          25 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
     517             : #ifndef MYSQLI_USE_MYSQLND
     518             :                 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
     519             :                 unsigned int s_errno;
     520             :                 /* we have to save error information, cause
     521             :                 MYSQLI_DISABLE_MQ will reset error information */
     522             :                 strcpy(s_error, mysql_error(mysql->mysql));
     523             :                 strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
     524             :                 s_errno = mysql_errno(mysql->mysql);
     525             : #else
     526           6 :                 MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
     527             : #endif
     528           6 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     529           6 :                 MYSQLI_DISABLE_MQ;
     530             : 
     531             : #ifndef MYSQLI_USE_MYSQLND
     532             :                 /* restore error information */
     533             :                 strcpy(mysql->mysql->net.last_error, s_error);
     534             :                 strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
     535             :                 mysql->mysql->net.last_errno = s_errno;
     536             : #else
     537           6 :                 *mysql->mysql->data->error_info = error_info;
     538             : #endif
     539           6 :                 RETURN_FALSE;
     540             :         }
     541          19 :         RETURN_TRUE;
     542             : }
     543             : /* }}} */
     544             : 
     545             : /* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
     546       18917 : PHP_FUNCTION(mysqli_query)
     547             : {
     548             :         MY_MYSQL                        *mysql;
     549             :         zval                            *mysql_link;
     550             :         MYSQLI_RESOURCE         *mysqli_resource;
     551       18917 :         MYSQL_RES                       *result = NULL;
     552       18917 :         char                            *query = NULL;
     553             :         size_t                          query_len;
     554       18917 :         zend_long                               resultmode = MYSQLI_STORE_RESULT;
     555             : 
     556       37834 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
     557          14 :                 return;
     558             :         }
     559             : 
     560       18903 :         if (!query_len) {
     561           1 :                 php_error_docref(NULL, E_WARNING, "Empty query");
     562           1 :                 RETURN_FALSE;
     563             :         }
     564             : #ifdef MYSQLI_USE_MYSQLND
     565       18902 :         if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) {
     566             : #else
     567             :         if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) {
     568             : #endif
     569           1 :                 php_error_docref(NULL, E_WARNING, "Invalid value for resultmode");
     570           1 :                 RETURN_FALSE;
     571             :         }
     572             : 
     573       18901 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     574             : 
     575       18891 :         MYSQLI_DISABLE_MQ;
     576             : 
     577             : 
     578             : #ifdef MYSQLI_USE_MYSQLND
     579       18891 :         if (resultmode & MYSQLI_ASYNC) {
     580          29 :                 if (mysqli_async_query(mysql->mysql, query, query_len)) {
     581           2 :                         MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     582           2 :                         RETURN_FALSE;
     583             :                 }
     584          27 :                 mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC;
     585          27 :                 RETURN_TRUE;
     586             :         }
     587             : #endif
     588             : 
     589       18862 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
     590          64 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     591          64 :                 RETURN_FALSE;
     592             :         }
     593             : 
     594       18798 :         if (!mysql_field_count(mysql->mysql)) {
     595             :                 /* no result set - not a SELECT */
     596       17307 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     597           0 :                         php_mysqli_report_index(query, mysqli_server_status(mysql->mysql));
     598             :                 }
     599       17307 :                 RETURN_TRUE;
     600             :         }
     601             : 
     602             : #ifdef MYSQLI_USE_MYSQLND
     603        1491 :         switch (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) {
     604             : #else
     605             :         switch (resultmode & ~MYSQLI_ASYNC) {
     606             : #endif
     607             :                 case MYSQLI_STORE_RESULT:
     608             : #ifdef MYSQLI_USE_MYSQLND
     609        1478 :                         if (resultmode & MYSQLI_STORE_RESULT_COPY_DATA) {
     610           0 :                                 result = mysqlnd_store_result_ofs(mysql->mysql);
     611             :                         } else
     612             : #endif
     613        1478 :                                 result = mysql_store_result(mysql->mysql);
     614        1478 :                         break;
     615             :                 case MYSQLI_USE_RESULT:
     616          13 :                         result = mysql_use_result(mysql->mysql);
     617             :                         break;
     618             :         }
     619        1491 :         if (!result) {
     620           2 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql),
     621           2 :                                                                                 "%s", mysql_error(mysql->mysql));
     622           1 :                 RETURN_FALSE;
     623             :         }
     624             : 
     625        1490 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     626           2 :                 php_mysqli_report_index(query, mysqli_server_status(mysql->mysql));
     627             :         }
     628             : 
     629        1490 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     630        1490 :         mysqli_resource->ptr = (void *)result;
     631        1490 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     632        1490 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     633             : }
     634             : /* }}} */
     635             : 
     636             : #if defined(MYSQLI_USE_MYSQLND)
     637             : #include "php_network.h"
     638             : /* {{{ mysqlnd_zval_array_to_mysqlnd_array functions */
     639          65 : static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_array)
     640             : {
     641             :         zval *elem;
     642          65 :         int i = 0, current = 0;
     643             : 
     644          65 :         if (Z_TYPE_P(in_array) != IS_ARRAY) {
     645           0 :                 return 0;
     646             :         }
     647          65 :         *out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *));
     648         311 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_array), elem) {
     649         123 :                 i++;
     650         246 :                 if (Z_TYPE_P(elem) != IS_OBJECT ||
     651         123 :                         !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) {
     652           0 :                         php_error_docref(NULL, E_WARNING, "Parameter %d not a mysqli object", i);
     653             :                 } else {
     654             :                         MY_MYSQL *mysql;
     655             :                         MYSQLI_RESOURCE *my_res;
     656         123 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     657         123 :                         if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
     658           2 :                                 php_error_docref(NULL, E_WARNING, "[%d] Couldn't fetch %s", i, ZSTR_VAL(intern->zo.ce->name));
     659           2 :                                 continue;
     660             :                         }
     661         121 :                         mysql = (MY_MYSQL*) my_res->ptr;
     662         121 :                         if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) {
     663           0 :                                 php_error_docref(NULL, E_WARNING, "Invalid object %d or resource %s", i, ZSTR_VAL(intern->zo.ce->name));
     664           0 :                                 continue;
     665             :                         }
     666         121 :                         (*out_array)[current++] = mysql->mysql;
     667             :                 }
     668             :         } ZEND_HASH_FOREACH_END();
     669          65 :         return 0;
     670             : }
     671             : /* }}} */
     672             : 
     673             : /* {{{ mysqlnd_zval_array_from_mysqlnd_array */
     674          65 : static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_array)
     675             : {
     676          65 :         MYSQLND **p = in_array;
     677             :         zval dest_array;
     678             :         zval *elem, *dest_elem;
     679          65 :         int ret = 0, i = 0;
     680             : 
     681          65 :         array_init_size(&dest_array, zend_hash_num_elements(Z_ARRVAL_P(out_array)));
     682             : 
     683         311 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(out_array), elem) {
     684         123 :                 i++;
     685         246 :                 if (Z_TYPE_P(elem) != IS_OBJECT ||
     686         123 :                                 !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) {
     687           0 :                         continue;
     688             :                 }
     689             :                 {
     690             :                         MY_MYSQL *mysql;
     691             :                         MYSQLI_RESOURCE *my_res;
     692         123 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     693         123 :                         if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
     694           2 :                                 php_error_docref(NULL, E_WARNING, "[%d] Couldn't fetch %s", i, ZSTR_VAL(intern->zo.ce->name));
     695           2 :                                 continue;
     696             :                         }
     697         121 :                         mysql = (MY_MYSQL *) my_res->ptr;
     698         121 :                         if (mysql->mysql == *p) {
     699          28 :                                 dest_elem = zend_hash_next_index_insert(Z_ARRVAL(dest_array), elem);
     700          28 :                                 if (dest_elem) {
     701          28 :                                         zval_add_ref(dest_elem);
     702             :                                 }
     703          28 :                                 ret++;
     704          28 :                                 p++;
     705             :                         }
     706             :                 }
     707             :         } ZEND_HASH_FOREACH_END();
     708             : 
     709             :         /* destroy old array and add new one */
     710          65 :         zval_ptr_dtor(out_array);
     711          65 :         ZVAL_COPY_VALUE(out_array, &dest_array);
     712             : 
     713          65 :         return 0;
     714             : }
     715             : /* }}} */
     716             : 
     717             : /* {{{ mysqlnd_dont_poll_zval_array_from_mysqlnd_array */
     718          33 : static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *in_zval_array, zval *out_array)
     719             : {
     720          33 :         MYSQLND **p = in_array;
     721             :         zval proxy, *elem, *dest_elem;
     722          33 :         int ret = 0;
     723             : 
     724          33 :         array_init(&proxy);
     725          33 :         if (in_array) {
     726          76 :                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_zval_array), elem) {
     727             :                         MY_MYSQL *mysql;
     728          29 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     729          29 :                         mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)intern->ptr)->ptr;
     730          29 :                         if (mysql->mysql == *p) {
     731          20 :                                 dest_elem = zend_hash_next_index_insert(Z_ARRVAL(proxy), elem);
     732          20 :                                 if (dest_elem) {
     733          20 :                                         zval_add_ref(dest_elem);
     734             :                                 }
     735          20 :                                 ret++;
     736          20 :                                 p++;
     737             :                         }
     738             :                 } ZEND_HASH_FOREACH_END();
     739             :         }
     740             : 
     741             :         /* destroy old array and add new one */
     742          33 :         zval_ptr_dtor(out_array);
     743          33 :         ZVAL_COPY_VALUE(out_array, &proxy);
     744             : 
     745          33 :         return 0;
     746             : }
     747             : /* }}} */
     748             : 
     749             : /* {{{ proto int mysqli_poll(array read, array write, array error, long sec [, long usec]) U
     750             :    Poll connections */
     751          42 : PHP_FUNCTION(mysqli_poll)
     752             : {
     753             :         zval                    *r_array, *e_array, *dont_poll_array;
     754          42 :         MYSQLND                 **new_r_array = NULL, **new_e_array = NULL, **new_dont_poll_array = NULL;
     755          42 :         zend_long                       sec = 0, usec = 0;
     756             :         enum_func_status ret;
     757             :         int                     desc_num;
     758             : 
     759          42 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) {
     760           6 :                 return;
     761             :         }
     762          36 :         if (sec < 0 || usec < 0) {
     763           2 :                 php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec");
     764           2 :                 RETURN_FALSE;
     765             :         }
     766             : 
     767          34 :         if (!r_array && !e_array) {
     768           1 :                 php_error_docref(NULL, E_WARNING, "No stream arrays were passed");
     769           1 :                 RETURN_FALSE;
     770             :         }
     771             : 
     772          33 :         if (r_array != NULL) {
     773          33 :                 mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array);
     774             :         }
     775          33 :         if (e_array != NULL) {
     776          32 :                 mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array);
     777             :         }
     778             : 
     779          33 :         ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num);
     780             : 
     781          33 :         mysqlnd_dont_poll_zval_array_from_mysqlnd_array(r_array != NULL ? new_dont_poll_array:NULL, r_array, dont_poll_array);
     782             : 
     783          33 :         if (r_array != NULL) {
     784          33 :                 mysqlnd_zval_array_from_mysqlnd_array(new_r_array, r_array);
     785             :         }
     786          33 :         if (e_array != NULL) {
     787          32 :                 mysqlnd_zval_array_from_mysqlnd_array(new_e_array, e_array);
     788             :         }
     789             : 
     790          33 :         if (new_dont_poll_array) {
     791          18 :                 efree(new_dont_poll_array);
     792             :         }
     793          33 :         if (new_r_array) {
     794          33 :                 efree(new_r_array);
     795             :         }
     796          33 :         if (new_e_array) {
     797          32 :                 efree(new_e_array);
     798             :         }
     799          33 :         if (ret == PASS) {
     800          29 :                 RETURN_LONG(desc_num);
     801             :         } else {
     802           4 :                 RETURN_FALSE;
     803             :         }
     804             : }
     805             : /* }}} */
     806             : 
     807             : /* {{{ proto int mysqli_reap_async_query(object link) U
     808             :    Poll connections */
     809          29 : PHP_FUNCTION(mysqli_reap_async_query)
     810             : {
     811             :         MY_MYSQL                *mysql;
     812             :         zval                    *mysql_link;
     813             :         MYSQLI_RESOURCE         *mysqli_resource;
     814          29 :         MYSQL_RES                       *result = NULL;
     815             : 
     816          58 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     817           3 :                 return;
     818             :         }
     819             : 
     820          26 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     821             : 
     822          26 :         if (FAIL == mysqlnd_reap_async_query(mysql->mysql)) {
     823           4 :                 RETURN_FALSE;
     824             :         }
     825             : 
     826          22 :         if (!mysql_field_count(mysql->mysql)) {
     827             :                 /* no result set - not a SELECT */
     828           7 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     829             : /*                      php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql)); */
     830             :                 }
     831           7 :                 RETURN_TRUE;
     832             :         }
     833             : 
     834          15 :         switch (mysql->async_result_fetch_type) {
     835             :                 case MYSQLI_STORE_RESULT:
     836           1 :                         result = mysql_store_result(mysql->mysql);
     837           1 :                         break;
     838             :                 case MYSQLI_USE_RESULT:
     839          14 :                         result = mysql_use_result(mysql->mysql);
     840             :                         break;
     841             :         }
     842             : 
     843          15 :         if (!result) {
     844           0 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql),
     845           0 :                                                                                 "%s", mysql_error(mysql->mysql));
     846           0 :                 RETURN_FALSE;
     847             :         }
     848             : 
     849          15 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     850             : /*              php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql)); */
     851             :         }
     852             : 
     853          15 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     854          15 :         mysqli_resource->ptr = (void *)result;
     855          15 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     856          15 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     857             : }
     858             : /* }}} */
     859             : 
     860             : /* {{{ proto object mysqli_stmt_get_result(object link) U
     861             :    Buffer result set on client */
     862         591 : PHP_FUNCTION(mysqli_stmt_get_result)
     863             : {
     864             :         MYSQL_RES               *result;
     865             :         MYSQLI_RESOURCE *mysqli_resource;
     866             :         MY_STMT                 *stmt;
     867             :         zval                    *mysql_stmt;
     868             : 
     869        1182 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     870           5 :                 return;
     871             :         }
     872         586 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     873             : 
     874         584 :         if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) {
     875           6 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
     876           6 :                 RETURN_FALSE;
     877             :         }
     878             : 
     879         578 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     880         578 :         mysqli_resource->ptr = (void *)result;
     881         578 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     882         578 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     883             : }
     884             : /* }}} */
     885             : #endif
     886             : 
     887             : /* {{{ proto object mysqli_get_warnings(object link) */
     888           5 : PHP_FUNCTION(mysqli_get_warnings)
     889             : {
     890             :         MY_MYSQL                        *mysql;
     891             :         zval                            *mysql_link;
     892             :         MYSQLI_RESOURCE         *mysqli_resource;
     893             :         MYSQLI_WARNING          *w;
     894             : 
     895          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     896           0 :                 return;
     897             :         }
     898           5 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     899             : 
     900           5 :         if (mysql_warning_count(mysql->mysql)) {
     901             : #ifdef MYSQLI_USE_MYSQLND
     902           5 :                 w = php_get_warnings(mysql->mysql->data);
     903             : #else
     904             :                 w = php_get_warnings(mysql->mysql);
     905             : #endif
     906             :         } else {
     907           0 :                 RETURN_FALSE;
     908             :         }
     909           5 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     910           5 :         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
     911           5 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     912           5 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
     913             : }
     914             : /* }}} */
     915             : 
     916             : /* {{{ proto object mysqli_stmt_get_warnings(object link) */
     917           7 : PHP_FUNCTION(mysqli_stmt_get_warnings)
     918             : {
     919             :         MY_STMT                         *stmt;
     920             :         zval                            *stmt_link;
     921             :         MYSQLI_RESOURCE         *mysqli_resource;
     922             :         MYSQLI_WARNING          *w;
     923             : 
     924          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) {
     925           2 :                 return;
     926             :         }
     927           5 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, stmt_link, MYSQLI_STATUS_VALID);
     928             : 
     929           3 :         if (mysqli_stmt_warning_count(stmt->stmt)) {
     930           1 :                 w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt));
     931             :         } else {
     932           2 :                 RETURN_FALSE;
     933             :         }
     934           1 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     935           1 :         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
     936           1 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     937           1 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
     938             : }
     939             : /* }}} */
     940             : 
     941             : #ifdef HAVE_MYSQLI_SET_CHARSET
     942             : /* {{{ proto bool mysqli_set_charset(object link, string csname)
     943             :    sets client character set */
     944         103 : PHP_FUNCTION(mysqli_set_charset)
     945             : {
     946             :         MY_MYSQL        *mysql;
     947             :         zval            *mysql_link;
     948             :         char            *cs_name;
     949             :         size_t          csname_len;
     950             : 
     951         206 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &csname_len) == FAILURE) {
     952           4 :                 return;
     953             :         }
     954          99 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     955             : 
     956          97 :         if (mysql_set_character_set(mysql->mysql, cs_name)) {
     957           2 :                 RETURN_FALSE;
     958             :         }
     959          95 :         RETURN_TRUE;
     960             : }
     961             : /* }}} */
     962             : #endif
     963             : 
     964             : #ifdef HAVE_MYSQLI_GET_CHARSET
     965             : /* {{{ proto object mysqli_get_charset(object link) U
     966             :    returns a character set object */
     967          10 : PHP_FUNCTION(mysqli_get_charset)
     968             : {
     969             :         MY_MYSQL                                *mysql;
     970             :         zval                                    *mysql_link;
     971          10 :         const char                              *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL;
     972             :         uint                                    minlength, maxlength, number, state;
     973             : #if !defined(MYSQLI_USE_MYSQLND)
     974             :         MY_CHARSET_INFO                 cs;
     975             : #else
     976             :         const MYSQLND_CHARSET   *cs;
     977             : #endif
     978             : 
     979          20 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     980           2 :                 return;
     981             :         }
     982           8 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     983             : 
     984             : 
     985             : #if !defined(MYSQLI_USE_MYSQLND)
     986             :         mysql_get_character_set_info(mysql->mysql, &cs);
     987             :         name = (char *)cs.csname;
     988             :         collation = (char *)cs.name;
     989             :         dir = (char *)cs.dir;
     990             :         minlength = cs.mbminlen;
     991             :         maxlength = cs.mbmaxlen;
     992             :         number = cs.number;
     993             :         state = cs.state;
     994             :         comment = cs.comment;
     995             : #else
     996           7 :         cs = mysql->mysql->data->charset;
     997           7 :         if (!cs) {
     998           0 :                 php_error_docref(NULL, E_WARNING, "The connection has no charset associated");
     999           0 :                 RETURN_NULL();
    1000             :         }
    1001           7 :         name = cs->name;
    1002           7 :         collation = cs->collation;
    1003           7 :         minlength = cs->char_minlen;
    1004           7 :         maxlength = cs->char_maxlen;
    1005           7 :         number = cs->nr;
    1006           7 :         comment = cs->comment;
    1007           7 :         state = 1;      /* all charsets are compiled in */
    1008             : #endif
    1009           7 :         object_init(return_value);
    1010             : 
    1011           7 :         add_property_string(return_value, "charset", (name) ? (char *)name : "");
    1012           7 :         add_property_string(return_value, "collation",(collation) ? (char *)collation : "");
    1013           7 :         add_property_string(return_value, "dir", (dir) ? (char *)dir : "");
    1014           7 :         add_property_long(return_value, "min_length", minlength);
    1015           7 :         add_property_long(return_value, "max_length", maxlength);
    1016           7 :         add_property_long(return_value, "number", number);
    1017           7 :         add_property_long(return_value, "state", state);
    1018           7 :         add_property_string(return_value, "comment", (comment) ? (char *)comment : "");
    1019             : }
    1020             : /* }}} */
    1021             : #endif
    1022             : 
    1023             : #if !defined(MYSQLI_USE_MYSQLND)
    1024             : extern char * mysqli_escape_string_for_tx_name_in_comment(const char * const name);
    1025             : 
    1026             : /* {{{ proto bool mysqli_begin_transaction_libmysql */
    1027             : static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name)
    1028             : {
    1029             :         int ret;
    1030             :         zend_bool err = FALSE;
    1031             :         smart_str tmp_str = {0};
    1032             :         if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
    1033             :                 if (tmp_str.s) {
    1034             :                         smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1035             :                 }
    1036             :                 smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
    1037             :         }
    1038             :         if (mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY)) {
    1039             :                 if (mysql_get_server_version(conn) < 50605L) {
    1040             :                         php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
    1041             :                         err = TRUE;
    1042             :                 } else if (mode & TRANS_START_READ_WRITE) {
    1043             :                         if (tmp_str.s) {
    1044             :                                 smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1045             :                         }
    1046             :                         smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
    1047             :                 } else if (mode & TRANS_START_READ_ONLY) {
    1048             :                         if (tmp_str.s) {
    1049             :                                 smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1050             :                         }
    1051             :                         smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
    1052             :                 }
    1053             :         }
    1054             :         smart_str_0(&tmp_str);
    1055             : 
    1056             :         if (err == FALSE){
    1057             :                 char * name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
    1058             :                 char * query;
    1059             :                 unsigned int query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
    1060             :                                                                                   name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
    1061             : 
    1062             :                 smart_str_free(&tmp_str);
    1063             :                 if (name_esc) {
    1064             :                         efree(name_esc);
    1065             :                 }
    1066             : 
    1067             :                 ret = mysql_real_query(conn, query, query_len);
    1068             :                 efree(query);
    1069             :         }
    1070             :         return ret;
    1071             : }
    1072             : /* }}} */
    1073             : #endif
    1074             : 
    1075             : /* {{{ proto bool mysqli_begin_transaction(object link, [int flags [, string name]])
    1076             :    Starts a transaction */
    1077           9 : PHP_FUNCTION(mysqli_begin_transaction)
    1078             : {
    1079             :         MY_MYSQL        *mysql;
    1080             :         zval            *mysql_link;
    1081           9 :         zend_long               flags = TRANS_START_NO_OPT;
    1082           9 :         char *          name = NULL;
    1083           9 :         size_t                  name_len = -1;
    1084           9 :         zend_bool       err = FALSE;
    1085             : 
    1086          18 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
    1087           6 :                 return;
    1088             :         }
    1089           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1090           3 :         if (flags < 0) {
    1091           1 :                 php_error_docref(NULL, E_WARNING, "Invalid value for parameter flags (" ZEND_LONG_FMT ")", flags);
    1092           1 :                 err = TRUE;
    1093             :         }
    1094           3 :         if (!name_len) {
    1095           0 :                 php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
    1096           0 :                 err = TRUE;
    1097             :         }
    1098           3 :         if (TRUE == err) {
    1099           1 :                 RETURN_FALSE;
    1100             :         }
    1101             : 
    1102             : #if !defined(MYSQLI_USE_MYSQLND)
    1103             :         if (mysqli_begin_transaction_libmysql(mysql->mysql, flags, name)) {
    1104             :                 RETURN_FALSE;
    1105             :         }
    1106             : #else
    1107           2 :         if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) {
    1108           0 :                 RETURN_FALSE;
    1109             :         }
    1110             : #endif
    1111           2 :         RETURN_TRUE;
    1112             : }
    1113             : /* }}} */
    1114             : 
    1115             : #if !defined(MYSQLI_USE_MYSQLND)
    1116             : /* {{{ proto bool mysqli_savepoint_libmysql */
    1117             : static int mysqli_savepoint_libmysql(MYSQL * conn, const char * const name, zend_bool release)
    1118             : {
    1119             :         int ret;
    1120             :         char * query;
    1121             :         unsigned int query_len = spprintf(&query, 0, release? "RELEASE SAVEPOINT `%s`":"SAVEPOINT `%s`", name);
    1122             :         ret = mysql_real_query(conn, query, query_len);
    1123             :         efree(query);
    1124             :         return ret;
    1125             : }
    1126             : /* }}} */
    1127             : #endif
    1128             : 
    1129             : /* {{{ proto bool mysqli_savepoint(object link, string name)
    1130             :    Starts a transaction */
    1131           7 : PHP_FUNCTION(mysqli_savepoint)
    1132             : {
    1133             :         MY_MYSQL        *mysql;
    1134             :         zval            *mysql_link;
    1135           7 :         char *          name = NULL;
    1136           7 :         size_t                  name_len = -1;
    1137             : 
    1138          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
    1139           4 :                 return;
    1140             :         }
    1141           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1142           3 :         if (!name || !name_len) {
    1143           1 :                 php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
    1144           1 :                 RETURN_FALSE;
    1145             :         }
    1146             : 
    1147             : #if !defined(MYSQLI_USE_MYSQLND)
    1148             :         if (mysqli_savepoint_libmysql(mysql->mysql, name, FALSE)) {
    1149             : #else
    1150           2 :         if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
    1151             : #endif
    1152           0 :                 RETURN_FALSE;
    1153             :         }
    1154           2 :         RETURN_TRUE;
    1155             : }
    1156             : /* }}} */
    1157             : 
    1158             : /* {{{ proto bool mysqli_release_savepoint(object link, string name)
    1159             :    Starts a transaction */
    1160           7 : PHP_FUNCTION(mysqli_release_savepoint)
    1161             : {
    1162             :         MY_MYSQL        *mysql;
    1163             :         zval            *mysql_link;
    1164           7 :         char *          name = NULL;
    1165           7 :         size_t                  name_len = -1;
    1166             : 
    1167          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
    1168           4 :                 return;
    1169             :         }
    1170           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1171           3 :         if (!name || !name_len) {
    1172           1 :                 php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
    1173           1 :                 RETURN_FALSE;
    1174             :         }
    1175             : #if !defined(MYSQLI_USE_MYSQLND)
    1176             :         if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) {
    1177             : #else
    1178           2 :         if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
    1179             : #endif
    1180           0 :                 RETURN_FALSE;
    1181             :         }
    1182           2 :         RETURN_TRUE;
    1183             : }
    1184             : /* }}} */
    1185             : 
    1186             : /* {{{ proto bool mysqli_get_links_stats()
    1187             :    Returns information about open and cached links */
    1188           7 : PHP_FUNCTION(mysqli_get_links_stats)
    1189             : {
    1190           7 :         if (ZEND_NUM_ARGS()) {
    1191           1 :                 php_error_docref(NULL, E_WARNING, "no parameters expected");
    1192           1 :                 return;
    1193             :         }
    1194           6 :         array_init(return_value);
    1195           6 :         add_assoc_long_ex(return_value, "total", sizeof("total") - 1, MyG(num_links));
    1196           6 :         add_assoc_long_ex(return_value, "active_plinks", sizeof("active_plinks") - 1, MyG(num_active_persistent));
    1197           6 :         add_assoc_long_ex(return_value, "cached_plinks", sizeof("cached_plinks") - 1, MyG(num_inactive_persistent));
    1198             : }
    1199             : /* }}} */
    1200             : 
    1201             : 
    1202             : /*
    1203             :  * Local variables:
    1204             :  * tab-width: 4
    1205             :  * c-basic-offset: 4
    1206             :  * End:
    1207             :  * vim600: noet sw=4 ts=4 fdm=marker
    1208             :  * vim<600: noet sw=4 ts=4
    1209             :  */

Generated by: LCOV version 1.10

Generated at Sun, 18 Sep 2016 08:20:09 +0000 (8 days ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.