Newsgroup: it.comp.www.php
Titolo: router php a al posto di .htaccess

ho creato due file: .htaccess e index.php
 
# .htaccess
RewriteEngine On
RewriteRule ^(.*)/(.*)/(.*)/(.*)/(.*)$ 
index.php?controller=$1&action=$2&param1=$3&param2=$4&param3=$5       [L]
 
 
<?php //index.php
print_r($_GET)
?>
 
Quindi mi collego: 
http://sito/a/b/c/d/e
 
 
e naturalmente ottengo:
 
Array
(
     [controller] => a
     [action] => b
     [param1] => c
     [param2] => d
     [param3] => e
)
 
Tutto ok!!!
 
Ma se volessi fare la stessa 'identica' cosa in php, dovrei usare 
preg_match_all.
 
Ho visto quindi vari esempi come questi:
http://stackoverflow.com/questions/11722711/url-routing-regex-php
 
http://blog.sosedoff.com/2009/09/20/rails-like-php-url-router/
 
 
solo che non mi sembra facciano esattamente ciï¿œ che vogliono (ognuno usa 
il suo sistema).
 
In pratica vorrei un esempio semplice, che faccia *esattamente* cio' che 
f l'.hraccess

 il suo sistema).
 
Permettono di avere un router generico in cui puoi definire le route da 
bootstrap, con named parameters.
Puoi vedere anche i sorgenti di symfony o di Zend Framework.
 
Bye.

 preg_match_all.
 
Non la puoi fare, a meno di qualche significato particolare degli apici 
di 'identica'.

…

> cio' che f l'.hraccess
 
volevo dire:
cio' che fa l'.hraccess
 

 di un routing particolare, ad esempio per qualche UnitTest
 
class miorouter {
 
     static private function getDefaultData() {
 
         $data = array(
             'controller' => 'welcome',
             'action' => 'index'
         );
 
         for ($i = 0; $i < 3; $i++) {
             $data['params' . $i] = null;
         }
 
         return $data;
     }
 
     static function execute() {
 
         $data = self::getDefaultData();
 
         // 'sovrascrittura' dati di default
         foreach ($_GET as $name => $value) {
             $data[$name] = $value;
         }
 
         $class = loader::loadController($data['controller']);
 
         call_user_func_array(
             array($class, $data['action']),
             $data['params']
         );
     }
 
}
 
In pratica se volessi aggiungere al mio framework, la funzionalità di 
test, dovrei fare questa modifica:
 
if ($data['controller'] == 'tests') {// se si tratta di un test
         $class = new testCase(...);
}else{// altrimenti carica uno dei normali controller
         $class = loader::loadController($data['controller']);
}
 
Naturalmente però ogni volta che voglio 'installare' una funzionalità 
aggiuntiva, dovrei intervenire sul router.
Ciò naturalmente non mi piace, e vorrei che quindi il router fosse 
configurabile, accettando eventuali 'rotte' (regole) aggiuntive, ad 
esempio implementando la funzione: miorouter::addRoute(...)
 
Il problema però è che voglio trovare un sistema ottimale per fargli 
elaborare le regole.
Per il momento sono un po' fuorviato...

Solitamente si usa un approccio diverso, cioè una volta identificato il controller, il metodo (action) e i parametri, si decide cosa fare.
 
Se usi un minimo di logica per organizzare la struttura delle cartelle (e nomi dei file/classi) dei tuoi controller puoi (come fanno un pò tutti) controllare se il controller richiesto esiste e ha il metodo richiesto, altrimenti sparare un 404.
 
Es:
 
/user/register -> Controller_User, metodo register()
/pinco/palla -> Controller_Pinco, metodo palla()
 
Te la giochi un pò con l'autoload (o puoi gestire tutto manualmente, come preferisci)
 
Ti consiglio di dare un'occhiata a come gestisce il routing Kohana, è un pò dispersivo e forse _troppo_ dinamico, ma è fatto molto bene.
 
Inoltre, personalmente ti consiglio di lasciare il .htaccess il più pulito possibile e lasciare la logica all'applicazione, io di solito mando tutta la querystring all'index.php (con qualche piccola accortezza).
 
Quindi se mi arriva 
example.com/pinco/palla/foo/bar
 il mio index riceve in $_GET['q'] = 'pinco/palla/foo/bar' e dopo ci pensa il router ad analizzare la richiesta

 Se usi un minimo di logica per organizzare la struttura delle cartelle (e nomi dei file/classi) dei tuoi controller puoi
 > (come fanno un pò tutti) controllare se il controller richiesto 
esiste e ha il metodo richiesto, altrimenti sparare un 404.
 
una domanda:
come si fa a generare il 404?


In php intendi?
Come si genera qualsiasi altro codice HTTP di risposta
 
http://php.net/manual/en/function.header.php
 
 
-- 
I fatti mi cosano

 
http://php.net/manual/en/function.header.php
 
 
ok, non ci avevo pensato