Giter VIP home page Giter VIP logo

uritemplate's Introduction

PHP URI Template

This is a URI Template implementation in PHP based on RFC 6570 URI Template. In addition to URI expansion, it also supports URI extraction (used by Google Cloud Core and Google Cloud Client Library).

CI Total Downloads Financial Contributors on Open Collective

Usage

Expansion

A very simple usage (string expansion).

<?php

use Rize\UriTemplate;

$uri = new UriTemplate();
$uri->expand('/{username}/profile', ['username' => 'john']);

>> '/john/profile'

Rize\UriTemplate supports all Expression Types and Levels specified by RFC6570.

<?php

use Rize\UriTemplate;

$uri = new UriTemplate();
$uri->expand('/search/{term:1}/{term}/{?q*,limit}', [
    'term'  => 'john',
    'q'     => ['a', 'b'],
    'limit' => 10,
])

>> '/search/j/john/?q=a&q=b&limit=10'

/ Path segment expansion

<?php

use Rize\UriTemplate;

$uri = new UriTemplate();
$uri->expand('http://{host}{/segments*}/{file}{.extensions*}', [
    'host'       => 'www.host.com',
    'segments'   => ['path', 'to', 'a'],
    'file'       => 'file',
    'extensions' => ['x', 'y'],
]);

>> 'http://www.host.com/path/to/a/file.x.y'

Rize\UriTemplate accepts base-uri as a 1st argument and default params as a 2nd argument. This is very useful when you're working with API endpoint.

Take a look at real world example.

<?php

use Rize\UriTemplate;

$uri = new UriTemplate('https://api.twitter.com/{version}', ['version' => 1.1]);
$uri->expand('/statuses/show/{id}.json', ['id' => '210462857140252672']);

>> https://api.twitter.com/1.1/statuses/show/210462857140252672.json

Extraction

It also supports URI Extraction (extract all variables from URI). Let's take a look at the example.

<?php

use Rize\UriTemplate;

$uri = new UriTemplate('https://api.twitter.com/{version}', ['version' => 1.1]);

$params = $uri->extract('/search/{term:1}/{term}/{?q*,limit}', '/search/j/john/?q=a&q=b&limit=10');

>> print_r($params);
(
    [term:1] => j
    [term] => john
    [q] => Array
        (
            [0] => a
            [1] => b
        )

    [limit] => 10
)

Note that in the example above, result returned by extract method has an extra keys named term:1 for prefix modifier. This key was added just for our convenience to access prefix data.

strict mode

<?php

use Rize\UriTemplate;

$uri = new UriTemplate();
$uri->extract($template, $uri, $strict = false)

Normally extract method will try to extract vars from a uri even if it's partially matched. For example

<?php

use Rize\UriTemplate;

$uri = new UriTemplate();
$params = $uri->extract('/{?a,b}', '/?a=1')

>> print_r($params);
(
    [a] => 1
    [b] => null
)

With strict mode, it will allow you to extract uri only when variables in template are fully matched with given uri.

Which is useful when you want to determine whether the given uri is matched against your template or not (in case you want to use it as routing service).

<?php

use Rize\UriTemplate;

$uri = new UriTemplate();

// Note that variable `b` is absent in uri
$params = $uri->extract('/{?a,b}', '/?a=1', true);

>>> null

// Now we give `b` some value
$params = $uri->extract('/{?a,b}', '/?a=1&b=2', true);

>>> print_r($params)
(
  [a] => 1
  [b] => 2
)

Array modifier %

By default, RFC 6570 only has 2 types of operators : and *. This % array operator was added to the library because current spec can't handle array style query e.g. list[]=a or key[user]=john.

Example usage for % modifier

<?php

$uri->expand('{?list%,keys%}', [
    'list' => [
        'a', 'b',
    ),
    'keys' => [
        'a' => 1,
        'b' => 2,
    ),
]);

// '?list[]=a&list[]=b&keys[a]=1&keys[b]=2'
>> '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2'

// [] get encoded to %5B%5D i.e. '?list[]=a&list[]=b&keys[a]=1&keys[b]=2'
$params = $uri->extract('{?list%,keys%}', '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2', )

>> print_r($params);
(
    [list] => Array
        (
            [0] => a
            [1] => b
        )

    [keys] => Array
        (
            [a] => 1
            [b] => 2
        )
)

Installation

Using composer

{
    "require": {
        "rize/uri-template": "~0.3"
    }
}

Changelogs

  • 0.2.0 Add a new modifier % which allows user to use list[]=a&list[]=b query pattern.
  • 0.2.1 Add nested array support for % modifier
  • 0.2.5 Add strict mode support for extract method
  • 0.3.0 Improve code quality + RFC3986 support for extract method by @Maks3w
  • 0.3.1 Improve extract method to parse two or more adjacent variables separated by dot by @corleonis

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

uritemplate's People

Contributors

alexander-schranz avatar backendtea avatar corleonis avatar danopz avatar kbond avatar lord2800 avatar maks3w avatar monkeywithacupcake avatar owenvoke avatar peter279k avatar rezigned avatar vincentlanglet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uritemplate's Issues

UnNamed ignores the dot (.) when there is a file extension in the path

I have problem parsing URI path with file extension at the end. So the my URLs are as follows.

I have endpoint: https://site.com/v1/company/us/123456.json and that mapps to following Swagger spcification: /v1/company/{country}/{companyId}.{format} where format can be either XML or JSON.

So my problem is that the code sees the path as like there is no file extension and the companyId=123456.json because the . is deemed as a valid character and not a separator as is the case with /

So my question is there any way around that problem?

issue w/ tests & uri-tempaltes submodule

I've just been tinkering with this repo, adding in the tests repo as a submodule & discovered that it fails on "/lookup{?Stra%C3%9Fe}", "/lookup?Stra%C3%9Fe=Gr%C3%BCner%20Weg"

the url-encoded unicode characters are getting double-encoded, leading to %C3 becoming %25C3- I tried to tinker around but wasn't able to figure out the appropriate location to adjust the parameters.

How to tell if a URL didn't match vs. had no modifiers?

I'm looking to integrate this into my routing library instead of the bad regex-based hack of a URL parser I have right now, but I can't seem to find how I tell if a uri template didn't match a given url. Is that not something this does right now?

URI Extraction Issue

I've just discovered URI-Template and it's a tremendous blessing for my applications! Thank you for this library.

While I'm still learning the behaviour of URI template formatting logic, I would expect the following to work:

URI:
/XYZ.shop/department/Electronics

Template:
/{app}.shop/department/{slug}

Expected Results:

  • app: XYZ
  • slug: Electronics

However, it's not liking the XYZ.shop in the first segment. Internally, it's assigning XYZ.shop to the {app}, but then ultimately failing when in Strict mode.

Should the above template work correctly, or am I misunderstanding the specification?

(the internal Regex is so complex, I don't dare mess with it.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.