Back to index

php5  5.3.10
mysqli_nonapi.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Authors: Georg Richter <georg@php.net>                               |
00016   |          Andrey Hristov <andrey@php.net>                             |
00017   |          Ulf Wendel <uw@php.net>                                     |
00018   +----------------------------------------------------------------------+
00019 
00020   $Id: mysqli_nonapi.c 321634 2012-01-01 13:15:04Z felipe $
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include <signal.h>
00028 
00029 #include "php.h"
00030 #include "php_ini.h"
00031 #include "ext/standard/info.h"
00032 #include "php_mysqli_structs.h"
00033 #include "mysqli_priv.h"
00034 
00035 #define SAFE_STR(a) ((a)?a:"")
00036 
00037 #ifndef zend_parse_parameters_none
00038 #define zend_parse_parameters_none()      \
00039         zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")
00040 #endif
00041 
00042 /* {{{ php_mysqli_set_error
00043  */
00044 static void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRMLS_DC)
00045 {
00046        MyG(error_no) = mysql_errno;
00047        if (MyG(error_msg)) {
00048               efree(MyG(error_msg));
00049        }
00050        if(mysql_err && *mysql_err) {
00051               MyG(error_msg) = estrdup(mysql_err);
00052        } else {
00053               MyG(error_msg) = NULL;
00054        }
00055 }
00056 /* }}} */
00057 
00058 
00059 void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor)
00060 {
00061        MY_MYSQL                    *mysql = NULL;
00062        MYSQLI_RESOURCE             *mysqli_resource = NULL;
00063        zval                        *object = getThis();
00064        char                        *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
00065        int                                hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
00066        zend_bool                   persistent = FALSE;
00067        long                        port = 0, flags = 0;
00068        uint                        hash_len;
00069        char                        *hash_key = NULL;
00070        zend_bool                   new_connection = FALSE;
00071        zend_rsrc_list_entry *le;
00072        mysqli_plist_entry *plist = NULL;
00073        zend_bool                   self_alloced = 0;
00074 
00075 
00076 #if !defined(MYSQL_USE_MYSQLND)
00077        if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
00078               php_error_docref(NULL TSRMLS_CC, E_WARNING,
00079                                           "Headers and client library minor version mismatch. Headers:%d Library:%ld",
00080                                           MYSQL_VERSION_ID, mysql_get_client_version());
00081        }
00082 #endif
00083 
00084        if (getThis() && !ZEND_NUM_ARGS() && in_ctor) {
00085               php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU);
00086               return;
00087        }
00088        hostname = username = dbname = passwd = socket = NULL;
00089 
00090        if (!is_real_connect) {
00091               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len,
00092                                                                &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
00093                      return;
00094               }
00095 
00096               if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
00097                      mysqli_resource = ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr;
00098                      if (mysqli_resource && mysqli_resource->ptr) {
00099                             mysql = (MY_MYSQL*) mysqli_resource->ptr;
00100                      }
00101               }
00102               if (!mysql) {
00103                      mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL));
00104                      self_alloced = 1;
00105               }
00106               flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
00107        } else {
00108               /* We have flags too */
00109               if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|sssslsl", &object, mysqli_link_class_entry,
00110                                                                       &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len,
00111                                                                       &flags) == FAILURE) {
00112                      return;
00113               }
00114 
00115               mysqli_resource = ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr;
00116               MYSQLI_FETCH_RESOURCE_CONN(mysql, &object, MYSQLI_STATUS_INITIALIZED);
00117 
00118               /* set some required options */
00119               flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
00120               /* remove some insecure options */
00121               flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
00122               if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
00123                      flags &= ~CLIENT_LOCAL_FILES;
00124               }
00125        }
00126 
00127        if (!socket_len || !socket) {
00128               socket = MyG(default_socket);
00129        }
00130        if (!port){
00131               port = MyG(default_port);
00132        }
00133        if (!passwd) {
00134               passwd = MyG(default_pw);
00135               passwd_len = strlen(SAFE_STR(passwd));
00136        }
00137        if (!username){
00138               username = MyG(default_user);
00139        }
00140        if (!hostname || !hostname_len) {
00141               hostname = MyG(default_host);
00142        }
00143 
00144        if (mysql->mysql && mysqli_resource &&
00145               (mysqli_resource->status > MYSQLI_STATUS_INITIALIZED))
00146        {
00147               /* already connected, we should close the connection */
00148               php_mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT, mysqli_resource->status TSRMLS_CC);
00149        }
00150 
00151        if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) {
00152               hostname += 2;
00153               if (!MyG(allow_persistent)) {
00154                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Persistent connections are disabled. Downgrading to normal");
00155               } else {
00156                      mysql->persistent = persistent = TRUE;
00157 
00158                      hash_len = spprintf(&hash_key, 0, "mysqli_%s_%s%ld%s%s%s", SAFE_STR(hostname), SAFE_STR(socket),
00159                                                         port, SAFE_STR(username), SAFE_STR(dbname),
00160                                                         SAFE_STR(passwd));
00161 
00162                      mysql->hash_key = hash_key;
00163 
00164                      /* check if we can reuse exisiting connection ... */
00165                      if (zend_hash_find(&EG(persistent_list), hash_key, hash_len + 1, (void **)&le) == SUCCESS) {
00166                             if (Z_TYPE_P(le) == php_le_pmysqli()) {
00167                                    plist = (mysqli_plist_entry *) le->ptr;
00168 
00169                                    do {
00170                                           if (zend_ptr_stack_num_elements(&plist->free_links)) {
00171                                                  mysql->mysql = zend_ptr_stack_pop(&plist->free_links);
00172 
00173                                                  MyG(num_inactive_persistent)--;
00174                                                  /* reset variables */
00175 
00176 #ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT
00177                                                  if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname)) {
00178 #else
00179                                                  if (!mysql_ping(mysql->mysql)) {
00180 #endif
00181 #ifdef MYSQLI_USE_MYSQLND
00182                                                         mysqlnd_restart_psession(mysql->mysql);
00183 #endif
00184                                                         MyG(num_active_persistent)++;
00185                                                         goto end;
00186                                                  } else {
00187                                                         mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
00188                                                         mysql->mysql = NULL;
00189                                                  }
00190                                           }
00191                                    } while (0);
00192                             }
00193                      } else {
00194                             zend_rsrc_list_entry le;
00195                             le.type = php_le_pmysqli();
00196                             le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
00197 
00198                             zend_ptr_stack_init_ex(&plist->free_links, 1);
00199                             zend_hash_update(&EG(persistent_list), hash_key, hash_len + 1, (void *)&le, sizeof(le), NULL);
00200                      }
00201               }
00202        }
00203        if (MyG(max_links) != -1 && MyG(num_links) >= MyG(max_links)) {
00204               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MyG(num_links));
00205               goto err;
00206        }
00207 
00208        if (persistent && MyG(max_persistent) != -1 &&
00209               (MyG(num_active_persistent) + MyG(num_inactive_persistent))>= MyG(max_persistent))
00210        {
00211               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)",
00212                                                         MyG(num_active_persistent) + MyG(num_inactive_persistent));
00213               goto err;
00214        }
00215        if (!mysql->mysql) {
00216 #if !defined(MYSQLI_USE_MYSQLND)
00217               if (!(mysql->mysql = mysql_init(NULL))) {
00218 #else
00219               if (!(mysql->mysql = mysqlnd_init(persistent))) {
00220 #endif
00221                      goto err;
00222               }
00223               new_connection = TRUE;
00224        }
00225 
00226 #ifdef HAVE_EMBEDDED_MYSQLI
00227        if (hostname_len) {
00228               unsigned int external=1;
00229               mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external);
00230        } else {
00231               mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
00232        }
00233 #endif
00234 
00235 #if !defined(MYSQLI_USE_MYSQLND)
00236        /* BC for prior to bug fix #53425 */
00237        flags |= CLIENT_MULTI_RESULTS;
00238 
00239        if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL)
00240 #else
00241        if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
00242                                           port, socket, flags TSRMLS_CC) == NULL)
00243 #endif
00244        {
00245               /* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
00246               php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
00247               php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
00248                                                                       "%s", mysql_error(mysql->mysql));
00249               if (!is_real_connect) {
00250                      /* free mysql structure */
00251                      mysqli_close(mysql->mysql, MYSQLI_CLOSE_DISCONNECTED);
00252                      mysql->mysql = NULL;
00253               }
00254               goto err;
00255        }
00256 
00257        /* clear error */
00258        php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
00259 
00260 #if !defined(MYSQLI_USE_MYSQLND)
00261        mysql->mysql->reconnect = MyG(reconnect);
00262 
00263        /* set our own local_infile handler */
00264        php_set_local_infile_handler_default(mysql);
00265 #endif
00266 
00267        mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
00268 
00269 end:
00270        if (!mysqli_resource) {
00271               mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
00272               mysqli_resource->ptr = (void *)mysql;
00273        }
00274        mysqli_resource->status = MYSQLI_STATUS_VALID;
00275 
00276        /* store persistent connection */
00277        if (persistent && (new_connection || is_real_connect)) {
00278               MyG(num_active_persistent)++;
00279        }
00280 
00281        MyG(num_links)++;
00282 
00283        mysql->multi_query = 0;
00284 
00285        if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
00286               MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
00287        } else {
00288               ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr = mysqli_resource;
00289        }
00290        if (!is_real_connect) {
00291               return;
00292        } else {
00293               RETURN_TRUE;
00294        }
00295 
00296 err:
00297        if (mysql->hash_key) {
00298               efree(mysql->hash_key);
00299               mysql->hash_key = NULL;
00300               mysql->persistent = FALSE;
00301        }
00302        if (!is_real_connect && self_alloced) {
00303               efree(mysql);
00304        }
00305        RETVAL_FALSE;
00306 }
00307 
00308 
00309 /* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])
00310    Open a connection to a mysql server */
00311 PHP_FUNCTION(mysqli_connect)
00312 {
00313        mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, FALSE);
00314 }
00315 /* }}} */
00316 
00317 
00318 /* {{{ proto object mysqli_link_construct()
00319   */
00320 PHP_FUNCTION(mysqli_link_construct)
00321 {
00322        mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, TRUE);
00323 }
00324 /* }}} */
00325 
00326 
00327 /* {{{ proto int mysqli_connect_errno(void)
00328    Returns the numerical value of the error message from last connect command */
00329 PHP_FUNCTION(mysqli_connect_errno)
00330 {
00331        RETURN_LONG(MyG(error_no));
00332 }
00333 /* }}} */
00334 
00335 /* {{{ proto string mysqli_connect_error(void)
00336    Returns the text of the error message from previous MySQL operation */
00337 PHP_FUNCTION(mysqli_connect_error)
00338 {
00339        if (MyG(error_msg)) {
00340               RETURN_STRING(MyG(error_msg),1);
00341        } else {
00342               RETURN_NULL();
00343        }
00344 }
00345 /* }}} */
00346 
00347 
00348 /* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype])
00349    Fetch a result row as an associative array, a numeric array, or both */
00350 PHP_FUNCTION(mysqli_fetch_array)
00351 {
00352        php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
00353 }
00354 /* }}} */
00355 
00356 /* {{{ proto mixed mysqli_fetch_assoc (object result)
00357    Fetch a result row as an associative array */
00358 PHP_FUNCTION(mysqli_fetch_assoc)
00359 {
00360        php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
00361 }
00362 /* }}} */
00363 
00364 
00365 /* {{{ proto mixed mysqli_fetch_all (object result [,int resulttype])
00366    Fetches all result rows as an associative array, a numeric array, or both */
00367 #if defined(MYSQLI_USE_MYSQLND)
00368 PHP_FUNCTION(mysqli_fetch_all)
00369 {
00370        MYSQL_RES     *result;
00371        zval          *mysql_result;
00372        long          mode = MYSQLND_FETCH_NUM;
00373 
00374        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) {
00375               return;
00376        }
00377        MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
00378 
00379        if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) {
00380               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, "
00381                                "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH");
00382               RETURN_FALSE;
00383        }
00384 
00385        mysqlnd_fetch_all(result, mode, return_value);
00386 }
00387 /* }}} */
00388 
00389 
00390 /* {{{ proto array mysqli_cache_stats(void) U
00391    Returns statistics about the zval cache */
00392 PHP_FUNCTION(mysqli_get_cache_stats)
00393 {
00394        if (zend_parse_parameters_none() == FAILURE) {
00395               return;
00396        }
00397        array_init(return_value);
00398 }
00399 /* }}} */
00400 
00401 
00402 /* {{{ proto array mysqli_get_client_stats(void)
00403    Returns statistics about the zval cache */
00404 PHP_FUNCTION(mysqli_get_client_stats)
00405 {
00406        if (zend_parse_parameters_none() == FAILURE) {
00407               return;
00408        }
00409        mysqlnd_get_client_stats(return_value);
00410 }
00411 /* }}} */
00412 
00413 
00414 /* {{{ proto array mysqli_get_connection_stats(void)
00415    Returns statistics about the zval cache */
00416 PHP_FUNCTION(mysqli_get_connection_stats)
00417 {
00418        MY_MYSQL      *mysql;
00419        zval          *mysql_link;
00420 
00421        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
00422                                                                 &mysql_link, mysqli_link_class_entry) == FAILURE) {
00423               return;
00424        }
00425        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00426 
00427        mysqlnd_get_connection_stats(mysql->mysql, return_value);
00428 }
00429 #endif
00430 /* }}} */
00431 
00432 
00433 /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
00434    Fetch a result row as an object */
00435 PHP_FUNCTION(mysqli_fetch_object)
00436 {
00437        php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
00438 }
00439 /* }}} */
00440 
00441 /* {{{ proto bool mysqli_multi_query(object link, string query)
00442    allows to execute multiple queries  */
00443 PHP_FUNCTION(mysqli_multi_query)
00444 {
00445        MY_MYSQL      *mysql;
00446        zval          *mysql_link;
00447        char          *query = NULL;
00448        int           query_len;
00449 
00450        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
00451               return;
00452        }
00453        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00454 
00455        MYSQLI_ENABLE_MQ;
00456        if (mysql_real_query(mysql->mysql, query, query_len)) {
00457 #ifndef MYSQLI_USE_MYSQLND
00458               char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
00459               unsigned int s_errno;
00460               /* we have to save error information, cause
00461               MYSQLI_DISABLE_MQ will reset error information */
00462               strcpy(s_error, mysql_error(mysql->mysql));
00463               strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
00464               s_errno = mysql_errno(mysql->mysql);
00465 #else
00466               MYSQLND_ERROR_INFO error_info = mysql->mysql->error_info;
00467 #endif
00468               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
00469               MYSQLI_DISABLE_MQ;
00470 
00471 #ifndef MYSQLI_USE_MYSQLND
00472               /* restore error information */
00473               strcpy(mysql->mysql->net.last_error, s_error);
00474               strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
00475               mysql->mysql->net.last_errno = s_errno;
00476 #else
00477               mysql->mysql->error_info = error_info;
00478 #endif
00479               RETURN_FALSE;
00480        }
00481        RETURN_TRUE;
00482 }
00483 /* }}} */
00484 
00485 /* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
00486 PHP_FUNCTION(mysqli_query)
00487 {
00488        MY_MYSQL                    *mysql;
00489        zval                        *mysql_link;
00490        MYSQLI_RESOURCE             *mysqli_resource;
00491        MYSQL_RES                   *result;
00492        char                        *query = NULL;
00493        int                         query_len;
00494        long                        resultmode = MYSQLI_STORE_RESULT;
00495 
00496        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
00497               return;
00498        }
00499 
00500        if (!query_len) {
00501               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query");
00502               RETURN_FALSE;
00503        }
00504        if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) {
00505               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
00506               RETURN_FALSE;
00507        }
00508 
00509        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00510 
00511        MYSQLI_DISABLE_MQ;
00512 
00513 
00514 #ifdef MYSQLI_USE_MYSQLND
00515        if (resultmode & MYSQLI_ASYNC) {
00516               if (mysqli_async_query(mysql->mysql, query, query_len)) {
00517                      MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
00518                      RETURN_FALSE;
00519               }
00520               mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC;
00521               RETURN_TRUE;
00522        }
00523 #endif
00524 
00525        if (mysql_real_query(mysql->mysql, query, query_len)) {
00526               MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
00527               RETURN_FALSE;
00528        }
00529 
00530        if (!mysql_field_count(mysql->mysql)) {
00531               /* no result set - not a SELECT */
00532               if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
00533                      php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
00534               }
00535               RETURN_TRUE;
00536        }
00537 
00538        switch (resultmode) {
00539               case MYSQLI_STORE_RESULT:
00540                      result = mysql_store_result(mysql->mysql);
00541                      break;
00542               case MYSQLI_USE_RESULT:
00543                      result = mysql_use_result(mysql->mysql);
00544                      break;
00545        }
00546        if (!result) {
00547               php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
00548                                                                       "%s", mysql_error(mysql->mysql));
00549               RETURN_FALSE;
00550        }
00551 
00552        if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
00553               php_mysqli_report_index(query, mysqli_server_status(mysql->mysql) TSRMLS_CC);
00554        }
00555 
00556        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
00557        mysqli_resource->ptr = (void *)result;
00558        mysqli_resource->status = MYSQLI_STATUS_VALID;
00559        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
00560 }
00561 /* }}} */
00562 
00563 
00564 #if defined(MYSQLI_USE_MYSQLND)
00565 #include "php_network.h"
00566 /* {{{ mysqlnd_zval_array_to_mysqlnd_array functions */
00567 static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_array TSRMLS_DC)
00568 {
00569        zval **elem;
00570        int i = 0, current = 0;
00571 
00572        if (Z_TYPE_P(in_array) != IS_ARRAY) {
00573               return 0;
00574        }
00575        *out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *));
00576        for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_array));
00577                zend_hash_get_current_data(Z_ARRVAL_P(in_array), (void **) &elem) == SUCCESS;
00578                zend_hash_move_forward(Z_ARRVAL_P(in_array))) {
00579               i++;
00580               if (Z_TYPE_PP(elem) != IS_OBJECT ||
00581                      !instanceof_function(Z_OBJCE_PP(elem), mysqli_link_class_entry TSRMLS_CC)) {
00582                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter %d not a mysqli object", i);
00583               } else {
00584                      MY_MYSQL *mysql;
00585                      MYSQLI_RESOURCE *my_res;
00586                      mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*elem TSRMLS_CC);
00587                      if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
00588                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "[%d] Couldn't fetch %s", i, intern->zo.ce->name);
00589                             continue;
00590                      }
00591                      mysql = (MY_MYSQL*) my_res->ptr;
00592                      if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) {
00593                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object %d or resource %s", i, intern->zo.ce->name);
00594                             continue;
00595                      }
00596                      (*out_array)[current++] = mysql->mysql;
00597               }
00598        }
00599        return 0;
00600 }
00601 /* }}} */
00602 
00603 
00604 /* {{{ mysqlnd_zval_array_from_mysqlnd_array */
00605 static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_array TSRMLS_DC)
00606 {
00607        MYSQLND **p = in_array;
00608        HashTable *new_hash;
00609        zval **elem, **dest_elem;
00610        int ret = 0;
00611 
00612        ALLOC_HASHTABLE(new_hash);
00613        zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(out_array)), NULL, ZVAL_PTR_DTOR, 0);
00614 
00615        for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(out_array));
00616                zend_hash_get_current_data(Z_ARRVAL_P(out_array), (void **) &elem) == SUCCESS;
00617                zend_hash_move_forward(Z_ARRVAL_P(out_array)))
00618        {
00619               if (Z_TYPE_PP(elem) != IS_OBJECT || !instanceof_function(Z_OBJCE_PP(elem), mysqli_link_class_entry TSRMLS_CC)) {
00620                      continue;
00621               }
00622               {
00623                      MY_MYSQL *mysql;
00624                      mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*elem TSRMLS_CC);
00625                      mysql = (MY_MYSQL *) ((MYSQLI_RESOURCE *)intern->ptr)->ptr;
00626                      if (mysql->mysql == *p) {
00627                             zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
00628                             if (dest_elem) {
00629                                    zval_add_ref(dest_elem);
00630                             }
00631                             ret++;
00632                             p++;
00633                      }
00634               }
00635        }
00636 
00637        /* destroy old array and add new one */
00638        zend_hash_destroy(Z_ARRVAL_P(out_array));
00639        efree(Z_ARRVAL_P(out_array));
00640 
00641        zend_hash_internal_pointer_reset(new_hash);
00642        Z_ARRVAL_P(out_array) = new_hash;
00643 
00644        return 0;
00645 }
00646 /* }}} */
00647 
00648 
00649 /* {{{ mysqlnd_dont_poll_zval_array_from_mysqlnd_array */
00650 static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *in_zval_array, zval *out_array TSRMLS_DC)
00651 {
00652        MYSQLND **p = in_array;
00653        HashTable *new_hash;
00654        zval **elem, **dest_elem;
00655        int ret = 0;
00656 
00657        ALLOC_HASHTABLE(new_hash);
00658        zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)), NULL, ZVAL_PTR_DTOR, 0);
00659        if (in_array) {
00660               for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_zval_array));
00661                       zend_hash_get_current_data(Z_ARRVAL_P(in_zval_array), (void **) &elem) == SUCCESS;
00662                       zend_hash_move_forward(Z_ARRVAL_P(in_zval_array)))
00663               {
00664                      MY_MYSQL *mysql;
00665                      mysqli_object *intern = (mysqli_object *)zend_object_store_get_object(*elem TSRMLS_CC);
00666                      mysql = (MY_MYSQL *) ((MYSQLI_RESOURCE *)intern->ptr)->ptr;
00667                      if (mysql->mysql == *p) {
00668                             zend_hash_next_index_insert(new_hash, (void *)elem, sizeof(zval *), (void **)&dest_elem);
00669                             if (dest_elem) {
00670                                    zval_add_ref(dest_elem);
00671                             }
00672                             ret++;
00673                             p++;
00674                      }
00675               }
00676        }
00677 
00678        /* destroy old array and add new one */
00679        zend_hash_destroy(Z_ARRVAL_P(out_array));
00680        efree(Z_ARRVAL_P(out_array));
00681 
00682        zend_hash_internal_pointer_reset(new_hash);
00683        Z_ARRVAL_P(out_array) = new_hash;
00684 
00685        return 0;
00686 }
00687 /* }}} */
00688 
00689 
00690 /* {{{ proto int mysqli_poll(array read, array write, array error, long sec [, long usec]) U
00691    Poll connections */
00692 PHP_FUNCTION(mysqli_poll)
00693 {
00694        zval                 *r_array, *e_array, *dont_poll_array;
00695        MYSQLND                     **new_r_array = NULL, **new_e_array = NULL, **new_dont_poll_array = NULL;
00696        long                 sec = 0, usec = 0;
00697        enum_func_status ret;
00698        uint                 desc_num;
00699 
00700        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) {
00701               return;
00702        }
00703        if (sec < 0 || usec < 0) {
00704               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Negative values passed for sec and/or usec");
00705               RETURN_FALSE;
00706        }
00707 
00708        if (r_array != NULL) {
00709               mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array TSRMLS_CC);
00710        }
00711        if (e_array != NULL) {
00712               mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array TSRMLS_CC);
00713        }
00714 
00715        ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num);
00716 
00717        mysqlnd_dont_poll_zval_array_from_mysqlnd_array(r_array != NULL ? new_dont_poll_array:NULL, r_array, dont_poll_array TSRMLS_CC);
00718 
00719        if (r_array != NULL) {
00720               mysqlnd_zval_array_from_mysqlnd_array(new_r_array, r_array TSRMLS_CC);
00721        }
00722        if (e_array != NULL) {
00723               mysqlnd_zval_array_from_mysqlnd_array(new_e_array, e_array TSRMLS_CC);
00724        }
00725 
00726        if (new_dont_poll_array) {
00727               efree(new_dont_poll_array);
00728        }
00729        if (new_r_array) {
00730               efree(new_r_array);
00731        }
00732        if (new_e_array) {
00733               efree(new_e_array);
00734        }
00735        if (ret == PASS) {
00736               RETURN_LONG(desc_num);
00737        } else {
00738               RETURN_FALSE;
00739        }
00740 }
00741 /* }}} */
00742 
00743 
00744 /* {{{ proto int mysqli_reap_async_query(object link) U
00745    Poll connections */
00746 PHP_FUNCTION(mysqli_reap_async_query)
00747 {
00748        MY_MYSQL             *mysql;
00749        zval                 *mysql_link;
00750        MYSQLI_RESOURCE             *mysqli_resource;
00751        MYSQL_RES                   *result;
00752 
00753        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00754               return;
00755        }
00756 
00757        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00758 
00759        if (FAIL == mysqlnd_reap_async_query(mysql->mysql)) {
00760               RETURN_FALSE;
00761        }
00762 
00763        if (!mysql_field_count(mysql->mysql)) {
00764               /* no result set - not a SELECT */
00765               if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
00766 /*                   php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql) TSRMLS_CC); */
00767               }
00768               RETURN_TRUE;
00769        }
00770 
00771        switch (mysql->async_result_fetch_type) {
00772               case MYSQLI_STORE_RESULT:
00773                      result = mysql_store_result(mysql->mysql);
00774                      break;
00775               case MYSQLI_USE_RESULT:
00776                      result = mysql_use_result(mysql->mysql);
00777                      break;
00778        }
00779 
00780        if (!result) {
00781               php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql) TSRMLS_CC,
00782                                                                       "%s", mysql_error(mysql->mysql));
00783               RETURN_FALSE;
00784        }
00785 
00786        if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
00787 /*            php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql) TSRMLS_CC); */
00788        }
00789 
00790        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
00791        mysqli_resource->ptr = (void *)result;
00792        mysqli_resource->status = MYSQLI_STATUS_VALID;
00793        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
00794 }
00795 /* }}} */
00796 
00797 
00798 /* {{{ proto object mysqli_stmt_get_result(object link) U
00799    Buffer result set on client */
00800 PHP_FUNCTION(mysqli_stmt_get_result)
00801 {
00802        MYSQL_RES            *result;
00803        MYSQLI_RESOURCE      *mysqli_resource;
00804        MY_STMT                     *stmt;
00805        zval                 *mysql_stmt;
00806 
00807        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
00808               return;
00809        }
00810        MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
00811 
00812        if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) {
00813               MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
00814               RETURN_FALSE;
00815        }
00816 
00817        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
00818        mysqli_resource->ptr = (void *)result;
00819        mysqli_resource->status = MYSQLI_STATUS_VALID;
00820        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
00821 }
00822 /* }}} */
00823 #endif
00824 
00825 
00826 /* {{{ proto object mysqli_get_warnings(object link) */
00827 PHP_FUNCTION(mysqli_get_warnings)
00828 {
00829        MY_MYSQL                    *mysql;
00830        zval                        *mysql_link;
00831        MYSQLI_RESOURCE             *mysqli_resource;
00832        MYSQLI_WARNING              *w;
00833 
00834        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00835               return;
00836        }
00837        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00838 
00839        if (mysql_warning_count(mysql->mysql)) {
00840               w = php_get_warnings(mysql->mysql TSRMLS_CC);
00841        } else {
00842               RETURN_FALSE;
00843        }
00844        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
00845        mysqli_resource->ptr = mysqli_resource->info = (void *)w;
00846        mysqli_resource->status = MYSQLI_STATUS_VALID;
00847        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
00848 }
00849 /* }}} */
00850 
00851 /* {{{ proto object mysqli_stmt_get_warnings(object link) */
00852 PHP_FUNCTION(mysqli_stmt_get_warnings)
00853 {
00854        MY_STMT                            *stmt;
00855        zval                        *stmt_link;
00856        MYSQLI_RESOURCE             *mysqli_resource;
00857        MYSQLI_WARNING              *w;
00858 
00859        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) {
00860               return;
00861        }
00862        MYSQLI_FETCH_RESOURCE_STMT(stmt, &stmt_link, MYSQLI_STATUS_VALID);
00863 
00864        if (mysqli_stmt_warning_count(stmt->stmt)) {
00865               w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt) TSRMLS_CC);
00866        } else {
00867               RETURN_FALSE;
00868        }
00869        mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
00870        mysqli_resource->ptr = mysqli_resource->info = (void *)w;
00871        mysqli_resource->status = MYSQLI_STATUS_VALID;
00872        MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
00873 }
00874 /* }}} */
00875 
00876 #ifdef HAVE_MYSQLI_SET_CHARSET
00877 /* {{{ proto bool mysqli_set_charset(object link, string csname)
00878    sets client character set */
00879 PHP_FUNCTION(mysqli_set_charset)
00880 {
00881        MY_MYSQL      *mysql;
00882        zval          *mysql_link;
00883        char          *cs_name;
00884        int                  csname_len;
00885 
00886        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &csname_len) == FAILURE) {
00887               return;
00888        }
00889        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00890 
00891        if (mysql_set_character_set(mysql->mysql, cs_name)) {
00892               RETURN_FALSE;
00893        }
00894        RETURN_TRUE;
00895 }
00896 /* }}} */
00897 #endif
00898 
00899 #ifdef HAVE_MYSQLI_GET_CHARSET
00900 /* {{{ proto object mysqli_get_charset(object link) U
00901    returns a character set object */
00902 PHP_FUNCTION(mysqli_get_charset)
00903 {
00904        MY_MYSQL                           *mysql;
00905        zval                               *mysql_link;
00906        const char                         *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL;
00907        uint                               minlength, maxlength, number, state;
00908 #if !defined(MYSQLI_USE_MYSQLND)
00909        MY_CHARSET_INFO                    cs;
00910 #else
00911        const MYSQLND_CHARSET       *cs;
00912 #endif
00913 
00914        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
00915               return;
00916        }
00917        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
00918 
00919 
00920 #if !defined(MYSQLI_USE_MYSQLND)
00921        mysql_get_character_set_info(mysql->mysql, &cs);
00922        name = (char *)cs.csname;
00923        collation = (char *)cs.name;
00924        dir = (char *)cs.dir;
00925        minlength = cs.mbminlen;
00926        maxlength = cs.mbmaxlen;
00927        number = cs.number;
00928        state = cs.state;
00929        comment = cs.comment;
00930 #else
00931        cs = mysql->mysql->charset;
00932        if (!cs) {
00933               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The connection has no charset associated");
00934               RETURN_NULL();
00935        }
00936        name = cs->name;
00937        collation = cs->collation;
00938        minlength = cs->char_minlen;
00939        maxlength = cs->char_maxlen;
00940        number = cs->nr;
00941        comment = cs->comment;
00942        state = 1;    /* all charsets are compiled in */
00943 #endif
00944        object_init(return_value);
00945 
00946        add_property_string(return_value, "charset", (name) ? (char *)name : "", 1);
00947        add_property_string(return_value, "collation",(collation) ? (char *)collation : "", 1);
00948        add_property_string(return_value, "dir", (dir) ? (char *)dir : "", 1);
00949        add_property_long(return_value, "min_length", minlength);
00950        add_property_long(return_value, "max_length", maxlength);
00951        add_property_long(return_value, "number", number);
00952        add_property_long(return_value, "state", state);
00953        add_property_string(return_value, "comment", (comment) ? (char *)comment : "", 1);
00954 }
00955 /* }}} */
00956 #endif
00957 
00958 /*
00959  * Local variables:
00960  * tab-width: 4
00961  * c-basic-offset: 4
00962  * End:
00963  * vim600: noet sw=4 ts=4 fdm=marker
00964  * vim<600: noet sw=4 ts=4
00965  */