“中国要复兴、富强,必须在开源软件领域起到主导作用,为了国家安全和人类发展,责无旁贷,我们须为此而奋斗”——By:云客
字段API提供字段储存、类型化、验证等功能,它是内容实体的基石,是学习实体之前不可忽略的内容,而她又是建立在类型化组件之上的。
“字段”含义的区别:
字段API组件中的“字段”和数据库中表的“字段”含义是不一样的,后者是数据库表中的一个列,前者是一个包含多个信息的数据对象,除包含了后者的值外,还有许多与后者相关的属性和配置,前者直接充当实体对象的属性;在数据库表字段这个层面上,许多cms将同一个数据模型的多个相关属性一一对应一个字段并储存在数据库的同一张表里,而drupal则不同,她为每一个属性建立一张表,表中有一个值字段来储存该属性的值,并提供其他字段来储存与该属性相关的信息,整张数据表向上层应用抽象成一个“字段”,最终形成字段api中的字段数据对象;所以他们的含义是不一样的,在使用层面感觉不到这一点,drupal的实现更加灵活,细粒度更低,带来很多很棒的功能,比如:系统允许多数据模型(内容类型)共用一个“字段”,这在底层实际上是一张字段表储存了不同内容类型的信息,在表中用bundle字段加以区别;自然实现了多值字段功能,支持翻译,十分优雅。
类型化api回顾:
(本节是对类型化组件的简单回顾与总结,更多请看本系列的类型化数据主题)在drupal中许多地方采用了“数据对象+元数据对象”的设计模式,如实体、插件、字段、类型化等,数据对象保存和操纵数据,元数据对象保存相关数据的数据,元数据(Metadata)对象有时又称数据定义对象,它们总是成对出现,类型化数据组件就是这种典型实现。
整个类型化组件提供三大类别数据:
基本数据:又可称为原始数据、基础数据,是构建复合数据和列表数据的基本单元
列表数据:可以视为保存同类数据类型的索引数组,它的元素可以是基本数据、复合数据、列表数据
复合数据:可以视为关联数组,或为保存属性为目的的对象,通过属性名保存各类数据
此外还提供引用类型数据,引用类型只是一个引用,并不代表真正的数据,通过以上三大类别的数据和引用类型数据就可以类型化所有数据,并提供更高一级别的使用了;我们要实例化一个类型化数据对象是从类型id开始的,通过类型id得到类型定义对象,再通过类型定义对象就可以知道数据对象类在哪里以及相关元数据,然后由数据对象提供的静态方法实例化自己,这个过程被封装在类型化数据管理器中,由它提供使用接口,当然我们也可以直接操作以上过程。
所有类型化数据对象都提供getValue、setValue方法,他们操作的是php的原始数据类型;复合类型和列表类型提供get、set方法,他们操作的是类型化数据对象(注意:这里复合类型的set方法设置的值应为php的原始类型,不支持类型化数据对象,而列表类型均可以,这是一个不规范的地方)
所有类型化数据对象都实现以下接口:
Drupal\Core\TypedData\TypedDataInterface
各类型数据对象实现的接口:
Drupal\Core\TypedData\PrimitiveInterface
Drupal\Core\TypedData\ListInterface
Drupal\Core\TypedData\ComplexDataInterface
各类元数据对象(数据定义对象)实现的接口:
Drupal\Core\TypedData\DataDefinitionInterface
Drupal\Core\TypedData\ListDataDefinitionInterface
Drupal\Core\TypedData\ComplexDataDefinitionInterface
引用类型的数据对象和定义对象实现的接口:
Drupal\Core\TypedData\DataReferenceInterface
Drupal\Core\TypedData\DataReferenceDefinitionInterface
请仔细观察这些接口,整个蓝图就出现了。
字段对象和字段定义对象:
字段组件依然采用了“数据对象+元数据对象”的设计模式,对应的称为字段对象和字段定义对象:
字段对象:
每个实体字段对象(实体的字段属性)都是一个列表类型的类型化数据对象,为什么是列表类型呢?这是因为每个字段对象都可以包含数据库中多行数据记录,每行记录对应一个字段项FieldItem,列表中的一个元素就对应着一个字段项,因此必须实现该接口:
Drupal\Core\Field\FieldItemListInterface(继承自列表数据接口:Drupal\Core\TypedData\ListInterface)
其中的每个列表元素是一个字段项FieldItem对象,是一个复合类型数据对象(对应数据库中的一行数据记录),列表元素必须实现以下接口:
\Drupal\Core\Field\FieldItemInterface(继承自复合数据接口:Drupal\Core\TypedData\ComplexDataInterface)
字段对象的默认实现:
Drupal\Core\Field\FieldItemList
其中列表元素对象的默认实现为:
Drupal\Core\Field\FieldItemBase
字段定义对象:
字段定义对象是来描述字段对象的元数据对象,但在系统中将字段定义分为两个级别,可以称为:通用级别和储存级别,它们一起实现字段定义对象的功能,通用字段定义对象实现该接口:
Drupal\Core\Field\FieldDefinitionInterface
(继承自列表数据定义对象:Drupal\Core\TypedData\ListDataDefinitionInterface)
字段储存定义对象实现该接口:
Drupal\Core\Field\FieldStorageDefinitionInterface
在通用字段定义对象中可以通过getFieldStorageDefinition()方法得到字段储存定义对象
字段定义对象的默认实现是:
Drupal\Core\Field\BaseFieldDefinition
其中的元素定义对象默认实现是:
Drupal\Core\Field\TypedData\FieldItemDataDefinition
系统默认提供的字段项FieldItem类型:
字段对象是字段项FieldItem对象组成的列表数据对象,字段项FieldItem的类型代表着字段类型,系统定义了许多字段类型,每个类型都对应着一个类型化数据类型,类型id格式如下:
"field_item:FIELD_TYPE"
默认类型如下(见本系列的类型化api主题),以类型id列出:
[46] => field_item:comment
[47] => field_item:datetime
[48] => field_item:file
[49] => field_item:image
[50] => field_item:link
[51] => field_item:list_float
[52] => field_item:list_integer
[53] => field_item:list_string
[54] => field_item:path
[55] => field_item:text
[56] => field_item:text_long
[57] => field_item:text_with_summary
[58] => field_item:boolean
[59] => field_item:changed
[60] => field_item:created
[61] => field_item:decimal
[62] => field_item:email
[63] => field_item:entity_reference
[64] => field_item:float
[65] => field_item:integer
[66] => field_item:language
[67] => field_item:map
[68] => field_item:password
[69] => field_item:string
[70] => field_item:string_long
[71] => field_item:timestamp
[72] => field_item:uri
[73] => field_item:uuid
(字段api上节完)
作者语:
几个月没有更新,让关注本系列的读者久等了,这是因为云客在生活中被所谓的几件生活大事耽搁,期间每日推荐的表哥依然坚持在公众号每日推送drupal的点点滴滴,晴空依然坚持发布主题教程,这种坚持在坚持者之间是有鼓励作用的,长久以来形成一种默契,如同一路前行的同伴,而云客离开了一阵子,很是失落,能够专注于行不被打扰是件多么幸福的事情,现在回来了,咱们继续,坚持学习drupal的朋友们一道坚持,在生活中平平安安,笃信好学,不被打扰,感受数字世界的魅力,享受drupal这个小桃源带来的幸福。
反馈互动