2008-09-24 24 views
15

तो मैं एक ढांचा लिख ​​रहा हूं जिस पर मैं कुछ ऐप्स का आधार बनाना चाहता हूं जिन पर मैं काम कर रहा हूं (ढांचा है इसलिए मेरे पास काम करने का माहौल है, और एक प्रणाली जो मुझे देगी उदाहरण के लिए, एक एकल साइन-ऑन का उपयोग करें)PHP आवेदन यूआरएल रूटिंग

मैं इस ढांचे को बनाना चाहता हूं, और ऐप्स ने संसाधन संसाधन उन्मुख वास्तुकला का उपयोग किया है।

अब, मैं एक यूआरएल रूटिंग क्लास बनाना चाहता हूं जो एपीपी लेखकों (और संभवतः सीएमएस ऐप उपयोगकर्ताओं द्वारा भी विस्तारित है), लेकिन भविष्य में यह वैसे भी आगे है) और मैं करने का सबसे अच्छा तरीका जानने की कोशिश कर रहा हूं यह देखकर कि अन्य ऐप्स इसे कैसे करते हैं।

उत्तर

12

मैं सामान्य ज्ञान के बाद से अपना खुद का प्रारूप बनाने पर reg ex का उपयोग करना पसंद करता हूं। मैंने एक छोटी सी कक्षा लिखी जो मैं उपयोग करता हूं जो मुझे इन reg ex routing टेबलों को घोंसला करने की अनुमति देता है। मैं कुछ ऐसा उपयोग करने के लिए उपयोग करता हूं जो विरासत द्वारा कार्यान्वित किया गया था लेकिन इसे विरासत की आवश्यकता नहीं थी इसलिए मैंने इसे फिर से लिखा।

मैं एक कुंजी पर एक reg ex और अपने नियंत्रण स्ट्रिंग के लिए मानचित्र करते हैं। नीचे उदाहरण लें।मैं /api/related/joe जाएँ और मेरी रूटर वर्ग एक नई वस्तु ApiController बनाता है और यह विधि 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", 
)); 

है आदेश में त्रुटियों कम रखने के लिए और सादगी अप आप अपनी तालिका उप-कहता है। इस तरह आप रूटिंग टेबल को उस कक्षा में डाल सकते हैं जो इसे नियंत्रित करता है। उपर्युक्त उदाहरण लेते हुए आप तीन थ्रेड कॉल को एक ही में जोड़ सकते हैं।

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

फिर आप इस तरह होने के लिए थ्रेडकंट्रोलर :: मार्ग को परिभाषित करते हैं।

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

इसके अलावा आप दाईं ओर अपनी रूटिंग स्ट्रिंग के लिए जो भी डिफ़ॉल्ट चाहते हैं उसे परिभाषित कर सकते हैं। बस उन्हें दस्तावेज करना न भूलें या आप लोगों को भ्रमित करेंगे। यदि आप दाईं ओर फ़ंक्शन नाम शामिल नहीं करते हैं तो मैं वर्तमान में इंडेक्स को कॉल कर रहा हूं। Here मेरा वर्तमान कोड है। आप त्रुटियों को संभालने के लिए इसे बदलना चाहते हैं कि आप कैसे पसंद करते हैं या डिफ़ॉल्ट क्रियाएं।

+0

दूसरा उदाहरण बहुत कुछ है जो मैं वास्तव में करने के बारे में सोच रहा था ... (RoR शैली) - मैं आपके कोड को देख लूंगा। – Mez

+0

यह Django पायथन के समान है। – kta

1

मैच के लिए जो आपत्ति मैं

का उपयोग करना चाहिए उदाहरण

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

लिए Regexs की एक सूची का उपयोग पेशेवरों: अच्छा और सरल, चलो मुझे मार्गों सीधे परिभाषित विपक्ष: आदेश दिया जा करने के लिए होता है, यह (बहुत प्रवण त्रुटि) में नई चीजों को जोड़ने के लिए आसान नहीं बनाने

यह afaik है, कैसे Django करता है यह

-4

01 पर नज़र डालने का प्रयास करेंपैटर्न।
Zend फ्रेमवर्क उदाहरण के लिए इसे इस्तेमाल करता है, लेकिन यह भी CakePHP, CodeIgniter ...

मेरे व्यक्तिगत रूप से MVC मॉडल पसंद नहीं है, लेकिन यह समय के रूप में "वेब के लिए देखें" घटक कार्यान्वित के सबसे है।

निर्णय काफी प्राथमिकता पर निर्भर करता ...

+0

मैं एक MVC बात का उपयोग कर रहा है। मैं तकनीकी पक्ष या यूआरएल रूटिंग की बात कर रहा हूं। यह मेरे प्रश्न का उत्तर नहीं है – Mez

0

मुझे लगता है कि चौखटे का एक बहुत अपाचे के mod_rewrite और एक सामने नियंत्रक का एक संयोजन का उपयोग करें। Mod_rewrite के साथ, आप इस तरह एक यूआरएल बदल सकते हैं:/लोग/get/3 इसमें: index.php? नियंत्रक = लोग & विधि = & आईडी = 3 प्राप्त करें। Index.php आपके फ्रंट कंट्रोलर को कार्यान्वित करेगा जो दिए गए पैरामीटर के आधार पर पृष्ठ अनुरोध को रूट करता है।

+0

