3v4l.org

run code in 300+ PHP versions simultaneously
<?php namespace { class Http { public static function get(string $url, array $params): Response { return new Response(json_encode(['url' => $url, 'params' => $params])); } } class Response { private $data = null; public function __construct($response) { $this->data = $response; } public function json() { return json_decode($this->data, true); } } } namespace Search { interface Specification { public function __invoke(array $params): array; } class Name implements Specification { private $name = null; public function __construct(string $name) { $this->name = $name; } public function __invoke(array $params): array { return [ 'name' => $this->name, ]; } } class Language implements Specification { const DEFAULT = 'en'; private $language = null; public function __construct(string $language) { $this->language = $language; } public function __invoke(array $params): array { return [ 'language' => $this->language ?? 'en', ]; } } class Fuzzy implements Specification { const DEFAULT = true; private $fuzzy = null; public function __construct(bool $fuzzy) { $this->fuzzy = $fuzzy; } public function __invoke(array $params): array { return [ 'fuzzy' => $this->fuzzy, ]; } } class Limit implements Specification { const DEFAULT = 10; private $max = null; public function __construct(int $limit) { $this->limit = $limit; } public function __invoke(array $params): array { return [ 'maxRows' => $this->limit ?: self::DEFAULT, ]; } } } namespace Api { interface Searchable { public function search(\Search\Specification... $criteria); } class Search implements Searchable { private $url = '/search'; private $defaults = [ 'maxRows' => \Search\Limit::DEFAULT, ]; public function search(\Search\Specification ...$criteria) { return \Http::get($this->url, array_reduce( $criteria, fn($params, $criteria) => $criteria($params) + $params, $this->defaults ))->json(); } } } namespace Controller { class Api { private $api; public function __construct(\Api\Searchable $someApi) { $this->api = $someApi; } public function search(string $name, int $limit = \Search\Limit::DEFAULT) { return $this->api->search( new \Search\Name($name), new \Search\Limit($limit) ); } public function lookup( string $name, string $language = \Search\Language::DEFAULT, bool $fuzzy = \Search\Fuzzy::DEFAULT, int $limit = \Search\Limit::DEFAULT ) { return $this->api->search( new \Search\Name($name), new \Search\Language($language), new \Search\Fuzzy($fuzzy), new \Search\Limit($limit) ); } } } namespace { $foo = new \Controller\Api(new \Api\Search()); var_export([ $foo->search('foo'), $foo->search('bar', 25), $foo->search('baz', 1), $foo->lookup('foo'), $foo->lookup('bar', 'de', false, 5), $foo->lookup('baz', 'za', true, 20), ]); }

preferences:
36.91 ms | 407 KiB | 5 Q