Using php5, mysqli, and multiple named database connections via CiviCRM, I get intermittent errors from database.mysqli.inc complaining that $url['port'] is not defined. After some work, I tracked down this problem by using E_ALL and civicrm_error.module. It's possible to avoid this problem by specifying the port in $db_url, but I believe a more general fix is appropriate. That said, I've only seen this problem come up occasionally, and I haven't been able to figure out why it doesn't happen either all the time or never. I first saw this happen in 5.3 but I see that 6.x and HEAD have the same code and thus the same problem, so I'm assigning this to 7.x-dev, and if this is accepted I will open new issues tagged for 5.x and 6.x to fix this there as well.

I believe this is happening now because the behaviour of parse_url() changed sometime between 4.1 and 4.7 to ignore missing elements of a url, as opposed to returning NULL or an empty string.

This problem doesn't occur in database.mysql.inc, but I see that an equivalent problem was fixed for pgsql two years ago: http://drupal.org/node/19868

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Crell’s picture

Version: 7.x-dev » 6.x-dev
Status: Needs review » Needs work

I've noticed this as well in D6, and an E_ALL error should be fixed in 6.

That said, I think you should use isset($url['port']) instead. It's faster than array_key_exists().

mvc’s picture

Version: 6.x-dev » 7.x-dev
Status: Needs work » Needs review
FileSize
735 bytes

Crell, why did you change the version tag of this patch? I realize the problem also exists in 6.x but after this is accepted against HEAD I'll submit patches for other branches.

That said, I accidentally created the original patch against 5.3, so I'm attaching one actually made against HEAD.

isset($url['port']) returns false if $url['port'] is defined but set to NULL, whereas array_key_exists() correctly returns true. In this particular case it's true that it wouldn't matter but I consider it bad form or at least confusing to use it to check for array values that may be NULL. Besides, array_key_exists() is already used many times in Drupal core (I see 23 instances in HEAD).

Crell’s picture

Title: undefined index: port in database.mysqli.inc » E_NOTICE: undefined index: port in database.mysqli.inc
Version: 7.x-dev » 6.x-dev
Status: Needs review » Reviewed & tested by the community

Changing title to get it noticed properly.

There is no 7.x right now. 6.x IS HEAD. 7.x is a placeholder for "We'll get back to this later sometime", and tells the 6.x committers to ignore this issue.

I suspect that many of those array_key_exists() locations really should be isset(). I don't recall if that's a formal or informal standard, but isset() is a language construct so it's faster than array_key_exists(), which is a function. In this instance, both have the same overall effect so we should use the faster isset().

That said, it's a no-brainer to switch to isset() here, so I will mark this RTBC and let Dries/Gabor decide which they want to do. (But one or the other should be done, as an E_NOTICE is an error.)

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Needs work

Uh. Let's use isset() and also conform to coding guidelines with not omitting the brackets and the newlines.

mvc’s picture

Status: Needs work » Needs review
FileSize
736 bytes

Crell, thanks for explaining the difference between the 7.x and 6.x CVS tags.

Gábor, I've made the changes you requested, so I'm changing this back to 'needs review'.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Blargh. Sorry, Gabor. I should have caught that. Applies cleanly and answers both of your statements.

Gábor Hojtsy’s picture

Status: Reviewed & tested by the community » Fixed

Thanks, committed. I also checked whether this applies to database.mysql.inc, but it does not, as a different connection method is used there. Also, database.pgsql.inc uses a different method, so this issue was limited to mysqli.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.