2011-06-28 3 views
1

J'essaie de créer un système de routage basé sur des annotations (quelque chose comme sur Recess Framework).Système de routage PHP

<?php 

class MyController extends ActionController { 

    /** !Route GET /hello/$firstname/$lastname **/ 
    public function helloAction($firstname, $lastname) { 
     echo('Hello '.$firstname.' '.$lastname); 
    } 
} 

?> 

Si je vais http://domain.com/hello/James/Bond j'obtenir

Hello James Bond 

J'ai donc deux questions:

1) Est-ce une bonne idée? Avantages et inconvénients vs système de routage centralisé (comme Zend Framework). Peut-être que je ne vois pas de problèmes que mon surgissement plus tard avec cette technique de routage.

2) Comment vérifier les itinéraires en double s'il y a dans regexp routes

<?php 

class MyController extends ActionController { 

    /** 
    *!Route GET /test/$id = { 
    * id: [a-z0-9] 
    *} 
    **/ 
    public function testAction($id) { 
     echo($id); 
    } 

    /** 
    *!Route GET /test/$id = { 
    * id: [0-9a-z] 
    *} 
    **/ 
    public function otherTestAction($id) { 
     echo($id); 
    } 
} 

?> 

Je reçois deux itinéraires: /test/[a-z0-9]/ et /test/[0-9a-z]/ et si je vais à http://domain.com/test/a12/ les deux voies sont valides.

Merci :)

Répondre

1

Moins:

  • Il peut être difficile de garder une vue d'ensemble des applications d'URL de toutes les méthodes de votre serveur.
  • Pour modifier une URL, vous devez modifier le code source, le mappage n'est pas séparé de l'application.

Si la signature de la méthode et la cartographie sont toujours aussi liés que l'exemple que vous pouvez utiliser la réflexion pour extraire la cartographie où helloAction est choisi comme /bonjour et chaque argument de la méthode est un sous-répertoire de ce dans le commander comme ils sont définis.

Ensuite, l'annotation ne serait pas nécessaire de dupliquer l'URL, seul le fait que la méthode est un point final, quelque chose comme ceci:

<?php 
    class MyController extends ActionController { 

     /** !endpoint(method=GET) **/ 
     public function helloAction($firstname, $lastname) { 
      echo('Hello '.$firstname.' '.$lastname); 
     } 
} 
+0

+1 pour une idée intéressante. Je vais prendre cela en considération. Merci – Tomas

0
  1. Je pense qu'il est une bonne idée/code Découplage et point d'entrée semble à peu près utilisé partout

  2. Habituellement, vous ne vérifiez pas: le premier qui correspond gagne.

+0

est-ce qu'il ne serait pas difficile de détecter une erreur alors sont des itinéraires en double et vous obtenez d'autres actions exécutées que vous avez réellement prévu? – Tomas

+0

Pour moi, cela ne déconnecte pas le code en point de terminaison, puisque le code contient le point de terminaison. – Kwebble

+0

@thomas: habituellement dans le débogage, vous devriez être capable de détecter quelle action a été exécutée, donc cela ne devrait pas poser de problème – Arend

0

Cela est une excellente idée, aussi longtemps que vous mettez en cache les routes compilées dans la production. Il y a un coût associé à l'analyse de vos fichiers lors du routage, donc vous voulez éviter cela lorsque vous ne développez pas.

Pour vérifier les doublons, ne pas vérifier en comparant la déclaration. Vérifiez simplement lors du routage. Si deux règles correspondent, lancez un DuplicateRouteException. Ainsi, lors du routage http://domain.com/test/a12/, vous verrez que les deux routes sont valides et lèveront l'exception.

+0

Je ne pense pas que vérifier les itinéraires en double lorsque le routage est une bonne idée, car lorsqu'il est difficile de tester toutes les routes et en mode de production, les utilisateurs ne doivent pas voir 'DuplicateRouteException'. – Tomas

+0

@Tomas: C'est la seule façon possible de tester les doublons dans le cas d'expressions régulières '/ test/[0-9] +' et '/ test/[az] * [0-9] +' sont deux des expressions régulières équivalentes pouvant conduire à dupliquer des routes. En production, votre gestionnaire d'erreur peut simplement router le trafic vers une page d'erreur ("" Oups, quelque chose s'est mal passé. "' '). Enregistrez l'exception. –

2

Essayez d'utiliser le Java annotation format qui devrait être beaucoup plus facile à analyser de façon uniforme.

Il ressemble à ceci:

<?php 
class MyController extends ActionController { 

    /** 
     @Route(get=/hello/$firstname/$lastname) 
     @OtherVal(var1=2,var2=foo) 
     @OtherVal2 
    **/ 
    public function helloAction($firstname, $lastname) { 
     echo('Hello '.$firstname.' '.$lastname); 
    } 
} 
?> 

et analyser l'annotation avec l'expression rationnelle suivante:

@(?P<annotation>[A-Za-z0-9_]*)(\((?P<params>[^\)]*))? 

Et bien sûr, cache ces si possible d'éviter l'analyse répétée.