Question

J'écris donc un cadre sur lequel je veux fonder quelques applications sur lesquelles je travaille (le cadre est là, donc j'ai un environnement de travail et un système qui me permettra, par exemple, de utilisez une connexion unique)

Je souhaite créer ce cadre et ses applications utilisent une architecture orientée ressources.

Maintenant, je veux créer une classe de routage d'URL qui puisse être étendue par les auteurs d'APP (et peut-être aussi par les utilisateurs de CMS App, mais c'est WAYYYY à venir) et j'essaie de trouver le meilleur moyen de le faire. en regardant comment les autres applications le font.

Était-ce utile?

La solution

Je préfère utiliser reg ex plutôt que de créer mon propre format car il est de notoriété publique. J'ai écrit une petite classe que j'utilise qui me permet d'imbriquer ces tables de routage régulières. J'avais l'habitude d'utiliser quelque chose de similaire qui était implémenté par héritage mais qui n'avait pas besoin d'héritage, je l'ai donc réécrit.

Je fais un enregistrement ex sur une clé et mappe à ma propre chaîne de contrôle. Prenons l'exemple ci-dessous. Je visite / api / related / joe et ma classe de routeur crée un nouvel objet ApiController et appelle sa méthode relatedDocuments (array ('tags' = > 'joe '));

// the 12 strips the subdirectory my app is running in
$index = urldecode(substr(

Je préfère utiliser reg ex plutôt que de créer mon propre format car il est de notoriété publique. J'ai écrit une petite classe que j'utilise qui me permet d'imbriquer ces tables de routage régulières. J'avais l'habitude d'utiliser quelque chose de similaire qui était implémenté par héritage mais qui n'avait pas besoin d'héritage, je l'ai donc réécrit.

Je fais un enregistrement ex sur une clé et mappe à ma propre chaîne de contrôle. Prenons l'exemple ci-dessous. Je visite / api / related / joe et ma classe de routeur crée un nouvel objet ApiController et appelle sa méthode relatedDocuments (array ('tags' = > 'joe '));

Route::process($index, array(
    "#^api/related/(.*)$#Di"    => "ApiController/relatedDocuments/tags",

    "#^thread/(.*)$#Di"         => "ThreadController/route/uri",

    "#^ajax/tag/(.*)/(.*)$#Di"  => "TagController/add/id/tags",
    "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id",
    "#^ajax/reply/(.*)$#Di"     => "ArticleController/newReply/id",
    "#^ajax/toggle/(.*)$#Di"    => "ApiController/toggle/toggle",

    "#^$#Di"                    => "HomeController",
));

Afin de limiter les erreurs et la simplicité, vous pouvez subdiviser votre table. De cette façon, vous pouvez placer la table de routage dans la classe qu’elle contrôle. En prenant l'exemple ci-dessus, vous pouvez combiner les trois appels de thread en un seul.

function route($args) {
    Route::process($args['uri'], array(
        "#^(.*)/post$#Di"    => "ThreadController/post/title",
        "#^(.*)/reply$#Di"   => "ThreadController/reply/title",
        "#^(.*)$#Di"         => "ThreadController/thread/title",
    ));
}

Ensuite, vous définissez ThreadController :: route comme ceci.

<*>

Vous pouvez également définir les valeurs par défaut de votre chaîne de routage à droite. Il suffit de ne pas oublier de les documenter ou vous allez confondre les gens. J'appelle actuellement index si vous n'incluez pas un nom de fonction à droite. Voici mon code actuel. Vous voudrez peut-être le modifier pour gérer les erreurs comme vous le souhaitez et / ou les actions par défaut.

SERVER["REQUEST_URI"], 12)); Route::process($index, array( "#^api/related/(.*)$#Di" => "ApiController/relatedDocuments/tags", "#^thread/(.*)/post$#Di" => "ThreadController/post/title", "#^thread/(.*)/reply$#Di" => "ThreadController/reply/title", "#^thread/(.*)$#Di" => "ThreadController/thread/title", "#^ajax/tag/(.*)/(.*)$#Di" => "TagController/add/id/tags", "#^ajax/reply/(.*)/post$#Di"=> "ThreadController/ajaxPost/id", "#^ajax/reply/(.*)$#Di" => "ArticleController/newReply/id", "#^ajax/toggle/(.*)$#Di" => "ApiController/toggle/toggle", "#^$#Di" => "HomeController", ));

Afin de limiter les erreurs et la simplicité, vous pouvez subdiviser votre table. De cette façon, vous pouvez placer la table de routage dans la classe qu’elle contrôle. En prenant l'exemple ci-dessus, vous pouvez combiner les trois appels de thread en un seul.

<*>

Ensuite, vous définissez ThreadController :: route comme ceci.

<*>

Vous pouvez également définir les valeurs par défaut de votre chaîne de routage à droite. Il suffit de ne pas oublier de les documenter ou vous allez confondre les gens. J'appelle actuellement index si vous n'incluez pas un nom de fonction à droite. Voici mon code actuel. Vous voudrez peut-être le modifier pour gérer les erreurs comme vous le souhaitez et / ou les actions par défaut.

Autres conseils

Encore un autre cadre? - de toute façon ...

Le truc, c’est que le routage consiste à tout transférer à votre contrôleur de routage.

Vous voudrez probablement utiliser quelque chose de similaire à ce que j'ai documenté ici:

http://www.hm2k.com/posts/friendly-urls

La deuxième solution vous permet d'utiliser des URL similaires à Zend Framework.

Utilisez une liste de regex pour faire correspondre l'objet que je devrais utiliser

Par exemple

^/users/[\w-]+/bookmarks/(.+)/$
^/users/[\w-]+/bookmarks/$
^/users/[\w-]+/$

Avantages: simple et agréable, me permet de définir directement les itinéraires Inconvénients: il faudrait commander, ne facilitant pas l'ajout de nouvelles choses (très sujettes aux erreurs)

C’est, autant que je sache, comment Django le fait

Je pense que de nombreux frameworks utilisent une combinaison de mod_rewrite d'Apache et d'un contrôleur frontal. Avec mod_rewrite, vous pouvez transformer une URL du type suivant: / people / get / 3 en ceci: index.php? controller = personnes & méthode = get & id = 3. Index.php implémenterait votre contrôleur frontal qui achemine la demande de page en fonction des paramètres donnés.

Comme vous vous en doutez, il existe de nombreuses façons de le faire.

Par exemple, dans le Slim Framework , un exemple de moteur de routage peut être le suivant (basé sur la motif $ {OBJECT} - > $ {METHODE DE DEMANDE} ($ {PATTERM}, $ {CALLBACK}) ):

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

Ainsi, l'instance initialisée ( $ app ) obtient une méthode par méthode de requête (par exemple, get, post, put, delete, etc.) et obtient une route en tant que premier paramètre et un rappel en tant que deuxième. .

La route peut obtenir des jetons - qui est "variable". qui changera au moment de l’exécution en fonction de certaines données (telles que le nom du membre, l’identifiant de l’article, le nom de l’emplacement de l’organisation ou autre chose, comme vous le savez, comme dans tout contrôleur de routage).

Personnellement, j'aime bien cette façon mais je ne pense pas que ce sera assez flexible pour un framework avancé.

Depuis que je travaille actuellement avec ZF et Yii, j’ai un exemple de routeur que j'ai créé dans le cadre d’une entreprise pour laquelle je travaille:

Le moteur de routage est basé sur regex (similaire à celui de @ gradbot) mais a une conversation à double sens. Ainsi, si l'un de vos clients ne peut pas exécuter mod_rewrite (dans Apache) ou ajouter des règles de réécriture sur son serveur, il peut toujours utiliser les URL traditionnelles avec une chaîne de requête.

Le fichier contient un tableau, chacun d’eux étant similaire à cet exemple:

Comme vous vous en doutez, il existe de nombreuses façons de le faire.

Par exemple, dans le Slim Framework , un exemple de moteur de routage peut être le suivant (basé sur la motif $ {OBJECT} - > $ {METHODE DE DEMANDE} ($ {PATTERM}, $ {CALLBACK}) ):

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

Ainsi, l'instance initialisée ( $ app ) obtient une méthode par méthode de requête (par exemple, get, post, put, delete, etc.) et obtient une route en tant que premier paramètre et un rappel en tant que deuxième. .

La route peut obtenir des jetons - qui est "variable". qui changera au moment de l’exécution en fonction de certaines données (telles que le nom du membre, l’identifiant de l’article, le nom de l’emplacement de l’organisation ou autre chose, comme vous le savez, comme dans tout contrôleur de routage).

Personnellement, j'aime bien cette façon mais je ne pense pas que ce sera assez flexible pour un framework avancé.

Depuis que je travaille actuellement avec ZF et Yii, j’ai un exemple de routeur que j'ai créé dans le cadre d’une entreprise pour laquelle je travaille:

Le moteur de routage est basé sur regex (similaire à celui de @ gradbot) mais a une conversation à double sens. Ainsi, si l'un de vos clients ne peut pas exécuter mod_rewrite (dans Apache) ou ajouter des règles de réécriture sur son serveur, il peut toujours utiliser les URL traditionnelles avec une chaîne de requête.

Le fichier contient un tableau, chacun d’eux étant similaire à cet exemple:

Comme vous vous en doutez, il existe de nombreuses façons de le faire.

Par exemple, dans le Slim Framework , un exemple de moteur de routage peut être le suivant (basé sur la motif $ {OBJECT} - > $ {METHODE DE DEMANDE} ($ {PATTERM}, $ {CALLBACK}) ):

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

Ainsi, l'instance initialisée ( $ app ) obtient une méthode par méthode de requête (par exemple, get, post, put, delete, etc.) et obtient une route en tant que premier paramètre et un rappel en tant que deuxième. .

La route peut obtenir des jetons - qui est "variable". qui changera au moment de l’exécution en fonction de certaines données (telles que le nom du membre, l’identifiant de l’article, le nom de l’emplacement de l’organisation ou autre chose, comme vous le savez, comme dans tout contrôleur de routage).

Personnellement, j'aime bien cette façon mais je ne pense pas que ce sera assez flexible pour un framework avancé.

Depuis que je travaille actuellement avec ZF et Yii, j’ai un exemple de routeur que j'ai créé dans le cadre d’une entreprise pour laquelle je travaille:

Le moteur de routage est basé sur regex (similaire à celui de @ gradbot) mais a une conversation à double sens. Ainsi, si l'un de vos clients ne peut pas exécuter mod_rewrite (dans Apache) ou ajouter des règles de réécriture sur son serveur, il peut toujours utiliser les URL traditionnelles avec une chaîne de requête.

Le fichier contient un tableau, chacun d’eux étant similaire à cet exemple:

Comme vous vous en doutez, il existe de nombreuses façons de le faire.

Par exemple, dans le Slim Framework , un exemple de moteur de routage peut être le suivant (basé sur la motif $ {OBJECT} - > $ {METHODE DE DEMANDE} ($ {PATTERM}, $ {CALLBACK}) ):

$app->get("/Home", function() {
    print('Welcome to the home page');
}

$app->get('/Profile/:memberName', function($memberName) {
    print( 'I\'m viewing ' . $memberName . '\'s profile.' );
}

$app->post('/ContactUs', function() {
    print( 'This action will be fired only if a POST request will occure');
}

Ainsi, l'instance initialisée ( $ app ) obtient une méthode par méthode de requête (par exemple, get, post, put, delete, etc.) et obtient une route en tant que premier paramètre et un rappel en tant que deuxième. .

La route peut obtenir des jetons - qui est "variable". qui changera au moment de l’exécution en fonction de certaines données (telles que le nom du membre, l’identifiant de l’article, le nom de l’emplacement de l’organisation ou autre chose, comme vous le savez, comme dans tout contrôleur de routage).

Personnellement, j'aime bien cette façon mais je ne pense pas que ce sera assez flexible pour un framework avancé.

Depuis que je travaille actuellement avec ZF et Yii, j’ai un exemple de routeur que j'ai créé dans le cadre d’une entreprise pour laquelle je travaille:

Le moteur de routage est basé sur regex (similaire à celui de @ gradbot) mais a une conversation à double sens. Ainsi, si l'un de vos clients ne peut pas exécuter mod_rewrite (dans Apache) ou ajouter des règles de réécriture sur son serveur, il peut toujours utiliser les URL traditionnelles avec une chaîne de requête.

Le fichier contient un tableau, chacun d’eux étant similaire à cet exemple:

<*>

Vous pouvez également utiliser des combinaisons plus complexes, telles que:

<*>

L’essentiel, à mon avis, c’est que les possibilités sont infinies. Tout dépend de la complexité de votre cadre et de ce que vous souhaitez en faire.

S'il s'agit, par exemple, d'un service Web ou d'un simple wrapper de site Web, il suffit de suivre le style d'écriture de Slim Framework: un code très simple et esthétique.

Cependant, si vous souhaitez développer des sites complexes à l'aide de ce logiciel, je pense que regex est la solution.

Bonne chance! :)

FURLTEMPLATES['login'] = array( 'i' => array( // Input - how the router parse an incomming path into query string params 'pattern' => '@Members/Login/?@i', 'matches' => array( 'Application' => 'Members', 'Module' => 'Login' ), ), 'o' => array( // Output - how the router parse a query string into a route '@Application=Members(&|&amp;)Module=Login/?@' => 'Members/Login/' ) );

Vous pouvez également utiliser des combinaisons plus complexes, telles que:

<*>

L’essentiel, à mon avis, c’est que les possibilités sont infinies. Tout dépend de la complexité de votre cadre et de ce que vous souhaitez en faire.

S'il s'agit, par exemple, d'un service Web ou d'un simple wrapper de site Web, il suffit de suivre le style d'écriture de Slim Framework: un code très simple et esthétique.

Cependant, si vous souhaitez développer des sites complexes à l'aide de ce logiciel, je pense que regex est la solution.

Bonne chance! :)

FURLTEMPLATES['article'] = array( 'i' => array( 'pattern' => '@CMS/Articles/([\d]+)/?@i', 'matches' => array( 'Application' => "CMS", 'Module' => 'Articles', 'Sector' => 'showArticle', 'ArticleID' => '$1' ), ), 'o' => array( '@Application=CMS(&|&amp;)Module=Articles(&|&amp;)Sector=showArticle(&|&amp;)ArticleID=([\d]+)@' => 'CMS/Articles/$4' ) );

Vous pouvez également utiliser des combinaisons plus complexes, telles que:

<*>

L’essentiel, à mon avis, c’est que les possibilités sont infinies. Tout dépend de la complexité de votre cadre et de ce que vous souhaitez en faire.

S'il s'agit, par exemple, d'un service Web ou d'un simple wrapper de site Web, il suffit de suivre le style d'écriture de Slim Framework: un code très simple et esthétique.

Cependant, si vous souhaitez développer des sites complexes à l'aide de ce logiciel, je pense que regex est la solution.

Bonne chance! :)

FURLTEMPLATES['login'] = array( 'i' => array( // Input - how the router parse an incomming path into query string params 'pattern' => '@Members/Login/?@i', 'matches' => array( 'Application' => 'Members', 'Module' => 'Login' ), ), 'o' => array( // Output - how the router parse a query string into a route '@Application=Members(&|&amp;)Module=Login/?@' => 'Members/Login/' ) );

Vous pouvez également utiliser des combinaisons plus complexes, telles que:

<*>

L’essentiel, à mon avis, c’est que les possibilités sont infinies. Tout dépend de la complexité de votre cadre et de ce que vous souhaitez en faire.

S'il s'agit, par exemple, d'un service Web ou d'un simple wrapper de site Web, il suffit de suivre le style d'écriture de Slim Framework: un code très simple et esthétique.

Cependant, si vous souhaitez développer des sites complexes à l'aide de ce logiciel, je pense que regex est la solution.

Bonne chance! :)

Vous devriez vérifier Pux https://github.com/c9s/Pux

Voici le synopsis

<?php
require 'vendor/autoload.php'; // use PCRE patterns you need Pux\PatternCompiler class.
use Pux\Executor;

class ProductController {
    public function listAction() {
        return 'product list';
    }
    public function itemAction($id) { 
        return "product $id";
    }
}
$mux = new Pux\Mux;
$mux->any('/product', ['ProductController','listAction']);
$mux->get('/product/:id', ['ProductController','itemAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$mux->post('/product/:id', ['ProductController','updateAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$mux->delete('/product/:id', ['ProductController','deleteAction'] , [
    'require' => [ 'id' => '\d+', ],
    'default' => [ 'id' => '1', ]
]);
$route = $mux->dispatch('/product/1');
Executor::execute($route);

Le framework MVC de Zend utilise par défaut une structure comme

/router/controller/action/key1/value1/key2/value2

router est le fichier du routeur (mappé via mod_rewrite , contrôleur provient d'un gestionnaire d'actions du contrôleur défini par une classe qui en dérive from Zend_Controller_Action et action fait référence à une méthode du contrôleur, nommée actionAction . Les paires clé / valeur peuvent être placées dans n'importe quel ordre et sont disponibles pour le méthode d'action en tant que tableau associatif.

J'ai déjà utilisé quelque chose de similaire dans mon propre code et jusqu'à présent, cela fonctionnait assez bien.

Essayez de regarder le MVC .
Zend Framework l'utilise par exemple, mais aussi CakePHP, CodeIgniter, ...

Personnellement, je n'aime pas le modèle MVC, mais il est la plupart du temps implémenté sous la forme "Affichage pour le Web". composant.

La décision dépend en grande partie de vos préférences ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top