Created
December 19, 2018 03:52
-
-
Save kevinquinnyo/f0332273b8bc129c875ea91293ed3b65 to your computer and use it in GitHub Desktop.
weird idea for extending TypeError and having richer 'types' in php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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('[email protected]'); | |
$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