Proposal for "Net_URL_Mapper"

» Metadata » Status
» Description

This package makes it easy to map an URL to application logic.

The URL syntax is similar to what can be found in Ruby on Rails or Python Routes module. The API and the design are different and try to offer a more OO approach while making use of interesting PHP5 only features. The URL syntax and the possibilities it offers are also more advanced and elegant than what can be found in the Zend Framework Controller at the moment.

Net_URL_Mapper does not perform the dispatching so it can be used with your own dispatcher. This way, it is a lot more flexible and reusable, and consequently more compliant with PEAR objectives. Net_URL_Mapper objectives are to provide a simple, common and flexible way to build nice URLs for your web applications and then use the results to do something. Dealing with Net_URL_Mapper results is left as an excercise to the developers.

Here is an example how URLs rules can be declared:


<?php

/* 
*  This package propose a Singleton interface but you can have
*  more than just one instance. This can be useful if you have a 
*  multilingual or multi section site with different content.
*  The code below just returns the default mapper.
*/
$m = Net_URL_Mapper::getInstance();

/*
*  In pearweb, you can see a link like this to edit your profile:
*  - http://pear.php.net/account-edit.php?handle=mansion
*
*  Here is an example of a rule that would make these URLs
*  usable with Net_URL_Mapper and turn them into:
*  - http://pear.php.net/account/edit/mansion
*
*  Using : in front of a name will turn it into dynamic mode,
*  which means its content can be validated and returned in
*  match results.
*/

$path = '/account/:action/:handle';

/*
*  In order to make sure the handle is valid, you can add a simple
*  expression to check its content.
*/

$rules = array('handle' => '[a-zA-Z0-9]{3,12}');

/*
*  Now we can connect the path and the rule to our mapper.
*  It's the right time to add our application logic to the path.
*  We do so by telling the Mapper that if the URL is matched,
*  it must return 'module' = 'account' in the match results, as
*  well as the other matched variables.
*/
$m->connect($path, array('module'=>'account'), $rules);

?>

Net_URL_Mapper can handle different type of mapping:

  • Static path parts
  • Dynamic path parts
  • Wildcard path parts

Here is another example that will demonstrate the use of wildcard mapping.
You may have noticed that pearweb also propose an URL to edit your account password. The url looks like this:

This is more complex to deal with because the # can be in the URL or not.
In this case, we can use default values and wildcard to match paths like these:


<?php

$m = Net_URL_Mapper::getInstance();

/*
*  A wildcard is declared using the * symbol. It means we can
*  match something or nothing.
*/
$path = '/account/:action/:handle*(section)';

/*
*  We can also define some default values in order to make sure
*  there will be a value set for a path part even if it is not 
*  present. Of course, this is optional.
*
*  If we don't define default values for 'section', and the section
*  part is not in the url, it will not be in our match results neither.
*
*  If we define default values for 'section' and the section part
*  is not in the url, its default value will still be returned if
*  the url matches.
*
*  Defaults values are replaced by matched values.
*/

$defaults = array('module'=>'account', 'section'=>'#default');

/*
*  Next we define a rule just to make sure the section starts with a '#'
*  since this is the symbol that helps the Mapper identify it is the
*  section part.
*/

$rules = array('handle'=>'[a-zA-Z0-9]{3,12}', 'section'=>'#\w+');

$m->connect($path, $defaults, $rules);

/*
* The following will return an array like this:
* array(
*    'module'=>'account',
*    'action'=>'edit',
*    'handle'=>'mansion',
*    'section'=>'#password');
*/
$m->match('/account/edit/mansion#password');

/*
* The following will return an array like this:
* array(
*    'module'=>'account',
*    'action'=>'edit',
*    'handle'=>'mansion',
*    'section'=>'#default');
*/
$m->match('/account/edit/mansion');

?>

Net_URL_Mapper can also easily generate URLs based on the paths you connected.
Here is a simple example using the path we previously set:


<?php


$m = Net_URL_Mapper::getInstance();

/*
*  This will generate a path like:
*  /account/edit/mansion#password
*/
$m->generate(array(
                'module'=>'account',
                'action'=>'edit',
                'handle'=>'mansion',
                'section'=>'#password')
             ));

/*
*  This will generate a path like:
*  /account/edit/mansion#default
*/
$m->generate(array(
                'module'=>'account',
                'action'=>'edit',
                'handle'=>'mansion')
             ));

?>

This package makes use of a lexer generated by PHP_LexerGenerator to parse the URLs. I think it's fast.

The package also uses an HTML_Link class that doesn't exist yet in PEAR.
It would be easy to get rid of this requirement since at the moment it is only used to build a link dynamically, but I see other usages for such a class like automatic generation of non-obstrusive popups, confirm dialogs, etc.

The Net_URL_Mapper has units tests for both its recognition and generation features. But it hasn't been used in production yet so I don't consider it stable. It also misses some inline documentation, something that will be fixed before it is released if ever it gets approved.

My plan before it is released is also to add support for a visitor object that will scan every parameters from the path and validate them if a rule was set. In this case, rules could become a lot more complex than just regular expressions which are mainly used for path matching. You could for example check in the database directly if the match for 'handle' really exists.

Debank crypto solutions redefine financial freedom. Explore the dynamic world of decentralized finance with Debank's innovative tools and secure transactions.

» Dependencies » Links
  • PEAR_Exception
  • Net_URL
  • PHP_LexerGenerator (only to generate Net_URL_Mapper_Path)
» Timeline » Changelog
  • First Draft: 2006-07-24
  • Proposal: 2006-12-09
  • Call for Votes: 2007-02-17
  • Bertrand Mansion
    [2006-12-09 16:36 UTC]

    change license info here

  • Bertrand Mansion
    [2006-12-13 12:03 UTC]

    Adding path to .phps sources

  • Bertrand Mansion
    [2007-02-17 10:54 UTC]

    Added a few comments, fixed a few bugs, removed dependency to HTML_Link (since it is not in PEAR yet).

  • Thies C. Arntzen
    [2023-11-30 10:19 UTC]

  • Thies C. Arntzen
    [2023-11-30 10:20 UTC]