paragonie/typed-arrays

Strictly typed scalar arrays for PHP 8.3 and newer

dev-main 2024-05-14 21:24 UTC

This package is auto-updated.

Last update: 2024-11-14 22:33:48 UTC


README

Build Status Latest Stable Version Latest Unstable Version License Downloads

Requires PHP 8.3. This is best described through example:

<?php
require_once 'vendor/autoload.php';

class Foo
{
    public function __construct(
        public readonly string⟦⟧ $foo,
        public readonly int⟦⟧ $bar
    ) {}
}

$x = new Foo(
    string⟦⟧('apple', 'bee'),
    int⟦⟧(4, 5, 120000),
);
var_dump($x->foo, $x->bar);
var_dump($x->foo[1]);

This should output the following:

object(string⟦⟧)#5 (2) {
  [0]=>
  string(5) "apple"
  [1]=>
  string(3) "bee"
}
object(int⟦⟧)#6 (3) {
  [0]=>
  int(4)
  [1]=>
  int(5)
  [2]=>
  int(120000)
}
string(3) "bee"

If you try to pass an incorrect type, you'll get a TypeError:

<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

class Foo
{
    public function __construct(
        public readonly string⟦⟧ $foo
    ) {}
}

$x = new Foo(
    string⟦⟧('apple', 'bee', 25)
);
var_dump($x->foo, $x->bar);

Should produce:

Fatal error: Uncaught TypeError: string⟦⟧(): Argument #3 must be of type string, int given

What Is This Package Doing?

We are using Unicode characters ( and ) to create a class that implements ArrayAccess. All arguments to these types are then strictly typed.

In effect, we have turned a class into a typed array that your IDE will not complain about.

Does It Support Multi-Level Types? e.g. string⟦⟧⟦⟧

You betcha.

<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

class Bar
{
    public function __construct(
        public readonly string⟦⟧⟦⟧ $double,
    ) {}
}

$test = new Bar(string⟦⟧⟦⟧(
    string⟦⟧('test'),
    string⟦⟧('example'),
));
var_dump($test->double);

This will produce:

object(string⟦⟧⟦⟧)#7 (2) {
  [0]=>
  object(string⟦⟧)#5 (1) {
    [0]=>
    string(4) "test"
  }
  [1]=>
  object(string⟦⟧)#6 (1) {
    [0]=>
    string(7) "example"
  }
}

Does This Support Arrays of Classes?

Of course!

<?php
declare(strict_types=1);
require_once 'vendor/autoload.php';

class Foo {}

class Bar
{
    public function __construct(
        public readonly Foo⟦⟧ $example
    ) {}
}

$test = new Bar(new Foo⟦⟧(new Foo));
var_dump($test);

Output:

object(Bar)#2 (1) {
  ["example"]=>
  object(Foo⟦⟧)#5 (1) {
    [0]=>
    object(Foo)#6 (0) {
    }
  }
}

How Does This Create Types for My Classes?

See: the autoloader.