Skip to content

Instantly share code, notes, and snippets.

@nyamsprod
Created August 31, 2023 21:26
Show Gist options
  • Save nyamsprod/4f464d0c52f1ed80e622ec8b2ef275e9 to your computer and use it in GitHub Desktop.
Save nyamsprod/4f464d0c52f1ed80e622ec8b2ef275e9 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace League\Uri;
use Closure;
use Countable;
use Iterator;
use IteratorAggregate;
use League\Uri\Components\Query;
use League\Uri\Contracts\QueryInterface;
use League\Uri\Contracts\UriComponentInterface;
use Stringable;
use function count;
use function is_iterable;
use function is_string;
use function str_starts_with;
final class URLSearchParams implements Countable, IteratorAggregate
{
private QueryInterface $query;
public function __construct(object|array|string|null $query)
{
$this->query = match (true) {
$query instanceof QueryInterface => $query->withSeparator('&'),
$query instanceof UriComponentInterface => Query::fromRFC3986($query->value()),
is_iterable($query) => Query::fromPairs($query),
$query instanceof Stringable,
null === $query,
is_string($query) => match (true) {
str_starts_with((string) $query, '?') => Query::fromRFC3986(substr((string) $query, 1)),
default => Query::fromRFC3986($query),
},
default => Query::fromPairs((function(object $object) {
foreach ($object as $key => $value) {
yield [$key, $value];
}
})($query)),
};
}
public static function fromUri(Stringable|string $uri): self
{
return new self(Query::fromUri($uri));
}
public function toString(): string
{
return $this->query->toString();
}
public function keys(): iterable
{
foreach ($this->query as [$key, $__]) {
yield $key;
}
}
public function values(): iterable
{
foreach ($this->query as [$__, $value]) {
yield $value;
}
}
public function has(string $name): bool
{
return $this->query->has($name);
}
public function get(string $name): ?string
{
return $this->query->get($name);
}
public function getAll(string $name): array
{
return $this->query->getAll($name);
}
public function count(): int
{
return count($this->query);
}
public function getIterator(): Iterator
{
yield from $this->query;
}
public function each(Closure $callback): void
{
foreach ($this->query as [$key, $value]) {
$callback($value, $key);
}
}
private function updateQuery(QueryInterface $query): void
{
if ($query->value() !== $this->query->value()) {
$this->query = $query;
}
}
public function append(string $key, Stringable|string|int|bool|null $value): void
{
$this->updateQuery($this->query->appendTo($key, $value));
}
public function deleteByKey(string $key): void
{
$this->updateQuery($this->query->withoutPairByKey($key));
}
public function deleteByPair(string $key, Stringable|string|int|bool|null $value): void
{
$this->updateQuery($this->query->withoutPairByKeyValue($key, $value));
}
public function set(string $key, Stringable|string|int|bool|null $value): void
{
$this->updateQuery($this->query->withPair($key, $value));
}
public function sort(): void
{
$this->updateQuery($this->query->sort());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment