]> granicus.if.org Git - php/commitdiff
Refactor PDO (incompleted)
authorXinchen Hui <laruence@gmail.com>
Wed, 16 Apr 2014 09:28:11 +0000 (17:28 +0800)
committerXinchen Hui <laruence@gmail.com>
Wed, 16 Apr 2014 09:28:11 +0000 (17:28 +0800)
ext/pdo/pdo.c
ext/pdo/pdo_dbh.c
ext/pdo/php_pdo_driver.h
ext/pdo/php_pdo_error.h
ext/pdo/php_pdo_int.h

index 77c2e1823e7b6bf37a5b04f9520001b2fa6069f2..a2b5decc5e0a89e552c09750dd0f88cb34e684fa 100644 (file)
@@ -76,11 +76,11 @@ PDO_API zend_class_entry *php_pdo_get_exception_base(int root TSRMLS_DC)
 #if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1))
        if (!root) {
                if (!spl_ce_RuntimeException) {
-                       zend_class_entry **pce;
+                       zend_class_entry *pce;
 
-                       if (zend_hash_find(CG(class_table), "runtimeexception", sizeof("RuntimeException"), (void **) &pce) == SUCCESS) {
-                               spl_ce_RuntimeException = *pce;
-                               return *pce;
+                       if ((pce = zend_hash_str_find_ptr(CG(class_table), "runtimeexception", sizeof("RuntimeException") - 1))) {
+                               spl_ce_RuntimeException = pce;
+                               return pce;
                        }
                } else {
                        return spl_ce_RuntimeException;
@@ -101,7 +101,7 @@ zend_class_entry *pdo_dbh_ce, *pdo_dbstmt_ce, *pdo_row_ce;
 PHP_FUNCTION(pdo_drivers)
 {
        HashPosition pos;
-       pdo_driver_t **pdriver;
+       pdo_driver_t *pdriver;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -110,8 +110,8 @@ PHP_FUNCTION(pdo_drivers)
        array_init(return_value);
 
        zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
-       while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
-               add_next_index_stringl(return_value, (char*)(*pdriver)->driver_name, (*pdriver)->driver_name_len);
+       while ((pdriver = zend_hash_get_current_data_ptr_ex(&pdo_driver_hash, &pos)) != NULL) {
+               add_next_index_stringl(return_value, (char*)pdriver->driver_name, pdriver->driver_name_len);
                zend_hash_move_forward_ex(&pdo_driver_hash, &pos);
        }
 }
@@ -185,31 +185,26 @@ PDO_API int php_pdo_register_driver(pdo_driver_t *driver)
                        driver->driver_name, driver->api_version, PDO_DRIVER_API);
                return FAILURE;
        }
-       if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
+       if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
                zend_error(E_ERROR, "You MUST load PDO before loading any PDO drivers");
                return FAILURE; /* NOTREACHED */
        }
 
