From: George Schlossnagle Date: Mon, 26 Jul 2004 07:42:46 +0000 (+0000) Subject: allow pdo to be functionally inherited from. X-Git-Tag: PRE_ZEND_VM_DISPATCH_PATCH~362 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c7b7791029db1d9ba982ff3271f38f48587807c8;p=php allow pdo to be functionally inherited from. --- diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index bad7590652..8b60718eab 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -33,6 +33,7 @@ #include "php_pdo_driver.h" #include "php_pdo_int.h" #include "zend_exceptions.h" +#include "zend_object_handlers.h" void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) { @@ -575,11 +576,12 @@ static union _zend_function *dbh_method_get(zval *object, char *method_name, int { zend_function *fbc; char *lc_method_name; + pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC); lc_method_name = emalloc(method_len + 1); zend_str_tolower_copy(lc_method_name, method_name, method_len); - if (zend_hash_find(&pdo_dbh_ce->function_table, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { + if (zend_hash_find(&dbh->ce->function_table, lc_method_name, method_len+1, (void**)&fbc) == FAILURE) { efree(lc_method_name); return NULL; } @@ -596,29 +598,25 @@ static int dbh_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) static union _zend_function *dbh_get_ctor(zval *object TSRMLS_DC) { - pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC); - - if(dbh->ce != pdo_dbh_ce) { - return dbh->ce->constructor; - } else { - static zend_internal_function ctor = {0}; + static zend_internal_function ctor = {0}; + ctor.type = ZEND_INTERNAL_FUNCTION; + ctor.function_name = "__construct"; + ctor.scope = pdo_dbh_ce; + ctor.handler = ZEND_FN(dbh_constructor); - ctor.type = ZEND_INTERNAL_FUNCTION; - ctor.function_name = "__construct"; - ctor.scope = pdo_dbh_ce; - ctor.handler = ZEND_FN(dbh_constructor); - - return (union _zend_function*)&ctor; - } + return (union _zend_function*)&ctor; } static zend_class_entry *dbh_get_ce(zval *object TSRMLS_DC) { - return pdo_dbh_ce; + pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC); + return dbh->ce; } static int dbh_get_classname(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) { + pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC); + *class_name = estrndup("PDO", sizeof("PDO")-1); *class_name_len = sizeof("PDO")-1; return 0; @@ -653,6 +651,7 @@ static zend_object_handlers pdo_dbh_object_handlers = { NULL }; + static void pdo_dbh_free_storage(zend_object *object TSRMLS_DC) { pdo_dbh_t *dbh = (pdo_dbh_t*)object; @@ -665,7 +664,9 @@ static void pdo_dbh_free_storage(zend_object *object TSRMLS_DC) /* XXX: don't really free it, just delete the rsrc id */ return; } - + if(dbh->properties) { + zend_hash_destroy(dbh->properties); + } dbh->methods->closer(dbh TSRMLS_CC); if (dbh->data_source) { @@ -689,10 +690,16 @@ zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC) dbh = emalloc(sizeof(*dbh)); memset(dbh, 0, sizeof(*dbh)); dbh->ce = ce; + ALLOC_HASHTABLE(dbh->properties); + zend_hash_init(dbh->properties, 0, NULL, ZVAL_PTR_DTOR, 0); retval.handle = zend_objects_store_put(dbh, NULL, pdo_dbh_free_storage, NULL TSRMLS_CC); - retval.handlers = &pdo_dbh_object_handlers; - + if(ce == pdo_dbh_ce) { + retval.handlers = &pdo_dbh_object_handlers; + } + else { + retval.handlers = &std_object_handlers; + } return retval; } diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 8288aa9eb3..2acd860b92 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -249,6 +249,16 @@ enum pdo_placeholder_support { /* represents a connection to a database */ struct _pdo_dbh_t { + /* these items mst appear in this order at the beginning of the + struct so that this can be cast as a zend_object. we need this + to allow the extending class to escape all the custom handlers + that PDO decalres. + */ + zend_class_entry *ce; + HashTable *properties; + unsigned int in_get:1; + unsigned int in_set:1; + /* driver specific methods */ struct pdo_dbh_methods *methods; /* driver specific data */ @@ -302,8 +312,6 @@ struct _pdo_dbh_t { enum pdo_case_conversion native_case, desired_case; - /* needed for inheritance to work */ - zend_class_entry *ce; #if 0 /* persistent hash key associated with this handle */ const char *persistent_id;