Commit 7aaa06b1022 for php.net

commit 7aaa06b1022cf118a38e7915bcda877ac855708c
Author: Gina Peter Banyard <girgias@php.net>
Date:   Sat Aug 15 17:04:54 2026 +0100

    odbc: use custom ZPP to extract result and connection (#23261)

diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index 468055732e1..3e7cdbb01b6 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -620,19 +620,32 @@ void odbc_sql_error(ODBC_SQL_ERROR_PARAMS)
 }
 /* }}} */

+#define Z_PARAM_ODBC_RESULT(dest) \
+	{ \
+		zend_object *__##dest = NULL; \
+		Z_PARAM_OBJ_OF_CLASS(__##dest, odbc_result_ce); \
+		dest = odbc_result_from_obj(__##dest); \
+	}
+
+#define Z_PARAM_ODBC_CONNECTION(dest) \
+	{ \
+		zend_object *__##dest = NULL; \
+		Z_PARAM_OBJ_OF_CLASS(__##dest, odbc_connection_ce); \
+		dest = odbc_link_from_obj(__##dest)->connection; \
+	}
+
+
 /* {{{ php_odbc_fetch_attribs */
 void php_odbc_fetch_attribs(INTERNAL_FUNCTION_PARAMETERS, int mode)
 {
 	odbc_result *result;
-	zval *pv_res;
 	zend_long flag;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_LONG(flag)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (mode) {
@@ -754,13 +767,12 @@ void odbc_bindcols(odbc_result *result)
 void odbc_transact(INTERNAL_FUNCTION_PARAMETERS, int type)
 {
 	RETCODE rc;
-	zval *pv_conn;
+	odbc_connection *conn;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	rc = SQLTransact(conn->henv, conn->hdbc, (SQLUSMALLINT)((type)?SQL_COMMIT:SQL_ROLLBACK));
@@ -778,15 +790,13 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type)
 {
 	odbc_result *result;
 	SQLLEN len;
-	zval *pv_res;
 	zend_long pv_num;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_LONG(pv_num)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (pv_num < 1) {
@@ -850,20 +860,19 @@ PHP_FUNCTION(odbc_longreadlen)
 /* {{{ Prepares a statement for execution */
 PHP_FUNCTION(odbc_prepare)
 {
-	zval *pv_conn;
 	char *query;
 	size_t query_len;
 	odbc_result *result = NULL;
 	RETCODE rc;
 	int i;
 	SQLUINTEGER      scrollopts;
+	odbc_connection *conn;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_STRING(query, query_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -964,7 +973,7 @@ static void odbc_release_params(odbc_result *result, odbc_params_t *params) {
 /* {{{ Execute a prepared statement */
 PHP_FUNCTION(odbc_execute)
 {
-	zval *pv_res, *tmp;
+	zval *tmp;
 	HashTable *pv_param_ht = (HashTable *) &zend_empty_array;
 	odbc_params_t *params = NULL;
 	SQLSMALLINT ctype;
@@ -973,12 +982,11 @@ PHP_FUNCTION(odbc_execute)
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(1, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_OPTIONAL
 		Z_PARAM_ARRAY_HT(pv_param_ht)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (result->numparams > 0) {
@@ -1120,7 +1128,6 @@ PHP_FUNCTION(odbc_execute)
 /* {{{ Get cursor name */
 PHP_FUNCTION(odbc_cursor)
 {
-	zval *pv_res;
 	SQLUSMALLINT max_len;
 	SQLSMALLINT len;
 	char *cursorname;
@@ -1128,10 +1135,9 @@ PHP_FUNCTION(odbc_cursor)
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	rc = SQLGetInfo(result->conn_ptr->hdbc,SQL_MAX_CURSOR_NAME_LEN, (void *)&max_len,sizeof(max_len),&len);
@@ -1176,14 +1182,14 @@ PHP_FUNCTION(odbc_cursor)
 /* {{{ Return information about the currently connected data source */
 PHP_FUNCTION(odbc_data_source)
 {
-	zval *zv_conn;
+	odbc_connection *conn;
 	zend_long zv_fetch_type;
 	RETCODE rc = 0; /* assume all is good */
 	UCHAR server_name[100], desc[200];
 	SQLSMALLINT len1=0, len2=0, fetch_type;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(zv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_LONG(zv_fetch_type)
 	ZEND_PARSE_PARAMETERS_END();

@@ -1194,7 +1200,6 @@ PHP_FUNCTION(odbc_data_source)
 		RETURN_THROWS();
 	}

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(zv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	/* now we have the "connection" lets call the DataSource object */
@@ -1234,7 +1239,7 @@ PHP_FUNCTION(odbc_data_source)
 /* XXX Use flags */
 PHP_FUNCTION(odbc_exec)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	char *query;
 	size_t query_len;
 	odbc_result *result = NULL;
@@ -1242,11 +1247,10 @@ PHP_FUNCTION(odbc_exec)
 	SQLUINTEGER      scrollopts;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_STRING(query, query_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -1319,11 +1323,11 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_
 	char *buf = NULL;
 	zend_long pv_row = 0;
 	bool pv_row_is_null = true;
-	zval *pv_res, *pv_res_arr, tmp;
+	zval *pv_res_arr, tmp;

 	if (return_array || result_type == ODBC_NONE) {
 		ZEND_PARSE_PARAMETERS_START(1, 2)
-			Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+			Z_PARAM_ODBC_RESULT(result)
 			Z_PARAM_OPTIONAL
 			Z_PARAM_LONG_OR_NULL(pv_row, pv_row_is_null)
 		ZEND_PARSE_PARAMETERS_END();
@@ -1331,14 +1335,13 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_
 		pv_res_arr = return_value;
 	} else {
 		ZEND_PARSE_PARAMETERS_START(2, 3)
-			Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+			Z_PARAM_ODBC_RESULT(result)
 			Z_PARAM_ZVAL(pv_res_arr)
 			Z_PARAM_OPTIONAL
 			Z_PARAM_LONG_OR_NULL(pv_row, pv_row_is_null)
 		ZEND_PARSE_PARAMETERS_END();
 	}

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (!pv_row_is_null && pv_row < 1) {
@@ -1533,10 +1536,9 @@ PHP_FUNCTION(odbc_result)
 	int i = 0;
 	RETCODE rc;
 	SQLLEN	fieldsize;
-	zval *pv_res;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_STR_OR_LONG(pv_field_str, pv_field_long)
 	ZEND_PARSE_PARAMETERS_END();

@@ -1548,7 +1550,6 @@ PHP_FUNCTION(odbc_result)
 		field_ind = (int) pv_field_long - 1;
 	}

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (result->numcols == 0) {
@@ -1734,18 +1735,16 @@ PHP_FUNCTION(odbc_result_all)
 	char *buf = NULL;
 	odbc_result *result;
 	RETCODE rc;
-	zval *pv_res;
 	char *pv_format = NULL;
 	size_t i, pv_format_len = 0;
 	SQLSMALLINT sql_c_type;

 	ZEND_PARSE_PARAMETERS_START(1, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_OPTIONAL
 		Z_PARAM_STRING(pv_format, pv_format_len)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (result->numcols == 0) {
@@ -1866,14 +1865,12 @@ PHP_FUNCTION(odbc_result_all)
 /* {{{ Free resources associated with a result */
 PHP_FUNCTION(odbc_free_result)
 {
-	zval *pv_res;
 	odbc_result *result;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	odbc_result_free(result);
@@ -2185,15 +2182,15 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
 /* {{{ Close an ODBC connection */
 PHP_FUNCTION(odbc_close)
 {
-	zval *pv_conn;
+	zend_object *obj;
 	odbc_link *link;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_OBJ_OF_CLASS(obj, odbc_connection_ce)
 	ZEND_PARSE_PARAMETERS_END();

-	link = Z_ODBC_LINK_P(pv_conn);
-	odbc_connection *connection = Z_ODBC_CONNECTION_P(pv_conn);
+	link = odbc_link_from_obj(obj);
+	odbc_connection *connection = link->connection;
 	CHECK_ODBC_CONNECTION(connection);

 	odbc_link_free(link);
@@ -2209,13 +2206,11 @@ PHP_FUNCTION(odbc_num_rows)
 {
 	odbc_result *result;
 	SQLLEN rows;
-	zval *pv_res;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	SQLRowCount(result->stmt, &rows);
@@ -2227,14 +2222,12 @@ PHP_FUNCTION(odbc_num_rows)
 PHP_FUNCTION(odbc_next_result)
 {
 	odbc_result *result;
-	zval *pv_res;
 	int rc, i;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (result->values) {
@@ -2274,13 +2267,11 @@ PHP_FUNCTION(odbc_next_result)
 PHP_FUNCTION(odbc_num_fields)
 {
 	odbc_result *result;
-	zval *pv_res;

 	ZEND_PARSE_PARAMETERS_START(1, 1)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	RETURN_LONG(result->numcols);
@@ -2291,15 +2282,13 @@ PHP_FUNCTION(odbc_num_fields)
 PHP_FUNCTION(odbc_field_name)
 {
 	odbc_result *result;
-	zval *pv_res;
 	zend_long pv_num;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_LONG(pv_num)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (pv_num < 1) {
@@ -2327,15 +2316,13 @@ PHP_FUNCTION(odbc_field_type)
 	odbc_result	*result;
 	char    	tmp[32];
 	SQLSMALLINT	tmplen;
-	zval		*pv_res;
 	zend_long		pv_num;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_LONG(pv_num)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (pv_num < 1) {
@@ -2378,14 +2365,12 @@ PHP_FUNCTION(odbc_field_num)
 	char *fname;
 	size_t i, field_ind, fname_len;
 	odbc_result *result;
-	zval *pv_res;

 	ZEND_PARSE_PARAMETERS_START(2, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_res, odbc_result_ce)
+		Z_PARAM_ODBC_RESULT(result)
 		Z_PARAM_STRING(fname, fname_len)
 	ZEND_PARSE_PARAMETERS_END();

-	result = Z_ODBC_RESULT_P(pv_res);
 	CHECK_ODBC_RESULT(result);

 	if (result->numcols == 0) {
@@ -2412,17 +2397,16 @@ PHP_FUNCTION(odbc_field_num)
 PHP_FUNCTION(odbc_autocommit)
 {
 	RETCODE rc;
-	zval *pv_conn;
+	odbc_connection *conn;
 	bool pv_onoff = false;
 	bool pv_onoff_is_null = true;

 	ZEND_PARSE_PARAMETERS_START(1, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_OPTIONAL
 		Z_PARAM_BOOL_OR_NULL(pv_onoff, pv_onoff_is_null)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	if (!pv_onoff_is_null) {
@@ -2462,17 +2446,15 @@ PHP_FUNCTION(odbc_rollback)
 /* {{{ php_odbc_lasterror */
 static void php_odbc_lasterror(INTERNAL_FUNCTION_PARAMETERS, int mode)
 {
-	odbc_connection *conn;
-	zval *pv_handle = NULL;
+	odbc_connection *conn = NULL;
 	char *ret;

 	ZEND_PARSE_PARAMETERS_START(0, 1)
 		Z_PARAM_OPTIONAL
-		Z_PARAM_OBJECT_OF_CLASS(pv_handle, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 	ZEND_PARSE_PARAMETERS_END();

-	if (pv_handle) {
-		conn = Z_ODBC_CONNECTION_P(pv_handle);
+	if (conn) {
 		CHECK_ODBC_CONNECTION(conn);

 		if (mode == 0) {
@@ -2578,14 +2560,14 @@ PHP_FUNCTION(odbc_setoption)
 /* {{{ Call the SQLTables function */
 PHP_FUNCTION(odbc_tables)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result   *result = NULL;
 	char *cat = NULL, *schema = NULL, *table = NULL, *type = NULL;
 	size_t cat_len = 0, schema_len = 0, table_len = 0, type_len = 0;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(1, 5)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_OPTIONAL
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_PATH_OR_NULL(schema, schema_len)
@@ -2593,7 +2575,6 @@ PHP_FUNCTION(odbc_tables)
 		Z_PARAM_PATH_OR_NULL(type, type_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -2647,14 +2628,14 @@ PHP_FUNCTION(odbc_tables)
 /* {{{ Returns a result identifier that can be used to fetch a list of column names in specified tables */
 PHP_FUNCTION(odbc_columns)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result *result = NULL;
 	char *cat = NULL, *schema = NULL, *table = NULL, *column = NULL;
 	size_t cat_len = 0, schema_len = 0, table_len = 0, column_len = 0;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(1, 5)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_OPTIONAL
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_PATH_OR_NULL(schema, schema_len)
@@ -2662,7 +2643,6 @@ PHP_FUNCTION(odbc_columns)
 		Z_PARAM_PATH_OR_NULL(column, column_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -2718,21 +2698,20 @@ PHP_FUNCTION(odbc_columns)
 /* {{{ Returns a result identifier that can be used to fetch a list of columns and associated privileges for the specified table */
 PHP_FUNCTION(odbc_columnprivileges)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result *result = NULL;
 	char *cat = NULL, *schema, *table, *column;
 	size_t cat_len = 0, schema_len, table_len, column_len;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(5, 5)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_STRING(schema, schema_len)
 		Z_PARAM_STRING(table, table_len)
 		Z_PARAM_STRING(column, column_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -2781,14 +2760,14 @@ PHP_FUNCTION(odbc_columnprivileges)
 /* {{{ Returns a result identifier to either a list of foreign keys in the specified table or a list of foreign keys in other tables that refer to the primary key in the specified table */
 PHP_FUNCTION(odbc_foreignkeys)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result *result = NULL;
 	char *pcat = NULL, *pschema, *ptable, *fcat, *fschema, *ftable;
 	size_t pcat_len = 0, pschema_len, ptable_len, fcat_len, fschema_len, ftable_len;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(7, 7)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(pcat, pcat_len)
 		Z_PARAM_STRING(pschema, pschema_len)
 		Z_PARAM_STRING(ptable, ptable_len)
@@ -2809,7 +2788,6 @@ PHP_FUNCTION(odbc_foreignkeys)
 		EMPTY_TO_NULL(ftable);
 #endif

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -2860,21 +2838,20 @@ PHP_FUNCTION(odbc_foreignkeys)
 /* {{{ Returns a result identifier containing information about data types supported by the data source */
 PHP_FUNCTION(odbc_gettypeinfo)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	zend_long pv_data_type = SQL_ALL_TYPES;
 	odbc_result *result = NULL;
 	RETCODE rc;
 	SQLSMALLINT data_type;

 	ZEND_PARSE_PARAMETERS_START(1, 2)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_OPTIONAL
 		Z_PARAM_LONG(pv_data_type)
 	ZEND_PARSE_PARAMETERS_END();

 	data_type = (SQLSMALLINT) pv_data_type;

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -2919,20 +2896,19 @@ PHP_FUNCTION(odbc_gettypeinfo)
 /* {{{ Returns a result identifier listing the column names that comprise the primary key for a table */
 PHP_FUNCTION(odbc_primarykeys)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result   *result = NULL;
 	char *cat = NULL, *schema = NULL, *table = NULL;
 	size_t cat_len = 0, schema_len, table_len;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(4, 4)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_STRING(schema, schema_len)
 		Z_PARAM_STRING(table, table_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -2980,21 +2956,20 @@ PHP_FUNCTION(odbc_primarykeys)
 /* {{{ Returns a result identifier containing the list of input and output parameters, as well as the columns that make up the result set for the specified procedures */
 PHP_FUNCTION(odbc_procedurecolumns)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result *result = NULL;
 	char *cat = NULL, *schema = NULL, *proc = NULL, *col = NULL;
 	size_t cat_len = 0, schema_len = 0, proc_len = 0, col_len = 0;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(1, 5)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_PATH_OR_NULL(schema, schema_len)
 		Z_PARAM_PATH_OR_NULL(proc, proc_len)
 		Z_PARAM_PATH_OR_NULL(col, col_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -3043,20 +3018,19 @@ PHP_FUNCTION(odbc_procedurecolumns)
 /* {{{ Returns a result identifier containing the list of procedure names in a datasource */
 PHP_FUNCTION(odbc_procedures)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result   *result = NULL;
 	char *cat = NULL, *schema = NULL, *proc = NULL;
 	size_t cat_len = 0, schema_len = 0, proc_len = 0;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(1, 4)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_PATH_OR_NULL(schema, schema_len)
 		Z_PARAM_PATH_OR_NULL(proc, proc_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -3104,7 +3078,7 @@ PHP_FUNCTION(odbc_procedures)
 /* {{{ Returns a result identifier containing either the optimal set of columns that uniquely identifies a row in the table or columns that are automatically updated when any value in the row is updated by a transaction */
 PHP_FUNCTION(odbc_specialcolumns)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	zend_long vtype, vscope, vnullable;
 	odbc_result *result = NULL;
 	char *cat = NULL, *schema = NULL, *name = NULL;
@@ -3113,7 +3087,7 @@ PHP_FUNCTION(odbc_specialcolumns)
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(7, 7)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_LONG(vtype)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_STRING(schema, schema_len)
@@ -3126,7 +3100,6 @@ PHP_FUNCTION(odbc_specialcolumns)
 	scope = (SQLUSMALLINT) vscope;
 	nullable = (SQLUSMALLINT) vnullable;

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -3176,7 +3149,7 @@ PHP_FUNCTION(odbc_specialcolumns)
 /* {{{ Returns a result identifier that contains statistics about a single table and the indexes associated with the table */
 PHP_FUNCTION(odbc_statistics)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	zend_long vunique, vreserved;
 	odbc_result *result = NULL;
 	char *cat = NULL, *schema, *name;
@@ -3185,7 +3158,7 @@ PHP_FUNCTION(odbc_statistics)
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(6, 6)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_STRING(schema, schema_len)
 		Z_PARAM_STRING(name, name_len)
@@ -3196,7 +3169,6 @@ PHP_FUNCTION(odbc_statistics)
 	unique = (SQLUSMALLINT) vunique;
 	reserved = (SQLUSMALLINT) vreserved;

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);
@@ -3246,20 +3218,19 @@ PHP_FUNCTION(odbc_statistics)
 /* {{{ Returns a result identifier containing a list of tables and the privileges associated with each table */
 PHP_FUNCTION(odbc_tableprivileges)
 {
-	zval *pv_conn;
+	odbc_connection *conn;
 	odbc_result   *result = NULL;
 	char *cat = NULL, *schema = NULL, *table = NULL;
 	size_t cat_len = 0, schema_len, table_len;
 	RETCODE rc;

 	ZEND_PARSE_PARAMETERS_START(4, 4)
-		Z_PARAM_OBJECT_OF_CLASS(pv_conn, odbc_connection_ce)
+		Z_PARAM_ODBC_CONNECTION(conn)
 		Z_PARAM_PATH_OR_NULL(cat, cat_len)
 		Z_PARAM_STRING(schema, schema_len)
 		Z_PARAM_STRING(table, table_len)
 	ZEND_PARSE_PARAMETERS_END();

-	odbc_connection *conn = Z_ODBC_CONNECTION_P(pv_conn);
 	CHECK_ODBC_CONNECTION(conn);

 	object_init_ex(return_value, odbc_result_ce);