I'm writing an Institutional custom D7x module, by request.
I perform some tests on db_[functions] in order to set db-related tasks on.

During a IO test
1. I created a dummie array, serialized it, and save to database.
2. Read the saved value and compare against a couple of inputs to find if changed
3. Found unexpected changes where there aren't

I'll show a simplified code to illustrate:

<?php
  $array1 = array(1, 2, 3);
  $ref_value = array('hello', (object)$array1);
  $value_to_save = serialize($ref_value);
  // some code to save $value_to_save at myTable.value where valueKey = 'test_key'
  // ...
  // some code to read the serialized value stored in myTable
  $read = db_select('myTable', 't')
  ->fields('t')
  ->condition('valueKey', db_like('test_key'))
  ->execute()->fetchAssoc();
  $read_value = unserialize($read['value']);
  $test_result = ( $ref_value == $read_value ) ? 'Works' : 'Warning unexpected values';
  drupal_set_message($test_result, 'information);
  // What a message !! 
?>

Then I review the values manually and they seems equal, but the operator "==" said FALSE, ..., i was near a headache, ... decided to see the serialized values and found the difference and the cause

<?php
  $test_result .= '<br>$value_to_save = '.$value_to_save.'<br>stored value ='.serialize($read_value);
  drupal_set_message($test_result, 'information);
?>

Now the message shows the difference:

  • Warning unexpected values

    $value_to_save = a:2:{i:0;s:5:"hello";i:1;O:8:"stdClass":3:{i:0;i:1;i:1;i:2;i:2;i:3;}}

    stored value = a:2:{i:0;s:5:"hello";i:1;O:8:"stdClass":3:{s:1:"0";i:1;s:1:"1";i:2;s:1:"2";i:3;}}

Note: the first stdClass is keyed by integers (as defined) while the second is keyed by strings: once readed and unserialized the stdClass keys are changed.
So there is a possible issue on comparing unserialized objects. And is usefull to write a small method to avoid headaches

<?php
function compare_normal_object_against_unserializedvalue_equals($normal, $unserialized, $verbose=FALSE){
  // Note the like a double-negation fn(fn-1())
  $tocompare = unserialize( serialize($normal) );
  $result = ($tocompare == $unserialized) ? TRUE : FALSE;
  if($verbose){
    $msg = ($result) ? 'Equals ' : 'Different ';
    $msg .= '<br>$normal = '.serialize($tocompare).'<br>$unserialized ='.serialize($unserialized);
     drupal_set_message($test_result, 'information);
  }
  return $result
}
?>

Now I got the expected behavior.
Hope it helps some body.

Greetings

Comments

ibnkhaldun created an issue. See original summary.

drumm’s picture

Version: x.y.z » 7.x-dev
Category: Task » Support request
avpaderno’s picture

Title: Unexpected php behavior while comparing serialized data values » Unexpected PHP behavior while comparing serialized data values
Issue tags: -, -stdClass, -array, -serialize(), -unserialize()

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.