Skip to content

Instantly share code, notes, and snippets.

@kevinquinnyo
Created December 19, 2018 03:52
Show Gist options
  • Save kevinquinnyo/f0332273b8bc129c875ea91293ed3b65 to your computer and use it in GitHub Desktop.
Save kevinquinnyo/f0332273b8bc129c875ea91293ed3b65 to your computer and use it in GitHub Desktop.
weird idea for extending TypeError and having richer 'types' in php
<?php
// experiment with 'rich types' in php?
class RichTypeError extends TypeError
{
// maybe customize this
}
class _email
{
private $email;
public function __construct(string $email)
{
if ((bool)preg_match('/.*@.*/', $email) === false) {
throw new RichTypeError('not a valid email');
}
$this->email = $email;
}
public function __toString()
{
return $this->email;
}
}
class _hostname
{
private $hostname;
public function __construct(string $hostname)
{
$pattern = '/(?:[_\p{L}0-9][-_\p{L}0-9]*\.)*(?:[\p{L}0-9][-\p{L}0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,})/';
if ((bool)preg_match($pattern, $hostname) === false) {
throw new RichTypeError('not a valid hostname');
}
}
public function __toString()
{
return $this->hostname;
}
}
// example of extending the _hostname validation type
class _my_mailserver extends _hostname
{
private $mailserver;
public function __construct(string $mailserver)
{
parent::__construct($mailserver);
if ((bool)preg_match('/myserver.com$/', $mailserver) === false) {
throw new RichTypeError('not a valid mailserver');
}
$this->mailserver = $mailserver;
}
public function __toString()
{
return $this->mailserver;
}
}
class _api_options
{
private $options;
public function __construct(array $options = [])
{
if (empty($options) === false && array_key_exists('auth', $options) === false) {
throw new RichTypeError('api options missing \'auth\' key.');
}
$this->options = $options;
}
public function __toArray()
{
return $this->options;
}
}
// this example is dumb
class Email
{
private $address;
// now we can typehint against these 'rich string' types instead of string
public function __construct(_email $address, _my_mailserver $mailserver, _api_options $apiOptions = null)
{
$this->address = $address;
$this->mailserver = $mailserver;
$this->apiOptions = $apiOptions; // dumb, just trying to use the rich array example
}
// do stuff
}
// all of this should pass
$address = new _email('asdf@gmail.com');
$mailserver = new _my_mailserver('mail.foo.myserver.com');
$options = new _api_options(['auth' => 'foo']);
$Email = new Email($address, $mailserver);
var_dump($Email);
// this will all fail
$address = new _email('asdf'); // throws RichTypeError
$mailserver = new _my_mailserver('example.com'); // throws RichTypeError
$options = new _api_options(['foo' => 'bar']); // throws RichTypeError
$Email = new Email($address, $mailserver); // won't get here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment