使用 PropertyAccessor 将值写入之前创建的对象
Write values to before created object with PropertyAccesor
我有一个 class 获取的字符串,其中包含我的数据库字段的名称和相应的值。我想创建一个新条目并想事先检查该字段是否存在于我的数据库中。
但是,由于对象是在我检查 属性 是否可读之前创建的,因此它抛出异常:
Fails Here: Warning: Illegal offset type in isset or empty
这里抛出错误:
try{
$accessor->isWritable($field['name'], $hw);
}catch (\Exception $exception){
throw new \Exception('Fails Here: '.$exception->getMessage());
}
免责声明
我知道这很危险,可能会因注入而造成伤害,但这是一个只有我作为用户的内部项目,我目前想不出更优雅的方式来做到这一点,无需编写add_new_row
或每个 table.
的类似函数
例子
- table
Hardware
有列 SerialNo
、Firmware
和 BuyDate
。
- table
Product
有列 isActive
和 Price
通过 ajax 我现在想为每个 table 发送一个数组以创建一个新条目。我通过 $.post()
:
得到一个这样的数组
$data = array(
'table' => 'Hardware',
'values' => array(
0 => array(
'name' => 'SerialNo',
'value' => '1234'
),
1 => array(
'name' => 'Firmware',
'value' => 'v1.04'
),
2 => array(
'name' => 'BuyDate',
'value' => '2018-08-23'
),
)
)
因此,为了对每个 table(例如 Hardware
和 Product
)使用相同的 class,我尝试这样做:
$accessor = PropertyAccess::createPropertyAccessor();
if($data['table'] === 'Hardware'){
$obj = new Hardware();
}else{
$obj = new Product();
}
foreach ($data['values'] as $field) {
try{
$accessor->isWritable($field['name'], $hw);
}catch (\Exception $exception){
throw new \Exception('Fails Here: '.$exception->getMessage());
}
if (!$accessor->isWritable($field['name'], $obj)) {
throw new InvalidArgumentException('Could not write: ' . $field['name']);
}
$accessor->setValue($field['name'], $obj, $field['value']);
$em->persist($obj);
}
它甚至没有抛出异常,我认为这是因为 $obj
看起来像这样(这就是抛出错误的意思,不是吗?)
Hardware {#2708 ▼
-id: null
-serialNo: null
-firmware: null
-buyDate: null
有没有办法按照我想要的方式做到这一点?
您混淆了 isWritable()
和 setValue()
的参数。如果你像这样交换它们,你的代码将按预期工作:
if (!$accessor->isWritable($obj, $field['name'])) {
throw new InvalidArgumentException('Could not write: ' . $field['name']);
}
$accessor->setValue($obj, $field['name'], $field['value']);
我有一个 class 获取的字符串,其中包含我的数据库字段的名称和相应的值。我想创建一个新条目并想事先检查该字段是否存在于我的数据库中。 但是,由于对象是在我检查 属性 是否可读之前创建的,因此它抛出异常:
Fails Here: Warning: Illegal offset type in isset or empty
这里抛出错误:
try{
$accessor->isWritable($field['name'], $hw);
}catch (\Exception $exception){
throw new \Exception('Fails Here: '.$exception->getMessage());
}
免责声明
我知道这很危险,可能会因注入而造成伤害,但这是一个只有我作为用户的内部项目,我目前想不出更优雅的方式来做到这一点,无需编写add_new_row
或每个 table.
例子
- table
Hardware
有列SerialNo
、Firmware
和BuyDate
。 - table
Product
有列isActive
和Price
通过 ajax 我现在想为每个 table 发送一个数组以创建一个新条目。我通过 $.post()
:
$data = array(
'table' => 'Hardware',
'values' => array(
0 => array(
'name' => 'SerialNo',
'value' => '1234'
),
1 => array(
'name' => 'Firmware',
'value' => 'v1.04'
),
2 => array(
'name' => 'BuyDate',
'value' => '2018-08-23'
),
)
)
因此,为了对每个 table(例如 Hardware
和 Product
)使用相同的 class,我尝试这样做:
$accessor = PropertyAccess::createPropertyAccessor();
if($data['table'] === 'Hardware'){
$obj = new Hardware();
}else{
$obj = new Product();
}
foreach ($data['values'] as $field) {
try{
$accessor->isWritable($field['name'], $hw);
}catch (\Exception $exception){
throw new \Exception('Fails Here: '.$exception->getMessage());
}
if (!$accessor->isWritable($field['name'], $obj)) {
throw new InvalidArgumentException('Could not write: ' . $field['name']);
}
$accessor->setValue($field['name'], $obj, $field['value']);
$em->persist($obj);
}
它甚至没有抛出异常,我认为这是因为 $obj
看起来像这样(这就是抛出错误的意思,不是吗?)
Hardware {#2708 ▼
-id: null
-serialNo: null
-firmware: null
-buyDate: null
有没有办法按照我想要的方式做到这一点?
您混淆了 isWritable()
和 setValue()
的参数。如果你像这样交换它们,你的代码将按预期工作:
if (!$accessor->isWritable($obj, $field['name'])) {
throw new InvalidArgumentException('Could not write: ' . $field['name']);
}
$accessor->setValue($obj, $field['name'], $field['value']);