📄 mysqli.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Georg Richter <georg@php.net> | +----------------------------------------------------------------------+ $Id: mysqli.c,v 1.72.2.16.2.14 2007/02/24 02:17:25 helly Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <signal.h>#include "php.h"#include "php_ini.h"#include "ext/standard/info.h"#include "ext/standard/php_string.h"#include "php_mysqli.h"#include "zend_exceptions.h"#define MYSQLI_STORE_RESULT 0#define MYSQLI_USE_RESULT 1ZEND_DECLARE_MODULE_GLOBALS(mysqli)static PHP_GINIT_FUNCTION(mysqli);static zend_object_handlers mysqli_object_handlers;static HashTable classes;static HashTable mysqli_driver_properties;static HashTable mysqli_link_properties;static HashTable mysqli_result_properties;static HashTable mysqli_stmt_properties;static HashTable mysqli_warning_properties;zend_class_entry *mysqli_link_class_entry;zend_class_entry *mysqli_stmt_class_entry;zend_class_entry *mysqli_result_class_entry;zend_class_entry *mysqli_driver_class_entry;zend_class_entry *mysqli_warning_class_entry;zend_class_entry *mysqli_exception_class_entry;extern void php_mysqli_connect(INTERNAL_FUNCTION_PARAMETERS);typedef int (*mysqli_read_t)(mysqli_object *obj, zval **retval TSRMLS_DC);typedef int (*mysqli_write_t)(mysqli_object *obj, zval *newval TSRMLS_DC);typedef struct _mysqli_prop_handler { mysqli_read_t read_func; mysqli_write_t write_func;} mysqli_prop_handler;static int le_pmysqli;/* Destructor for Persistent Connections */ZEND_RSRC_DTOR_FUNC(php_mysqli_dtor){ if (rsrc->ptr) { MYSQL *mysql = (MYSQL *)rsrc->ptr;#if defined(HAVE_MYSQLND) mysqlnd_end_psession(mysql);#endif mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT); }}int php_le_pmysqli(void){ return le_pmysqli;}#ifndef HAVE_MYSQLND/* {{{ php_free_stmt_bind_buffer */void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type){ unsigned int i; if (!bbuf.var_cnt) { return; } for (i=0; i < bbuf.var_cnt; i++) { /* free temporary bind buffer */ if (type == FETCH_RESULT && bbuf.buf[i].val) { efree(bbuf.buf[i].val); } if (bbuf.vars[i]) { zval_ptr_dtor(&bbuf.vars[i]); } } if (bbuf.vars) { efree(bbuf.vars); } /* Don't free bbuf.is_null for FETCH_RESULT since we have allocated is_null and buf in one block so we free only buf, which is the beginning of the block. When FETCH_SIMPLE then buf wasn't allocated together with buf and we have to free it. */ if (type == FETCH_RESULT) { efree(bbuf.buf); } else if (type == FETCH_SIMPLE){ efree(bbuf.is_null); } bbuf.var_cnt = 0; return;}/* }}} */#endif/* {{{ php_clear_stmt_bind */void php_clear_stmt_bind(MY_STMT *stmt TSRMLS_DC){ if (stmt->stmt) { if (mysqli_stmt_close(stmt->stmt, TRUE)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error occured while closing statement"); return; } } /* mysqlnd keeps track of the binding and has freed its structures in stmt_close() above */#ifndef HAVE_MYSQLND /* Clean param bind */ php_free_stmt_bind_buffer(stmt->param, FETCH_SIMPLE); /* Clean output bind */ php_free_stmt_bind_buffer(stmt->result, FETCH_RESULT);#endif if (stmt->query) { efree(stmt->query); } efree(stmt); return;}/* }}} *//* {{{ php_clear_mysql */void php_clear_mysql(MY_MYSQL *mysql) { if (mysql->li_read) { efree(Z_STRVAL_P(mysql->li_read)); FREE_ZVAL(mysql->li_read); mysql->li_read = NULL; }}/* }}} *//* {{{ mysqli_objects_free_storage */static void mysqli_objects_free_storage(void *object TSRMLS_DC){ zend_object *zo = (zend_object *)object; mysqli_object *intern = (mysqli_object *)zo; MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; my_efree(my_res); zend_object_std_dtor(&intern->zo TSRMLS_CC); efree(intern);}/* }}} *//* {{{ mysqli_link_free_storage */static void mysqli_link_free_storage(void *object TSRMLS_DC){ zend_object *zo = (zend_object *)object; mysqli_object *intern = (mysqli_object *)zo; MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; if (my_res && my_res->ptr) { MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr; if (mysql->mysql) { if (!mysql->persistent) { mysql_close(mysql->mysql); } } php_clear_mysql(mysql); efree(mysql); } mysqli_objects_free_storage(object TSRMLS_CC);}/* }}} *//* {{{ mysqli_stmt_free_storage */static void mysqli_stmt_free_storage(void *object TSRMLS_DC){ zend_object *zo = (zend_object *)object; mysqli_object *intern = (mysqli_object *)zo; MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; if (my_res && my_res->ptr) { MY_STMT *stmt = (MY_STMT *)my_res->ptr; php_clear_stmt_bind(stmt TSRMLS_CC); } mysqli_objects_free_storage(object TSRMLS_CC);}/* }}} *//* {{{ mysqli_result_free_storage */static void mysqli_result_free_storage(void *object TSRMLS_DC){ zend_object *zo = (zend_object *)object; mysqli_object *intern = (mysqli_object *)zo; MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; if (my_res && my_res->ptr) { mysql_free_result(my_res->ptr); } mysqli_objects_free_storage(object TSRMLS_CC);}/* }}} *//* {{{ mysqli_warning_free_storage */static void mysqli_warning_free_storage(void *object TSRMLS_DC){ zend_object *zo = (zend_object *)object; mysqli_object *intern = (mysqli_object *)zo; MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr; if (my_res && my_res->ptr) { php_clear_warnings((MYSQLI_WARNING *)my_res->info); my_res->ptr = NULL; } mysqli_objects_free_storage(object TSRMLS_CC);}/* }}} *//* {{{ mysqli_read_na */static int mysqli_read_na(mysqli_object *obj, zval **retval TSRMLS_DC){ *retval = NULL; php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property"); return FAILURE;}/* }}} *//* {{{ mysqli_write_na */static int mysqli_write_na(mysqli_object *obj, zval *newval TSRMLS_DC){ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property"); return FAILURE;}/* }}} *//* {{{ mysqli_read_property */zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC){ zval tmp_member; zval *retval; mysqli_object *obj; mysqli_prop_handler *hnd; zend_object_handlers *std_hnd; int ret; ret = FAILURE; obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); if (member->type != IS_STRING) { tmp_member = *member; zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; } if (obj->prop_handler != NULL) { ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); } if (ret == SUCCESS) { if (strcmp(obj->zo.ce->name, "mysqli_driver") && (!obj->ptr || ((MYSQLI_RESOURCE *)(obj->ptr))->status < MYSQLI_STATUS_INITIALIZED)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", obj->zo.ce->name ); retval = EG(uninitialized_zval_ptr); return(retval); } ret = hnd->read_func(obj, &retval TSRMLS_CC); if (ret == SUCCESS) { /* ensure we're creating a temporary variable */ retval->refcount = 0; } else { retval = EG(uninitialized_zval_ptr); } } else { std_hnd = zend_get_std_object_handlers(); retval = std_hnd->read_property(object, member, type TSRMLS_CC); } if (member == &tmp_member) { zval_dtor(member); } return(retval);}/* }}} *//* {{{ mysqli_write_property */void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC){ zval tmp_member; mysqli_object *obj; mysqli_prop_handler *hnd; zend_object_handlers *std_hnd; int ret; if (member->type != IS_STRING) { tmp_member = *member; zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; } ret = FAILURE; obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); } if (ret == SUCCESS) { hnd->write_func(obj, value TSRMLS_CC); if (! PZVAL_IS_REF(value) && value->refcount == 0) { value->refcount++; zval_ptr_dtor(&value); } } else { std_hnd = zend_get_std_object_handlers(); std_hnd->write_property(object, member, value TSRMLS_CC); } if (member == &tmp_member) { zval_dtor(member); }}/* }}} *//* {{{ void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) */void mysqli_add_property(HashTable *h, char *pname, mysqli_read_t r_func, mysqli_write_t w_func TSRMLS_DC) { mysqli_prop_handler p; p.read_func = (r_func) ? r_func : mysqli_read_na; p.write_func = (w_func) ? w_func : mysqli_write_na; zend_hash_add(h, pname, strlen(pname) + 1, &p, sizeof(mysqli_prop_handler), NULL);}/* }}} */static union _zend_function *php_mysqli_constructor_get(zval *object TSRMLS_DC){ mysqli_object *obj = (mysqli_object *)zend_objects_get_address(object TSRMLS_CC); zend_class_entry * ce = Z_OBJCE_P(object); if (ce != mysqli_link_class_entry && ce != mysqli_stmt_class_entry && ce != mysqli_result_class_entry && ce != mysqli_driver_class_entry && ce != mysqli_warning_class_entry) { return zend_std_get_constructor(object TSRMLS_CC); } else { static zend_internal_function f; f.function_name = obj->zo.ce->name; f.scope = obj->zo.ce; f.arg_info = NULL; f.num_args = 0; f.fn_flags = 0; f.type = ZEND_INTERNAL_FUNCTION; if (obj->zo.ce == mysqli_link_class_entry) { f.handler = ZEND_FN(mysqli_connect); } else if (obj->zo.ce == mysqli_stmt_class_entry) { f.handler = ZEND_FN(mysqli_stmt_construct); } else if (obj->zo.ce == mysqli_result_class_entry) { f.handler = ZEND_FN(mysqli_result_construct); } else if (obj->zo.ce == mysqli_driver_class_entry) { f.handler = ZEND_FN(mysqli_driver_construct); } else if (obj->zo.ce == mysqli_warning_class_entry) { f.handler = ZEND_MN(mysqli_warning___construct); } return (union _zend_function*)&f; }}/* {{{ mysqli_objects_new */PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC){ zend_object_value retval; mysqli_object *intern; zval *tmp; zend_class_entry *mysqli_base_class; zend_objects_free_object_storage_t free_storage; intern = emalloc(sizeof(mysqli_object)); memset(intern, 0, sizeof(mysqli_object)); intern->ptr = NULL; intern->prop_handler = NULL; mysqli_base_class = class_type; while (mysqli_base_class->type != ZEND_INTERNAL_CLASS && mysqli_base_class->parent != NULL) { mysqli_base_class = mysqli_base_class->parent; } zend_hash_find(&classes, mysqli_base_class->name, mysqli_base_class->name_length + 1, (void **) &intern->prop_handler); zend_object_std_init(&intern->zo, class_type TSRMLS_CC); zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); /* link object */ if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) { free_storage = mysqli_link_free_storage; } else if (instanceof_function(class_type, mysqli_stmt_class_entry TSRMLS_CC)) { /* stmt object */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -