1. Go to this page and download the library: Download eboreum/caster library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
declare(strict_types=1);
use Eboreum\Caster\Caster;
/**
* @throws InvalidArgumentException
*/
function foo(mixed $value): void
{
if (false === is_string($value) && false === is_int($value)) {
throw new InvalidArgumentException(sprintf(
'Expects argument $value to be a string or an integer. Found: %s',
Caster::create()->castTyped($value),
));
}
}
try {
foo(['bar']);
} catch (InvalidArgumentException $e) {
echo $e->getMessage();
}
Expects argument $value to be a string or an integer. Found: (array(1)) [(int) 0 => (string(3)) "bar"]
declare(strict_types=1);
namespace My\Application;
use Eboreum\Caster\Abstraction\Formatter\AbstractArrayFormatter;
use Eboreum\Caster\Caster as EboreumCaster;
use Eboreum\Caster\CharacterEncoding;
use Eboreum\Caster\Collection\Formatter\ArrayFormatterCollection;
use Eboreum\Caster\Contract\CasterInterface;
use function assert;
use function dirname;
use function json_encode;
use function sprintf;
class Caster extends EboreumCaster
{
private static ?Caster $instance = null;
public static function getInstance(): self
{
if (null === self::$instance) {
self::$instance = new self(CharacterEncoding::getInstance());
$instance = self::$instance->withCustomArrayFormatterCollection(new ArrayFormatterCollection([
new class extends AbstractArrayFormatter
{
public function format(CasterInterface $caster, array $array): ?string
{
return 'I am an array!';
}
public function isHandling(array $array): bool
{
return true;
}
},
]));
assert($instance instanceof Caster);
self::$instance = $instance;
// Do more custom configuring before the instance is forever locked and returned
}
return self::$instance;
}
}
echo sprintf(
'Instances \\%s::getInstance() !== \\%s::getInstance(): %s',
EboreumCaster::class,
Caster::class,
json_encode(EboreumCaster::getInstance() !== Caster::getInstance()),
) . "\n";
echo sprintf(
'But \\%s::getInstance() === \\%s::getInstance() (same): %s',
Caster::class,
Caster::class,
json_encode(Caster::getInstance() === Caster::getInstance()),
) . "\n";
declare(strict_types=1);
use Eboreum\Caster\Abstraction\Formatter\AbstractArrayFormatter;
use Eboreum\Caster\Caster;
use Eboreum\Caster\Collection\Formatter\ArrayFormatterCollection;
use Eboreum\Caster\Contract\CasterInterface;
$caster = Caster::create();
$caster = $caster->withCustomArrayFormatterCollection(new ArrayFormatterCollection([
new class extends AbstractArrayFormatter
{
public function format(CasterInterface $caster, array $array): ?string
{
if (false === $this->isHandling($array)) {
return null; // Pass on to next formatter or lastly DefaultArrayFormatter
}
if (1 === count($array)) {
/*
* /!\ CAUTION /!\
* Do NOT do this in practice! You disable sensitive string masking.
*/
return print_r($array, true);
}
if (2 === count($array)) {
return 'I am an array!';
}
if (3 === count($array)) {
$array[0] = 'SURPRISE!';
// Override and use DefaultArrayFormatter for rendering output
return $caster->getDefaultArrayFormatter()->format($caster, $array);
}
return null; // Pass on to next formatter or lastly DefaultArrayFormatter
}
public function isHandling(array $array): bool
{
return true;
}
},
]));
echo $caster->cast(['foo']) . "\n";
echo $caster->cast(['foo', 'bar']) . "\n";
echo $caster->cast(['foo', 'bar', 'baz']) . "\n";
echo $caster->cast(['foo', 'bar', 'baz', 'bim']) . "\n";
echo $caster->castTyped(['foo', 'bar', 'baz', 'bim']) . "\n";
Array
(
[0] => foo
)
I am an array!
[0 => "SURPRISE!", 1 => "bar", 2 => "baz"]
[0 => "foo", 1 => "bar", 2 => "baz", ... and 1 more element] (sample)
(array(4)) [(int) 0 => (string(3)) "foo", (int) 1 => (string(3)) "bar", (int) 2 => (string(3)) "baz", ... and 1 more element] (sample)
declare(strict_types=1);
use Eboreum\Caster\Abstraction\Formatter\AbstractObjectFormatter;
use Eboreum\Caster\Caster;
use Eboreum\Caster\Collection\Formatter\ObjectFormatterCollection;
use Eboreum\Caster\Contract\CasterInterface;
$caster = Caster::create();
$caster = $caster->withCustomObjectFormatterCollection(new ObjectFormatterCollection([
new class extends AbstractObjectFormatter
{
public function format(CasterInterface $caster, object $object): ?string
{
if (false === $this->isHandling($object)) {
return null; // Pass on to next formatter or lastly DefaultObjectFormatter
}
assert($object instanceof DateTimeInterface);
return sprintf(
'%s (%s)',
Caster::makeNormalizedClassName(new ReflectionObject($object)),
$object->format('c'),
);
}
public function isHandling(object $object): bool
{
return ($object instanceof DateTimeInterface);
}
},
new class extends AbstractObjectFormatter
{
public function format(CasterInterface $caster, object $object): ?string
{
if (false === $this->isHandling($object)) {
return null; // Pass on to next formatter or lastly DefaultObjectFormatter
}
assert($object instanceof Throwable);
return sprintf(
'%s {$code = %s, $file = %s, $line = %s, $message = %s}',
Caster::makeNormalizedClassName(new ReflectionObject($object)),
$caster->cast($object->getCode()),
$caster->cast('.../' . basename($object->getFile())),
$caster->cast($object->getLine()),
$caster->cast($object->getMessage()),
);
}
public function isHandling(object $object): bool
{
return ($object instanceof Throwable);
}
},
]));
echo $caster->cast(new stdClass()) . "\n";
echo $caster->cast(new DateTimeImmutable('2019-01-01T00:00:00+00:00')) . "\n";
echo $caster->cast(new RuntimeException('test', 1)) . "\n";
declare(strict_types=1);
use Eboreum\Caster\Abstraction\Formatter\AbstractResourceFormatter;
use Eboreum\Caster\Caster;
use Eboreum\Caster\Collection\Formatter\ResourceFormatterCollection;
use Eboreum\Caster\Common\DataType\Resource_;
use Eboreum\Caster\Contract\CasterInterface;
$caster = Caster::create();
$caster = $caster->withCustomResourceFormatterCollection(new ResourceFormatterCollection([
new class extends AbstractResourceFormatter
{
public function format(CasterInterface $caster, Resource_ $resource): ?string
{
if (false === $this->isHandling($resource)) {
return null; // Pass on to next formatter or lastly DefaultResourceFormatter
}
if ('stream' === get_resource_type($resource->getResource())) {
return sprintf(
'opendir/fopen/tmpfile/popen/fsockopen/pfsockopen %s',
preg_replace(
'/^(Resource id) #\d+$/',
'$1 #42',
(string)$resource->getResource(),
),
);
}
return null; // Pass on to next formatter or lastly DefaultResourceFormatter
}
},
new class extends AbstractResourceFormatter
{
public function format(CasterInterface $caster, Resource_ $resource): ?string
{
if (false === $this->isHandling($resource)) {
return null; // Pass on to next formatter or lastly DefaultResourceFormatter
}
if ('xml' === get_resource_type($resource->getResource())) {
$identifier = preg_replace(
'/^(Resource id) #\d+$/',
'$1 #42',
(string)$resource->getResource(),
);
assert(is_string($identifier));
return sprintf(
'XML %s',
$identifier,
);
}
return null; // Pass on to next formatter or lastly DefaultResourceFormatter
}
},
]));
echo $caster->cast(fopen(__FILE__, 'r+')) . "\n";
opendir/fopen/tmpfile/popen/fsockopen/pfsockopen Resource id #42
declare(strict_types=1);
use Eboreum\Caster\Abstraction\Formatter\AbstractStringFormatter;
use Eboreum\Caster\Caster;
use Eboreum\Caster\Collection\Formatter\StringFormatterCollection;
use Eboreum\Caster\Contract\CasterInterface;
$caster = Caster::create();
$caster = $caster->withCustomStringFormatterCollection(new StringFormatterCollection([
new class extends AbstractStringFormatter
{
public function format(CasterInterface $caster, string $string): ?string
{
if (false === $this->isHandling($string)) {
return null; // Pass on to next formatter or lastly DefaultStringFormatter
}
if ('What do we like?' === (string)$string) {
return $caster->cast('CAKE!');
}
return null; // Pass on to next formatter or lastly DefaultStringFormatter
}
public function isHandling(string $string): bool
{
return true;
}
},
]));
echo $caster->cast('What do we like?') . "\n";
echo $caster->castTyped('Mmmm, cake') . "\n";
"CAKE!"
(string(10)) "Mmmm, cake"
declare(strict_types=1);
use Eboreum\Caster\Caster;
use Eboreum\Caster\Collection\EncryptedStringCollection;
use Eboreum\Caster\EncryptedString;
$caster = Caster::create();
$caster = $caster->withMaskedEncryptedStringCollection(new EncryptedStringCollection([
new EncryptedString('bar'),
new EncryptedString('bim'),
new EncryptedString('345'),
new EncryptedString('456'),
]));
echo $caster->castTyped('foo bar baz bim bum') . "\n"; // Notice: Original string length is not revealed
echo "\n\n";
echo $caster->castTyped('0123456789') . "\n"; // Notice: 3456 are masked because 345 and 456 overlap