Instantly share code, notes, and snippets.

Embed
What would you like to do?
PHP named params
<?php
namespace Util;
/**
* Workaround to avoid long unnamed argument list
*
* Usage:
*
* 1. Required params
*
* extract(
* NamedParams::assert(['name1', 'name2'],
* $params
* );
*
* 2. Optional params (with default values)
*
* extract(
* NamedParams::assert(['name3', 'name4' => 'defaultValue'],
* $params
* );
*
* 3. Type hinting
*
* extract(
* NamedParams::assert(['name5' => ['type' => 'array'], 'name6' => ['type' => Connection::class]]),
* $params
* );
*
* Type can be class name or type name (as returned by gettype() call)
*
* 4. Type hinting and optional params together
*
* extract(
* NamedParams::assert(['name7' => ['type' => 'integer', 'defaultValue' => 5]]),
* $params
* );
*
*/
class NamedParams
{
/**
* @param array $expectedParams
* @param array $inputParams
*/
public static function assert(array $expectedParams, array $inputParams)
{
// normalize to: param_name => [type => ..., defaultValue => ...]
$normalizedExpectedParams = [];
foreach ($expectedParams as $key => $val) {
// already array, nothing to do
if (is_array($val)) {
$normalizedExpectedParams[$key] = $val;
continue;
}
// 'name' => val
if (!is_int($key)) {
$normalizedExpectedParams[$key] = ['defaultValue' => $val];
continue;
}
// 'name'
$normalizedExpectedParams[$val] = [];
}
$redundantParams = array_diff_key($inputParams, $normalizedExpectedParams);
if (!empty($redundantParams)) {
throw new \InvalidArgumentException(sprintf('redundant params: %s', implode(', ', $redundantParams)));
}
$outputParams = [];
foreach ($normalizedExpectedParams as $key => $val) {
if (array_key_exists($key, $inputParams)) {
if (isset($val['type'])) {
$isValidInstance = ($inputParams[$key] instanceof $val['type']);
$isValidScalarType = (gettype($inputParams[$key]) == $val['type']);
if (!$isValidInstance && !$isValidScalarType) {
throw new \InvalidArgumentException(
sprintf('invalid type, %s param should be %s', $key, $val['type'])
);
}
}
$outputParams[$key] = $inputParams[$key];
continue;
}
if (array_key_exists('defaultValue', $val)) {
$outputParams[$key] = $val['defaultValue'];
continue;
}
throw new \InvalidArgumentException(sprintf('missing param: %s', $key));
}
return $outputParams;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment