PHP examples

Simple model

A simple model with some scalar properties.
{
  "definitions": {
    "Student": {
      "description": "A simple student struct",
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      }
    }
  },
  "root": "Student"
}

Student.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;

use PSX\Schema\Attribute\Description;

#[Description('A simple student struct')]
class Student implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    protected ?int $age = null;
    public function setFirstName(?string $firstName) : void
    {
        $this->firstName = $firstName;
    }
    public function getFirstName() : ?string
    {
        return $this->firstName;
    }
    public function setLastName(?string $lastName) : void
    {
        $this->lastName = $lastName;
    }
    public function getLastName() : ?string
    {
        return $this->lastName;
    }
    public function setAge(?int $age) : void
    {
        $this->age = $age;
    }
    public function getAge() : ?int
    {
        return $this->age;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('firstName', $this->firstName);
        $record->put('lastName', $this->lastName);
        $record->put('age', $this->age);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}


Model with inheritance

A student struct which extends from a different struct.
{
  "definitions": {
    "Human": {
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      }
    },
    "Student": {
      "parent": {
        "type": "reference",
        "target": "Human"
      },
      "type": "struct",
      "properties": {
        "studentId": {
          "type": "string"
        }
      }
    }
  },
  "root": "Student"
}

Human.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Human implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    protected ?int $age = null;
    public function setFirstName(?string $firstName) : void
    {
        $this->firstName = $firstName;
    }
    public function getFirstName() : ?string
    {
        return $this->firstName;
    }
    public function setLastName(?string $lastName) : void
    {
        $this->lastName = $lastName;
    }
    public function getLastName() : ?string
    {
        return $this->lastName;
    }
    public function setAge(?int $age) : void
    {
        $this->age = $age;
    }
    public function getAge() : ?int
    {
        return $this->age;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('firstName', $this->firstName);
        $record->put('lastName', $this->lastName);
        $record->put('age', $this->age);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

Student.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Student extends Human implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $studentId = null;
    public function setStudentId(?string $studentId) : void
    {
        $this->studentId = $studentId;
    }
    public function getStudentId() : ?string
    {
        return $this->studentId;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = parent::toRecord();
        $record->put('studentId', $this->studentId);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}


Model with reference

A student struct which reference a faculty struct.
{
  "definitions": {
    "Student": {
      "description": "A student struct with an assigned faculty",
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        },
        "faculty": {
          "type": "reference",
          "target": "Faculty"
        }
      }
    },
    "Faculty": {
      "type": "struct",
      "properties": {
        "name": {
          "type": "string"
        }
      }
    }
  },
  "root": "Student"
}

Student.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;

use PSX\Schema\Attribute\Description;

#[Description('A student struct with an assigned faculty')]
class Student implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    protected ?int $age = null;
    protected ?Faculty $faculty = null;
    public function setFirstName(?string $firstName) : void
    {
        $this->firstName = $firstName;
    }
    public function getFirstName() : ?string
    {
        return $this->firstName;
    }
    public function setLastName(?string $lastName) : void
    {
        $this->lastName = $lastName;
    }
    public function getLastName() : ?string
    {
        return $this->lastName;
    }
    public function setAge(?int $age) : void
    {
        $this->age = $age;
    }
    public function getAge() : ?int
    {
        return $this->age;
    }
    public function setFaculty(?Faculty $faculty) : void
    {
        $this->faculty = $faculty;
    }
    public function getFaculty() : ?Faculty
    {
        return $this->faculty;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('firstName', $this->firstName);
        $record->put('lastName', $this->lastName);
        $record->put('age', $this->age);
        $record->put('faculty', $this->faculty);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

Faculty.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Faculty implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $name = null;
    public function setName(?string $name) : void
    {
        $this->name = $name;
    }
    public function getName() : ?string
    {
        return $this->name;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('name', $this->name);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}


Map with string values

A student struct which contains a map with arbitrary string values.
{
  "definitions": {
    "Student": {
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        },
        "properties": {
          "type": "map",
          "schema": {
            "type": "string"
          }
        }
      }
    }
  },
  "root": "Student"
}

Student.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Student implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    protected ?int $age = null;
    /**
     * @var \PSX\Record\Record<string>|null
     */
    protected ?\PSX\Record\Record $properties = null;
    public function setFirstName(?string $firstName) : void
    {
        $this->firstName = $firstName;
    }
    public function getFirstName() : ?string
    {
        return $this->firstName;
    }
    public function setLastName(?string $lastName) : void
    {
        $this->lastName = $lastName;
    }
    public function getLastName() : ?string
    {
        return $this->lastName;
    }
    public function setAge(?int $age) : void
    {
        $this->age = $age;
    }
    public function getAge() : ?int
    {
        return $this->age;
    }
    /**
     * @param \PSX\Record\Record<string>|null $properties
     */
    public function setProperties(?\PSX\Record\Record $properties) : void
    {
        $this->properties = $properties;
    }
    /**
     * @return \PSX\Record\Record<string>|null
     */
    public function getProperties() : ?\PSX\Record\Record
    {
        return $this->properties;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('firstName', $this->firstName);
        $record->put('lastName', $this->lastName);
        $record->put('age', $this->age);
        $record->put('properties', $this->properties);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}


Model with discriminator

