Installation
composer require ardenexal/fhir-models
Ensure your project uses PHP 8.0+ (check composer.json constraints).
First Use Case: Parsing FHIR JSON
use Ardenexal\Fhir\Models\FhirResource;
$json = file_get_contents('patient-example.json');
$resource = FhirResource::fromJson($json);
// Access fields (e.g., Patient resource)
$name = $resource->getName()[0]->getFamily();
Key Classes to Know
FhirResource: Base class for all FHIR resources (e.g., Patient, Observation).FhirBundle: For handling FHIR Bundles (collections of resources).FhirFactory: Static helper for creating resources from JSON/XML.Where to Look First
src/Models/ for resource-specific classes (e.g., Patient.php).tests/ folder for usage examples (if available).Read-Only Parsing The package is designed for read-only operations. Validate input JSON/XML before parsing:
$json = '{"resourceType": "Patient", "id": "example"}';
$resource = FhirResource::fromJson($json);
if (!$resource->isValid()) {
throw new \InvalidArgumentException("Invalid FHIR resource: " . $resource->getErrors());
}
Type-Safe Access
Use getter methods (e.g., getId(), getName()) instead of direct property access. For nested fields:
$telecom = $resource->getTelecom()[0];
$phone = $telecom->getValue(); // Returns "tel:+1-555-555-5555"
Bundle Processing Parse a FHIR Bundle (e.g., from a search response):
$bundle = FhirBundle::fromJson($bundleJson);
foreach ($bundle->getEntry() as $entry) {
$resource = $entry->getResource();
if ($resource instanceof \Ardenexal\Fhir\Models\Patient) {
// Process Patient
}
}
Filtering Resources
Use instanceof checks to filter resources by type:
$patients = array_filter($bundle->getEntry(), fn($entry) =>
$entry->getResource() instanceof \Ardenexal\Fhir\Models\Patient
);
Service Container Binding Bind the factory for dependency injection:
// config/app.php
'bindings' => [
\Ardenexal\Fhir\Models\FhirFactory::class => fn() => new \Ardenexal\Fhir\Models\FhirFactory(),
],
Request Parsing (API Endpoints) Parse FHIR payloads in Laravel controllers:
use Illuminate\Http\Request;
public function store(Request $request) {
$resource = FhirResource::fromJson($request->getContent());
// Process or store $resource
}
Database Storage (Read-Only Limitation) Since the package is read-only, pair it with a database library (e.g., Eloquent) to persist data:
$patientData = $resource->toArray(); // Convert to array for storage
Patient::create($patientData);
Custom Resource Handling
Extend FhirResource for domain-specific logic:
class CustomPatient extends \Ardenexal\Fhir\Models\Patient {
public function isActive() {
return $this->getActive() === true;
}
}
Validation Rules Use Laravel’s validation to pre-check FHIR payloads:
$validated = $request->validate([
'resource' => 'required|json',
]);
$resource = FhirResource::fromJson($validated['resource']);
Read-Only Constraint
$resource->id = 'new-id') will fail silently or throw errors.toArray() to modify data, then recreate the resource or store in a database.No FHIR Version Flexibility
php-fhir-tools repo). Parsing older versions (e.g., DSTU2) may fail.Nested Resource Handling
Composition.section.entry) require chained getters. Typos in property names (e.g., getSection() vs. getSections()) will return null.dd(get_object_vars($resource));
Performance with Large Bundles
$bundle = FhirBundle::fromJson($json, true); // Stream parsing (if supported)
Validate JSON First Use a tool like FHIR Validator to catch malformed input before parsing.
Check Resource Type Always verify the resource type before casting:
if (!$resource instanceof \Ardenexal\Fhir\Models\Patient) {
throw new \RuntimeException("Expected Patient resource");
}
Enable Strict Typing
Add this to composer.json to catch type issues early:
"config": {
"platform": {
"php": "8.0"
}
}
Custom Serialization
Override toArray() or toJson() in a child class for custom output:
class ApiPatient extends \Ardenexal\Fhir\Models\Patient {
public function toApiArray() {
return [
'id' => $this->getId(),
'name' => $this->getName()[0]->getFamily(),
];
}
}
Event Listeners Trigger events when parsing resources (e.g., log invalid fields):
$resource = FhirResource::fromJson($json);
if (!$resource->isValid()) {
event(new \App\Events\FhirValidationFailed($resource->getErrors()));
}
Caching Parsed Resources Cache parsed resources to avoid reprocessing identical JSON:
$cacheKey = md5($json);
$resource = cache()->remember($cacheKey, now()->addHours(1), fn() =>
FhirResource::fromJson($json)
);
No Built-in Config The package has no configuration file. All behavior is hardcoded (e.g., FHIR version, validation rules).
Namespace Conflicts
The package uses Ardenexal\Fhir\Models. Ensure your project doesn’t have naming conflicts (e.g., a Models namespace in your app).
How can I help you explore Laravel packages today?