Frage

So einen Rahmen Ich schreibe, auf das ich ein paar Anwendungen basieren soll, die ich arbeite (der Rahmen ist es, so habe ich ein Umfeld zu arbeiten, und ein System, das mich lassen, zum Beispiel, verwenden, um eine Single-sign-on)

Ich möchte diesen Rahmen machen, und die Anwendungen hat es eine Ressource Oriented Architecture verwenden.

Nun, ich mag eine URL-Routing-Klasse erstellen, die von APP Autoren erweiterbar ist (und möglicherweise auch von CMS App-Benutzer, aber das ist sehr weit nördlich voraus in der Zukunft) und ich versuche, den besten Weg, um herauszufinden, es zu tun indem sie sich, wie andere apps tun es.

War es hilfreich?

Lösung

Ich ziehe reg ex verwenden über mein eigenes Format zu machen, da es allgemein bekannt ist. Ich schrieb eine kleine Klasse, die ich verwende, die mir diese reg ex-Routing-Tabellen zu nisten können. Ich benutze zu nutzen, um etwas Ähnliches, die durch Vererbung umgesetzt wurde, aber es hat nicht Erbe brauchen, damit ich es neu geschrieben.

Ich habe eine reg ex auf einem Schlüssel und Karte zu meiner eigenen Steuer String. Nehmen Sie das Beispiel unten. Ich besuche /api/related/joe und meine Router Klasse erstellt ein neues Objekt ApiController und nennt es die Methode relatedDocuments(array('tags' => 'joe'));

// the 12 strips the subdirectory my app is running in
$index = urldecode(substr($_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",
));

Um Fehler zu halten und Einfachheit können Sie Ihre Tabelle unterteilen. Auf diese Weise können Sie die Routing-Tabelle in die Klasse setzen, die sie steuert. das obige Beispiel nehmen können Sie die drei Gewinde Anrufe zu einem einzigen kombiniert werden.

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",
));

Dann ThreadController Sie definieren :: Route so sein.

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

Sie können auch definieren, was defaults Sie auf der rechten Seite für Ihren Verteilkennung wollen. Nur vergessen Sie nicht, sie zu dokumentieren, oder Sie werden die Menschen verwirren. Ich rufe zur Zeit Index, wenn Sie auf der rechten Seite keinen Funktionsnamen enthalten. Hier ist mein aktueller Code. Sie können es ändern möchten, Fehler zu behandeln, wie Sie mögen und oder das Mahnverfahren.

Andere Tipps

Noch ein weiterer Rahmen? - sowieso ...

Der Trick ist, mit Routing ist es alle Controller über Ihr Routing zu übergeben.

Sie würde wahrscheinlich etwas Ähnliches verwenden möchten, was ich hier dokumentiert:

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

Die zweite Lösung ermöglicht es Ihnen, URLs ähnlich wie Zend Framework verwendet werden.

eine Liste von regexs Verwendungszweck anzupassen, welche das Objekt soll ich verwenden

Zum Beispiel

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

Pros: Schön und einfach, läßt definiere ich Routen direkt Nachteile: Müßten bestellt werden, nicht so dass es leicht, neue Dinge fügen in (sehr fehleranfällig)

Das ist afaik, wie Django tut es

Ich denke, eine Menge von Frameworks eine Kombination von Apache mod_rewrite und einem Front-Controller verwenden. Mit mod_rewrite können Sie eine URL wie folgt drehen: / Leute / / 3 in diese: index.php? controller = Menschen & method = bekommen & id = 3. Index.php würde Ihre Front-Controller, welche Routen die Seitenanfrage gegeben basierend auf den Parametern implementieren.

Wie zu erwarten, gibt es viele Möglichkeiten, es zu tun.

Zum Beispiel in Schlanke Rahmen , ein Beispiel für das Routing-Engine auf die die folllowing kann (basierend Muster ${OBJECT}->${REQUEST METHOD}(${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');
}

Also, die initialisierte Instanz ($app) wird ein Verfahren pro Request-Methode (zum Beispiel erhalten, Post, setzen, löschen etc.) und bekommt eine Route als ersten Parameter und Callback als die zweite.

Die Route kann Token erhalten - die „Variable“ ist, dass zur Laufzeit basierend auf einige Daten (wie Elementname, Artikelnummer, Organisation Ortsnamen oder was auch immer - wissen Sie, wie in jedem Routing-Controller) wird sich ändern.

Persönlich mag ich diese Art und Weise, aber ich glaube nicht, dass es flexibel genug, um für einen erweiterte Rahmen sein wird.

Da ich arbeite derzeit mit ZF und Yü, ich habe ein Beispiel für einen Router, den ich als Teil eines Rahmens für ein Unternehmen erstellt habe ich arbeite:

Die Route Motor basiert auf regex (ähnlich @ gradbot ist ein), sondern bekam ein Zwei-Wege-Gespräch, so dass, wenn ein Kunde von Ihnen nicht mod_rewrite (in Apache) laufen kann oder Rewrite-Regeln auf seinem Server hinzufügen, kann er oder sie nach wie vor die traditionellen URLs mit Query-String verwenden.

Die Datei enthält ein Array, wobei jedes davon, jedes Element ist ähnlich wie dieses Beispiel:

$_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(&|&)Module=Login/?@' => 'Members/Login/'
    )
);

Sie können auch komplexere Kombinationen, wie verwenden

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

Unterm Strich, so denke ich, ist, dass die Möglichkeiten sind endlos, es hängt nur ab, wie komplex Sie Ihren Rahmen zu sein und Sie mit ihm zu tun, was wollen.

Wenn es zum Beispiel nur sollte einen Web-Service oder einfachen Website-Wrapper sein - gehen Sie einfach mit Slim Rahmen Stil des Schreibens - sehr einfach und gut aussehenden Code.

Wenn Sie jedoch es mit komplexen Websites entwickeln wollen, glaube ich Regex ist die Lösung.

Viel Glück! :)

Sie sollten überprüfen Pux https://github.com/c9s/Pux

Hier ist die Übersicht

<?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);

Zend MVC-Framework verwendet standardmäßig eine Struktur wie

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

Dabei gelten router die Router-Datei (über mod_rewrite abgebildet, ist controller von einem Controller Action-Handler, die durch eine Klasse definiert ist, die von Zend_Controller_Action und action leitet verweist auf ein Verfahren, das in der Steuerung, genannt actionAction. Die Schlüssel / Wert-Paare gehen in beliebiger Reihenfolge und sind für die Aktionsmethode als assoziatives Array zur Verfügung.

Ich habe etwas ähnliches in der Vergangenheit in meinem eigenen Code verwendet, und bisher ist es ziemlich gut funktioniert.

Versuchen Sie Blick auf, MVC Muster.
Zend Framework verwendet es zum Beispiel, aber auch CakePHP, CodeIgniter, ...

Ich persönlich mag das MVC-Modell nicht, aber es ist die meiste Zeit als „Ansicht für das Web“ Komponente umgesetzt werden.

Die Entscheidung ziemlich abhängig von Vorlieben ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top