|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-05-09 07:23 UTC] netvicious at gmail dot com
Description:
------------
If you have one open link to an Interbase/Firebird database and you open **another** one to the same database the first link it's closed.
On my php.ini I have this (exactly the same than on PHP 5.6):
ibase.allow_persistent = 1
; Maximum number of persistent links. -1 means no limit.
ibase.max_persistent = -1
; Maximum number of links (persistent + non-persistent). -1 means no limit.
ibase.max_links = -1
The same script below was running perfectly on PHP 5.6
NikiC on StackOverflow writed this:
In particular, I don't think this line is correct: lxr.php.net/xref/PHP_MASTER/ext/interbase/interbase.c#943 This zend_list_close should probably be a zend_list_delete, otherwise it will simply always destroy the resource.
Already posted to:
http://stackoverflow.com/questions/37049534/multiple-connections-to-interbase-with-php-7-0
https://bugs.launchpad.net/ubuntu/+source/php7.0/+bug/1578600
Regards,
Test script:
---------------
// DB_xxx are defined variables with the users, password, ..... of the database.
// We have the same problem if we use ibase_pconnect or ibase_connect
$conx = ibase_connect(DB_HOST . ":" . DB_NAME,DB_USER,DB_PWD,DB_CHARACTER) or die(ibase_errcode() . ' ' . ibase_errmsg());
$conx2 = ibase_connect(DB_HOST . ":" . DB_NAME,DB_USER,DB_PWD,DB_CHARACTER) or die(ibase_errcode() . ' ' . ibase_errmsg());
$sql = 'SELECT something from somewhere';
$query = ibase_query($conx, $sql);
while ($row = ibase_fetch_assoc($query)) {
echo $row['something'];
}
Expected result:
----------------
$conx should keep the database connection instead of be closed.
Actual result:
--------------
The test script should not write nothing, but on the error log you will see something like:
supplied resource is not a valid Firebird/InterBase link resource in ....
ibase_fetch_assoc(): Dynamic SQL Error SQL error code = -504 Invalid cursor reference Cursor is not open ....
It seems $conx has been closed when creating the $conx2 connection.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 05:00:01 2025 UTC |
The resource refcount management in ext/interbase is in general very broken. It uses zend_list_delete() in *_close() functions, which is not memory safe, and adds additional refs elsewhere to compensate. I'm not even clear on how some parts of this are *supposed* to work. For example, what should this code do? $link = ibase_connect($foo); $link2 = ibase_connect($foo); ibase_close($link2); Should this ibase_close() call close all of $link, $link2 and the default link? After all, all of these share the same connection. If ibase_close($link2) should not close $link, then we can't reuse the same connection for both (or need to introduce a double indirection). Or make ibase_close() effectively a no-op.Between 7.0.2 and 7.0.3 there are a lot of chantes (7.0.0 to 7.0.3 the list it's bigger). **7.0.2************************************************************************** xlink = (zend_resource*) le->ptr; if ((!persistent && xlink->type == le_link) || xlink->type == le_plink) { if (IBG(default_link) > 0) { zval *link = zend_hash_index_find(&EG(regular_list), IBG(default_link)); if (link) { zend_list_delete(Z_RES_P(link)); } } xlink->gc.refcount++; xlink->gc.refcount++; IBG(default_link) = xlink->handle; RETVAL_RES(xlink); } else { zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1); } **7.0.3************************************************************************** xlink = (zend_resource*) le->ptr; if ((!persistent && xlink->type == le_link) || xlink->type == le_plink) { if (IBG(default_link)) { zend_list_close(IBG(default_link)); } xlink->gc.refcount++; xlink->gc.refcount++; IBG(default_link) = xlink; RETVAL_RES(xlink); } else { zend_hash_str_del(&EG(regular_list), hash, sizeof(hash)-1); } They only changed some things related to lists and a way to check the "default_link". I don't know where it's the problem, but the word default_link says to me something like there only can be one NON-persistent link to the firebird/interbase database. Because that code it paster before it's inside one if /* try to reuse a connection */ if ((le = zend_hash_str_find_ptr(&EG(regular_list), hash, sizeof(hash)-1)) != NULL) { And after that if we have something that seems to create a persistent one /* ... or a persistent one */ do { One thing I don't understand it's if we reused a connection why after the if of reusing connection we do a persistent one. If it's really one OR the RETVAL should exit the function like one return statement (I don't know if it does a return).I sent a comment to the Firebird dev mailing list but anybody looked at this bug. As I said my workaround was to use a static var on the database access library I include on all the php files which use BDs. class ps_DB { ... private static $conn = 0; function connect() { if (self::$lid == 0) { self::$lid = ibase_pconnect(DB_HOST . ":" . DB_NAME,DB_USER,DB_PWD,DB_CHARACTER); ... Using this static variable we will use always the same BD connection and it will work.