Type converters

Type converters are the classes that

  • Parse string representations of database types returned by Postgres into native PHP types;

  • Generate string representations from native PHP types that can be used as query parameters.

These classes are pretty low-level and it is generally not needed to manually instantiate them: this is handled by an implementation of TypeConverterFactory. In the “wrapper” part of the package, it is seldom needed to use them directly at all: calling input() and output() is handled by Result and Connection / PreparedStatement classes, respectively.

Type converter implementations

The below classes and interfaces, except builtin ones prefixed by a backslash, belong to either \sad_spirit\pg_wrapper\converters or \sad_spirit\pg_wrapper\types (classes representing complex types) namespace. Those are omitted for brevity.

StubConverter

This is the only implementation of TypeConverter that does not extend BaseConverter. As its name implies, it does not perform conversion and is returned by

  • methods of StubTypeConverterFactory,

  • DefaultTypeConverterFactory::getConverterForTypeOID() if a proper converter cannot be determined.

BaseConverter

Abstract base class for converters, handles null values and provides several helper methods for parsing.

BooleanConverter

Converts Postgres boolean values from / to PHP’s bool

ByteaConverter

Converts binary data for bytea fields from / to string representation using hex encoding.

EnumConverter

Converts values of Postgres ENUM type from / to cases of PHP’s string-backed enum. The converter instance is configured with name of enum:

$converter = new EnumConverter(SomeEnum::class);
datetime\IntervalConverter

Postgres interval type <-> \DateInterval

JSONConverter

JSON string <-> Any PHP value that can be serialized.

StringConverter

Postgres character types <-> PHP string. This does not perform any conversion in input(), casts PHP value to string in output().

BaseNumericConverter

Abstract base class for numeric converters, implements ConnectionAware to check server version and allow non-decimal literals and separators when output() targets Postgres 16+

NumericConverter

As numeric type of Postgres can have almost unlimited precision, input() keeps the value as string, only returning special “float” values for Infinity and NaN

FloatConverter

Postgres float types <-> PHP’s float

IntegerConverter

Postgres integer types <-> PHP’s int (the value may be left as string by input() on 32bit builds of PHP, as int8 values may overflow)

datetime\BaseDateTimeConverter

Abstract base class for date and time converters, implements ConnectionAware to check server’s DateStyle setting and select proper format specification. Its input() method and those of its subclasses return instances of \DateTimeImmutable.

  • datetime\DateConverter - converts date type

  • datetime\TimeConverter - converts time type

  • datetime\TimeTzConverter - converts timetz (time with time zone) type

  • datetime\TimeStampConverter - converts timestamp type

  • datetime\TimeStampTzConverter - converts timestamptz (timestamp with time zone) type

ContainerConverter

Abstract base class for converters of “container” types: those are composed of multiple values of some “base” type. Usually the converter for “container” type uses the converter for “base” type to parse / generate parts of the value.

containers\ArrayConverter

Postgres array <-> PHP array. The converter instance is configured by an instance of base type converter, e.g.

$dateArrayConverter = new ArrayConverter(new DateConverter());
// This will return an array of \DateTimeImmutable instances
$dateArrayConverter->input($value);
containers\CompositeConverter

Postgres composite (row) type <-> PHP array. The converter instance is configured by an array representing the composite type fields, thus for type defined like this

create type foo as (id integer, name text, added timestamp with time zone);

a converter may be created like this

$fooConverter = new CompositeConverter([
    'id'    => new IntegerConverter(),
    'name'  => new StringConverter(),
    'added' => new TimeStampTzConverter()
]);
containers\HstoreConverter

hstore type from contrib/hstore Postgres extension <-> array<string, ?string>. This type for storing key => value pairs was quite useful before JSON support was added to Postgres.

containers\IntegerVectorConverter

int2vector or oidvector <-> array<int|string>. These types are used only in system catalogs and are not documented.

geometric\LineConverter

line <-> instance of Line. This converter does not extend geometric\BaseGeometricConverter as the line type is represented by three float coefficients of linear equation and does not depend on point type.

containers\MultiRangeConverter

Multirange type (Postgres 14+) <-> instance of MultiRange. The converter instance is configured by an instance of range subtype converter and possibly a classname of custom MultiRange subclass:

$intMultiRangeConverter    = new MultiRangeConverter(new IntegerConverter());
$customMultiRangeConverter = new MultiRangeConverter(new CustomConverter(), CustomMultiRange::class);
geometric\PointConverter

Postgres point type <-> instance of Point.

containers\RangeConverter

Range type <-> instance of Range. The converter instance is configured by an instance of range subtype converter and possibly a classname of custom Range subclass:

$dateRangeConverter   = new RangeConverter(new DateConverter());
$customRangeConverter = new RangeConverter(new CustomConverter(), CustomRange::class);
TidConverter

Postgres tid type (represents physical location of a row within a table) <-> instance of Tid.

geometric\BaseGeometricConverter

Abstract base class for converters of geometric types. All the types converted by subclasses of this are based on the point type and use PointConverter to process their own string representations.

geometric\BoxConverter

Postgres box type <-> instance of Box

geometric\CircleConverter

Postgres circle type <-> instance of Circle

geometric\LSegConverter

Postgres lseg type <-> instance of LineSegment

geometric\PathConverter

Postgres path type <-> instance of Path

geometric\PolygonConverter

Postgres polygon type <-> instance of Polygon

Creating custom converters

A custom converter is only needed for a new base type, as values of the derived types can be converted by configuring the existing ones as described above.

The best course of action will be to extend either BaseConverter or ContainerConverter based on the properties of the type.

BaseConverter

This base class implements input() and output() methods that handle null values as pgsql extension itself converts NULL fields of any type to PHP null values.

It delegates handling of non-null values to the two new abstract methods

inputNotNull(string $native): mixed

Converts a string received from PostgreSQL to PHP variable of the proper type.

outputNotNull(mixed $value): string

Returns a string representation of PHP variable not identical to null.

ContainerConverter

This class defines helper methods for parsing complex string representations. Those accept the string received from the database and position of the current symbol that is updated once parts of the string is processed.

nextChar(string $str, int &$p): ?string

Gets next non-whitespace character from input, position is updated. Returns null if input ended.

expectChar(string $string, int &$pos, string $char): void

Throws a TypeConversionException if next non-whitespace character in input is not the given char, moves to the next symbol otherwise.

inputNotNull() is implemented in ContainerConverter, a new abstract method is defined instead

parseInput(string $native, int &$pos): mixed

Parses a string representation into PHP variable from given position. This may be called from any position in the string and should return once it finishes parsing the value.