PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Networking » Net_URL_Mapper » Manual

A package to map (and generate) pretty urls.

Introduction

Net_URL_Mapper 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.

Features

Net_URL_Mapper can handle different types of mapping:

In the following examples we assume that URLs are mapped to a desginated controller and an action. But the controller and action keys provided could be called anything and are not mandatory.

Static path parts

The following code snippet maps the URL /home:

<?php
require_once 'Net/URL/Mapper.php';

$m = Net_URL_Mapper::getInstance();
$m->connect('home', array('controller' => 'index', 'action' => 'index'));
var_dump($m->match($_SERVER['REQUEST_URI']));
?>

Dynamic path parts

The following code snippet maps a URL such as /news/1, /news/2 to a designated controller and action.

<?php
require_once 'Net/URL/Mapper.php';

$m = Net_URL_Mapper::getInstance();
$m->connect('news/:id', array('controller' => 'news', 'action' => 'read'));
var_dump($m->match($_SERVER['REQUEST_URI']));
?>

Wildcard path parts

The following code snippet maps all URLs with /content to a controller called content and an action called display. Optionally, we'll determine the section on the page using a wildcard. The default for section is #toc (Table Of Contents).

<?php
require_once 'Net/URL/Mapper.php';

$m = Net_URL_Mapper::getInstance();

$path     = 'content/*(section)';
$defaults = array(
    'controller' => 'content',
    'action'     => 'display',
    'section'    => '#toc',
);

$m->connect($path, $defaults);
var_dump($m->match($_SERVER['REQUEST_URI']));
?>

Examples

The coming examples assume/need the following setup:

.htaccess


DirectoryIndex router.php
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(js|ico|gif|jpg|png|css)$ /router.php

init.php

<?php
require_once 'Net/URL/Mapper.php';
$m = Net_URL_Mapper::getInstance();
?>

Blog routing

The following snippets maps a couple blog URLs.

blog-router.php

<?php
require 'init.php';

$m->connect('blog', array('page' => 'frontpage.php'));
$m->connect(
    'blog/feed/:type',
    array('page' => 'feed.php', 'type' => 'rss')
);
$m->connect(
    'blog/archives/:year/:month',
    array(
        'page' => 'archive.php',
        'year' => date('Y'),
        'month' => date('m')
    )
);

$route = $m->match($_SERVER['REQUEST_URI']);
if ($route === null) {
    // no match
    $route = array(
        'page' => 'frontpage.php',
    );
}
include dirname(__FILE__) . '/inc/' . $route['page'];
?>

Zend Framework routing

A really simple example for Zend Framework-style URL routing. ;-) This is not meant to work in production, it's not necessarily secure and serves as a proof of concept or base for a real implementation.

zf-router.php

<?php
require 'init.php';

$path     = '/:module/:controller/:action';
$defaults = array(
    'module'     => 'default',
    'controller' => 'index',
    'action'     => 'index',
);

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

$route = $m->match($_SERVER['REQUEST_URI']);

// Fix the controller's name to adhere to ZF's standard, FooController
$controllerClass  = ucfirst(strtolower($route['controller'])) . 'Controller';

// Fix the action's name to adhere to ZF's standard, barAction()
$controllerAction = strtolower($route['action']) . 'Action';

// load the controller class
require 'app/modules/' . $route['module'] . '/' . $class . '.php';

$controllerObj = new $controllerClass;
call_user_func(array($controllerObj, $controllerAction)); // pseudo dispatcher
?>

Generate a URL

The following snippet explains how to generate a fancy URL automatically from the defined routes.

generate-url.php

<?php
require 'init.php';

$m->connect('blog', array('page' => 'frontpage.php'));
$m->connect(
    'blog/feed/:type',
    array('page' => 'feed.php', 'type' => 'rss')
);
$m->connect(
    'blog/archives/:year/:month',
    array(
        'page' => 'archive.php',
        'year' => date('Y'),
        'month' => date('m')
    )
);

$url1 = $m->generate(array(
    'page' => 'feed.php',
    'type' => 'atom',
)); // blog/feed/atom

$url2 = $m->generate(array(
    'page'  => 'archive.php',
    'year'  => '2008',
    'month' => '06',
)); // blog/archives/2008/06

?>