'Getting blob type Doctrine entity property returns data only once

I use Doctrine to store options/various bits of odd data in an array and serialise it to database where it gets stored as a blob. Everything was working fine until today I had to get that array twice and noticed that it gets the correct value only the first time. Any successive attempts return false, which is what unserialize/stream_get_contents returns on failure.

My best guess is that doctrine closes the stream after it fetches the data, but it doesn't make much sense. I need the data to be available throughout the request. I'm not an expert with streams so:

How can I fetch blob data multiple times or prevent the stream from closing?

Doctrine entity and it's methods:

/**
 * @var resource
 *
 * @ORM\Column(name="options", type="blob")
 */
private $options;

/**
 * Set options
 *
 * @param array $options
 *
 * @return Campaign
 */
public function setOptions($options)
{
    $this->options = serialize($options);

    return $this;
}

/**
 * Get options
 *
 * @return array
 */
public function getOptions()
{
    return unserialize(stream_get_contents($this->options));
}

Retrieve serialized options array:

$campaign   = $this->em->getRepository('TreasureForgeMessageBundle:Campaign')->find(1);
$options1   = $campaign->getOptions(); // Correct options array
$options2   = $campaign->getOptions(); // false
$options3   = $campaign->getOptions(); // false

Many thanks!



Solution 1:[1]

The problem you are experiencing occur because you do not rewind() your handle in between read operations.

However, unserializing the option array on each access is a bad idea considering performance. The $options string would have to be converted to an array on each access. Instead, you should tell doctrine that $options is an array, which will then be automatically serialized and unserialized only when data is read from and written to the database:

/**
 * @var array
 *
 * @ORM\Column(name="options", type="array")
 */
private $options;

/**
 * Set options
 *
 * @param array $options
 *
 * @return Campaign
 */
public function setOptions($options)
{
    $this->options = $options;

    return $this;
}

/**
 * Get options
 *
 * @return array
 */
public function getOptions()
{
    return $this->options;
}

Update:

Doctrine array types are described here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mike