📄 php_odbc.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Stig S鎡her Bakken <ssb@php.net> | | Andreas Karajannis <Andreas.Karajannis@gmd.de> | | Frank M. Kromann <frank@kromann.info> Support for DB/2 CLI | | Kevin N. Shallow <kshallow@tampabay.rr.com> Birdstep Support| | Daniel R. Kalowsky <kalowsky@php.net> | +----------------------------------------------------------------------+*//* $Id: php_odbc.c,v 1.143.2.21.2.4 2007/01/16 18:56:45 iliaa Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif #include "php.h"#include "php_globals.h"#include "ext/standard/info.h"#include "ext/standard/php_string.h"#include "ext/standard/php_standard.h"#include "php_odbc.h"#include "php_odbc_includes.h"#include "php_globals.h"#if HAVE_UODBC#include <fcntl.h>#include "ext/standard/head.h"#include "php_ini.h"#ifdef PHP_WIN32#include <winsock.h>#define ODBC_TYPE "Win32"#define PHP_ODBC_TYPE ODBC_TYPE#endif/* * not defined elsewhere */#ifndef TRUE#define TRUE 1#define FALSE 0#endifvoid odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent);static int le_result, le_conn, le_pconn;#define SAFE_SQL_NTS(n) ((SWORD) ((n)?(SQL_NTS):0))static unsigned char a3_arg3_and_3_force_ref[] = { 3, BYREF_NONE, BYREF_FORCE, BYREF_ALLOW};/* {{{ odbc_functions[] */function_entry odbc_functions[] = { PHP_FE(odbc_autocommit, NULL) PHP_FE(odbc_binmode, NULL) PHP_FE(odbc_close, NULL) PHP_FE(odbc_close_all, NULL) PHP_FE(odbc_columns, NULL) PHP_FE(odbc_commit, NULL) PHP_FE(odbc_connect, NULL) PHP_FE(odbc_cursor, NULL)#ifdef HAVE_SQLDATASOURCES PHP_FE(odbc_data_source, NULL)#endif PHP_FE(odbc_execute, NULL) PHP_FE(odbc_error, NULL) PHP_FE(odbc_errormsg, NULL) PHP_FE(odbc_exec, NULL)#ifdef PHP_ODBC_HAVE_FETCH_HASH PHP_FE(odbc_fetch_array, NULL) PHP_FE(odbc_fetch_object, NULL)#endif PHP_FE(odbc_fetch_row, NULL) PHP_FE(odbc_fetch_into, a3_arg3_and_3_force_ref) PHP_FE(odbc_field_len, NULL) PHP_FE(odbc_field_scale, NULL) PHP_FE(odbc_field_name, NULL) PHP_FE(odbc_field_type, NULL) PHP_FE(odbc_field_num, NULL) PHP_FE(odbc_free_result, NULL) PHP_FE(odbc_gettypeinfo, NULL) PHP_FE(odbc_longreadlen, NULL)#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) PHP_FE(odbc_next_result, NULL)#endif PHP_FE(odbc_num_fields, NULL) PHP_FE(odbc_num_rows, NULL) PHP_FE(odbc_pconnect, NULL) PHP_FE(odbc_prepare, NULL) PHP_FE(odbc_result, NULL) PHP_FE(odbc_result_all, NULL) PHP_FE(odbc_rollback, NULL) PHP_FE(odbc_setoption, NULL) PHP_FE(odbc_specialcolumns, NULL) PHP_FE(odbc_statistics, NULL) PHP_FE(odbc_tables, NULL) PHP_FE(odbc_primarykeys, NULL)#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35) && !defined(HAVE_BIRDSTEP) /* not supported now */ PHP_FE(odbc_columnprivileges, NULL) PHP_FE(odbc_tableprivileges, NULL)#endif#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35) /* not supported */ PHP_FE(odbc_foreignkeys, NULL) PHP_FE(odbc_procedures, NULL)#if !defined(HAVE_BIRDSTEP) PHP_FE(odbc_procedurecolumns, NULL)#endif#endif PHP_FALIAS(odbc_do, odbc_exec, NULL) PHP_FALIAS(odbc_field_precision, odbc_field_len, NULL) { NULL, NULL, NULL }};/* }}} *//* {{{ odbc_module_entry */zend_module_entry odbc_module_entry = { STANDARD_MODULE_HEADER, "odbc", odbc_functions, PHP_MINIT(odbc), PHP_MSHUTDOWN(odbc), PHP_RINIT(odbc), PHP_RSHUTDOWN(odbc), PHP_MINFO(odbc), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES};/* }}} */#ifdef ZTSint odbc_globals_id;#elseZEND_API php_odbc_globals odbc_globals;#endif#ifdef COMPILE_DL_ODBCZEND_GET_MODULE(odbc)#endif/* {{{ _free_odbc_result */static void _free_odbc_result(zend_rsrc_list_entry *rsrc TSRMLS_DC){ odbc_result *res = (odbc_result *)rsrc->ptr; int i; RETCODE rc; if (res) { if (res->values) { for(i = 0; i < res->numcols; i++) { if (res->values[i].value) efree(res->values[i].value); } efree(res->values); res->values = NULL; } if (res->stmt) {#if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35) SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc, (UWORD)SQL_COMMIT);#endif rc = SQLFreeStmt(res->stmt,SQL_DROP); /* We don't want the connection to be closed after the last statment has been closed * Connections will be closed on shutdown * zend_list_delete(res->conn_ptr->id); */ } efree(res); }}/* }}} *//* {{{ safe_odbc_disconnect * disconnect, and if it fails, then issue a rollback for any pending transaction (lurcher) */static void safe_odbc_disconnect( void *handle ){ int ret; ret = SQLDisconnect( handle ); if ( ret == SQL_ERROR ) { SQLTransact( NULL, handle, SQL_ROLLBACK ); SQLDisconnect( handle ); }}/* }}} *//* {{{ _close_odbc_conn */static void _close_odbc_conn(zend_rsrc_list_entry *rsrc TSRMLS_DC){ int i, nument, type; void *ptr; odbc_result *res; odbc_connection *conn = (odbc_connection *)rsrc->ptr; nument = zend_hash_next_free_element(&EG(regular_list)); for(i = 1; i < nument; i++) { ptr = zend_list_find(i, &type); if (ptr && (type == le_result)) { res = (odbc_result *)ptr; if (res->conn_ptr == conn) { zend_list_delete(i); } } } safe_odbc_disconnect(conn->hdbc); SQLFreeConnect(conn->hdbc); SQLFreeEnv(conn->henv); efree(conn); ODBCG(num_links)--;}/* }}} *//* {{{ void _close_odbc_pconn */static void _close_odbc_pconn(zend_rsrc_list_entry *rsrc TSRMLS_DC){ int i, nument, type; void *ptr; odbc_result *res; odbc_connection *conn = (odbc_connection *)rsrc->ptr; nument = zend_hash_next_free_element(&EG(persistent_list)); for(i = 1; i < nument; i++) { ptr = zend_list_find(i, &type); if (ptr && (type == le_result)) { res = (odbc_result *)ptr; if (res->conn_ptr == conn) { zend_list_delete(i); } } } safe_odbc_disconnect(conn->hdbc); SQLFreeConnect(conn->hdbc); SQLFreeEnv(conn->henv); free(conn); ODBCG(num_links)--; ODBCG(num_persistent)--;}/* }}} *//* {{{ PHP_INI_DISP(display_link_nums) */static PHP_INI_DISP(display_link_nums){ char *value; TSRMLS_FETCH(); if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) { value = ini_entry->orig_value; } else if (ini_entry->value) { value = ini_entry->value; } else { value = NULL; } if (value) { if (atoi(value) == -1) { PUTS("Unlimited"); } else { php_printf("%s", value); } }}/* }}} *//* {{{ PHP_INI_DISP(display_defPW) */static PHP_INI_DISP(display_defPW){ char *value; TSRMLS_FETCH(); if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) { value = ini_entry->orig_value; } else if (ini_entry->value) { value = ini_entry->value; } else { value = NULL; } if (value) {#if PHP_DEBUG php_printf("%s", value);#else PUTS("********");#endif } else { PUTS("<i>no value</i>"); }}/* }}} *//* {{{ PHP_INI_DISP(display_binmode) */static PHP_INI_DISP(display_binmode){ char *value; TSRMLS_FETCH(); if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) { value = ini_entry->orig_value; } else if (ini_entry->value) { value = ini_entry->value; } else { value = NULL; } if (value) { switch(atoi(value)) { case 0: PUTS("passthru"); break; case 1: PUTS("return as is"); break; case 2: PUTS("return as char"); break; } }}/* }}} *//* {{{ PHP_INI_DISP(display_lrl) */static PHP_INI_DISP(display_lrl){ char *value; TSRMLS_FETCH(); if (type == PHP_INI_DISPLAY_ORIG && ini_entry->modified) { value = ini_entry->orig_value; } else if (ini_entry->value) { value = ini_entry->value; } else { value = NULL; } if (value) { if (atoi(value) <= 0) { PUTS("Passthru"); } else { php_printf("return up to %s bytes", value); } }}/* }}} *//* {{{ PHP_INI_BEGIN */PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("odbc.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateInt, allow_persistent, php_odbc_globals, odbc_globals) STD_PHP_INI_ENTRY_EX("odbc.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateInt, max_persistent, php_odbc_globals, odbc_globals, display_link_nums) STD_PHP_INI_ENTRY_EX("odbc.max_links", "-1", PHP_INI_SYSTEM, OnUpdateInt, max_links, php_odbc_globals, odbc_globals, display_link_nums) STD_PHP_INI_ENTRY("odbc.default_db", NULL, PHP_INI_ALL, OnUpdateString, defDB, php_odbc_globals, odbc_globals) STD_PHP_INI_ENTRY("odbc.default_user", NULL, PHP_INI_ALL, OnUpdateString, defUser, php_odbc_globals, odbc_globals) STD_PHP_INI_ENTRY_EX("odbc.default_pw", NULL, PHP_INI_ALL, OnUpdateString, defPW, php_odbc_globals, odbc_globals, display_defPW) STD_PHP_INI_ENTRY_EX("odbc.defaultlrl", "4096", PHP_INI_ALL, OnUpdateInt, defaultlrl, php_odbc_globals, odbc_globals, display_lrl) STD_PHP_INI_ENTRY_EX("odbc.defaultbinmode", "1", PHP_INI_ALL, OnUpdateInt, defaultbinmode, php_odbc_globals, odbc_globals, display_binmode) STD_PHP_INI_BOOLEAN("odbc.check_persistent", "1", PHP_INI_SYSTEM, OnUpdateInt, check_persistent, php_odbc_globals, odbc_globals)PHP_INI_END()/* }}} */#ifdef ZTSstatic void php_odbc_init_globals(php_odbc_globals *odbc_globals_p TSRMLS_DC){ ODBCG(num_persistent) = 0;}#endif/* {{{ PHP_MINIT_FUNCTION */PHP_MINIT_FUNCTION(odbc){#ifdef SQLANY_BUG ODBC_SQL_CONN_T foobar; RETCODE rc;#endif#ifdef ZTS ts_allocate_id(&odbc_globals_id, sizeof(php_odbc_globals), php_odbc_init_globals, NULL);#else ODBCG(num_persistent) = 0;#endif REGISTER_INI_ENTRIES(); le_result = zend_register_list_destructors_ex(_free_odbc_result, NULL, "odbc result", module_number); le_conn = zend_register_list_destructors_ex(_close_odbc_conn, NULL, "odbc link", module_number); le_pconn = zend_register_list_destructors_ex(NULL, _close_odbc_pconn, "odbc link persistent", module_number); Z_TYPE(odbc_module_entry) = type; REGISTER_STRING_CONSTANT("ODBC_TYPE", PHP_ODBC_TYPE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ODBC_BINMODE_PASSTHRU", 0, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ODBC_BINMODE_RETURN", 1, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ODBC_BINMODE_CONVERT", 2, CONST_CS | CONST_PERSISTENT); /* Define Constants for options these Constants are defined in <sqlext.h> */ REGISTER_LONG_CONSTANT("SQL_ODBC_CURSORS", SQL_ODBC_CURSORS, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CUR_USE_DRIVER", SQL_CUR_USE_DRIVER, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CUR_USE_IF_NEEDED", SQL_CUR_USE_IF_NEEDED, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CUR_USE_ODBC", SQL_CUR_USE_ODBC, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CONCURRENCY", SQL_CONCURRENCY, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CONCUR_READ_ONLY", SQL_CONCUR_READ_ONLY, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CONCUR_LOCK", SQL_CONCUR_LOCK, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CONCUR_ROWVER", SQL_CONCUR_ROWVER, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CONCUR_VALUES", SQL_CONCUR_VALUES, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CURSOR_TYPE", SQL_CURSOR_TYPE, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CURSOR_FORWARD_ONLY", SQL_CURSOR_FORWARD_ONLY, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CURSOR_KEYSET_DRIVEN", SQL_CURSOR_KEYSET_DRIVEN, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CURSOR_DYNAMIC", SQL_CURSOR_DYNAMIC, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_CURSOR_STATIC", SQL_CURSOR_STATIC, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_KEYSET_SIZE", SQL_KEYSET_SIZE, CONST_PERSISTENT | CONST_CS); /* these are for the Data Source type */ REGISTER_LONG_CONSTANT("SQL_FETCH_FIRST", SQL_FETCH_FIRST, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_FETCH_NEXT", SQL_FETCH_NEXT, CONST_PERSISTENT | CONST_CS); /* * register the standard data types */ REGISTER_LONG_CONSTANT("SQL_CHAR", SQL_CHAR, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_VARCHAR", SQL_VARCHAR, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_LONGVARCHAR", SQL_LONGVARCHAR, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_DECIMAL", SQL_DECIMAL, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_NUMERIC", SQL_NUMERIC, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_BIT", SQL_BIT, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("SQL_TINYINT", SQL_TINYINT, CONST_PERSISTENT | CONST_CS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -