首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >$bundle与bundle()的区别

$bundle与bundle()的区别
EN

Drupal用户
提问于 2019-09-23 10:41:09
回答 1查看 160关注 0票数 3

背景信息:我试图操作列表类型文本字段的可用选项,具体取决于主机包:

代码语言:javascript
复制
function wtbase_options_list_alter(array &$options, array $context) {
  $fieldDefinition = $context['fieldDefinition'];
  if ($fieldDefinition->getName() == 'field_aos_cell' && $fieldDefinition->bundle() != 'link') {
    foreach ($options as $key => $value) {
      if ($key == 'link-horizontally-opposing') {
        unset($options[$key]);
      }
    }
  }
}

$fieldDefinition->bundle部分非常令人困惑。似乎有一个变量$fieldDefinition->bundle (包含预期的包名link)和一个函数$fieldDefinition->bundle() (包含field_config)。但是我无法访问变量bundle,因为这与Cannot access protected property Drupal\field\Entity\FieldConfig::$bundle崩溃了。

经过深入研究,我找到了FieldConfigBase::getTargetBundle(),它确实返回了预期的结果,并且没有崩溃(目前为止)。

这就引出了两个问题:

$bundlebundle()getTargetBundle()之间有什么区别,我应该使用哪一种?我更喜欢使用变量,因为它们在Xdebug中是可见的,而函数不是。

更普遍的观点是,在什么时候使用函数和什么时候使用变量有一些指导原则吗?在上面的示例中,Xdebug打印了相同的奇怪结果,例如entity_typeentityTypeIdgetEntityType()getEntityTypeId()

--

问题1的更新和澄清:

我知道成员属性和成员函数之间的技术区别。但是,我深感困惑的是,属性$bundle和完全相同名称的函数bundle()正在从完全不同的实体/上下文返回值。在我的示例中,$fieldDefinition->bundle返回一个段落包名link,而$fieldDefinition->bundle()似乎从FieldConfig返回包名。我知道这在技术上是可能的..。但是为什么会有人写这样的代码呢?我还没有在Drupal中的任何其他地方体验过这种行为,通常$entity->bundle$entity->bundle()返回相同的结果。

EN

回答 1

Drupal用户

发布于 2019-09-23 11:04:14

bundle是对象的属性。它是储存价值的地方。属性可以通过以下三种方式之一分配:

  • public:这些属性可以直接在对象上设置或读取。例如:$object->key = 'value';$value = $object->key;
  • private:这些只能通过类本身的方法(函数)访问。其他任何东西都无法访问它。这可以用于对要存储在属性中的数据类型强制执行规则。可以运行检查以确保它是允许的数据类型。
  • protected:这些类似于私有属性,但是如果类扩展了类,则扩展类可以访问该属性。如果属性是私有的,扩展类将无法访问它。

您需要理解的一件事是,$node->bundle$node->bundle()是不一样的。第一个是属性,另一个是方法。这应该有助于理解,作为一个(非真实的)例子:

代码语言:javascript
复制
class Node {
  protected $bundle;

  public function bundle() {
    return $this->bundle;
  }
}

上述类具有属性$bundle和方法(函数) bundle()。该方法返回存储在属性中的值。

看看您所看到的错误:Cannot access protected property Drupal\field\Entity\FieldConfig::$bundle。这是因为您试图访问$bundle属性,但它是受保护的,这意味着您不能从类之外访问它。

要获得节点的包,需要调用节点上的bundle()方法,这将为您提供包类型。这是你关于使用哪一个问题的答案。

更普遍的观点是,在什么时候使用函数和什么时候使用变量有一些指导原则吗?

通常认为最好的做法是不提供对对象的属性的直接访问,而是在对象上创建setter和getter方法(函数)来设置和检索属性值。这样你就可以说,强制执行一种模式:

代码语言:javascript
复制
class Example {

  protected $username

  public function setUsername($username) {
    if (!is_string($username)) {
      throw new \Exception('Username must be a string');
    }
    elseif (!preg_match('/^[a-zA-Z0-9_-]{3,12}$/', $username)) {
      throw new \Exception('Username must be between 3 and 12 characters, and may contain only alphanumerics, underscores or hyphens');
    }

    $this->username = $username;
  }

  public function getUsername() {
    return $this->username;
  }
}

以上强制表示用户名既是一个字符串,也是正确的长度,并且只包含允许的字符。

编辑:来自Leigh的其他评论:

避免直接访问属性的另一个原因是当您有多个值时。例如,如果在节点上有一个字段"my_field“,如果使用$ node ->my_ field ->value,则该字段具有多个值,则只返回1个值。

票数 3
EN
页面原文内容由Drupal提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://drupal.stackexchange.com/questions/286641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档