Skip to content

Instantly share code, notes, and snippets.

@lsloan
Last active April 8, 2016 16:35
Show Gist options
  • Select an option

  • Save lsloan/b559e1fcb3432e89cb1548518020b0f9 to your computer and use it in GitHub Desktop.

Select an option

Save lsloan/b559e1fcb3432e89cb1548518020b0f9 to your computer and use it in GitHub Desktop.
PHP: Developers often want scalar/basic type hints. This drop-in class enables type hints through the use of a custom error handler.
<?php
define('TYPEHINT_PCRE', '/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/');
class Typehint {
private static $Typehints = array(
'boolean' => 'is_bool',
'integer' => 'is_int',
'float' => 'is_float',
'string' => 'is_string',
'resrouce' => 'is_resource'
);
private function __Constrct() {}
public static function initializeHandler() {
set_error_handler('Typehint::handleTypehint');
return TRUE;
}
private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue) {
foreach ($ThBackTrace as $ThTrace) {
// Match the function; Note we could do more defensive error checking.
if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction) {
$ThArgValue = $ThTrace['args'][$ThArgIndex - 1];
return TRUE;
}
}
return FALSE;
}
public static function handleTypehint($ErrLevel, $ErrMessage) {
if ($ErrLevel == E_RECOVERABLE_ERROR) {
if (preg_match(TYPEHINT_PCRE, $ErrMessage, $ErrMatches)) {
list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches;
if (isset(self::$Typehints[$ThHint])) {
$ThBacktrace = debug_backtrace();
$ThArgValue = NULL;
if (self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue)) {
if (call_user_func(self::$Typehints[$ThHint], $ThArgValue)) {
return TRUE;
}
}
}
}
}
return FALSE;
}
}
Typehint::initializeHandler();

Adapted from comment by "Daniel dot L dot Wood at Gmail dot Com" on PHP documentation site:

http://php.net/manual/en/language.oop5.typehinting.php#83442

Developers often want scalar/basic type hints. This drop-in class enables type hints through the use of a custom error handler.

Why?

  1. Developers are sick of using the is_* functions to validate parameters.
  2. Reduction of redundant coding for defensive coders.
  3. Functions and methods become self-defining and self-documenting as to required input.

Note: You should include this code above all other code in your include headers and if you are the using set_error_handler() function you should be aware that this uses it as well. You may need to chain your set_error_handlers()

Also: Follow the typehint discussions on the PHP Internals boards.

<?php
function teststring(string $string) { echo $string; }
function testinteger(integer $integer) { echo $integer; }
function testfloat(float $float) { echo $float; }
// This will work for class methods as well.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment