0

I'm building a multilanguage website with Laravel4.

In the database i have column named "content" that contains serialized values for multiple languages. For example:

a:3:{s:2:"gb";s:15:"This is English";s:2:"es";s:5:"Hola!";s:2:"si";s:19:"Slovenija je zakon!";}

The serialized array contains of:

  1. Language abbreviation, taken from Session
  2. Content that comes from the input field

Now when I add new language to the database it creates new serialized string. Great! But when I want to unserialize that string and add a value into it, i get the following error:

unserialize() [<a href='function.unserialize'>function.unserialize</a>]: Error at offset 0 of 30 bytes

Any ideas what is going on? I understand the meaning of the error, but it just makes no sense, since I'm sure that value in the database is serialized string.

public function setContentAttribute($value)
{   
    $lang = (Session::has('my.locale') ? Session::get('my.locale') : Config::get('app.locale'));
    /* Create new serialized string */
    if(empty($this->content)) {    
        $data[$lang] = $value['content'];
        $this->attributes['content'] = serialize($data);
    /* Update values */
    } else {
        $data = $this->content;
        $data = unserialize($data)
        $data[$lang] = $value['content'];
        $this->attributes['content'] = serialize($data);
    }
}

P.S: I'm using mutators for adding values to database.

I hope it's clear enough. If there is anything unclear, please comment and I'll fix it.
Thanks!

intelis
  • 7,829
  • 14
  • 58
  • 102
  • Errors when unserialising suggest the string has been modified (i.e. corrupted). Have a look at this: http://stackoverflow.com/questions/10152904 – George Brighton Sep 23 '13 at 19:33
  • I'm using both accessors and mutators. Is it possible, that a mutator is messing with my `$this->content` when i retrieve value from database? – intelis Sep 23 '13 at 19:40
  • 1
    Not necessarily a mutator, but I suspect something is. Grab the output after serialising the data and compare it with the string that you pass to `unserialise()` from the database. – George Brighton Sep 23 '13 at 19:50
  • Well, you were right, something is changing my string. I'm pretty sure it's that accessor. Is there a was to get value raw value from db, even though I set accessor on that column? thanks.. – intelis Sep 23 '13 at 20:01
  • it is possible that you are using VARCHAR which has a limit of 255 instead of a TEXT, thus truncating the serialized string. when you query it, it then returns a corrupted value thus throwing that error you have.. – reikyoushin Sep 23 '13 at 20:29
  • What's different between the strings? And yes, accessors shouldn't modify a value if you don't want them to. – George Brighton Sep 23 '13 at 20:30

1 Answers1

0

Ok, I've managed to fix it. I was unserializing my code twice - once in the accessor and once in the mutator. Here is a working example:

public function getVsebinaAttribute($value)
    {
        $data = unserialize($value);
        $lang = $this->getLang();
        if (!empty($data[$lang])) {
            return $data[$lang];
        } else {
            return '# Value has not yet been added';
        }
    }
    public function setVsebinaAttribute($value)
    {
        if (isset($this->attributes['vsebina'])) {
            $data = unserialize($this->attributes['vsebina']);
        } else {
            $data = array();
        }

        $lang = $this->getLang();
        $data[$lang] = $value;
        $this->attributes['vsebina'] = serialize($data);
    }

    protected function getLang()
    {
        return Session::has('my.locale') ? Session::get('my.locale') : Config::get('app.locale');
    }
intelis
  • 7,829
  • 14
  • 58
  • 102