summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xext/pdo/pdo.c16
-rwxr-xr-xext/pdo/pdo_dbh.c149
-rwxr-xr-xext/pdo/pdo_stmt.c124
-rwxr-xr-xext/pdo/php_pdo_int.h3
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;