summaryrefslogtreecommitdiff
path: root/ext/mysqli/mysqli.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mysqli/mysqli.c')
-rw-r--r--ext/mysqli/mysqli.c131
1 files changed, 128 insertions, 3 deletions
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 8e0cfc2911..30a0c13eb8 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -36,7 +36,20 @@
ZEND_DECLARE_MODULE_GLOBALS(mysqli)
static zend_object_handlers mysqli_object_handlers;
+static HashTable classes;
+static HashTable mysqli_link_properties;
+static HashTable mysqli_result_properties;
+static HashTable mysqli_stmt_properties;
PR_MAIN *prmain;
+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 *member, zval *newval TSRMLS_DC);
+
+typedef struct _mysqli_prop_handler {
+ mysqli_read_t read_func;
+ mysqli_write_t write_func;
+} mysqli_prop_handler;
/* {{{ php_free_stmt_bind_buffer */
void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type)
@@ -96,6 +109,9 @@ static void mysqli_objects_dtor(void *object, zend_object_handle handle TSRMLS_D
mysqli_object *intern = (mysqli_object *)object;
MYSQLI_RESOURCE *my_res = (MYSQLI_RESOURCE *)intern->ptr;
+ zend_hash_destroy(intern->zo.properties);
+ FREE_HASHTABLE(intern->zo.properties);
+
/* link object */
if (intern->zo.ce == mysqli_link_class_entry) {
if (my_res && my_res->ptr) {
@@ -111,7 +127,7 @@ static void mysqli_objects_dtor(void *object, zend_object_handle handle TSRMLS_D
}
}
my_efree(my_res);
- zend_objects_destroy_object(object, handle TSRMLS_CC);
+ efree(object);
}
/* }}} */
@@ -122,7 +138,85 @@ static void mysqli_objects_clone(void *object, void **object_clone TSRMLS_DC)
/* TODO */
}
/* }}} */
-
+
+/* {{{ 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 *member, 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, zend_bool silent TSRMLS_DC)
+{
+ zval tmp_member;
+ zval *retval;
+ 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(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ if (ret == SUCCESS) {
+ 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, silent 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)
+{
+ return;
+}
+/* }}} */
+
+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);
+}
+
/* {{{ mysqli_objects_new
*/
PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_type TSRMLS_DC)
@@ -136,6 +230,9 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_
intern->zo.in_get = 0;
intern->zo.in_set = 0;
intern->ptr = NULL;
+ intern->prop_handler = NULL;
+
+ zend_hash_find(&classes, class_type->name, class_type->name_length + 1, (void **) &intern->prop_handler);
ALLOC_HASHTABLE(intern->zo.properties);
zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
@@ -197,6 +294,7 @@ static void php_mysqli_init_globals(zend_mysqli_globals *mysqli_globals)
mysqli_globals->default_pw = NULL;
mysqli_globals->default_socket = NULL;
mysqli_globals->profiler = 0;
+ mysqli_globals->multi_query = 0;
}
/* }}} */
@@ -204,16 +302,40 @@ static void php_mysqli_init_globals(zend_mysqli_globals *mysqli_globals)
*/
PHP_MINIT_FUNCTION(mysqli)
{
+ zend_class_entry *ce;
ZEND_INIT_MODULE_GLOBALS(mysqli, php_mysqli_init_globals, NULL);
REGISTER_INI_ENTRIES();
memcpy(&mysqli_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
mysqli_object_handlers.clone_obj = zend_objects_store_clone_obj;
+ mysqli_object_handlers.read_property = mysqli_read_property;
+ mysqli_object_handlers.write_property = mysqli_write_property;
+ mysqli_object_handlers.get_property_ptr_ptr = NULL;
+// mysqli_object_handlers.call_method = php_mysqli_connect;
+
+/* todo: call method */
+
+ zend_hash_init(&classes, 0, NULL, NULL, 1);
REGISTER_MYSQLI_CLASS_ENTRY("mysqli", mysqli_link_class_entry, mysqli_link_methods);
+
+ ce = mysqli_link_class_entry;
+ zend_hash_init(&mysqli_link_properties, 0, NULL, NULL, 1);
+ MYSQLI_ADD_PROPERTIES(&mysqli_link_properties, mysqli_link_property_entries);
+ zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_link_properties, sizeof(mysqli_link_properties), NULL);
+
REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods);
+ ce = mysqli_result_class_entry;
+ zend_hash_init(&mysqli_result_properties, 0, NULL, NULL, 1);
+ MYSQLI_ADD_PROPERTIES(&mysqli_result_properties, mysqli_result_property_entries);
+ zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_result_properties, sizeof(mysqli_result_properties), NULL);
+
REGISTER_MYSQLI_CLASS_ENTRY("mysqli_stmt", mysqli_stmt_class_entry, mysqli_stmt_methods);
+ ce = mysqli_stmt_class_entry;
+ zend_hash_init(&mysqli_stmt_properties, 0, NULL, NULL, 1);
+ MYSQLI_ADD_PROPERTIES(&mysqli_stmt_properties, mysqli_stmt_property_entries);
+ zend_hash_add(&classes, ce->name, ce->name_length+1, &mysqli_stmt_properties, sizeof(mysqli_stmt_properties), NULL);
/* mysqli_options */
REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, CONST_CS | CONST_PERSISTENT);
@@ -310,6 +432,9 @@ PHP_MINIT_FUNCTION(mysqli)
*/
PHP_MSHUTDOWN_FUNCTION(mysqli)
{
+ zend_hash_destroy(&mysqli_link_properties);
+ zend_hash_destroy(&classes);
+
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
@@ -421,7 +546,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
fields = mysql_fetch_fields(result);
if (!(row = mysql_fetch_row(result))) {
- RETURN_FALSE;
+ RETURN_NULL();
}
array_init(return_value);