तो, स्पष्ट रूप से अपने गैर आरओए यूआरएल को अनदेखा कर रहा है, यह मेरे उत्तर के जैसा ही है, लेकिन विशिष्ट नियमों के साथ mod_rewrite का उपयोग करके, और कोड के बजाए विशिष्ट पैरामीटर के माध्यम से "रूटिंग" कर रहा है? – Mez

-1

Zend के MVC ढांचे डिफ़ॉल्ट रूप से की तरह

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

जहां router रूटर फ़ाइल (mod_rewrite के माध्यम से मैप किया गया है एक संरचना का उपयोग करता, controller एक नियंत्रक कार्रवाई हैंडलर जो एक वर्ग है कि Zend_Controller_Action और action से निकला द्वारा परिभाषित किया गया है से है actionAction नामक नियंत्रक में एक विधि का संदर्भ देता है। कुंजी/मान जोड़े किसी भी क्रम में जा सकते हैं और एक्शन विधि को एक एसोसिएटिव सरणी के रूप में उपलब्ध कर सकते हैं।

मैंने पैस में कुछ ऐसा ही उपयोग किया है टी अपने स्वयं के कोड में, और अब तक यह काफी अच्छी तरह से काम किया है।

+0

क्रियाएं आरओए सिस्टम पर लागू नहीं होती हैं, केवल आरपीसी स्टाइल सिस्टम – Mez

+0

पर आप बिल्कुल सही हैं ... मैंने सवाल को गलत तरीके से पढ़ा है। वह, और आरओए ने मुझे फेंक दिया। मैंने हमेशा इसे आरईएसटी कहा है। –

+0

हालांकि यह बिल्कुल सही नहीं है। सिर्फ रिकार्ड के लिए। – DanMan

2

फिर भी एक और ढांचा? - वैसे भी ...

यह चाल राउटिंग के साथ है जो इसे अपने रूटिंग नियंत्रक को पारित करने के लिए है।

आप शायद मैं यहाँ क्या प्रलेखित किया है करने के लिए कुछ इसी तरह का उपयोग करना चाहते हैं:

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

दूसरा समाधान आप Zend फ्रेमवर्क के समान URL का उपयोग करने के लिए अनुमति देता है।

+5

एक कामकाजी ढांचे का निर्माण एक दीक्षा संस्कार है। हर कोई PHP प्रोग्रामर इसे करना चाहिए। – user1709251

0

जैसा कि आप उम्मीद कर सकते हैं, ऐसा करने के कई तरीके हैं।

उदाहरण के लिए, Slim Framework में, मार्ग इंजन का एक उदाहरण हो सकता है folllowing (पैटर्न ${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'); 
} 

तो, initialized उदाहरण ($app) प्रति अनुरोध विधि एक विधि (हो जाता है उदाहरण के लिए प्राप्त करें, पोस्ट करें, डालें, हटाएं आदि) और दूसरे पैरामीटर के रूप में पहला पैरामीटर और कॉलबैक के रूप में मार्ग प्राप्त करें।

मार्ग टोकन प्राप्त कर सकता है - जो "चर" है जो रनटाइम पर कुछ डेटा (जैसे सदस्य का नाम, आलेख आईडी, संगठन स्थान का नाम या जो भी हो, आपको हर रूटिंग नियंत्रक की तरह) के आधार पर बदल जाएगा।

व्यक्तिगत रूप से, मुझे इस तरह से पसंद है लेकिन मुझे नहीं लगता कि यह एक उन्नत ढांचे के लिए पर्याप्त लचीला होगा।

जब से मैं जेडएफ और Yii साथ वर्तमान में काम कर रहा हूँ, मैं एक रूटर मैं एक कंपनी के लिए एक रूपरेखा के भाग के रूप बना लिया है मैं के लिए काम कर रहा हूँ का एक उदाहरण है:

मार्ग इंजन आधारित है रेगेक्स पर (@ ग्रेबॉट के समान), लेकिन दो-तरफा वार्तालाप मिला, इसलिए यदि आपका कोई ग्राहक mod_rewrite (अपाचे में) नहीं चला सकता है या उसके सर्वर पर रीराइट नियम जोड़ सकता है, तो वह अभी भी पारंपरिक का उपयोग कर सकता है क्वेरी स्ट्रिंग वाले यूआरएल।

फ़ाइल एक सरणी, तो इसके दोनों शामिल हैं, प्रत्येक आइटम इस उदाहरण के समान है:

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

तुम भी इस तरह के रूप में और अधिक जटिल संयोजन, उपयोग कर सकते हैं:

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

लब्बोलुआब , जैसा कि मुझे लगता है, यह है कि संभावनाएं अनंत हैं, यह केवल इस बात पर निर्भर करती है कि आप अपने ढांचे को कितना जटिल बनाना चाहते हैं और आप इसके साथ क्या करना चाहते हैं।

यदि यह है, उदाहरण के लिए, केवल एक वेब सेवा या सरल वेबसाइट रैपर होने का इरादा है - बस स्लिम फ्रेमवर्क की लेखन की शैली के साथ जाएं - बहुत आसान और अच्छा दिखने वाला कोड।

हालांकि, यदि आप इसका उपयोग कर जटिल साइट विकसित करना चाहते हैं, तो मुझे लगता है कि रेगेक्स समाधान है।

शुभकामनाएं! :)

0

आप Pux https://github.com/c9s/Pux

की जांच करनी चाहिए यहाँ सार

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

क्या आप 404 के लिए मार्ग जोड़ सकते हैं? –

संबंधित मुद्दे