Problem/Motivation

With the $conf['dev_query'] = 1;specified in settings.php, the following errors are generated at the top of the page, logged in as admin user (non-user 1).

Notice: Trying to get property of non-object in includes/database.mysqli.inc on line 108
Notice: Trying to get property of non-object in includes/database.mysqli.inc on line 108
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at includes/database.mysqli.inc:108) in includes/bootstrap.inc on line 1172
Warning: Cannot modify header information - headers already sent by (output started at includes/database.mysqli.inc:108) in includes/bootstrap.inc on line 736
Warning: Cannot modify header information - headers already sent by (output started at includes/database.mysqli.inc:108) in includes/bootstrap.inc on line 737
Warning: Cannot modify header information - headers already sent by (output started at includes/database.mysqli.inc:108) in includes/bootstrap.inc on line 738
Warning: Cannot modify header information - headers already sent by (output started at includes/database.mysqli.inc:108) in includes/bootstrap.inc on line 739

The initial "trying to get property of non-object" error message appears twice because there are two queries that are executed before the session is created and the $user object is initialized. The reason is that drupal_is_denied() is invoked before $user is populated, which happens on the next bootstrap phase. ie. DRUPAL_BOOTSTRAP_ACCESS is executed before DRUPAL_BOOTSTRAP_SESSION.

I placed the following code snippet at the top of the _db_query() function:

  if (!is_object($user)) {
    print '<div>'. $query . '</div>';
  }

It found that the following two queries are run before the $user global is initialized as an object:

SELECT 1 FROM access WHERE type = 'host' AND LOWER('127.0.0.1') LIKE LOWER(mask) AND status = 0 LIMIT 0, 1
SELECT u.*, s.* FROM users u INNER JOIN sessions s ON u.uid = s.uid WHERE s.sid = '12345678901234567890'

This problem only affects MySQL. PGSQL is not affected because database.pgsql.inc does not contain this query comment functionality as database.mysql.inc and database.mysqli.inc do

Proposed resolution

Wrap the $user->uid part of the if statement in a !empty().

Failing the !empty($user->uid) would imply that either the $user is not an object, or that the $user->uid is false or zero (in the case of anonymous) which is precisely what this code is testing for to use the $user->name inside the query comment functionality inside the _db_query() functions.

The attached patch fixes this for both mysql drivers. The pgsql driver is not affected.

Remaining tasks

  • Write patch.
  • Determine if D7 or D8 are affected.
  • Review patch.
  • Commit.

User interface changes

Some early database query calls (that may be displayed by devel module in onscreen logs) will show as 'Anonymous' instead of the current user's name in the query's comment.

API changes

None.

Data model changes

None.

Comments

eileenmcnaughton’s picture

This patch worked for me - although I applied against mysql.inc not mysqli.inc to make it work

Status: Needs review » Needs work

The last submitted patch, database.dev_query.patch, failed testing.

pounard’s picture

Experienced the same bug, because dev_query settings forces the _db_query() function to mess up with username, it will fail on every database access prior to session set.

In my case, having the dev_query settings in database is OK because variable_init() is called after the session stuff has been set. But as soon as I set the dev_query setting in the settings.php file, it crashed badly.

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, database.dev_query.patch, failed testing.

jwilson3’s picture

Issue summary: View changes

I've marked an earlier issue as a duplicate of this one because this one has a patch:

#321089: Early bootstrap queries generate notices when query logging is enabled

FWIW, this issue has been reported no less than 4 times, here are the two others:

jwilson3’s picture

StatusFileSize
new1.45 KB

The original test breaks when $user global is not yet defined as an object:

$user->uid

The patch from the OP adds this isset():

isset($user) && $user->uid

However, I believe just a !empty() around the $user->uid would be enough to catch when the item is not an object AND/OR the $user->uid is not an authenticated user.

!empty($user->uid)
jwilson3’s picture

Status: Needs work » Needs review
jwilson3’s picture

Title: Notice: Trying to get property of non-object in includes/database.mysql.inc on line 102 » Notice: Trying to get property of non-object in includes/database.mysql.inc and includes/database.mysqli.inc
Issue summary: View changes

Updated the issue title

jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Issue summary: View changes
jwilson3’s picture

Title: Notice: Trying to get property of non-object in includes/database.mysql.inc and includes/database.mysqli.inc » Early mysql queries generate notices when query logging is enabled

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.