使用 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.

的类似函数

例子

通过 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(例如 HardwareProduct)使用相同的 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']);