I'm getting a whole bunch of these errors when I view images on my local dev site:

Object of class stdClass could not be converted to string in D:\xampp\htdocs\modules\relatedlinks\relatedlinks.module on line 1084.

It's pretty much a standard install with various modules tacked on. I'm not sure what info you need to debug.

-- Sugendran

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Pierre Lannoy’s picture

Hi all !

Same problem here (www.voile-rc.com) but doesn't produce side effect (all is apparently functioning...).

Pierre

Sugendran’s picture

Just some further info. There aren't any manual links, as this is a fresh install.

Zen’s picture

Status: Active » Postponed (maintainer needs more info)

I'm unable to reproduce this. Could you guys please try to isolate this issue by perhaps disabling all contrib modules (most likely node modules) and then enabling them one by one?

Thanks,
-K

styro’s picture

Status: Postponed (maintainer needs more info) » Active

I'm pretty sure this is something to do with PHP 5 or more specifically PHP 5.2.

Although I'm still using a 4.7 version (v 1.11.2.2) of relatedlinks, I got this error on line 1083 (in the _relatedlinks_collate_links() function) after an upgrade of PHP from 4.4 to 5.2.0 today (on Debian Etch).

You still get related links blocks showing up though and they seem to be related - I haven't checked whether or not it affects the actual links listed in the block though.

I haven't had much luck figuring out what is happening, but for me it only seems to trigger on nodes that have taxonomy terms attached. Nodes without terms attached don't seem to trigger it. Nodes with just related links search keywords don't seem to trigger it either.

styro’s picture

Strange things happening...

Changing this (line 1083 in 1.11.2.2):

<?php
  $set = array_intersect_assoc($set1, $set2) + array_diff_assoc($set1, $set2);
?>

to this: (I was trying to narrow down which operation on that line was causing the trouble)

<?php
  $seta = array_intersect_assoc($set1, $set2);
  $setb = array_diff_assoc($set1, $set2);
  $set = $seta + $setb;
?>

caused the errors to disappear.

Even wierder though - the errors stayed away after switching it back to the original code. Note: APC is disabled, and the cache table was emptied. I'm a bit mystified and I can't reproduce the errors any longer...

styro’s picture

My previous message wasn't quite right. It seems the warnings are only created once per node, so to test it you have to load a node that hasn't triggered the warning before. Emptying the cache tables doesn't reset this either.

As far as I can tell this seems linked to the relatedlinks_tracker table. ie this bug only seems to happen when the relatedlinks_tracker.updated field is 0 for that particular node (reproduced by manually setting 'updated' to 0). So far it seems that only nodes with both search keywords and terms attached and relatedlinks_tracker.updated = 0 will trigger this - there is also at least one other factor I haven't isolated yet. So it seems eventually as all nodes get visited the problem will sort itself out... ;)

I've upgraded another server to PHP 5.2 confirming that the PHP version has something to do with it. PHP 4.4 doesn't trigger this, but 5.2 does.

The warnings happen in groups of 4, most of the time all 4 will be triggered by the array_diff_assoc($set1, $set2) part of line 1093 (I'm now using version 1.51.2.5 of relatedlinks on Drupal 5.1). But sometimes 2 warnings will be produced by the array_diff_assoc($set1, $set2) part and 2 will be produced by the array_intersect_assoc($set1, $set2) part.

styro’s picture

Of course everything I listed above is pretty much the way relatedlinks works by design in terms of when this code in question gets run and stale links are rechecked.

It seems as though this behaviour is really a PHP 5.2 bug (or at least a change from documented behaviour)...

With array_diff_assoc() and array_intersect_assoc() array elements are compared like this (first converted to strings):

(string) $elem1 === (string) $elem2

According to http://php.net/types.string, an object converted to a string is supposed to be "Object". But with PHP 5.2 you can only convert objects that have a __toString() method.

Currently, I'm still using the old mysql module to connect to my DB which could be why my objects are missing __toString(). This would possibly explain when Zen can't reproduce this. Tomorrow I'll check whether mysqli result objects work better.

At this stage I'm not going to look into ugly workarounds for array_diff_assoc() and array_intersect_assoc() unless mysqli makes no difference to the result.

styro’s picture

Bummer - mysqli makes no difference.

styro’s picture

Status: Active » Needs review
FileSize
1.02 KB

OK, here is one possible workaround patch. It's a bit ugly though - basically it has separate code for PHP versions 5.1+

Instead of just:

<?php
    $set = array_intersect_assoc($set1, $set2) + array_diff_assoc($set1, $set2);
?>

We now have:

<?php
    if (function_exists('array_intersect_key')) {
      $set = array_intersect_key($set1, $set2) + array_diff_key($set1, $set2);
    }
    else {
      $set = array_intersect_assoc($set1, $set2) + array_diff_assoc($set1, $set2);
    }
?>

array_*_key() are closer (as far as I can see) to what the author intended as they just compare array keys (node ids in this case) rather than the elements. Not comparing the elements means we avoid needing to convert the elements to strings as array_*_assoc() try to do which is a problem in PHP 5.2. The array_*_key() functions should be faster too.

Unfortunately the array_*_key() don't exist in versions of PHP earlier than 5.1, so we need to leave both approaches in place.

Better solutions would be for either (this is my uninformed opinion):

Fix PHP 5.2 so that (string)$object is "Object" when $object doesn't have a __toString() method. This would make PHP match earlier behaviour.

or less optimal:

db_fetch_object() could provide a __toString() method on the objects it returns. mysqli_fetch_object() and pg_fetch_object() etc can be provided with a base class to use. This might be a useful thing for the gophp5 efforts in Drupal 7.

styro’s picture

Just wondering if anyone has had any luck with the above patch?

@Zen: Have you used relatedlinks on PHP 5.2 yourself yet? I'm pretty sure that running PHP 5.2 is the key to being able to replicate this.

waddles’s picture

Version: 5.x-1.0-beta » 5.x-1.0
Status: Needs review » Reviewed & tested by the community

This patch works for me too. Thanks so much styro!

m3avrck’s picture

I like this approach too and it should be faster for those that use PHP5.2 Date module does this too.

dman’s picture

Wow thanks!
This was confusing the hell out of me. ... just trying to see what it WANTED to be doing was hard enough, let alone why it started going wrong. It was fine for a while, but seems to have started sometime after enabling search.module as well.
+1

styro’s picture

Version: 5.x-1.0 » 5.x-2.x-dev
Status: Reviewed & tested by the community » Needs review
FileSize
1.07 KB

Rerolling patch against 2.x-dev

juerg’s picture

Styro,
Thanks for providing the patch. This is just to confirm that it solved the above mentioned problem. I was using the patch from #11 against 5.2.2-beta (using PHP 5.2).
Juerg

Zen’s picture

Version: 5.x-2.x-dev » 6.x-1.x-dev
Status: Needs review » Fixed

Sorry for the (ridiculously long) delay. Patch committed. Many thanks.

-K

Status: Fixed » Closed (fixed)

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