PHP Uygulama URL Yönlendirme

7 Cevap php

Bu yüzden ben üzerinde çalışıyorum birkaç apps dayandırmak istediğiniz bir çerçeve yazıyorum (framework yüzden orada çalışmak için bir ortam var, ve ben, örneğin, bir tek kullanmak sağlayacak bir sistem sign-on)

Ben bu çerçeve yapmak istiyorum, ve uygulamalar bir Kaynak Odaklı Mimari kullanımı vardır.

Şimdi, APP yazarlar tarafından genişletilebilir bir URL yönlendirme sınıf oluşturmak istiyorsanız (CMS Uygulaması kullanıcılar tarafından da muhtemelen ve, ama bu gelecekte WAYYYY ileride) ve ben bakarak bunu yapmak için en iyi şekilde anlamaya çalışıyorum diğer uygulamalar bunu nasıl.

Bazı cevapları kendim sonrası edeceğiz ve umarım, oylama bana bu iyi fikir ya da değil, ama aslında, ben PHP birden fazla uygulamayı yönlendirme en iyi yolu ne olurdu çalışmak isteyip istemediğinize karar vermenize yardımcı olacaktır.

Ben eklemek herhangi bir oylama aswell yöntemler önermek için çekinmeyin. Ben kullanarak sonuna kadar başkasının yöntem ise, ben bu cevabı kabul edeceğiz.

7 Cevap

Bu ortak bir şeydir beri benim kendi biçimini yapım üzerinde Tescil eski kullanmayı tercih. Sanırım bu belgeli eski yönlendirme tabloları yuva için bana izin verir hangi kullanmak bir küçük sınıf yazdı. Ben miras tarafından yürütülen benzer bir şey kullanmak için kullanabilirsiniz ama ben yeniden yazdım bu yüzden miras gerek yoktu.

Ben kendi kontrol dize için bir anahtar ve harita üzerinde bir reg eski yapın. Aşağıda örnek alın. I /api/related/joe ziyaret ve benim yönlendirici class ApiController yeni bir nesne oluşturur ve bu yöntem çağırır 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",
));

Hataları aşağı tutmak için ve basitlik yukarı Eğer tablo alt bölümlere. Bu şekilde denetlediği sınıfa yönlendirme tablosunu koyabilirsiniz. Eğer bir tek içine üç iplik aramaları birleştirebilirsiniz Yukarıdaki örnek alınarak.

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

Sonra bu böyle olmak ThreadController :: yol tanımlar.

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

Ayrıca size sağda yönlendirme dize için istedikleri varsayılan tanımlayabilirsiniz. Sadece bunları belgelemek için unutma ya da insanları yanıltır. Eğer sağda bir işlev adı dahil etmezseniz ben şu anda bir dizin arıyorum. Here benim geçerli kod. Sizin gibi ve veya varsayılan eylemler nasıl hataları işlemek için değiştirmek isteyebilirsiniz.

Ben kullanarak hangi nesne maç Regexs bir listesini kullanın

Örneğin

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

Pros: Nice and simple, lets me define routes directly Cons: Would have to be ordered, not making it easy to add new things in (very error prone)

Bu Django bunu nasıl yaptığını, afaik olduğunu

Yine başka bir framework? - Neyse ...

Yönlendirme, yönlendirme denetleyicisi üzerinden tüm geçmektir ile hiledir.

Herhalde burada belgelenen ettik ne benzer bir şey kullanmak isterdim:

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

İkinci çözüm Zend Framework benzer URL'leri kullanmanıza olanak sağlar.

Tahmin edebileceğiniz gibi, bunu yapmak için pek çok yolu vardır.

Örneğin, Slim Framework olarak, yönlendirme motoru bir örnek olabilir folllowing (modeline dayanarak ${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');
}

Yani, başlatılan örneği ($app) (örneğin, yazı almak koymak, silme vb) isteği yöntemine göre bir yöntem alır ve ikinci olarak ilk parametre ve geri arama gibi bir yol alır.

(- Bilirsin, sadece her yönlendirme denetleyicisi gibi bu tür üye adı, makale id, kuruluş yeri adı ya da her neyse), bazı verilere dayalı zamanında değişecek "değişken" dir - rota belirteçleri alabilirsiniz.

Şahsen, bu şekilde seversin ama gelişmiş bir çerçeve için yeterince esnek olacak sanmıyorum.

Ben ZF ve Yii ile şu anda çalışıyorum beri, ben ne için çalışıyorum bir şirket için bir çerçevenin parçası olarak yarattık yönlendirici bir örnek var:

Rota motor (@ gradbot ait benzer) regex dayalı, ancak iki yönlü bir konuşma var, bu yüzden senin bir istemci (Apache) mod_rewrite'ın çalıştırmak ya da onun sunucuda kuralları yeniden ekleyebilirsiniz olamaz eğer, o Hala sorgu dizesi ile geleneksel URL'leri kullanabilirsiniz.

Dosya bir dizi, bunu her biri, her bir öğe bu örneğe benzer içerir:

$_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/'
    )
);

Ayrıca gibi daha karmaşık kombinasyonlarını kullanabilirsiniz:

$_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'
    )
);

Alt satırda, ben düşünüyorum, sadece bağlıdır, olasılıklar sınırsız olduğunu ne kadar karmaşık sizin çerçeve olmak isteyen ve ne onunla yapmak istiyoruz.

Eğer durum bu ise, örneğin, sadece bir web hizmeti veya basit web sitesi sarıcı olması amaçlanmıştır - sadece yazma Slim çatınızdaki tarzı ile gitmek - çok kolay ve iyi görünümlü kodu.

Bunu kullanarak karmaşık siteleri geliştirmek istiyorsanız Ancak, ben regex çözüm olduğunu düşünüyorum.

İyi şanslar! :)

Sen PUX kontrol etmelisiniz https://github.com/c9s/Pux

İşte özet olduğunu

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

Varsayılan zerdüştlerin MVC çerçevesi gibi bir yapı kullanır

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

burada router mod_rewrite, controller {[(3) türeyen bir sınıf tarafından tanımlanan bir kontrolör eylemciye dan efllenir yönlendirici dosyası (bir ]} ve action adında denetleyicisi, actionAction bir yöntem başvuruyor. anahtar / değer çiftleri herhangi bir sırayla gitmek ve bir ilişkisel dizi olarak eylem yöntemi mevcuttur olabilir.

Ben kendi kodunda geçmişte benzer bir şey kullandım ve şimdiye kadar oldukça iyi çalıştı.

Try taking look at MVC pattern.
Zend Framework uses it for example, but also CakePHP, CodeIgniter, ...

Ben şahsen MVC modelini sevmiyorum, ama bu bileşen "web için View" olarak uygulanan çoğu zaman bulunuyor.

Karar oldukça fazla tercihine bağlıdır ...