Skip to content

FHIR DataTypes

Ivan William edited this page Aug 29, 2026 · 1 revision

FHIR DataType Reference

All 32 DataType classes in src/DataType/. Every DataType extends the abstract DataType class which provides a recursive toArray() method — nested DataType objects serialize to clean FHIR JSON automatically.


Base Class

namespace Satusehat\Integration\DataType;

abstract class DataType
{
    public function toArray(): array;
    protected function toArrayRecursive($value);
    protected function bool(?bool $val): ?bool;
    protected function str(?string $val): ?string;
    protected function int(?int $val): ?int;
    protected function float(?float $val): ?float;
    protected function dt(?string $val): ?string;
}

All subtypes override toArray() to handle their specific nested DataTypes. build() on every PayloadBuilder calls toArray() recursively.


Core Types

Identifier

Unique identifier with a system namespace.

use Satusehat\Integration\DataType\Identifier;
use Satusehat\Integration\DataType\Period;

$identifier = new Identifier(
    system: 'https://fhir.kemkes.go.id/id/NIK',
    value: '3312345678901234',
    use: 'official',
    type: null,
    period: new Period(start: '2020-01-01', end: null),
);

// toArray():
// [
//     'system' => 'https://fhir.kemkes.go.id/id/NIK',
//     'value'  => '3312345678901234',
//     'use'    => 'official',
//     'period' => ['start' => '2020-01-01']
// ]
Property Type Description
use ?string usual, official, temp, nickname, anonymous, old, maiden
type ?CodeableConcept Type of identifier
system ?string Namespace URI (e.g. https://fhir.kemkes.go.id/id/NIK)
value ?string The actual identifier value
period ?Period Time period the identifier is valid
assigner ?Reference Organization that assigned the identifier

HumanName

A human name with family, given, prefix, and suffix.

use Satusehat\Integration\DataType\HumanName;
use Satusehat\Integration\DataType\Period;

$name = new HumanName(
    family: 'Doe',
    given: ['John', 'Michael'],
    use: 'official',
    prefix: ['Dr.'],
    suffix: ['PhD'],
    text: null,
    period: new Period(start: '2020-01-01'),
);

// toArray():
// [
//     'family'  => 'Doe',
//     'given'   => ['John', 'Michael'],
//     'use'     => 'official',
//     'prefix'  => ['Dr.'],
//     'suffix'  => ['PhD'],
//     'period'  => ['start' => '2020-01-01']
// ]
Property Type Description
use ?string usual, official, temp, nickname, anonymous, old, maiden
text ?string Text representation of the full name
family ?string Family name (surname)
given array Given names (first, middle)
prefix array Prefix (e.g. Dr., Mr.)
suffix array Suffix (e.g. PhD, Jr.)
period ?Period Time period the name is valid

Address

A physical address.

use Satusehat\Integration\DataType\Address;

$address = new Address(
    use: 'home',
    type: 'physical',
    text: null,
    line: ['Jl. Sudirman No.1', 'Lt. 5'],
    city: 'Jakarta Selatan',
    district: 'Kebayoran Baru',
    state: 'DKI Jakarta',
    postalCode: '12190',
    country: 'ID',
);

// toArray():
// [
//     'use'         => 'home',
//     'type'        => 'physical',
//     'line'        => ['Jl. Sudirman No.1', 'Lt. 5'],
//     'city'        => 'Jakarta Selatan',
//     'district'    => 'Kebayoran Baru',
//     'state'       => 'DKI Jakarta',
//     'postalCode'  => '12190',
//     'country'     => 'ID'
// ]
Property Type Description
use ?string home, work, temp, old, billing
type ?string postal, physical, both
text ?string Text representation
line array Street address lines
city ?string City/municipality
district ?string District (kecamatan)
state ?string State/province
postalCode ?string Postal code
country ?string Country (ISO 3166-1 alpha-2)

ContactPoint

Phone, fax, email, or other contact.

use Satusehat\Integration\DataType\ContactPoint;

$phone = new ContactPoint(
    system: 'phone',
    value: '081234567890',
    use: 'mobile',
    rank: 1,
);

// toArray():
// [
//     'system' => 'phone',
//     'value'  => '081234567890',
//     'use'    => 'mobile',
//     'rank'   => 1
// ]
Property Type Description
system ?string phone, fax, email, pager, url, sms, other
value ?string The actual value
use ?string home, work, temp, old, billing
rank ?int Preferred contact (1 = highest)

Reference

A reference to another FHIR resource.

use Satusehat\Integration\DataType\Reference;

$ref = new Reference(
    reference: 'Patient/12345678-1234-1234-1234-123456789012',
    display: 'John Doe',
    type: 'Patient',
);

// toArray():
// [
//     'reference' => 'Patient/12345678-1234-1234-1234-123456789012',
//     'display'  => 'John Doe',
//     'type'     => 'Patient'
// ]
Property Type Description
reference ?string The reference string (e.g. Patient/123)
display ?string Human-readable label
type ?string Resource type (e.g. Patient)

Period

A time range with start and end.

use Satusehat\Integration\DataType\Period;

$period = new Period(
    start: '2024-01-01',
    end: '2024-12-31',
);

// toArray():
// ['start' => '2024-01-01', 'end' => '2024-12-31']
Property Type Description
start ?string Start date/time (ISO 8601)
end ?string End date/time (ISO 8601)

Coding

A single code from a terminology system.

use Satusehat\Integration\DataType\Coding;

$gender = new Coding(
    system: 'http://hl7.org/fhir/administrative-gender',
    code: 'male',
    display: 'Male',
    version: '4.0.1',
);

// toArray():
// [
//     'system'  => 'http://hl7.org/fhir/administrative-gender',
//     'code'    => 'male',
//     'display' => 'Male',
//     'version' => '4.0.1'
// ]
Property Type Description
system ?string The terminology system URI
version ?string Version of the code system
code ?string The code value
display ?string Human-readable display text

CodeableConcept

A concept that may be defined by multiple Codings, with optional text.

use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;

$concept = new CodeableConcept(
    coding: [
        new Coding(
            system: 'http://terminology.hl7.org/CodeSystem/condition-clinical',
            code: 'active',
            display: 'Active'
        )
    ],
    text: 'Active Condition'
);

// toArray():
// [
//     'coding' => [
//         ['system' => '...', 'code' => 'active', 'display' => 'Active']
//     ],
//     'text'   => 'Active Condition'
// ]
Property Type Description
coding Coding[] Array of Coding objects
text ?string Plain text representation

Narrative

Human-readable text, typically XHTML.

use Satusehat\Integration\DataType\Narrative;

$narrative = new Narrative(
    status: 'generated',
    div: '<div xmlns="http://www.w3.org/1999/xhtml">Patient John Doe</div>',
);

// toArray():
// [
//     'status' => 'generated',
//     'div'    => '<div xmlns="http://www.w3.org/1999/xhtml">...</div>'
// ]

Attachment

Content attachment — data, URL, or reference.

use Satusehat\Integration\DataType\Attachment;

$attachment = new Attachment(
    contentType: 'application/pdf',
    language: 'id-ID',
    data: base64_encode('PDF content here'),
    url: null,
    size: null,
    hash: null,
    title: 'Medical Report',
    creation: '2024-01-15',
);

Quantity Types

Quantity

A measured or measurable amount.

use Satusehat\Integration\DataType\Quantity;

$q = new Quantity(
    value: 72,
    comparator: null,
    unit: 'beats/minute',
    system: 'http://unitsofmeasure.org',
    code: '/min',
);
Property Type Description
value ?float Numeric value
comparator ?string <, <=, >=, >
unit ?string Human-readable unit
system ?string UCUM system URI
code ?string UCUM unit code

SimpleQuantity

Quantity constrained to a single value/unit (no comparator).

use Satusehat\Integration\DataType\SimpleQuantity;

$sq = new SimpleQuantity(
    value: 500,
    unit: 'mg',
    system: 'http://unitsofmeasure.org',
    code: 'mg',
);

Range

A range of values (low to high).

use Satusehat\Integration\DataType\Range;
use Satusehat\Integration\DataType\Quantity;

$range = new Range(
    low: new Quantity(value: 60, unit: 'bpm', system: 'http://unitsofmeasure.org', code: '/min'),
    high: new Quantity(value: 100, unit: 'bpm', system: 'http://unitsofmeasure.org', code: '/min'),
    text: '60-100 bpm',
);

Ratio

A ratio of two quantities.

use Satusehat\Integration\DataType\Ratio;
use Satusehat\Integration\DataType\Quantity;

$ratio = new Ratio(
    numerator: new Quantity(value: 500, unit: 'mg', system: 'http://unitsofmeasure.org', code: 'mg'),
    denominator: new Quantity(value: 1, unit: 'tablet', system: null, code: null),
);

Age, Count, Distance, Duration

All extend Quantity with domain-specific semantics:

use Satusehat\Integration\DataType\Age;

$age = new Age(value: 35, unit: 'years', system: 'http://unitsofmeasure.org', code: 'a');

use Satusehat\Integration\DataType\Distance;
$distance = new Distance(value: 10, unit: 'kilometers', system: 'http://unitsofmeasure.org', code: 'km');

use Satusehat\Integration\DataType\Duration;
$duration = new Duration(value: 7, unit: 'days', system: 'http://unitsofmeasure.org', code: 'd');

use Satusehat\Integration\DataType\Count;
$count = new Count(value: 3, unit: 'tablets', system: null, code: null);

use Satusehat\Integration\DataType\Money;
$money = new Money(value: 15000.00, currency: 'IDR');

Structured Types

Timing

Event scheduling with repeat pattern.

use Satusehat\Integration\DataType\Timing;
use Satusehat\Integration\DataType\TimingRepeat;

$timing = new Timing(
    event: ['2024-01-15T09:00:00+07:00'],
    repeat: new TimingRepeat(
        frequency: 3,
        period: 1,
        periodUnit: 'd',
        timeOfDay: ['09:00:00', '13:00:00', '18:00:00'],
        dayOfWeek: ['mon', 'tue', 'wed', 'thu', 'fri'],
    ),
    code: new CodeableConcept(coding: [new Coding(
        system: 'http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation',
        code: 'BID',
        display: 'BID'
    )]),
);

TimingRepeat

Repeat pattern for Timing events.

use Satusehat\Integration\DataType\TimingRepeat;

$repeat = new TimingRepeat(
    frequency: 2,
    frequencyMax: 4,
    period: 1,
    periodUnit: 'd',        // s|min|h|d|wk|mo|a
    dayOfWeek: ['mon', 'wed', 'fri'],
    timeOfDay: ['08:00:00', '20:00:00'],
    when: ['CM', 'AC'],
    offset: 0,
);

Dosage

Medication dosage instruction.

use Satusehat\Integration\DataType\Dosage;
use Satusehat\Integration\DataType\DosageDoseAndRate;
use Satusehat\Integration\DataType\Quantity;
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;

$dosage = new Dosage(
    sequence: 1,
    text: 'Amoxicillin 500mg — 3x1 sehari setelah makan',
    timing: null,
    route: new CodeableConcept(coding: [new Coding(
        system: 'http://www.whocc.no/atc',
        code: 'ORAL',
        display: 'Oral'
    )]),
    doseAndRate: [
        new DosageDoseAndRate(
            doseQuantity: new Quantity(
                value: 500,
                unit: 'mg',
                system: 'http://unitsofmeasure.org',
                code: 'mg'
            )
        )
    ],
);

DosageDoseAndRate

Dose quantity and optional rate.

use Satusehat\Integration\DataType\DosageDoseAndRate;
use Satusehat\Integration\DataType\Quantity;
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;

$doseRate = new DosageDoseAndRate(
    type: new CodeableConcept(coding: [new Coding(
        system: 'http://terminology.hl7.org/CodeSystem/dose-rate-type',
        code: 'ordered',
        display: 'Ordered'
    )]),
    doseQuantity: new Quantity(value: 500, unit: 'mg', system: 'http://unitsofmeasure.org', code: 'mg'),
);

Annotation

A text note with optional author and time.

use Satusehat\Integration\DataType\Annotation;
use Satusehat\Integration\DataType\Reference;

$note = new Annotation(
    authorReference: new Reference(reference: 'Practitioner/10009880728', display: 'Dr. Smith'),
    time: '2024-01-15T10:30:00+07:00',
    text: 'Pasien mengeluh pusing sejak 3 hari terakhir',
);

Extension

FHIR extension wrapper for extra data not covered by the base spec.

use Satusehat\Integration\DataType\Extension;
use Satusehat\Integration\DataType\CodeableConcept;
use Satusehat\Integration\DataType\Coding;

$ext = new Extension(
    url: 'http://hl7.org/fhir/StructureDefinition/condition-assertedDate',
    valueCodeableConcept: new CodeableConcept(coding: [new Coding(
        system: 'http://hl7.org/fhir/valueset-condition-ver-status',
        code: 'confirmed',
        display: 'Confirmed'
    )]),
);

Utility Types

Signature

Digital signature.

use Satusehat\Integration\DataType\Signature;
use Satusehat\Integration\DataType\Coding;
use Satusehat\Integration\DataType\Reference;

$signature = new Signature(
    type: [new Coding(
        system: 'urn:iso-astm:E1762-2013',
        code: '1.2.840.10065.1.12',
        display: 'Author签名'
    )],
    when: '2024-01-15T12:00:00+07:00',
    whoReference: new Reference(reference: 'Practitioner/10009880728'),
    onBehalfOfReference: null,
);

RelatedArtifact

Related resources or citations.

use Satusehat\Integration\DataType\RelatedArtifact;
use Satusehat\Integration\DataType\Coding;

$citation = new RelatedArtifact(
    type: 'citation',
    label: 'Journal Article',
    display: 'Smith et al. 2024',
    citation: 'Smith J, et al. Effects of X on Y. JAMA 2024.',
    url: 'https://doi.org/10.1000/journal.2024',
    document: null,
);
Property Type Description
type ?string documentation, justification, citation, predecessor, successor, derived-from, depends-on, composed-of
label ?string Short label
display ?string Human-readable summary
citation ?string Citation text
url ?string URL reference
document ?Attachment Actual document

Expression

FHIRPath expression.

use Satusehat\Integration\DataType\Expression;

$expr = new Expression(
    description: 'Patient age calculation',
    language: 'text/fhirpath',
    expression: '%context.birthDate.value',
);

TriggerDefinition

Event trigger definition.

use Satusehat\Integration\DataType\TriggerDefinition;

$trigger = new TriggerDefinition(
    type: 'named-event',
    name: 'patient-create',
    timingTiming: null,
    timingReference: null,
    timingDate: null,
    timingDateTime: '2024-01-15T00:00:00+07:00',
    data: null,
    condition: null,
);

DataRequirement

Data requirements for a module definition.

use Satusehat\Integration\DataType\DataRequirement;
use Satusehat\Integration\DataType\Coding;

$req = new DataRequirement(
    type: 'Observation',
    profile: ['http://hl7.org/fhir/StructureDefinition/vitalsigns'],
    mustSupport: ['code', 'valueQuantity'],
    codeFilter: [
        (object)['path' => 'code', valueSet: 'http://loinc.org/vs/LH7VID'],
    ],
);

ParameterDefinition

Parameter definition for operation definitions.

use Satusehat\Integration\DataType\ParameterDefinition;

$param = new ParameterDefinition(
    name: 'patientId',
    use: 'in',
    min: 1,
    max: '1',
    documentation: 'The logical ID of the patient',
    type: 'string',
    searchType: null,
);

Nested DataType Serialization

DataTypes nest inside each other and toArray() handles the conversion:

$observation = (new PayloadBuilderObservation)
    ->setSubject(new Reference(
        reference: "Patient/{$patientId}",
        display: 'John Doe'
    ))
    ->setValueQuantity(new Quantity(
        value: 72,
        unit: 'beats/minute',
        system: 'http://unitsofmeasure.org',
        code: '/min'
    ))
    ->build();

// The Reference → {'reference': '...', 'display': '...'}
// The Quantity   → {'value': 72, 'unit': '...', ...}
// All nested automatically via toArray()

Clone this wiki locally