Skip to content

Commit

Permalink
IDN encode/decode
Browse files Browse the repository at this point in the history
  • Loading branch information
sirn-se committed Feb 4, 2024
1 parent f337b5c commit b732a72
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 4 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Will cause paths to use absolute form, i.e. starting with `/`.

Will attempt to normalize paths, e.g. `./a/./path/../to//something` will transform to `a/to/something`.

`IDN_ENCODE`
`IDN_ENCODE` + `IDN_ENCODE`

Will IDN-encode host using non-ASCII characters. Only available with [Intl extension](https://www.php.net/manual/en/intl.installation.php).

Expand Down Expand Up @@ -145,7 +145,7 @@ class Phrity\Net\UriFactory implements Psr\Http\Message\UriFactoryInterface

| Version | PHP | |
| --- | --- | --- |
| `2.0` | `^8.0` | Query helpers, with([]) and getComponents() methods |
| `2.0` | `^8.0` | Query helpers, with([]) and getComponents() methods, IDN encode/decode |
| `1.3` | `^7.4\|^8.0` | |
| `1.2` | `^7.4\|^8.0` | IDNA modifier |
| `1.1` | `^7.4\|^8.0` | Require port, Absolute path, Normalize path modifiers |
Expand Down
21 changes: 19 additions & 2 deletions docs/README.md → docs/Uri.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ All `get`, `with` and the `toString()` methods accept option flags.

### Host options

#### The `IDN_ENCODE` option
#### The `IDN_ENCODE` and `IDN_DECODE` options

Using this option will IDN-encode host using non-ASCII characters.
Using `IDN_ENCODE` option will IDN-encode host using non-ASCII characters.
Only available with [Intl extension](https://www.php.net/manual/en/intl.installation.php).

```php
Expand All @@ -312,6 +312,23 @@ $clone->getHost(); // -> "xn--7ca5b9p776i"
echo "{$clone} \n"; // -> "https://xn--7ca5b9p776i"
```

Using `IDN_DECODE` option will IDN-decode host previously encoded to ASCII-only characters.
Only available with [Intl extension](https://www.php.net/manual/en/intl.installation.php).

```php
$uri = new Uri('https://xn--zca0cg32z7rau82strvd.com');

$uri->getHost(); // -> "xn--zca0cg32z7rau82strvd.com"
$uri->toString(); // -> "https://xn--zca0cg32z7rau82strvd.com"

$uri->getHost(Uri::IDN_DECODE); // -> "ηßöø必Дあ.com"
$uri->toString(Uri::IDN_DECODE); // -> "https://xηßöø必Дあ.com"

$clone = $uri->withHost('xn--7ca5b9p776i', Uri::IDN_DECODE);
$clone->getHost(); // -> "œüç∂"
echo "{$clone} \n"; // -> "https://œüç∂"
```

### Port options

#### The `REQUIRE_PORT` option
Expand Down
6 changes: 6 additions & 0 deletions src/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ public function getHost(int $flags = 0): string
if ($flags & self::IDN_ENCODE) {
return $this->idnEncode($this->host);
}
if ($flags & self::IDN_DECODE) {
return $this->idnDecode($this->host);
}
return $this->host;
}

Expand Down Expand Up @@ -484,6 +487,9 @@ protected function setHost(string $host, int $flags = 0): void
if ($flags & self::IDN_ENCODE) {
$host = $this->idnEncode($host);
}
if ($flags & self::IDN_DECODE) {
$host = $this->idnDecode($host);
}
$this->host = mb_strtolower($host);
}

Expand Down
20 changes: 20 additions & 0 deletions tests/UriExtensionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,26 @@ public function testIdnEncodeHost(): void
$this->assertSame('', $clone->getHost());
}

public function testIdnDecodeHost(): void
{
// Get converted host
$uri = new Uri('https://xn--zca0cg32z7rau82strvd.com');
$this->assertSame('xn--zca0cg32z7rau82strvd.com', $uri->getHost());

$this->assertSame('ηßöø必дあ.com', $uri->getHost(Uri::IDN_DECODE));
$this->assertSame('https://xn--zca0cg32z7rau82strvd.com', $uri->toString());
$this->assertSame('https://ηßöø必дあ.com', $uri->toString(Uri::IDN_DECODE));

// Should convert host on clone
$clone = $uri->withHost('xn--zca0cg32z7rau82strvd.com', Uri::IDN_DECODE);
$this->assertSame('ηßöø必дあ.com', $clone->getHost());
$this->assertSame('https://ηßöø必дあ.com', $clone->__toString());

// Should not attempt conversion
$clone = $uri->withHost('', Uri::IDN_DECODE);
$this->assertSame('', $clone->getHost());
}

public function testWithMethod(): void
{
$uri = new Uri('http://domain.tld:80/path?query=1#fragment');
Expand Down

0 comments on commit b732a72

Please sign in to comment.