处理!isset值而不检查isset

时间:2014-06-27 18:28:58

标签: php exception-handling null isset

我有一个从与此结构类似的API中提取的对象:

class stdClass#544 (5) {
  public $id =>
  string(1) "4"
  public $name =>
  class stdClass#545 (6) {
    public $en =>
    string(6) "Test"
  }
  public $description =>
  class stdClass#546 (6) {
    public $en =>
    string(20) "My Description."
  }
}

但是,API略有不一致。有时,某些对象没有description属性:

class stdClass#544 (5) {
  public $id =>
  string(1) "7"
  public $name =>
  class stdClass#545 (6) {
    public $en =>
    string(6) "Another Test"
  }
}

当我循环访问API时,我将值从对象映射到数组:

$values = array();
foreach( $objects as $object ) {
  $values = array(
    'id' => $object->id,
    'name' => $object->name->en,
    'description' => $object->description->en,
  );
  someFunction($values);
}

但是,由于有时description不是对象的set / existing属性,因此如果缺少description,则会抛出异常。

处理有时不存在的属性映射的最佳方法是什么?在分配它们之前,我显然可以检查每个属性的存在:

$values = array();
if ( isset($object->id) )
  $values['id'] = $object->id;

if ( isset($object->name) and isset($object->name->en) )
  $values['id'] = $object->name->en;

if ( isset($object->description) and isset($object->description->en) )
  $values['description'] = $object->description->en;

但是这种方法很快变得麻烦并且难以维护,尤其是当存在比我列出的更多属性时。上面的例子是我的问题的简化版本。实际上还有更多属性。因此,手动检查属性的存在会变得更加困难,当它们是嵌套属性时更是如此。

我发现一个简单的解决方案是使用@符号,这会强制PHP忽略异常:

$values = array();
foreach( $objects as $object ) {
  @$values = array(
    'id' => $object->id,
    'name' => $object->name->en,
    'description' => $object->description->en,
  );
  someFunction($values);
}

这会导致descriptionnull(这对我来说很理想)。没有异常被抛出。不过,我非常确定@用于调试目的,我认为以这种方式使用它是不合适的。

处理此问题的最佳方法是什么?如果属性/键不存在于对象中而不必手动检查每个属性的存在,我可以以某种方式轻易地将我的数组中的值设置为null吗?

1 个答案:

答案 0 :(得分:2)

您可以定义要从数组中的对象中提取的键,然后在foreach循环中提取每个键。

修改

注意到你有时会访问对象中的对象。如果您只需要深入1级,则下面的示例应该这样做。

如果您要提取的值是深度为额外级别的对象的属性,则将相应的键设为keyName => subKeyName的数组。

$a = new stdClass();
$a->id = 'hello';
$a->description = 'world';
$a->name = new stdClass();
$a->name->en = 'name';

$keys = ['id','description','notset',['name' => 'en']];
$value = [];
foreach($keys as $key) {

    if(is_array($key)) {
        $subkey = current($key);
        $key = key($key);
        $value[$key] = (isset($a->$key->$subkey))
          ? $a->$key->$subkey : null;
    }
    else {
        $value[$key] = (isset($a->$key)) 
          ? $a->$key : null;
    }
}

var_dump($value);