-       return zend_hash_add(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len,
-                       (void**)&driver, sizeof(pdo_driver_t *), NULL);
+       return zend_hash_str_add_mem(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len, (void**)&driver, sizeof(pdo_driver_t *)) != NULL;
 }
 
 PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver)
 {
-       if (!zend_hash_exists(&module_registry, "pdo", sizeof("pdo"))) {
+       if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) {
                return;
        }
 
-       zend_hash_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
+       zend_hash_str_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len);
 }
 
 pdo_driver_t *pdo_find_driver(const char *name, int namelen)
 {
-       pdo_driver_t **driver = NULL;
-       
-       zend_hash_find(&pdo_driver_hash, (char*)name, namelen, (void**)&driver);
-
-       return driver ? *driver : NULL;
+       return zend_hash_str_find_ptr(&pdo_driver_hash, (char*)name, namelen);
 }
 
 PDO_API int php_pdo_parse_data_source(const char *data_source,
@@ -397,20 +392,20 @@ PHP_MINFO_FUNCTION(pdo)
 {
        HashPosition pos;
        char *drivers = NULL, *ldrivers = estrdup("");
-       pdo_driver_t **pdriver;
+       pdo_driver_t *pdriver;
        
        php_info_print_table_start();
        php_info_print_table_header(2, "PDO support", "enabled");
 
        zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
-       while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
-               spprintf(&drivers, 0, "%s, %s", ldrivers, (*pdriver)->driver_name);
+       while ((pdriver = zend_hash_get_current_data_ptr_ex(&pdo_driver_hash, &pos))) {
+               spprintf(&drivers, 0, "%s, %s", ldrivers, pdriver->driver_name);
                zend_hash_move_forward_ex(&pdo_driver_hash, &pos);
                efree(ldrivers);
                ldrivers = drivers;
        }
        
-       php_info_print_table_row(2, "PDO drivers", drivers ? drivers+2 : "");
+       php_info_print_table_row(2, "PDO drivers", drivers ? drivers + 2 : "");
 
        if (drivers) {
                efree(drivers);
index 1eb0e8af3cbfe4f866d3c333955c827213d4ecf0..d3d067e57d5812486705502d7f5df7f6a94dd899 100644 (file)
@@ -74,25 +74,21 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate
        if (dbh && dbh->error_mode != PDO_ERRMODE_EXCEPTION) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
        } else {
-               zval *ex, *info;
+               zval ex, info;
                zend_class_entry *def_ex = php_pdo_get_exception_base(1 TSRMLS_CC), *pdo_ex = php_pdo_get_exception();
 
-               MAKE_STD_ZVAL(ex);
-               object_init_ex(ex, pdo_ex);
+               object_init_ex(&ex, pdo_ex);
 
-               zend_update_property_string(def_ex, ex, "message", sizeof("message")-1, message TSRMLS_CC);
-               zend_update_property_string(def_ex, ex, "code", sizeof("code")-1, *pdo_err TSRMLS_CC);
+               zend_update_property_string(def_ex, &ex, "message", sizeof("message")-1, message TSRMLS_CC);
+               zend_update_property_string(def_ex, &ex, "code", sizeof("code")-1, *pdo_err TSRMLS_CC);
                
-               MAKE_STD_ZVAL(info);
-               array_init(info);
+               array_init(&info);
 
-               add_next_index_string(info, *pdo_err);
-               add_next_index_long(info, 0);
+               add_next_index_string(&info, *pdo_err);
+               add_next_index_long(&info, 0);
+               zend_update_property(pdo_ex, &ex, "errorInfo", sizeof("errorInfo")-1, &info TSRMLS_CC);
 
-               zend_update_property(pdo_ex, ex, "errorInfo", sizeof("errorInfo")-1, info TSRMLS_CC);
-               zval_ptr_dtor(&info);
-
-               zend_throw_exception_object(ex TSRMLS_CC);
+               zend_throw_exception_object(&ex TSRMLS_CC);
        }
        
        if (message) {
@@ -108,7 +104,7 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{
        char *supp = NULL;
        long native_code = 0;
        char *message = NULL;
-       zval *info = NULL;
+       zval info;
 
        if (dbh == NULL || dbh->error_mode == PDO_ERRMODE_SILENT) {
                return;
@@ -124,21 +120,21 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{
                msg = "<<Unknown error>>";
        }
 
+       ZVAL_UNDEF(&info);
        if (dbh->methods->fetch_err) {
-               MAKE_STD_ZVAL(info);
-               array_init(info);
+               array_init(&info);
 
-               add_next_index_string(info, *pdo_err);
+               add_next_index_string(&info, *pdo_err);
                
-               if (dbh->methods->fetch_err(dbh, stmt, info TSRMLS_CC)) {
-                       zval **item;
+               if (dbh->methods->fetch_err(dbh, stmt, &info TSRMLS_CC)) {
+                       zval *item;
 
-                       if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(info), 1, (void**)&item)) {
-                               native_code = Z_LVAL_PP(item);
+                       if ((item = zend_hash_index_find(Z_ARRVAL(info), 1)) != NULL) {
+                               native_code = Z_LVAL_P(item);
                        }
                        
-                       if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(info), 2, (void**)&item)) {
-                               supp = estrndup(Z_STRVAL_PP(item), Z_STRLEN_PP(item));
+                       if ((item = zend_hash_index_find(Z_ARRVAL(info), 2)) != NULL) {
+                               supp = estrndup(Z_STRVAL_P(item), Z_STRLEN_P(item));
                        }
                }
        }
@@ -152,23 +148,22 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{
        if (dbh->error_mode == PDO_ERRMODE_WARNING) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
        } else if (EG(exception) == NULL) {
-               zval *ex;
+               zval ex;
                zend_class_entry *def_ex = php_pdo_get_exception_base(1 TSRMLS_CC), *pdo_ex = php_pdo_get_exception();
 
-               MAKE_STD_ZVAL(ex);
-               object_init_ex(ex, pdo_ex);
+               object_init_ex(&ex, pdo_ex);
 
-               zend_update_property_string(def_ex, ex, "message", sizeof("message")-1, message TSRMLS_CC);
-               zend_update_property_string(def_ex, ex, "code", sizeof("code")-1, *pdo_err TSRMLS_CC);
+               zend_update_property_string(def_ex, &ex, "message", sizeof("message") - 1, message TSRMLS_CC);
+               zend_update_property_string(def_ex, &ex, "code", sizeof("code") - 1, *pdo_err TSRMLS_CC);
                
-               if (info) {
-                       zend_update_property(pdo_ex, ex, "errorInfo", sizeof("errorInfo")-1, info TSRMLS_CC);
+               if (!ZVAL_IS_UNDEF(&info)) {
+                       zend_update_property(pdo_ex, &ex, "errorInfo", sizeof("errorInfo") - 1, &info TSRMLS_CC);
                }
 
-               zend_throw_exception_object(ex TSRMLS_CC);
+               zend_throw_exception_object(&ex TSRMLS_CC);
        }
 
-       if (info) {
+       if (!ZVAL_IS_UNDEF(&info)) {
                zval_ptr_dtor(&info);
        }
 
@@ -270,27 +265,28 @@ static PHP_METHOD(PDO, dbh_constructor)
                return;
        }
        
-       dbh = (pdo_dbh_t *) zend_object_store_get_object(object TSRMLS_CC);
+       dbh = Z_PDO_DBH_P(object);
 
        /* is this supposed to be a persistent connection ? */
        if (options) {
-               zval **v;
+               zval *v;
                int plen = 0;
                char *hashkey = NULL;
-               zend_rsrc_list_entry *le;
+               zend_resource *le;
                pdo_dbh_t *pdbh = NULL;
 
-               if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_PERSISTENT, (void**)&v)) {
-                       if (Z_TYPE_PP(v) == IS_STRING && !is_numeric_string(Z_STRVAL_PP(v), Z_STRLEN_PP(v), NULL, NULL, 0) && Z_STRLEN_PP(v) > 0) {
+               if ((v = zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_PERSISTENT)) != NULL) {
+                       if (Z_TYPE_P(v) == IS_STRING &&
+                               !is_numeric_string(Z_STRVAL_P(v), Z_STRLEN_P(v), NULL, NULL, 0) && Z_STRLEN_P(v) > 0) {
                                /* user specified key */
                                plen = spprintf(&hashkey, 0, "PDO:DBH:DSN=%s:%s:%s:%s", data_source,
                                                username ? username : "",
                                                password ? password : "",
-                                               Z_STRVAL_PP(v));
+                                               Z_STRVAL_P(v));
                                is_persistent = 1;
                        } else {
                                convert_to_long_ex(v);
-                               is_persistent = Z_LVAL_PP(v) ? 1 : 0;
+                               is_persistent = Z_LVAL_P(v) ? 1 : 0;
                                plen = spprintf(&hashkey, 0, "PDO:DBH:DSN=%s:%s:%s", data_source,
                                                username ? username : "",
                                                password ? password : "");
@@ -299,8 +295,8 @@ static PHP_METHOD(PDO, dbh_constructor)
 
                if (is_persistent) {
                        /* let's see if we have one cached.... */
-                       if (SUCCESS == zend_hash_find(&EG(persistent_list), hashkey, plen+1, (void*)&le)) {
-                               if (Z_TYPE_P(le) == php_pdo_list_entry()) {
+                       if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashkey, plen)) != NULL) {
+                               if (le->type == php_pdo_list_entry()) {
                                        pdbh = (pdo_dbh_t*)le->ptr;
 
                                        /* is the connection still alive ? */
@@ -327,7 +323,7 @@ static PHP_METHOD(PDO, dbh_constructor)
                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "out of memory while allocating PDO handle");
                                }
                                memcpy((char *)pdbh->persistent_id, hashkey, plen+1);
-                               pdbh->persistent_id_len = plen+1;
+                               pdbh->persistent_id_len = plen;
                                pdbh->refcount = 1;
                                pdbh->std.properties = NULL;
                        }
@@ -338,21 +334,19 @@ static PHP_METHOD(PDO, dbh_constructor)
                        if (pdbh->std.properties) {
                                zend_hash_destroy(dbh->std.properties); 
                                efree(dbh->std.properties);
-                               if (dbh->std.properties_table) {
-                                       efree(dbh->std.properties_table);
-                               }
                        } else {
                                pdbh->std.ce = dbh->std.ce;
                                pdbh->def_stmt_ce = dbh->def_stmt_ce;
-                               pdbh->def_stmt_ctor_args = dbh->def_stmt_ctor_args;
+                               ZVAL_COPY_VALUE(&pdbh->def_stmt_ctor_args, &dbh->def_stmt_ctor_args);
                                pdbh->std.properties = dbh->std.properties;
-                               pdbh->std.properties_table = dbh->std.properties_table;
+                               //???
+                               //pdbh->std.properties_table = dbh->std.properties_table;
                        }
                        /* kill the non-persistent thingamy */
                        efree(dbh);
                        /* switch over to the persistent one */
                        dbh = pdbh;
-                       zend_object_store_set_object(object, dbh TSRMLS_CC);
+                       zend_object_store_set_object(object, &dbh->std TSRMLS_CC);
                        dbh->refcount++;
                }
 
@@ -384,7 +378,7 @@ static PHP_METHOD(PDO, dbh_constructor)
                /* all set */
 
                if (is_persistent) {
-                       zend_rsrc_list_entry le;
+                       zend_resource le;
 
                        /* register in the persistent list etc. */
                        /* we should also need to replace the object store entry,
@@ -393,9 +387,8 @@ static PHP_METHOD(PDO, dbh_constructor)
                        le.type = php_pdo_list_entry();
                        le.ptr = dbh;
 
-                       if (FAILURE == zend_hash_update(&EG(persistent_list),
-                                       (char*)dbh->persistent_id, dbh->persistent_id_len, (void*)&le,
-                                       sizeof(le), NULL)) {
+                       if (zend_hash_str_update_mem(&EG(persistent_list), 
+                                               (char*)dbh->persistent_id, dbh->persistent_id_len, &le, sizeof(le))) {
                                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to register persistent entry");
                        }
                }
@@ -403,15 +396,15 @@ static PHP_METHOD(PDO, dbh_constructor)
                dbh->driver = driver;
 options:
                if (options) {
-                       zval **attr_value;
-                       char *str_key;
+                       zval *attr_value;
+                       zend_string *str_key;
                        ulong long_key;
                        
                        zend_hash_internal_pointer_reset(Z_ARRVAL_P(options));
-                       while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(options), (void**)&attr_value) 
+                       while ((attr_value = zend_hash_get_current_data(Z_ARRVAL_P(options))) != NULL
                                && HASH_KEY_IS_LONG == zend_hash_get_current_key(Z_ARRVAL_P(options), &str_key, &long_key, 0)) {
                                
-                               pdo_dbh_attribute_set(dbh, long_key, *attr_value TSRMLS_CC);
+                               pdo_dbh_attribute_set(dbh, long_key, attr_value TSRMLS_CC);
                                zend_hash_move_forward(Z_ARRVAL_P(options));
                        }
                }
@@ -427,7 +420,7 @@ options:
 
 static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args TSRMLS_DC) /* {{{ */
 {
-       if (ctor_args) {
+       if (!ZVAL_IS_UNDEF(ctor_args)) {
                if (Z_TYPE_P(ctor_args) != IS_ARRAY) {
                        pdo_raise_impl_error(dbh, NULL, "HY000", "constructor arguments must be passed as an array" TSRMLS_CC);
                        return NULL;
@@ -438,47 +431,45 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry
                }
        }
 
-       Z_TYPE_P(object) = IS_OBJECT;
        object_init_ex(object, dbstmt_ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
+       // ??? Z_SET_REFCOUNT_P(object, 1);
+       //Z_SET_ISREF_P(object);
        
        return object;
 } /* }}} */
 
 static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args TSRMLS_DC) /* {{{ */
 {      
-       zval *query_string;
+       zval query_string;
        zval z_key;
 
-       MAKE_STD_ZVAL(query_string);
-       ZVAL_STRINGL(query_string, stmt->query_string, stmt->query_stringlen, 1);
-       ZVAL_STRINGL(&z_key, "queryString", sizeof("queryString")-1, 0);
-       std_object_handlers.write_property(object, &z_key, query_string, 0 TSRMLS_CC);
+       ZVAL_STRINGL(&query_string, stmt->query_string, stmt->query_stringlen);
+       ZVAL_STRINGL(&z_key, "queryString", sizeof("queryString") - 1);
+       std_object_handlers.write_property(object, &z_key, &query_string, NULL TSRMLS_CC);
        zval_ptr_dtor(&query_string);
 
        if (dbstmt_ce->constructor) {
                zend_fcall_info fci;
                zend_fcall_info_cache fcc;
-               zval *retval = NULL;
+               zval retval;
 
                fci.size = sizeof(zend_fcall_info);
                fci.function_table = &dbstmt_ce->function_table;
-               fci.function_name = NULL;
-               fci.object_ptr = object;
+               ZVAL_UNDEF(&fci.function_name);
+               fci.object = Z_OBJ_P(object);
                fci.symbol_table = NULL;
-               fci.retval_ptr_ptr = &retval;
-               if (ctor_args) {
+               fci.retval = &retval;
+               if (!ZVAL_IS_UNDEF(ctor_args)) {
                        HashTable *ht = Z_ARRVAL_P(ctor_args);
                        uint idx;
                        Bucket *p;
 
                        fci.param_count = 0;
-                       fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
+                       fci.params = safe_emalloc(sizeof(zval), ht->nNumOfElements, 0);
                        for (idx = 0; idx < ht->nNumUsed; idx++) {
                                p = ht->arData + idx;
-                               if (!p->xData) continue;
-                               fci.params[fci.param_count++] = (zval**)&p->xData;
+                               if (ZVAL_IS_UNDEF(&p->val)) continue;
+                               ZVAL_COPY_VALUE(&fci.params[fci.param_count++], &p->val);
                        }
                } else {
                        fci.param_count = 0;
@@ -490,13 +481,13 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry
                fcc.function_handler = dbstmt_ce->constructor;
                fcc.calling_scope = EG(scope);
                fcc.called_scope = Z_OBJCE_P(object);
-               fcc.object_ptr = object;
+               fcc.object = Z_OBJ_P(object);
 
                if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                        zval_dtor(object);
                        ZVAL_NULL(object);
                        object = NULL; /* marks failure */
-               } else if (retval) {
+               } else if (!ZVAL_IS_UNDEF(&retval)) {
                        zval_ptr_dtor(&retval);
                }
                        
@@ -511,12 +502,12 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry
    Prepares a statement for execution and returns a statement object */
 static PHP_METHOD(PDO, prepare)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        pdo_stmt_t *stmt;
        char *statement;
        int statement_len;
-       zval *options = NULL, **opt, **item, *ctor_args;
-       zend_class_entry *dbstmt_ce, **pce;
+       zval *options = NULL, *opt, *item, ctor_args;
+       zend_class_entry *dbstmt_ce, *pce;
 
        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &statement,
                        &statement_len, &options)) {
@@ -526,10 +517,10 @@ static PHP_METHOD(PDO, prepare)
        PDO_DBH_CLEAR_ERR();
        PDO_CONSTRUCT_CHECK;
 
-       if (ZEND_NUM_ARGS() > 1 && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_STATEMENT_CLASS, (void**)&opt)) {
-               if (Z_TYPE_PP(opt) != IS_ARRAY || zend_hash_index_find(Z_ARRVAL_PP(opt), 0, (void**)&item) == FAILURE
-                       || Z_TYPE_PP(item) != IS_STRING
-                       || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE
+       if (ZEND_NUM_ARGS() > 1 && (opt = zend_hash_index_find(Z_ARRVAL_P(options), PDO_ATTR_STATEMENT_CLASS)) != NULL) {
+               if (Z_TYPE_P(opt) != IS_ARRAY || (item = zend_hash_index_find(Z_ARRVAL_P(opt), 0)) == NULL
+                       || Z_TYPE_P(item) != IS_STRING
+                       || (pce = zend_lookup_class(Z_STR_P(item) TSRMLS_CC)) == NULL
                ) {
                        pdo_raise_impl_error(dbh, NULL, "HY000", 
                                "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
@@ -538,7 +529,7 @@ static PHP_METHOD(PDO, prepare)
                        PDO_HANDLE_DBH_ERR();
                        RETURN_FALSE;
                }
-               dbstmt_ce = *pce;
+               dbstmt_ce = pce;
                if (!instanceof_function(dbstmt_ce, pdo_dbstmt_ce TSRMLS_CC)) {
                        pdo_raise_impl_error(dbh, NULL, "HY000", 
                                "user-supplied statement class must be derived from PDOStatement" TSRMLS_CC);
@@ -551,8 +542,8 @@ static PHP_METHOD(PDO, prepare)
                        PDO_HANDLE_DBH_ERR();
                        RETURN_FALSE;
                }
-               if (zend_hash_index_find(Z_ARRVAL_PP(opt), 1, (void**)&item) == SUCCESS) {
-                       if (Z_TYPE_PP(item) != IS_ARRAY) {
+               if ((item = zend_hash_index_find(Z_ARRVAL_P(opt), 1)) != NULL) {
+                       if (Z_TYPE_P(item) != IS_ARRAY) {
                                pdo_raise_impl_error(dbh, NULL, "HY000", 
                                        "PDO::ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); "
                                        "ctor_args must be an array"
@@ -560,23 +551,23 @@ static PHP_METHOD(PDO, prepare)
                                PDO_HANDLE_DBH_ERR();
                                RETURN_FALSE;
                        }
-                       ctor_args = *item;
+                       ZVAL_COPY_VALUE(&ctor_args, item);
                } else {
-                       ctor_args = NULL;
+                       ZVAL_UNDEF(&ctor_args);
                }
        } else {
                dbstmt_ce = dbh->def_stmt_ce;
-               ctor_args = dbh->def_stmt_ctor_args;
+               ZVAL_COPY_VALUE(&ctor_args, &dbh->def_stmt_ctor_args);
        }
 
-       if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args TSRMLS_CC)) {
+       if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, &ctor_args TSRMLS_CC)) {
                pdo_raise_impl_error(dbh, NULL, "HY000", 
                        "failed to instantiate user-supplied statement class"
                        TSRMLS_CC);
                PDO_HANDLE_DBH_ERR();
                RETURN_FALSE;
        }
-       stmt = (pdo_stmt_t*)zend_object_store_get_object(return_value TSRMLS_CC);
+       stmt = Z_PDO_STMT_P(return_value);
        
        /* unconditionally keep this for later reference */
        stmt->query_string = estrndup(statement, statement_len);
@@ -584,14 +575,14 @@ static PHP_METHOD(PDO, prepare)
        stmt->default_fetch_type = dbh->default_fetch_type;
        stmt->dbh = dbh;
        /* give it a reference to me */
-       zend_objects_store_add_ref(getThis() TSRMLS_CC);
+       Z_ADDREF_P(getThis() TSRMLS_CC);
        php_pdo_dbh_addref(dbh TSRMLS_CC);
-       stmt->database_object_handle = *getThis();
+       ZVAL_COPY_VALUE(&stmt->database_object_handle, getThis());
        /* we haven't created a lazy object yet */
        ZVAL_NULL(&stmt->lazy_object_ref);
 
        if (dbh->methods->preparer(dbh, statement, statement_len, stmt, options TSRMLS_CC)) {
-               pdo_stmt_construct(stmt, return_value, dbstmt_ce, ctor_args TSRMLS_CC);
+               pdo_stmt_construct(stmt, return_value, dbstmt_ce, &ctor_args TSRMLS_CC);
                return;
        }
 
@@ -608,7 +599,7 @@ static PHP_METHOD(PDO, prepare)
    Initiates a transaction */
 static PHP_METHOD(PDO, beginTransaction)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -641,7 +632,7 @@ static PHP_METHOD(PDO, beginTransaction)
    Commit a transaction */
 static PHP_METHOD(PDO, commit)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -667,7 +658,7 @@ static PHP_METHOD(PDO, commit)
    roll back a transaction */
 static PHP_METHOD(PDO, rollBack)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -693,7 +684,7 @@ static PHP_METHOD(PDO, rollBack)
    determine if inside a transaction */
 static PHP_METHOD(PDO, inTransaction)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -759,9 +750,9 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D
 
                case PDO_ATTR_DEFAULT_FETCH_MODE:
                        if (Z_TYPE_P(value) == IS_ARRAY) {
-                               zval **tmp;
-                               if (zend_hash_index_find(Z_ARRVAL_P(value), 0, (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) {
-                                       if (Z_LVAL_PP(tmp) == PDO_FETCH_INTO || Z_LVAL_PP(tmp) == PDO_FETCH_CLASS) {
+                               zval *tmp;
+                               if ((tmp = zend_hash_index_find(Z_ARRVAL_P(value), 0)) != NULL && Z_TYPE_P(tmp) == IS_LONG) {
+                                       if (Z_LVAL_P(tmp) == PDO_FETCH_INTO || Z_LVAL_P(tmp) == PDO_FETCH_CLASS) {
                                                pdo_raise_impl_error(dbh, NULL, "HY000", "FETCH_INTO and FETCH_CLASS are not yet supported as default fetch modes" TSRMLS_CC);
                                                return FAILURE;
                                        }
@@ -785,8 +776,8 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D
                        
                case PDO_ATTR_STATEMENT_CLASS: {
                        /* array(string classname, array(mixed ctor_args)) */
-                       zend_class_entry **pce;
-                       zval **item;
+                       zend_class_entry *pce;
+                       zval *item;
 
                        if (dbh->is_persistent) {
                                pdo_raise_impl_error(dbh, NULL, "HY000", 
@@ -796,9 +787,9 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D
                                return FAILURE;
                        }
                        if (Z_TYPE_P(value) != IS_ARRAY
-                               || zend_hash_index_find(Z_ARRVAL_P(value), 0, (void**)&item) == FAILURE
-                               || Z_TYPE_PP(item) != IS_STRING
-                               || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE
+                               || (item = zend_hash_index_find(Z_ARRVAL_P(value), 0)) == NULL
+                               || Z_TYPE_P(item) != IS_STRING
+                               || (pce = zend_lookup_class(Z_STR_P(item) TSRMLS_CC)) == NULL
                        ) {
                                pdo_raise_impl_error(dbh, NULL, "HY000", 
                                        "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
@@ -807,25 +798,25 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D
                                PDO_HANDLE_DBH_ERR();
                                return FAILURE;
                        }
-                       if (!instanceof_function(*pce, pdo_dbstmt_ce TSRMLS_CC)) {
+                       if (!instanceof_function(pce, pdo_dbstmt_ce TSRMLS_CC)) {
                                pdo_raise_impl_error(dbh, NULL, "HY000", 
                                        "user-supplied statement class must be derived from PDOStatement" TSRMLS_CC);
                                PDO_HANDLE_DBH_ERR();
                                return FAILURE;
                        }
-                       if ((*pce)->constructor && !((*pce)->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) {
+                       if (pce->constructor && !(pce->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) {
                                pdo_raise_impl_error(dbh, NULL, "HY000", 
                                        "user-supplied statement class cannot have a public constructor" TSRMLS_CC);
                                PDO_HANDLE_DBH_ERR();
                                return FAILURE;
                        }
-                       dbh->def_stmt_ce = *pce;
-                       if (dbh->def_stmt_ctor_args) {
+                       dbh->def_stmt_ce = pce;
+                       if (!ZVAL_IS_UNDEF(&dbh->def_stmt_ctor_args)) {
                                zval_ptr_dtor(&dbh->def_stmt_ctor_args);
-                               dbh->def_stmt_ctor_args = NULL;
+                               ZVAL_UNDEF(&dbh->def_stmt_ctor_args);
                        }
-                       if (zend_hash_index_find(Z_ARRVAL_P(value), 1, (void**)&item) == SUCCESS) {
-                               if (Z_TYPE_PP(item) != IS_ARRAY) {
+                       if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
+                               if (Z_TYPE_P(item) != IS_ARRAY) {
                                        pdo_raise_impl_error(dbh, NULL, "HY000", 
                                                "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); "
                                                "ctor_args must be an array"
@@ -833,8 +824,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D
                                        PDO_HANDLE_DBH_ERR();
                                        return FAILURE;
                                }
-                               Z_ADDREF_PP(item);
-                               dbh->def_stmt_ctor_args = *item;
+                               ZVAL_COPY(&dbh->def_stmt_ctor_args, item);
                        }
                        return SUCCESS;
                }
@@ -868,7 +858,7 @@ fail:
    Set an attribute */
 static PHP_METHOD(PDO, setAttribute)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        long attr;
        zval *value;
 
@@ -890,7 +880,7 @@ static PHP_METHOD(PDO, setAttribute)
    Get an attribute */
 static PHP_METHOD(PDO, getAttribute)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        long attr;
 
        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &attr)) {
@@ -915,19 +905,20 @@ static PHP_METHOD(PDO, getAttribute)
                        RETURN_LONG(dbh->error_mode);
 
                case PDO_ATTR_DRIVER_NAME:
-                       RETURN_STRINGL((char*)dbh->driver->driver_name, dbh->driver->driver_name_len, 1);
+                       RETURN_STRINGL((char*)dbh->driver->driver_name, dbh->driver->driver_name_len);
 
                case PDO_ATTR_STATEMENT_CLASS:
                        array_init(return_value);
-                       add_next_index_string(return_value, dbh->def_stmt_ce->name);
-                       if (dbh->def_stmt_ctor_args) {
-                               Z_ADDREF_P(dbh->def_stmt_ctor_args);
-                               add_next_index_zval(return_value, dbh->def_stmt_ctor_args);
+                       add_next_index_str(return_value, STR_COPY(dbh->def_stmt_ce->name));
+                       if (!ZVAL_IS_UNDEF(&dbh->def_stmt_ctor_args)) {
+                               Z_ADDREF(dbh->def_stmt_ctor_args);
+                               add_next_index_zval(return_value, &dbh->def_stmt_ctor_args);
                        }
                        return;
                case PDO_ATTR_DEFAULT_FETCH_MODE:
                        RETURN_LONG(dbh->default_fetch_type);
-
+               default:
+                       break;
        }
        
        if (!dbh->methods->get_attribute) {
@@ -954,7 +945,7 @@ static PHP_METHOD(PDO, getAttribute)
    Execute a query that does not return a row set, returning the number of affected rows */
 static PHP_METHOD(PDO, exec)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        char *statement;
        int statement_len;
        long ret;
@@ -979,12 +970,11 @@ static PHP_METHOD(PDO, exec)
 }
 /* }}} */
 
-
 /* {{{ proto string PDO::lastInsertId([string seqname])
    Returns the id of the last row that we affected on this connection.  Some databases require a sequence or table name to be passed in.  Not always meaningful. */
 static PHP_METHOD(PDO, lastInsertId)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        char *name = NULL;
        int namelen;
 
@@ -998,12 +988,16 @@ static PHP_METHOD(PDO, lastInsertId)
                pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()" TSRMLS_CC);
                RETURN_FALSE;
        } else {
-               Z_STRVAL_P(return_value) = dbh->methods->last_id(dbh, name, (unsigned int *)&Z_STRLEN_P(return_value) TSRMLS_CC);
-               if (!Z_STRVAL_P(return_value)) {
+               int id_len;
+               char *id;
+               id = dbh->methods->last_id(dbh, name, (unsigned int *)&id_len TSRMLS_CC);
+               if (!id) {
                        PDO_HANDLE_DBH_ERR();
                        RETURN_FALSE;
                } else {
-                       Z_TYPE_P(return_value) = IS_STRING;
+                       //??? use zend_string ?
+                       RETVAL_STRINGL(id, id_len);
+                       efree(id);
                }
        }
 }
@@ -1013,7 +1007,7 @@ static PHP_METHOD(PDO, lastInsertId)
    Fetch the error code associated with the last operation on the database handle */
 static PHP_METHOD(PDO, errorCode)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1021,7 +1015,7 @@ static PHP_METHOD(PDO, errorCode)
        PDO_CONSTRUCT_CHECK;
 
        if (dbh->query_stmt) {
-               RETURN_STRING(dbh->query_stmt->error_code, 1);
+               RETURN_STRING(dbh->query_stmt->error_code);
        }
        
        if (dbh->error_code[0] == '\0') {
@@ -1032,7 +1026,7 @@ static PHP_METHOD(PDO, errorCode)
         * Making sure that we fallback to the default implementation
         * if the dbh->error_code is not null.
         */
-       RETURN_STRING(dbh->error_code, 1);
+       RETURN_STRING(dbh->error_code);
 }
 /* }}} */
 
@@ -1044,7 +1038,7 @@ static PHP_METHOD(PDO, errorInfo)
        int error_count_diff     = 0;
        int error_expected_count = 3;
 
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1086,7 +1080,7 @@ static PHP_METHOD(PDO, errorInfo)
    Prepare and execute $sql; returns the statement object for iteration */
 static PHP_METHOD(PDO, query)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        pdo_stmt_t *stmt;
        char *statement;
        int statement_len;
@@ -1105,11 +1099,11 @@ static PHP_METHOD(PDO, query)
        PDO_DBH_CLEAR_ERR();
        PDO_CONSTRUCT_CHECK;
 
-       if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args TSRMLS_CC)) {
+       if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args TSRMLS_CC)) {
                pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user supplied statement class" TSRMLS_CC);
                return;
        }
-       stmt = (pdo_stmt_t*)zend_object_store_get_object(return_value TSRMLS_CC);
+       stmt = Z_PDO_STMT_P(return_value);
        
        /* unconditionally keep this for later reference */
        stmt->query_string = estrndup(statement, statement_len);
@@ -1120,7 +1114,7 @@ static PHP_METHOD(PDO, query)
        stmt->active_query_stringlen = statement_len;
        stmt->dbh = dbh;
        /* give it a reference to me */
-       zend_objects_store_add_ref(getThis() TSRMLS_CC);
+       Z_ADDREF_P(getThis());
        php_pdo_dbh_addref(dbh TSRMLS_CC);
        stmt->database_object_handle = *getThis();
        /* we haven't created a lazy object yet */
@@ -1141,14 +1135,14 @@ static PHP_METHOD(PDO, query)
                                        stmt->executed = 1;
                                }
                                if (ret) {
-                                       pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args TSRMLS_CC);
+                                       pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args TSRMLS_CC);
                                        return;
                                }
                        }
                }
                /* something broke */
                dbh->query_stmt = stmt;
-               dbh->query_stmt_zval = *return_value;
+               ZVAL_COPY_VALUE(&dbh->query_stmt_zval, return_value);
                PDO_HANDLE_STMT_ERR();
        } else {
                PDO_HANDLE_DBH_ERR();
@@ -1163,7 +1157,7 @@ static PHP_METHOD(PDO, query)
    quotes string for use in a query.  The optional paramtype acts as a hint for drivers that have alternate quoting styles.  The default value is PDO_PARAM_STR */
 static PHP_METHOD(PDO, quote)
 {
-       pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+       pdo_dbh_t *dbh = Z_PDO_DBH_P(getThis());
        char *str;
        int str_len;
        long paramtype = PDO_PARAM_STR;
@@ -1182,7 +1176,8 @@ static PHP_METHOD(PDO, quote)
        }
 
        if (dbh->methods->quoter(dbh, str, str_len, &qstr, &qlen, paramtype TSRMLS_CC)) {
-               RETURN_STRINGL(qstr, qlen, 0);
+               //??? memleak
+               RETURN_STRINGL(qstr, qlen);
        }
        PDO_HANDLE_DBH_ERR();
        RETURN_FALSE;
@@ -1210,7 +1205,7 @@ static PHP_METHOD(PDO, __sleep)
 static PHP_METHOD(PDO, getAvailableDrivers)
 {
        HashPosition pos;
-       pdo_driver_t **pdriver;
+       pdo_driver_t *pdriver;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1219,8 +1214,8 @@ static PHP_METHOD(PDO, getAvailableDrivers)
        array_init(return_value);
 
        zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos);
-       while (SUCCESS == zend_hash_get_current_data_ex(&pdo_driver_hash, (void**)&pdriver, &pos)) {
-               add_next_index_stringl(return_value, (char*)(*pdriver)->driver_name, (*pdriver)->driver_name_len);
+       while ((pdriver = zend_hash_get_current_data_ptr_ex(&pdo_driver_hash, &pos)) != NULL) {
+               add_next_index_stringl(return_value, (char*)pdriver->driver_name, pdriver->driver_name_len);
                zend_hash_move_forward_ex(&pdo_driver_hash, &pos);
        }
 }
@@ -1311,7 +1306,7 @@ int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
        while (funcs->fname) {
                ifunc->type = ZEND_INTERNAL_FUNCTION;
                ifunc->handler = funcs->handler;
-               ifunc->function_name = (char*)funcs->fname;
+               ifunc->function_name = STR_INIT(funcs->fname, strlen(funcs->fname), 0);
                ifunc->scope = dbh->std.ce;
                ifunc->prototype = NULL;
                if (funcs->flags) {
@@ -1343,7 +1338,7 @@ int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
                namelen = strlen(funcs->fname);
                lc_name = emalloc(namelen+1);
                zend_str_tolower_copy(lc_name, funcs->fname, namelen);
-               zend_hash_add(dbh->cls_methods[kind], lc_name, namelen+1, &func, sizeof(func), NULL);
+               zend_hash_str_add_mem(dbh->cls_methods[kind], lc_name, namelen, &func, sizeof(func));
                efree(lc_name);
                funcs++;
        }
@@ -1351,25 +1346,16 @@ int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
        return 1;
 }
 
-static union _zend_function *dbh_method_get(
-#if PHP_API_VERSION >= 20041225
-       zval **object_pp,
-#else
-       zval *object,
-#endif
-       char *method_name, int method_len, const zend_literal *key TSRMLS_DC)
+static union _zend_function *dbh_method_get(zend_object **object, zend_string *method_name, const zend_literal *key TSRMLS_DC)
 {
        zend_function *fbc = NULL;
-       char *lc_method_name;
-#if PHP_API_VERSION >= 20041225
-       zval *object = *object_pp;
-#endif
-       pdo_dbh_t *dbh = zend_object_store_get_object(object TSRMLS_CC);
+       pdo_dbh_t *dbh = php_pdo_dbh_fetch_object(*object);
+       zend_string *lc_method_name;
 
-       lc_method_name = emalloc(method_len + 1);
-       zend_str_tolower_copy(lc_method_name, method_name, method_len);
+       lc_method_name = STR_INIT(method_name->val, method_name->len, 0);
+       zend_str_tolower_copy(lc_method_name->val, method_name->val, method_name->len);
 
-       if ((fbc = std_object_handlers.get_method(object_pp, method_name, method_len, key TSRMLS_CC)) == NULL) {
+       if ((fbc = std_object_handlers.get_method(object, method_name, key TSRMLS_CC)) == NULL) {
                /* not a pre-defined method, nor a user-defined method; check
                 * the driver specific methods */
                if (!dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH]) {
@@ -1380,16 +1366,11 @@ static union _zend_function *dbh_method_get(
                        }
                }
 
-               if (zend_hash_find(dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH],
-                               lc_method_name, method_len+1, (void**)&fbc) == FAILURE) {
-                       if (!fbc) {
-                               fbc = NULL;
-                       }
-               }
+               fbc = zend_hash_find_ptr(dbh->cls_methods[PDO_DBH_DRIVER_METHOD_KIND_DBH], lc_method_name);
        }
 
 out:
-       efree(lc_method_name);
+       STR_RELEASE(lc_method_name);
        return fbc;
 }
 
@@ -1399,6 +1380,7 @@ static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC)
 }
 
 static zend_object_handlers pdo_dbh_object_handlers;
+static void pdo_dbh_free_storage(zend_object *std TSRMLS_DC);
 
 void pdo_dbh_init(TSRMLS_D)
 {
@@ -1409,6 +1391,9 @@ void pdo_dbh_init(TSRMLS_D)
        pdo_dbh_ce->create_object = pdo_dbh_new;
 
        memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
+       pdo_dbh_object_handlers.offset = XtOffsetOf(pdo_dbh_t, std);
+       pdo_dbh_object_handlers.dtor_obj = zend_objects_destroy_object;
+       pdo_dbh_object_handlers.free_obj = pdo_dbh_free_storage;
        pdo_dbh_object_handlers.get_method = dbh_method_get;
        pdo_dbh_object_handlers.compare_objects = dbh_compare;
        
@@ -1539,7 +1524,7 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC)
                pefree((char *)dbh->persistent_id, dbh->is_persistent);
        }
 
-       if (dbh->def_stmt_ctor_args) {
+       if (!ZVAL_IS_UNDEF(&dbh->def_stmt_ctor_args)) {
                zval_ptr_dtor(&dbh->def_stmt_ctor_args);
        }
        
@@ -1563,8 +1548,9 @@ PDO_API void php_pdo_dbh_delref(pdo_dbh_t *dbh TSRMLS_DC)
        dbh_free(dbh TSRMLS_CC);
 }
 
-static void pdo_dbh_free_storage(pdo_dbh_t *dbh TSRMLS_DC)
+static void pdo_dbh_free_storage(zend_object *std TSRMLS_DC)
 {
+       pdo_dbh_t *dbh = php_pdo_dbh_fetch_object(std);
        if (dbh->in_txn && dbh->methods && dbh->methods->rollback) {
                dbh->methods->rollback(dbh TSRMLS_CC);
                dbh->in_txn = 0;
@@ -1573,39 +1559,34 @@ static void pdo_dbh_free_storage(pdo_dbh_t *dbh TSRMLS_DC)
        if (dbh->is_persistent && dbh->methods && dbh->methods->persistent_shutdown) {
                dbh->methods->persistent_shutdown(dbh TSRMLS_CC);
        }
-       zend_object_std_dtor(&dbh->std TSRMLS_CC);
-       dbh->std.properties = NULL;
-       dbh->std.properties_table = NULL;
-       dbh_free(dbh TSRMLS_CC);
+       zend_object_std_dtor(std TSRMLS_CC);
 }
 
-zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC)
+zend_object *pdo_dbh_new(zend_class_entry *ce TSRMLS_DC)
 {
-       zend_object_value retval;
        pdo_dbh_t *dbh;
 
-       dbh = emalloc(sizeof(*dbh));
-       memset(dbh, 0, sizeof(*dbh));
+       dbh = ecalloc(1, sizeof(pdo_dbh_t) + sizeof(zval) * (ce->default_properties_count - 1));
        zend_object_std_init(&dbh->std, ce TSRMLS_CC);
        object_properties_init(&dbh->std, ce);
        rebuild_object_properties(&dbh->std);
        dbh->refcount = 1;
        dbh->def_stmt_ce = pdo_dbstmt_ce;
        
-       retval.handle = zend_objects_store_put(dbh, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbh_free_storage, NULL TSRMLS_CC);
-       retval.handlers = &pdo_dbh_object_handlers;
+       zend_objects_store_put(&dbh->std TSRMLS_CC);
+       dbh->std.handlers = &pdo_dbh_object_handlers;
        
-       return retval;
+       return &dbh->std;
 }
 
 /* }}} */
 
 ZEND_RSRC_DTOR_FUNC(php_pdo_pdbh_dtor)
 {
-       if (rsrc->ptr) {
-               pdo_dbh_t *dbh = (pdo_dbh_t*)rsrc->ptr;
+       if (res->ptr) {
+               pdo_dbh_t *dbh = (pdo_dbh_t*)res->ptr;
                dbh_free(dbh TSRMLS_CC);
-               rsrc->ptr = NULL;
+               res->ptr = NULL;
        }
 }
 
index 56a69cac30da5d117e663f0af66efac9fed5088f..5abb15a177f4f99d81903e75007cb979dc1a1e25 100644 (file)
@@ -194,21 +194,21 @@ enum pdo_null_handling {
 /* {{{ utils for reading attributes set as driver_options */
 static inline long pdo_attr_lval(zval *options, enum pdo_attribute_type option_name, long defval TSRMLS_DC)
 {
-       zval **v;
+       zval *v;
 
-       if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
+       if (options && (v = zend_hash_index_find(Z_ARRVAL_P(options), option_name))) {
                convert_to_long_ex(v);
-               return Z_LVAL_PP(v);
+               return Z_LVAL_P(v);
        }
        return defval;
 }
 static inline char *pdo_attr_strval(zval *options, enum pdo_attribute_type option_name, char *defval TSRMLS_DC)
 {
-       zval **v;
+       zval *v;
 
-       if (options && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(options), option_name, (void**)&v)) {
+       if (options && (v = zend_hash_index_find(Z_ARRVAL_P(options), option_name))) {
                convert_to_string_ex(v);
-               return estrndup(Z_STRVAL_PP(v), Z_STRLEN_PP(v));
+               return estrndup(Z_STRVAL_P(v), Z_STRLEN_P(v));
        }
        return defval ? estrdup(defval) : NULL;
 }
@@ -426,13 +426,6 @@ enum pdo_placeholder_support {
 
 /* represents a connection to a database */
 struct _pdo_dbh_t {
-       /* these items must 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 declares.
-    */
-       zend_object std;
-
        /* driver specific methods */
        struct pdo_dbh_methods *methods;
        /* driver specific data */
@@ -496,7 +489,7 @@ struct _pdo_dbh_t {
        
        zend_class_entry *def_stmt_ce;
 
-       zval *def_stmt_ctor_args;
+       zval def_stmt_ctor_args;
 
        /* when calling PDO::query(), we need to keep the error
         * context from the statement around until we next clear it.
@@ -507,8 +500,21 @@ struct _pdo_dbh_t {
 
        /* defaults for fetches */
        enum pdo_fetch_type default_fetch_type;
+
+       /* these items must 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 declares.
+    */
+       zend_object std;
 };
 
+static inline pdo_dbh_t *php_pdo_dbh_fetch_object(zend_object *obj) {
+       return (pdo_dbh_t *)((char*)(obj) - XtOffsetOf(pdo_dbh_t, std));
+}
+
+#define Z_PDO_DBH_P(zv) php_pdo_dbh_fetch_object(Z_OBJ_P((zv)))
+
 /* describes a column */
 struct pdo_column_data {
        char *name;
@@ -541,13 +547,6 @@ struct pdo_bound_param_data {
 
 /* represents a prepared statement */
 struct _pdo_stmt_t {
-       /* these items must 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 declares.
-    */
-       zend_object std;
-
        /* driver specifics */
        struct pdo_stmt_methods *methods;
        void *driver_data;
@@ -626,8 +625,21 @@ struct _pdo_stmt_t {
        /* used by the query parser for driver specific
         * parameter naming (see pgsql driver for example) */
        const char *named_rewrite_template;
+
+       /* these items must 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 declares.
+    */
+       zend_object std;
 };
 
+static inline pdo_stmt_t *php_pdo_stmt_fetch_object(zend_object *obj) {
+       return (pdo_stmt_t *)((char*)(obj) - XtOffsetOf(pdo_stmt_t, std));
+}
+
+#define Z_PDO_STMT_P(zv) php_pdo_stmt_fetch_object(Z_OBJ_P((zv)))
+
 /* call this in MINIT to register your PDO driver */
 PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
 /* call this in MSHUTDOWN to unregister your PDO driver */
index 74fe0ad0fef3e28fc7806b8a86c13f1379eaddae..60bb89a8f86d30e638b902f95738a2ad374d50aa 100644 (file)
@@ -29,7 +29,7 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC);
        strlcpy(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE)); \
        if (dbh->query_stmt) { \
                dbh->query_stmt = NULL; \
-               zend_objects_store_del_ref(&dbh->query_stmt_zval TSRMLS_CC); \
+               zval_ptr_dtor(&dbh->query_stmt_zval); \
        } \
 } while (0)
 #define PDO_STMT_CLEAR_ERR()    strcpy(stmt->error_code, PDO_ERR_NONE)
index e1868644a331f2d39a86c218733fdef3d0ba60c0..d25f5c3ba4ab5b28ac63e4a80870cc565ee5c225 100644 (file)
@@ -33,12 +33,12 @@ int php_pdo_list_entry(void);
 void pdo_dbh_init(TSRMLS_D);
 void pdo_stmt_init(TSRMLS_D);
 
-extern zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC);
+extern zend_object *pdo_dbh_new(zend_class_entry *ce TSRMLS_DC);
 extern const zend_function_entry pdo_dbh_functions[];
 extern zend_class_entry *pdo_dbh_ce;
 extern ZEND_RSRC_DTOR_FUNC(php_pdo_pdbh_dtor);
 
-extern zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC);
+extern zend_object *pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC);
 extern const zend_function_entry pdo_dbstmt_functions[];
 extern zend_class_entry *pdo_dbstmt_ce;
 void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC);
@@ -47,7 +47,7 @@ extern zend_object_handlers pdo_dbstmt_object_handlers;
 int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC);
 int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg);
 
-extern zend_object_value pdo_row_new(zend_class_entry *ce TSRMLS_DC);
+extern zend_object *pdo_row_new(zend_class_entry *ce TSRMLS_DC);
 extern const zend_function_entry pdo_row_functions[];
 extern zend_class_entry *pdo_row_ce;
 void pdo_row_free_storage(pdo_stmt_t *stmt TSRMLS_DC);