检查entity_metadata_wrapper上的字段是否存在


22

我正在遍历字段集合,并使用Entity_metadata_wrapper包装字段集合项。我想在调用字段的value方法之前检查字段的存在(这会导致在没有值的字段上产生错误),但是我找不到解决方法。

$field_collection_item = field_collection_item_load($id);
$item_wrapper = entity_metadata_wrapper('field_collection_item', $field_collection_item);

// this results in an error if the field_contrib_headshot field is empty
$headshot = $item_wrapper->field_contributor->field_contrib_headshot->value();

我当前的解决方法是使用field_get_items该字段是否为空,但是我希望能够通过元数据包装器做到这一点。

Answers:


26

只需调用PHP函数isset()

$headshot = array();
if (isset($item_wrapper->field_contributor->field_contrib_headshot)) {
  $headshot = $item_wrapper->field_contributor->field_contrib_headshot->value();
}

EntityStructureWrapper __isset()根据Overloading的原理实现该功能。


是的,这始终是我的工作方式,减少了与内部的联系,更易于阅读IMO。已投票!
科茨(Cottser)2014年

9

任何时候只要有实体引用或字段集合,isset()都不会对我有用。每当我们有一个实体引用正在执行时,什么似乎可行:

if($wrapped_entity->entity_reference_field->getIdentifier()) {
  // This code only fires if there is an entity reference or field collection set.
}

这个答案和以下帖子对我有用
tyler.frankenstein 2015年

4

entity_reference由于方法链接,您似乎在某处。但是,请看EntityStructureWrapper的__isset()方法

检查像:

$has_headshot = $item_wrapper->field_contributor->__isset('field_contrib_headshot');

然后使用一个IF块来做你的逻辑...

编辑:

$has_headshot 现在是所需的有效支票。


我不确定您的意思是“看起来好像在某处有实体引用”,如果您能解释一下,我将不胜感激。__isset尽管我需要添加完整的字段名称,但在字段集合上的效果很好:field_contrib_headshot而不是contrib_headshot
Nick Tomlin

字段是值;字符串,数字等等。field_contributor正在引用另一个字段field_contrib_headshot...您以某种方式嵌套在其中。我假设您正在使用entity_reference或诸如field_group之类的东西来嵌套这些东西……仅此而已。
tenken

为您工作的__isset()代码段是什么?
tenken

那是:$item_wrapper->field_contributor->__isset('field_contrib_headshot')
尼克·汤姆林

我觉得直接调用__isset()很奇怪,为什么不呢? $has_headshot = isset($item_wrapper->field_contributor->field_contrib_headshot);
Cottser 2014年

1
$wrapper = entity_metadata_wrapper('node', 123);
if($wrapper->__isset('field_middle_name')) {
    // Do something awesome with the middle name.
} else {
    // Don't do anything awesome, they don't have a middle name.
}

实体参考字段和字段集合

// also check if there is an identifier, __isset alone is not enough!
if ($wrapper->__isset('field_project_number') && $wrapper->field_project_number->getIdentifier()) {
    $number =  $wrapper->field_project_number->field_project_number_complete->value();
    return $number;
}

直接从http://dropbucket.org/node/1201复制和粘贴,但似乎是迄今为止最好的示例……


1

对于EntityMetadataWrapper:

如果您运行的代码块不应该运行,或者遇到PHP错误,请查看下面的一些示例。本示例使用属性nid。

可能所有错误

if ($wrapper->__isset('nid')) {
  $var = $wrapper->nid->value();
}
else {
  // Do something it's FALSE;
}

要么

if ($wrapper->__isset('nid')) {
  $var = $wrapper->nid->getIdentifier();
}
else {
  // Do something it's FALSE;
}

要么

if ($wrapper->nid->value()) {
  // Do something it's TRUE.
}
else {
  // Do something it's FALSE;
}

您可能会发现,即使没有nid,使用像这样的isset也会评估为true。-> getIdentifier()或-> value()或-> raw()可能会引发异常。

总是正确的

if (isset($wrapper->nid)) {
  // Do something it must be TRUE....Ah Hem wait.. this runs every time.
}

使用此替代

try {
  $var = $wrapper->nid->raw();
} 
catch (EntityMetadataWrapperException $e) {
  $var = FALSE;
}

0

我发现isset()不能用于函数调用的结果。由于使用以下语句返回了布尔值,因此我能够验证包装的元素实际上是否具有值。

if ( $wrapper->field_media_alternate[0]->value() ) {
  //...valid logic...
} else {
  //...not valid logic...
}

0

人们常常会误会这一点。在实体元数据包装器上调用isset时,您正在检查实体捆绑包是否支持该属性。它与字段的实际值无关。

确实没有独立的方法来检查是否设置了值。您只需要评估value()或最好是raw()。(如果它是一个多值字段,也可以调用count(),但是raw()将返回一个空数组,因此实际上并不是必需的。)

$w = entity_metadata_wrapper('node', $nid);
//Start by checking whether the node bundle supports field_entityref_myfield.
if (isset($w->field_entityref_myfield)) {
  //If we called value(), then that would cause the referenced entity
  //to be loaded, whereas raw() just gives us the entity_id if the value
  //is set, and Null if it isn't.
  if ($w->field_entityref_myfield->raw()) {
    //Do some things based on the entity-reference being set.
  } else {
    //Do some other things based on the entity-reference NOT being set.
  }
}

重申一下,raw()是您应该用来检查字段是否存在的值。它可靠且计算便宜。


0

这是我的个人帮助函数,用于从潜在未设置的实体引用链中获取值:

function _get_wrapped_value_ifset($wentity, $field_chain){
  $root = $wentity;
  try{
    foreach ( $field_chain as $field_name ) {
      $root = $root->{$field_name};
    }
    return $root->value();
  }
  catch (EntityMetadataWrapperException $e){
    return null;
  }
}

$ wentity是包装的实体,$ field_chain是一个field_names数组,如下所示:

[
  'field_reference_from_the_wentity',
  'field_wanted_field_from_the_referenced_entity'
] 

您也可以这样做:

[
  'field_reference_from_the_wentity', 
  'field_reference_from_the_referenced_entity',
  ... 
  'field_wanted_field_from_the_N_referenced_entity'
]

它会工作的!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.