# Data in postgresql bytea field is corrupted when saved

**URL:** <https://discourse.cakephp.org/t/data-in-postgresql-bytea-field-is-corrupted-when-saved/1448>\
**Category:** Need Help\
**Created:** [November 3, 2016, 10:11pm UTC](https://discourse.cakephp.org/t/data-in-postgresql-bytea-field-is-corrupted-when-saved/1448 "2016-11-03T22:11:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ldoerksen](https://avatars.discourse-cdn.com/v4/letter/l/e9bcb4/32.png) [@ldoerksen](https://discourse.cakephp.org/u/ldoerksen)\
**Post date:** [November 3, 2016, 10:11pm UTC](https://discourse.cakephp.org/t/data-in-postgresql-bytea-field-is-corrupted-when-saved/1448/1 "2016-11-03T22:11:00Z")

</div>

Hello there,  
I am fighting with a problem for hours now.  
this is my first forum entry, so I hope not to forget any needed information.  
I am developing a management app where I need to save pictures directly into the database(Dont ask me why, just got the project from another developer-group). I thought this would go quite simple, but then i encounterd a problem.

I am sending all data via AJAX(AngularJs), so the picture is base64\_encoded.

At first I thought it already got corrupted on this way, but when base64\_decoding and saving the data, I get the exact picture. But when I save it into the database(postgresql) and retrieve it back, the picture is corrupted.  
The picture is saved in a BYTEA field. Here is the beforeSave() method(Where I prepare the data to be saved):

**public function beforeSave(Event $e, EntityInterface $entity, ArrayObject $options){**  
**if(isset($entity-\>picture)){**  
**$entity-\>picture = base64\_decode(str\_replace([‘data:image/png;base64,’, ‘data:image/jpeg;base64,’], ‘’, $entity-\>picture));**  
**}**  
**$entity-\>picture\_type = ‘image/png’;**  
**$entity-\>picture\_hash = hash(‘sha256’, $entity-\>picture);**  
**$entity-\>logo = $entity-\>picture;**  
**$entity-\>logo\_hash = $entity-\>picture\_hash;**  
**$entity-\>logo\_type = $entity-\>picture\_type;**  
**}**

Am I doing anything wrong?

---

<div class="post-metadata">

**Author:** ![ldoerksen](https://avatars.discourse-cdn.com/v4/letter/l/e9bcb4/32.png) [@ldoerksen](https://discourse.cakephp.org/u/ldoerksen)\
**Post date:** [November 4, 2016, 3:27pm UTC](https://discourse.cakephp.org/t/data-in-postgresql-bytea-field-is-corrupted-when-saved/1448/2 "2016-11-04T15:27:05Z")

</div>

I found the answer.  
It was not, that the image got corrupted while saving, but while reading.  
I tried everything before, read it from the database, save it as file, but everything failed.  
I was so frustrated, that I actually wrote code to upload the data via PDO.  
This was when I encountered a missing piece of information on the Php Website which says,  
that Bytea fields get returned as stream. I already knew that what I got as return value was a resource, but I never used streams before:

[http://php.net/manual/en/pdo.lobs.php](http://php.net/manual/en/pdo.lobs.php)

Long Story Short: I have to use stream\_get\_contents() to read the data correctly.

---

<div class="post-metadata">

**Author:** ![hectorviov](https://avatars.discourse-cdn.com/v4/letter/h/6bbea6/32.png) [@hectorviov](https://discourse.cakephp.org/u/hectorviov)\
**Post date:** [March 9, 2018, 5:22am UTC](https://discourse.cakephp.org/t/data-in-postgresql-bytea-field-is-corrupted-when-saved/1448/3 "2018-03-09T05:22:46Z")

</div>

Hello, how do you use the stream\_get\_contents() to get it from the database? I’m struggling when I call find in the table, the bytea field always returns null. Please help…

---

<div class="post-metadata">

**Author:** ![ldoerksen](https://avatars.discourse-cdn.com/v4/letter/l/e9bcb4/32.png) [@ldoerksen](https://discourse.cakephp.org/u/ldoerksen)\
**Post date:** [March 9, 2018, 8:09am UTC](https://discourse.cakephp.org/t/data-in-postgresql-bytea-field-is-corrupted-when-saved/1448/4 "2018-03-09T08:09:56Z")

</div>

I use this method:

```
public function beforeFind(Event $event, Query $query, ArrayObject $options){
  $query->formatResults(function($results) use($options){
    return $results->map(function($row) use($options){
      if(isset($row['picture'])){
        if(isset($options['withPicture'])){
           $row['picture'] = "data:image/png;base64,".base64_encode(stream_get_contents($row['picture'])); //Before the row gets put into an entity, where it will be null
        }
         else{
          $row['picture'] = '';
        }
        if(isset($options['withLogo'])){
          $row['logo'] = "data:image/png;base64,".base64_encode(stream_get_contents($row['logo']));
        }
        else{
          $row['logo'] = '';
        }
      }
      return $row;
    });
  });
}

```

After find, the stream won’t be accesible in the entity. Therefore you have to read the streams content here.