A struct which uses a discriminator mapping.
{
  "definitions": {
    "Human": {
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "location": {
          "type": "reference",
          "target": "Location"
        }
      }
    },
    "Location": {
      "type": "struct",
      "base": true,
      "properties": {
        "type": {
          "type": "string"
        }
      },
      "discriminator": "type",
      "mapping": {
        "Web": "web",
        "World": "world"
      }
    },
    "Web": {
      "parent": {
        "type": "reference",
        "target": "Location"
      },
      "type": "struct",
      "properties": {
        "url": {
          "type": "string"
        }
      }
    },
    "World": {
      "parent": {
        "type": "reference",
        "target": "Location"
      },
      "type": "struct",
      "properties": {
        "lat": {
          "type": "string"
        },
        "long": {
          "type": "string"
        }
      }
    }
  },
  "root": "Human"
}

Human.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Human implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $firstName = null;
    protected ?string $lastName = null;
    protected ?Location $location = null;
    public function setFirstName(?string $firstName) : void
    {
        $this->firstName = $firstName;
    }
    public function getFirstName() : ?string
    {
        return $this->firstName;
    }
    public function setLastName(?string $lastName) : void
    {
        $this->lastName = $lastName;
    }
    public function getLastName() : ?string
    {
        return $this->lastName;
    }
    public function setLocation(?Location $location) : void
    {
        $this->location = $location;
    }
    public function getLocation() : ?Location
    {
        return $this->location;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('firstName', $this->firstName);
        $record->put('lastName', $this->lastName);
        $record->put('location', $this->location);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

Location.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;

use PSX\Schema\Attribute\DerivedType;
use PSX\Schema\Attribute\Discriminator;

#[Discriminator('type')]
#[DerivedType('Web', 'web')]
#[DerivedType('World', 'world')]
abstract class Location implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $type = null;
    public function setType(?string $type) : void
    {
        $this->type = $type;
    }
    public function getType() : ?string
    {
        return $this->type;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('type', $this->type);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

Web.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Web extends Location implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $url = null;
    public function setUrl(?string $url) : void
    {
        $this->url = $url;
    }
    public function getUrl() : ?string
    {
        return $this->url;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = parent::toRecord();
        $record->put('url', $this->url);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

World.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class World extends Location implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $lat = null;
    protected ?string $long = null;
    public function setLat(?string $lat) : void
    {
        $this->lat = $lat;
    }
    public function getLat() : ?string
    {
        return $this->lat;
    }
    public function setLong(?string $long) : void
    {
        $this->long = $long;
    }
    public function getLong() : ?string
    {
        return $this->long;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = parent::toRecord();
        $record->put('lat', $this->lat);
        $record->put('long', $this->long);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}


Model with generics

A struct which uses generics.
{
  "definitions": {
    "Student": {
      "type": "object",
      "properties": {
        "matricleNumber": {
          "type": "integer"
        }
      }
    },
    "StudentMap": {
      "type": "struct",
      "parent": {
        "type": "reference",
        "target": "Map",
        "template": {
          "T": "Student"
        }
      }
    },
    "Map": {
      "type": "object",
      "properties": {
        "totalResults": {
          "type": "integer"
        },
        "entries": {
          "type": "array",
          "schema": {
            "type": "generic",
            "name": "T"
          }
        }
      }
    }
  },
  "root": "StudentMap"
}

Student.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Student implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?int $matricleNumber = null;
    public function setMatricleNumber(?int $matricleNumber) : void
    {
        $this->matricleNumber = $matricleNumber;
    }
    public function getMatricleNumber() : ?int
    {
        return $this->matricleNumber;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('matricleNumber', $this->matricleNumber);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

Map.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;

/**
 * @template T
 */
class Map implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?int $totalResults = null;
    /**
     * @var array<T>|null
     */
    protected ?array $entries = null;
    public function setTotalResults(?int $totalResults) : void
    {
        $this->totalResults = $totalResults;
    }
    public function getTotalResults() : ?int
    {
        return $this->totalResults;
    }
    /**
     * @param array<T>|null $entries
     */
    public function setEntries(?array $entries) : void
    {
        $this->entries = $entries;
    }
    /**
     * @return array<T>|null
     */
    public function getEntries() : ?array
    {
        return $this->entries;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('totalResults', $this->totalResults);
        $record->put('entries', $this->entries);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}

StudentMap.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;

/**
 * @extends Map<Student>
 */
class StudentMap extends Map implements \JsonSerializable, \PSX\Record\RecordableInterface
{
}


Import other TypeSchema specification

A struct which references an external TypeSchema.
{
  "import": {
    "my_ns": "file:///generic.json"
  },
  "definitions": {
    "Faculty": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        },
        "students": {
          "type": "array",
          "schema": {
            "type": "reference",
            "target": "my_ns:StudentMap"
          }
        }
      }
    }
  },
  "root": "Faculty"
}

Faculty.php

<?php

declare(strict_types = 1);

namespace TypeSchema\DTO;


class Faculty implements \JsonSerializable, \PSX\Record\RecordableInterface
{
    protected ?string $description = null;
    /**
     * @var array<StudentMap>|null
     */
    protected ?array $students = null;
    public function setDescription(?string $description) : void
    {
        $this->description = $description;
    }
    public function getDescription() : ?string
    {
        return $this->description;
    }
    /**
     * @param array<StudentMap>|null $students
     */
    public function setStudents(?array $students) : void
    {
        $this->students = $students;
    }
    /**
     * @return array<StudentMap>|null
     */
    public function getStudents() : ?array
    {
        return $this->students;
    }
    public function toRecord() : \PSX\Record\RecordInterface
    {
        /** @var \PSX\Record\Record<mixed> $record */
        $record = new \PSX\Record\Record();
        $record->put('description', $this->description);
        $record->put('students', $this->students);
        return $record;
    }
    public function jsonSerialize() : object
    {
        return (object) $this->toRecord()->getAll();
    }
}


Edit this page