【问题标题】:How to load JSON into field of Silverstripe Dataobject如何将 JSON 加载到 Silverstripe Dataobject 的字段中
【发布时间】:2019-03-04 02:21:09
【问题描述】:

最近的 Silverstripe 版本升级到 4.3.1 似乎破坏了将数据对象作为 JSON 加载到文本字段中的某些功能。

对象如下所示:

class Foo extends DataObject 

  private static $db = [
    'Name' => 'Varchar',
    'Description' => 'Text',
    'Models' => 'Text',
  ];

然后有一个函数可以使用从表单请求生成的 JSON 加载对象:

$data = json_decode($request->getBody(), true);
$foo = new Foo();
$foo->update($data);

以下是 JSON $data 的示例:

"Name":"Test",
"Description":"Wangle fangle blurble wurgle.",
"Models":{
   "fish":{"trout":10,"salmon":15,"sturgeon":20},
   "vegetable":{"carrot":1,"cabbage":2,"leek":3},
   "sauce":{"chipotle":6,"tomato":4,"soy":2}
 }

直到最近,“模型”结构才会作为文本保存到“模型”字段中:

 "fish":{"trout":10,"salmon":15,"sturgeon":20},
 "vegetable":{"carrot":1,"cabbage":2,"leek":3},
 "sauce":{"chipotle":6,"tomato":4,"soy":2}

但现在我们得到以下错误:

DataObject::setField: Models only accepts scalars at /var/www/example/vendor/silverstripe/framework/src/ORM/DataObject.php:2648

DataObject.php 中的第 2640 行说:

If this is a proper database field, we shouldn't be getting non-DBField objects

最近是否有阻止尝试将 JSON 对象加载到字段中的安全修复程序?

谁能帮忙将模型 JSON 保存到文本字段中?

【问题讨论】:

标签: php silverstripe silverstripe-4


【解决方案1】:

@wmk 在这里大放异彩,这是防止安全漏洞的预期行为(请参阅SS-2018-021)。 4.3.1 中的更改是为了防止您在将数据库字段指定为标量类型时无意中允许用户将非标量值插入数据模型中。

在您的情况下,您正在尝试将数组写入文本字段,该字段被 silverstripe/framework 正确阻止。

对您来说最简单的解决方法是重新编码您知道要存储为 JSON 文本 blob 的数据数组部分,例如:

$data = json_decode($request->getBody(), true);
$data['Models'] = json_encode($data['Models']); // re-encode as JSON before saving
$foo = new Foo();
$foo->update($data);

这将确保您仍将 JSON 作为文本写入文本字段。

正如@wmk 提到的,另一个可行的选择是编写自己的 DBField,它接受非标量值并负责将它们安全地写入数据库。如果您正在编写处理GIS or spatial data 的DBField,这将很有用。在您的特定示例中,我认为您可以像我的示例一样确保它仍然被编码为字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-19
    • 2013-04-17
    • 2018-03-02
    • 2013-11-22
    • 1970-01-01
    • 2015-12-23
    • 2017-04-20
    • 1970-01-01
    相关资源
    最近更新 更多