ql/uri-template

实现了RFC 6570第4级

这个包的官方仓库似乎已不存在,因此该包已被冻结。

1.1.3 2018-06-10 16:08 UTC

This package is auto-updated.

Last update: 2023-12-12 10:21:51 UTC


README

Build Status Coverage Status Latest Stable Version

这是RFC 6570的完整实现。

目前市面上有其他许多PHP实现的RFC 6570,但这个版本在以下特性上做得更好

  • 妥善处理非ASCII字符编码问题。
  • 有100%的单元测试代码覆盖率。
  • 单元测试不仅覆盖了RFC的非错误示例,还包括了文本中描述的失败情况。
  • 不使用任何正则表达式。
  • 主扩展器是一个可调用的PHP类,便于使用,并允许它被自动加载(与单个函数不同)。
  • 如果您的代码希望在使用之前确保模板有效,此包还提供了一个'严格类',如果在URI模板中使用了无效的语法,它将抛出异常。
  • 此包与HHVM兼容无问题。

这个特定的实现只允许UTF-8字符集中的URI模板。

安装

此代码可通过 composer 获得。在 composer.json 文件的require部分使用 ql/uri-template 作为包名即可。

这是一个包含此包的最小 composer.json 文件

{
    "require": {
        "ql/uri-template": "1.*"
    }
}

用法

<?php
use QL\UriTemplate\UriTemplate;

$tpl = '/authenticate/{username}{?password}';
$tpl = new UriTemplate($tpl);

$url = $tpl->expand([
    'username' => 'mnagi',
    'password' => 'hunter2',
]);

echo $url; // outputs "/authenticate/mnagi?password=hunter2"

注意,上述示例在模板或变量集无效时会抛出异常。某些应用程序可能 期望 无格式URI模板,并希望以更优雅的方式处理它们。在这种情况下,建议您直接使用 Expander 类。

<?php
use QL\UriTemplate\Expander;

$tpl = '/authenticate/{username}{?password}';
$exp = new Expander;

$url = $exp($tpl, ['username' => 'mnagi', 'password' => 'hunter2' ]);

echo $url; // outputs "/authenticate/mnagi?password=hunter2"

错误处理

两者之间的区别(除了它们的调用方式外)在于存在某种类型的错误时

<?php
use QL\UriTemplate\Expander;
use QL\UriTemplate\UriTemplate;
use QL\UriTemplate\Exception;

$badTpl = '/foo{ba';
$expander = new Expander;

// error with template in Expander
$expander($badTpl, []);
echo $expander->lastError() . "\n"; // "Unclosed expression at offset 4: /foo{ba"

// error with template in UriTemplate
try {
    $tpl = new UriTemplate($badTpl);
} catch (Exception $e) {
    echo $e->getMessage() . "\n"; // outputs "Unclosed expression at offset 4: /foo{ba"
}

// error with variables in template
$expander('/foo/{bar}', ['bar' => new stdClass]);
echo $expander->lastError() . "\n"; // "Objects without a __toString() method are not allowed as variable values."

// error with variables in UriTemplate
$tpl = new UriTemplate('/foo/{bar}');
$tpl->expand(['bar' => STDIN]); // this will throw an exception with message "Resources are not allowed as variable values."

选项

Expander 类的 invoke 方法允许传递一个选项数组给它。目前唯一可用的选项是,如果调用代码没有传递所有模板变量,则保留模板变量。

以下是一个URI模板和变量集的示例

Template:  /events{?product,date,days,seats,before,at,after}
Variables: { "product": 10, "days": 20 }

"preserveTpl" set to false: /events?product=10&days=20
"preserveTpl" set to true:  /events?product=10&days=20{&date,seats,before,at,after}

开启 preserveTpl 的完整代码示例

use QL\UriTemplate\Expander;

$tpl = '/events{?product,date,days,seats,before,at,after}';
$vars = ['product' => 10, 'days' => 20];
$expander = new Expander;
$result = $expander($tpl, $vars, ['preserveTpl' => true]);
echo $result . "\n";

要求

此包需要PHP 5.4+,ctype扩展和mbstring扩展。此外,它仅允许UTF-8模板(虽然这可能在将来改变)。