yii2
yii2 copied to clipboard
yii\rbac\DbManager serialization issue
I got this error
for emergency I solve this with extends yii\rbac\DbManager and overwrite function:
public function getRule($name)
{
if ($this->rules !== null) {
return isset($this->rules[$name]) ? $this->rules[$name] : null;
}
$row = (new Query())->select(['data'])
->from($this->ruleTable)
->where(['name' => $name])
->one($this->db);
if ($row === false) {
return null;
}
$data = $row['data'];
if (is_resource($data)) {
$data = stream_get_contents($data);
}
return unserialize($data);
}
to this
public function getRule($name)
{
if ($this->rules !== null) {
return isset($this->rules[$name]) ? $this->rules[$name] : null;
}
$row = (new Query())->select(['data' => 'convert_from("data", \'UTF-8\')'])
->from($this->ruleTable)
->where(['name' => $name])
->one($this->db);
if ($row === false) {
return null;
}
$data = $row['data'];
if (is_resource($data)) {
$data = stream_get_contents($data);
}
return unserialize($data);
}
how data stored in auth_rule table:
any suggestion? why this happens?
Additional info
Q | A |
---|---|
Yii version | 2.0.40 |
PHP version | 5.6 |
Operating system | MacOS |
Postgresql | 13.2 |
This is well known problem with unserialize and utf8 data. I'm not sure if we can do much about it. Maybe switching to json would be better...
@bizley JSON isn't supported by all DBMS we have.
I was thinking more of a text column with json-encoded data than json column.
But...
I did some testing because I remembered that unserializing issue from way back and I realized everything works... as long as the data is utf8. Then I saw that OP is converting the data to utf8 in the database so this is the reason. While we can easily enforce "encoding" as UTF8 in MySQL (and this is done in RBAC migration) this is not that trivial for other DBs including PostgreSQL. So I think that first of all we should have it mentioned somewhere that UTF8 is really needed for that table, and second - maybe we can have rules not serialized in the DB?
Having rules not serialized sounds interesting. I wonder why we serialize them...
I believe (absolutely no data supporting this statement) that 99% of users are not having rules that require their data to be stored in DB. I think the same applies to the items with additional data property. Anyway, we could have only info, that a rule is used, stored in DB and then just instantiate its object when executing it is required. Having the rule object is required anyway and I cannot image a case where one rule has so many customizations that we need to serialize them and store the snapshots in DB.
Can anyone prove me wrong?
https://github.com/yiisoft/yii2/issues/13501