From:             gomar dot bijl at cal-consult dot nl
Operating system: WinXp
PHP version:      5.2.6
PHP Bug Type:     ODBC related
Bug description:  ODBC_Pconnect should not Commit/Rollback database 
transactions of previous data

Description:
------------
Hi

We have a problem with the (ODBC) persistent database connection. We have
found that every PHP-session, using the same dsn, user and password, are
getting the same persistent connection by a reasonable chance.
Also meaning that if a database transaction was not finished, other
PHP-session can do a rollback or commit of that transaction. 

Due to resource problems with (temporarily) connections the persistent
connections are used, so we do. But “leftovers” of database transactions
were not intended. 
Also if one want to open an another connection in one PHP-session the
result is the same connection. (E.g. we use a DB-log-file to log errors en
warning, so you don’t want to do a rollback on the DB-log-file, in
peculiar.)


To overcome these problems one has to tag the connections. I suggest to
use a new parameter on ODBC_(p)connect: Tag, a string parameter. If used it
tries to re-connect to the connection with the same tag, if not existing it
creates a new-connection. 
For example the tag parameter is filled with the session_ID() to ensure
that a connection is bounded to one PHP-session. But also an extension on
this value is possible:  (Session_ID() + ‘Log’) or (Session_ID() +
‘Data’).
And if somebody does not uses this tag parameter, it works in the old way,
so these solution is downwards compatible.


Reproduce code:
---------------
So the adjusted description will be:
resource odbc_pconnect (string $dsn , string $user , string $password [,
int $cursor_type [, string $tag ]  ] )

Eg ODBC_pconnect( $dns, $user,, $password, SQL_CUR_DEFAULT, Session_ID()+
‘LOG’)

The change of the PHP source of the function odbc_do_connect is minimal:
void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
{
        char    *db = NULL;
        char    *uid = NULL;
        char    *pwd = NULL;
        char    *tag = NULL;
        zval **pv_db, **pv_uid, **pv_pwd, **pv_opt, **pv_tag;
        odbc_connection *db_conn;
        char *hashed_details;
        int hashed_len, cur_opt;

        /*  Now an optional 4th parameter specifying the cursor type
         *  defaulting to the cursors default
         */
        switch(ZEND_NUM_ARGS()) {
                case 3: 
                        if (zend_get_parameters_ex(3, &pv_db, &pv_uid, &pv_pwd) 
== FAILURE) {
                                WRONG_PARAM_COUNT;
                        }
                        /* Use Default: Probably a better way to do this */
                        cur_opt = SQL_CUR_DEFAULT;
                        tag = '';
                        break;
                case 4:
                        if (zend_get_parameters_ex(4, &pv_db, &pv_uid, &pv_pwd, 
&pv_opt) ==
FAILURE) {
                                WRONG_PARAM_COUNT;
                        }
                        convert_to_long_ex(pv_opt);
                        cur_opt = Z_LVAL_PP(pv_opt);

                        /* Confirm the cur_opt range */
                        if (! (cur_opt == SQL_CUR_USE_IF_NEEDED || 
                                cur_opt == SQL_CUR_USE_ODBC || 
                                cur_opt == SQL_CUR_USE_DRIVER || 
                                cur_opt == SQL_CUR_DEFAULT) ) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Invalid Cursor type
(%d)", cur_opt);
                                RETURN_FALSE;
                        }
                        tag = '';
                        break;
                case 5:
                        if (zend_get_parameters_ex(5, &pv_db, &pv_uid, &pv_pwd, 
&pv_opt,
&pv_tag) == FAILURE) {
                                WRONG_PARAM_COUNT;
                        }
                        convert_to_long_ex(pv_opt);
                        cur_opt = Z_LVAL_PP(pv_opt);

                        /* Confirm the cur_opt range */
                        if (! (cur_opt == SQL_CUR_USE_IF_NEEDED || 
                                cur_opt == SQL_CUR_USE_ODBC || 
                                cur_opt == SQL_CUR_USE_DRIVER || 
                                cur_opt == SQL_CUR_DEFAULT) ) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Invalid Cursor type
(%d)", cur_opt);
                                RETURN_FALSE;
                        }
                        convert_to_string_ex(pv_tag);
                        tag = Z_STRVAL_PP(pv_tag);
                        break;
                default:
                        WRONG_PARAM_COUNT;
                        break;
        }

        convert_to_string_ex(pv_db);
        convert_to_string_ex(pv_uid);
        convert_to_string_ex(pv_pwd);

        db = Z_STRVAL_PP(pv_db);
        uid = Z_STRVAL_PP(pv_uid);
        pwd = Z_STRVAL_PP(pv_pwd);

        if (ODBCG(allow_persistent) <= 0) {
                persistent = 0;
        }

        hashed_len = spprintf(&hashed_details, 0, "%s_%s_%s_%s_%d_%s", 
ODBC_TYPE,
db, uid, pwd, cur_opt, tag);


Expected result:
----------------
.

Actual result:
--------------
.

-- 
Edit bug report at http://bugs.php.net/?id=45322&edit=1
-- 
Try a CVS snapshot (PHP 5.2): 
http://bugs.php.net/fix.php?id=45322&r=trysnapshot52
Try a CVS snapshot (PHP 5.3): 
http://bugs.php.net/fix.php?id=45322&r=trysnapshot53
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=45322&r=trysnapshot60
Fixed in CVS:                 http://bugs.php.net/fix.php?id=45322&r=fixedcvs
Fixed in release:             
http://bugs.php.net/fix.php?id=45322&r=alreadyfixed
Need backtrace:               http://bugs.php.net/fix.php?id=45322&r=needtrace
Need Reproduce Script:        http://bugs.php.net/fix.php?id=45322&r=needscript
Try newer version:            http://bugs.php.net/fix.php?id=45322&r=oldversion
Not developer issue:          http://bugs.php.net/fix.php?id=45322&r=support
Expected behavior:            http://bugs.php.net/fix.php?id=45322&r=notwrong
Not enough info:              
http://bugs.php.net/fix.php?id=45322&r=notenoughinfo
Submitted twice:              
http://bugs.php.net/fix.php?id=45322&r=submittedtwice
register_globals:             http://bugs.php.net/fix.php?id=45322&r=globals
PHP 4 support discontinued:   http://bugs.php.net/fix.php?id=45322&r=php4
Daylight Savings:             http://bugs.php.net/fix.php?id=45322&r=dst
IIS Stability:                http://bugs.php.net/fix.php?id=45322&r=isapi
Install GNU Sed:              http://bugs.php.net/fix.php?id=45322&r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=45322&r=float
No Zend Extensions:           http://bugs.php.net/fix.php?id=45322&r=nozend
MySQL Configuration Error:    http://bugs.php.net/fix.php?id=45322&r=mysqlcfg

Reply via email to