diff options
-rwxr-xr-x | ext/pdo/pdo.c | 16 | ||||
-rwxr-xr-x | ext/pdo/pdo_dbh.c | 149 | ||||
-rwxr-xr-x | ext/pdo/pdo_stmt.c | 124 | ||||
-rwxr-xr-x | ext/pdo/php_pdo_int.h | 3 |
4 files changed, 72 insertions, 220 deletions
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index a925d534d7..409d193337 100755 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -32,7 +32,6 @@ #include "php_pdo_driver.h" #include "php_pdo_int.h" #include "zend_exceptions.h" -#include "zend_interfaces.h" #if defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)) extern PHPAPI zend_class_entry *spl_ce_RuntimeException; @@ -342,19 +341,8 @@ PHP_MINIT_FUNCTION(pdo) #endif zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - INIT_CLASS_ENTRY(ce, "PDO", pdo_dbh_functions); - pdo_dbh_ce = zend_register_internal_class(&ce TSRMLS_CC); - pdo_dbh_ce->create_object = pdo_dbh_new; - - INIT_CLASS_ENTRY(ce, "PDOStatement", pdo_dbstmt_functions); - pdo_dbstmt_ce = zend_register_internal_class(&ce TSRMLS_CC); - pdo_dbstmt_ce->get_iterator = pdo_stmt_iter_get; - pdo_dbstmt_ce->create_object = pdo_dbstmt_new; - zend_class_implements(pdo_dbstmt_ce TSRMLS_CC, 1, zend_ce_traversable); - - INIT_CLASS_ENTRY(ce, "PDORow", pdo_row_functions); - pdo_row_ce = zend_register_internal_class(&ce TSRMLS_CC); - pdo_row_ce->create_object = pdo_row_new; + pdo_dbh_init(TSRMLS_C); + pdo_stmt_init(TSRMLS_C); return SUCCESS; } diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 6587de1bce..787db5db86 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -406,8 +406,17 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry return object; } /* }}} */ -static void pdo_stmt_construct(zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args TSRMLS_DC) /* {{{ */ +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 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 TSRMLS_CC); + zval_ptr_dtor(&query_string); + if (dbstmt_ce->constructor) { zend_fcall_info fci; zend_fcall_info_cache fcc; @@ -493,9 +502,9 @@ static PHP_METHOD(PDO, prepare) PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } - if (dbstmt_ce->constructor && !(dbstmt_ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + if (dbstmt_ce->constructor && !(dbstmt_ce->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) { pdo_raise_impl_error(dbh, NULL, "HY000", - "user-supplied statement class must have a public constructor" TSRMLS_CC); + "user-supplied statement class cannot have a public constructor" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } @@ -538,7 +547,7 @@ static PHP_METHOD(PDO, prepare) ZVAL_NULL(&stmt->lazy_object_ref); if (dbh->methods->preparer(dbh, statement, statement_len, stmt, options TSRMLS_CC)) { - pdo_stmt_construct(return_value, dbstmt_ce, ctor_args TSRMLS_CC); + pdo_stmt_construct(stmt, return_value, dbstmt_ce, ctor_args TSRMLS_CC); return; } @@ -882,7 +891,7 @@ static PHP_METHOD(PDO, query) stmt->executed = 1; } if (ret) { - pdo_stmt_construct(return_value, pdo_dbstmt_ce, NULL TSRMLS_CC); + pdo_stmt_construct(stmt, return_value, pdo_dbstmt_ce, NULL TSRMLS_CC); return; } } @@ -947,61 +956,6 @@ function_entry pdo_dbh_functions[] = { }; /* {{{ overloaded object handlers for PDO class */ -static zval *dbh_prop_read(zval *object, zval *member, int type TSRMLS_DC) -{ - zval *return_value; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - - return return_value; -} - -static void dbh_prop_write(zval *object, zval *member, zval *value TSRMLS_DC) -{ - return; -} - -static zval *dbh_read_dim(zval *object, zval *offset, int type TSRMLS_DC) -{ - zval *return_value; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - - return return_value; -} - -static void dbh_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC) -{ - return; -} - -static int dbh_prop_exists(zval *object, zval *member, int check_empty TSRMLS_DC) -{ - return 0; -} - -static int dbh_dim_exists(zval *object, zval *member, int check_empty TSRMLS_DC) -{ - return 0; -} - -static void dbh_prop_delete(zval *object, zval *offset TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a PDO DBH"); -} - -static void dbh_dim_delete(zval *object, zval *offset TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete dimensions from a PDO DBH"); -} - -static HashTable *dbh_get_properties(zval *object TSRMLS_DC) -{ - return NULL; -} - int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC) { function_entry *funcs; @@ -1103,65 +1057,26 @@ out: return fbc; } -static int dbh_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) +static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC) { - return FAILURE; + return -1; } +static zend_object_handlers pdo_dbh_object_handlers; -static union _zend_function *dbh_get_ctor(zval *object TSRMLS_DC) +void pdo_dbh_init(TSRMLS_D) { - 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); + zend_class_entry ce; - return (union _zend_function*)&ctor; -} + INIT_CLASS_ENTRY(ce, "PDO", pdo_dbh_functions); + pdo_dbh_ce = zend_register_internal_class(&ce TSRMLS_CC); + pdo_dbh_ce->create_object = pdo_dbh_new; -static zend_class_entry *dbh_get_ce(zval *object TSRMLS_DC) -{ - 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) -{ - *class_name = estrndup("PDO", sizeof("PDO")-1); - *class_name_len = sizeof("PDO")-1; - return 0; + memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + pdo_dbh_object_handlers.get_method = dbh_method_get; + pdo_dbh_object_handlers.compare_objects = dbh_compare; } -static int dbh_compare(zval *object1, zval *object2 TSRMLS_DC) -{ - return -1; -} - -static zend_object_handlers pdo_dbh_object_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, - dbh_prop_read, - dbh_prop_write, - dbh_read_dim, - dbh_write_dim, - NULL, - NULL, - NULL, - dbh_prop_exists, - dbh_prop_delete, - dbh_dim_exists, - dbh_dim_delete, - dbh_get_properties, - dbh_method_get, - dbh_call_method, - dbh_get_ctor, - dbh_get_ce, - dbh_get_classname, - dbh_compare, - NULL, /* cast */ - NULL -}; - static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) { if (--dbh->refcount) @@ -1184,13 +1099,8 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) pefree(dbh, dbh->is_persistent); } -static void pdo_dbh_free_storage(zend_object *object TSRMLS_DC) +static void pdo_dbh_free_storage(pdo_dbh_t *dbh TSRMLS_DC) { - pdo_dbh_t *dbh = (pdo_dbh_t*)object; - if (!dbh) { - return; - } - if (dbh->properties) { zend_hash_destroy(dbh->properties); efree(dbh->properties); @@ -1206,16 +1116,19 @@ zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; pdo_dbh_t *dbh; + zval *tmp; + dbh = emalloc(sizeof(*dbh)); memset(dbh, 0, sizeof(*dbh)); dbh->ce = ce; dbh->refcount = 1; ALLOC_HASHTABLE(dbh->properties); zend_hash_init(dbh->properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(dbh->properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - retval.handle = zend_objects_store_put(dbh, (zend_objects_store_dtor_t)zend_objects_destroy_object, pdo_dbh_free_storage, NULL TSRMLS_CC); + 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; - + return retval; } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 6f0b9e0e33..1e2c6520e1 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -34,6 +34,7 @@ #include "php_pdo_driver.h" #include "php_pdo_int.h" #include "zend_exceptions.h" +#include "zend_interfaces.h" #include "php_memory_streams.h" #if COMPILE_DL_PDO @@ -1671,66 +1672,30 @@ function_entry pdo_dbstmt_functions[] = { }; /* {{{ overloaded handlers for PDOStatement class */ -static zval *dbstmt_prop_read(zval *object, zval *member, int type TSRMLS_DC) +static void dbstmt_prop_write(zval *object, zval *member, zval *value TSRMLS_DC) { - zval *return_value; pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); convert_to_string(member); if(strcmp(Z_STRVAL_P(member), "queryString") == 0) { - MAKE_STD_ZVAL(return_value); - ZVAL_STRINGL(return_value, stmt->query_string, stmt->query_stringlen, 1); + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "property queryString is read only" TSRMLS_CC); } else { - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); + std_object_handlers.write_property(object, member, value TSRMLS_CC); } - return return_value; -} - -static void dbstmt_prop_write(zval *object, zval *member, zval *value TSRMLS_DC) -{ - return; -} - -static zval *dbstmt_read_dim(zval *object, zval *offset, int type TSRMLS_DC) -{ - zval *return_value; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - - return return_value; -} - -static void dbstmt_write_dim(zval *object, zval *offset, zval *value TSRMLS_DC) -{ - return; -} - -static int dbstmt_prop_exists(zval *object, zval *member, int check_empty TSRMLS_DC) -{ - return 0; } -static int dbstmt_dim_exists(zval *object, zval *member, int check_empty TSRMLS_DC) +static void dbstmt_prop_delete(zval *object, zval *member TSRMLS_DC) { - return 0; -} - -static void dbstmt_prop_delete(zval *object, zval *offset TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a PDOStatement"); -} + pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); -static void dbstmt_dim_delete(zval *object, zval *offset TSRMLS_DC) -{ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete dimensions from a PDOStatement"); -} + convert_to_string(member); -static HashTable *dbstmt_get_properties(zval *object TSRMLS_DC) -{ - return NULL; + if(strcmp(Z_STRVAL_P(member), "queryString") == 0) { + pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "property queryString is read only" TSRMLS_CC); + } else { + std_object_handlers.unset_property(object, member TSRMLS_CC); + } } static union _zend_function *dbstmt_method_get( @@ -1776,54 +1741,35 @@ out: return fbc; } -static int dbstmt_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) +static int dbstmt_compare(zval *object1, zval *object2 TSRMLS_DC) { - return FAILURE; + return -1; } -static union _zend_function *dbstmt_get_ctor(zval *object TSRMLS_DC) -{ - return std_object_handlers.get_constructor(object TSRMLS_CC); -} +static zend_object_handlers pdo_dbstmt_object_handlers; -static zend_class_entry *dbstmt_get_ce(zval *object TSRMLS_DC) +void pdo_stmt_init(TSRMLS_D) { - return std_object_handlers.get_class_entry(object TSRMLS_CC); -} + zend_class_entry ce; -static int dbstmt_get_classname(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) -{ - return std_object_handlers.get_class_name(object, class_name, class_name_len, parent TSRMLS_CC); -} + INIT_CLASS_ENTRY(ce, "PDOStatement", pdo_dbstmt_functions); + pdo_dbstmt_ce = zend_register_internal_class(&ce TSRMLS_CC); + pdo_dbstmt_ce->get_iterator = pdo_stmt_iter_get; + pdo_dbstmt_ce->create_object = pdo_dbstmt_new; + zend_class_implements(pdo_dbstmt_ce TSRMLS_CC, 1, zend_ce_traversable); + zend_declare_property_null(pdo_dbstmt_ce, "queryString", sizeof("queryString")-1, ZEND_ACC_PUBLIC TSRMLS_CC); -static int dbstmt_compare(zval *object1, zval *object2 TSRMLS_DC) -{ - return -1; -} + memcpy(&pdo_dbstmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); + pdo_dbstmt_object_handlers.write_property = dbstmt_prop_write; + pdo_dbstmt_object_handlers.unset_property = dbstmt_prop_delete; + pdo_dbstmt_object_handlers.get_method = dbstmt_method_get; + pdo_dbstmt_object_handlers.compare_objects = dbstmt_compare; -zend_object_handlers pdo_dbstmt_object_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, - dbstmt_prop_read, - dbstmt_prop_write, - dbstmt_read_dim, - dbstmt_write_dim, - NULL, - NULL, - NULL, - dbstmt_prop_exists, - dbstmt_prop_delete, - dbstmt_dim_exists, - dbstmt_dim_delete, - dbstmt_get_properties, - dbstmt_method_get, - dbstmt_call_method, - dbstmt_get_ctor, - dbstmt_get_ce, - dbstmt_get_classname, - dbstmt_compare, - NULL, /* cast */ - NULL -}; + INIT_CLASS_ENTRY(ce, "PDORow", pdo_row_functions); + pdo_row_ce = zend_register_internal_class(&ce TSRMLS_CC); + pdo_row_ce->ce_flags |= ZEND_ACC_FINAL_CLASS; /* when removing this a lot of handlers need to be redone */ + pdo_row_ce->create_object = pdo_row_new; +} static void free_statement(pdo_stmt_t *stmt TSRMLS_DC) { @@ -1879,6 +1825,7 @@ void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC) zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; + zval *tmp; pdo_stmt_t *stmt; stmt = emalloc(sizeof(*stmt)); @@ -1887,6 +1834,7 @@ zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) stmt->refcount = 1; ALLOC_HASHTABLE(stmt->properties); zend_hash_init(stmt->properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(stmt->properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); retval.handle = zend_objects_store_put(stmt, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbstmt_free_storage, NULL TSRMLS_CC); retval.handlers = &pdo_dbstmt_object_handlers; @@ -2164,7 +2112,7 @@ static int row_compare(zval *object1, zval *object2 TSRMLS_DC) return -1; } -zend_object_handlers pdo_row_object_handlers = { +static zend_object_handlers pdo_row_object_handlers = { ZEND_OBJECTS_STORE_HANDLERS, row_prop_or_dim_read, row_prop_or_dim_write, diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h index 41b3f1ccf1..82ccf3826f 100755 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -25,6 +25,9 @@ extern zend_class_entry *pdo_exception_ce; 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 function_entry pdo_dbh_functions[]; extern zend_class_entry *pdo_dbh_ce; |