PHP के साथ URL पुनर्लेखन


139

मेरे पास एक URL है जो दिखता है:

url.com/picture.php?id=51

मैं उस URL को किस प्रकार परिवर्तित करूंगा:

picture.php/Some-text-goes-here/51

मुझे लगता है कि वर्डप्रेस वही करता है।

मैं PHP में मैत्रीपूर्ण URL बनाने के बारे में कैसे जाऊँ?


1
अपाचे फ़ाइलों के कॉन्फ़िगरेशन में आपको बहुत कुछ ट्विक करने की आवश्यकता है ... उदाहरण दें कि आपको वास्तव में क्या चाहिए? आप इस पाठ को कैसे सम्मिलित करते हैं? क्या यह पूर्वनिर्धारित है या यह गतिशील रूप से बनाया गया है? सही उत्तर प्राप्त करने के लिए जितनी जानकारी हो सके उतनी अधिक जानकारी दें ... और yea url थोड़ा अधिक वर्णनात्मक हो सकता है :)
user123_456

1
क्यों PHP? इसके लिए अपाचे की mod_rewriteजरूरत है और एसओ के बारे में यहां बहुत सारे सवाल हैं। और यदि आप "सोचते हैं" कि वर्डप्रेस वही करता है, तो आप बस इसे क्यों नहीं देखते हैं ? ;)
नीटनफिर

पढ़ें mod_rewrite

आप यह क्यों कर रहे हैं? क्या लक्ष्य URL का पुनर्लेखन है, यदि ऐसा है तो .htaccess या कुछ इसी तरह का उपयोग करें। यदि लक्ष्य केवल स्ट्रिंग को बदलना है, तो $ _GET केवल क्वेरिस्ट्रिंग प्राप्त करता है?
एडेनो' 20:13

पाठ एक छवि का शीर्षक होगा और फिर स्लैश के बाद आईडी :) मुझे अपाचे के mod_rewrite को पेश करना होगा। आशा है कि यह बहुत मुश्किल नहीं है: D
Jazerix

जवाबों:


194

आप अनिवार्य रूप से यह 2 तरीके कर सकते हैं:

Mod_rewrite के साथ .htaccess रूट

.htaccessअपने रूट फ़ोल्डर में नामक एक फाइल जोड़ें , और कुछ इस तरह जोड़ें:

RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1

यह अपाचे को इस फ़ोल्डर के लिए mod_rewrite को सक्षम करने के लिए बताएगा, और यदि उसे नियमित अभिव्यक्ति से मेल खाने वाला URL पूछा जाता है, तो वह इसे आंतरिक रूप से वही लिखता है जो आप चाहते हैं, अंत उपयोगकर्ता के बिना इसे देखकर। आसान, लेकिन अनम्य, इसलिए यदि आपको अधिक शक्ति की आवश्यकता है:

PHP मार्ग

इसके बजाय अपने .htaccess में निम्नलिखित डालें: (प्रमुख स्लैश पर ध्यान दें)

FallbackResource /index.php

यह इसे आपकी index.phpसभी फ़ाइलों को चलाने के लिए कहेगा, जो सामान्य रूप से आपकी साइट पर नहीं मिल सकती हैं। वहाँ तो आप उदाहरण के लिए कर सकते हैं:

$path = ltrim($_SERVER['REQUEST_URI'], '/');    // Trim leading slash(es)
$elements = explode('/', $path);                // Split path on slashes
if(empty($elements[0])) {                       // No path elements means home
    ShowHomepage();
} else switch(array_shift($elements))             // Pop off first item and switch
{
    case 'Some-text-goes-here':
        ShowPicture($elements); // passes rest of parameters to internal function
        break;
    case 'more':
        ...
    default:
        header('HTTP/1.1 404 Not Found');
        Show404Error();
}

यह बड़ी साइटें और सीएमएस-सिस्टम इसे कैसे करते हैं, क्योंकि यह पार्सिंग यूआरएल, कॉन्फिग और डेटाबेस आश्रित यूआरएल आदि में कहीं अधिक लचीलापन देता है। छिटपुट उपयोग के लिए हार्डकोडेड रीराइट नियमों को .htaccessठीक करेगा।


इसे हार्ड-कोडिंग के बजाय, आप स्ट्रिंग को पूरी तरह से अनदेखा करने के लिए रेगेक्स का उपयोग कर सकते हैं। दूसरे शब्दों में, केवल एक चीज जो आईडी भाग है। जाने के लिए picture.php/invalid-text/51भी उसी स्थान पर पुनर्निर्देशित किया जाएगा। आप यह देखने के लिए एक चेक भी जोड़ सकते हैं कि क्या स्ट्रिंग सही है और यदि नहीं, तो फिर से सही स्थान पर पुनः निर्देशित करें। इसी तरह मैंने htaccess का उपयोग करते हुए अपनी एक साइट पर किया।
माइक

7
छोटी साइटों के लिए सुविधाजनक है, लेकिन वास्तव में व्यावहारिक नहीं है अगर आपको और /blog/25साथ ही साथ पार्स करना है । इसके अलावा, यह बहुत बुरा अभ्यास माना जाता है (और अगर आप Google PR दंडित हो जाते हैं!) यदि सभी बेतरतीब ढंग से उत्पन्न URL 404 को ठीक से नहीं लौटाते हैं।/picture/51/download/684
नील्स Keurentjes

5
कम से कम मेरे सिस्टम पर, वह FallbackResource /index.php(प्रमुख स्लैश पर ध्यान दें)
जैक जेम्स

4
@olli: बुरा अभ्यास टिप्पणी विशेष रूप से "गैर-मौजूद URL के लिए 404 वापस नहीं करने" को संदर्भित करता है, जो उत्तर में समाधान द्वारा हल किया जाता है। पहले सवाल के रूप में - FallbackResourceकेवल उन फ़ाइलों के लिए किक करता है जो वास्तव में फाइल सिस्टम पर मौजूद नहीं हैं, इसलिए कमबैक । इसलिए यदि आपके पास एक फ़ाइल है /static/styles.cssऔर इसे देखें क्योंकि http://mydomain.tld/static/styles.cssकोड को कभी भी निष्पादित नहीं किया जाता है, जिससे यह अपेक्षित और पारदर्शी रूप से काम करता है।
Niels Keurentjes

आपको if($elements[0] === NULL)इसके बजाय उपयोग करना चाहिए , क्योंकि $elementsअभी भी एक की गिनती वापस आ जाएगी, भले ही वह खाली हो।
अग्निशमन

57

यदि आप केवल picture.phpतब के लिए मार्ग बदलना चाहते हैं, तो पुनर्लेखन नियम जोड़ना .htaccessआपकी आवश्यकताओं की पूर्ति करेगा, लेकिन, यदि आप Wordpress की तरह URL पुनर्लेखन चाहते हैं तो PHP एक तरीका है। यहाँ से शुरू करने के लिए सरल उदाहरण है।

फ़ोल्डर संरचना

दो फ़ाइलों कि रूट फ़ोल्डर में की जरूरत है कर रहे हैं, .htaccessऔर index.php, और यह के बाकी जगह के लिए अच्छा होगा .php, अलग फ़ोल्डर में फ़ाइलें की तरह inc/

root/
  inc/
  .htaccess
  index.php

.htaccess

RewriteEngine On
RewriteRule ^inc/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

इस फ़ाइल में चार निर्देश हैं:

  1. RewriteEngine - पुनर्लेखन इंजन को सक्षम करें
  2. RewriteRule- inc/फ़ोल्डर में सभी फ़ाइलों तक पहुंच से इनकार करें, उस फ़ोल्डर में किसी भी कॉल को रीडायरेक्ट करेंindex.php
  3. RewriteCond - अन्य सभी फ़ाइलों (जैसे छवियां, सीएसएस या स्क्रिप्ट) तक सीधी पहुंच की अनुमति दें
  4. RewriteRule - किसी और चीज को रीडायरेक्ट करना index.php

index.php

क्योंकि सब कुछ अब index.php पर पुनर्निर्देशित किया गया है, यह निर्धारित किया जाएगा कि क्या url सही है, सभी पैरामीटर मौजूद हैं, और यदि पैरामीटर के प्रकार सही हैं।

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

$rules = array( 
    'picture'   => "/picture/(?'text'[^/]+)/(?'id'\d+)",    // '/picture/some-text/51'
    'album'     => "/album/(?'album'[\w\-]+)",              // '/album/album-slug'
    'category'  => "/category/(?'category'[\w\-]+)",        // '/category/category-slug'
    'page'      => "/page/(?'page'about|contact)",          // '/page/about', '/page/contact'
    'post'      => "/(?'post'[\w\-]+)",                     // '/post-slug'
    'home'      => "/"                                      // '/'
);

अगला है आग्रह उरी तैयार करना।

$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' );
$uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' );
$uri = urldecode( $uri );

अब जब हमारे पास अनुरोध uri है, तो अंतिम चरण नियमित अभिव्यक्ति नियमों पर uri का परीक्षण करना है।

foreach ( $rules as $action => $rule ) {
    if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) {
        /* now you know the action and parameters so you can 
         * include appropriate template file ( or proceed in some other way )
         */
    }
}

सफल मैच, चूंकि हम regex में subpatterns नाम का उपयोग करते हैं, $paramsसरणी को लगभग उसी तरह भरते हैं जैसे PHP $_GETसरणी को भरता है । हालाँकि, डायनेमिक url का उपयोग करते समय, $_GETमापदंडों को बिना किसी जाँच के पॉप्युलेट किया जाता है।

    / चित्र / कुछ + पाठ / 51

    सरणी
    (
        [०] => / चित्र / कुछ पाठ / ५१
        [पाठ] => कुछ पाठ
        [१] => कुछ पाठ
        [आईडी] => ५१
        [२] => ५१
    )

    picture.php? पाठ कुछ + पाठ और आईडी = = 51

    सरणी
    (
        [पाठ] => कुछ पाठ
        [आईडी] => ५१
    )

कोड की इन कुछ पंक्तियों और नियमित अभिव्यक्तियों की एक बुनियादी जानकारी एक ठोस मार्ग प्रणाली का निर्माण शुरू करने के लिए पर्याप्त है।

पूर्ण स्रोत

define( 'INCLUDE_DIR', dirname( __FILE__ ) . '/inc/' );

$rules = array( 
    'picture'   => "/picture/(?'text'[^/]+)/(?'id'\d+)",    // '/picture/some-text/51'
    'album'     => "/album/(?'album'[\w\-]+)",              // '/album/album-slug'
    'category'  => "/category/(?'category'[\w\-]+)",        // '/category/category-slug'
    'page'      => "/page/(?'page'about|contact)",          // '/page/about', '/page/contact'
    'post'      => "/(?'post'[\w\-]+)",                     // '/post-slug'
    'home'      => "/"                                      // '/'
);

$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' );
$uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' );
$uri = urldecode( $uri );

foreach ( $rules as $action => $rule ) {
    if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) {
        /* now you know the action and parameters so you can 
         * include appropriate template file ( or proceed in some other way )
         */
        include( INCLUDE_DIR . $action . '.php' );

        // exit to avoid the 404 message 
        exit();
    }
}

// nothing is found so handle the 404 error
include( INCLUDE_DIR . '404.php' );

2
आप मापदंडों को कैसे पढ़ते हैं? यह $ post_id = htmlentities ($ _ GET ['पोस्ट']) के साथ काम नहीं करता है;
andrebruton

@Danijel क्या मेरे पास एक पूर्ण स्रोत कोड हो सकता है? मैंने ऊपर कोड की कोशिश की, लेकिन केवल पाठ आउटपुट था, सीएसएस कोई प्रभाव नहीं। धन्यवाद।
4 छोड़ दो

6

यह एक .htaccess फ़ाइल है जो लगभग सभी को index.php पर भेजती है

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_URI} !-l
RewriteCond %{REQUEST_FILENAME} !\.(ico|css|png|jpg|gif|js)$ [NC]
# otherwise forward it to index.php
RewriteRule . index.php

फिर आप पर निर्भर है $ _SERVER ["REQUEST_URI"] और चित्र के लिए मार्ग।


8
अपाचे ने FallbackResourceनिर्देश को कुछ प्रमुख संस्करणों में पेश किया , जो अब कम व्यवहार लागत पर इस व्यवहार को लागू करने का पसंदीदा तरीका है क्योंकि इसे पूरे पुनर्लेखन इंजन को लॉन्च करने की आवश्यकता नहीं है। यहाँ प्रलेखन । आपके नियम भी त्रुटिपूर्ण हैं क्योंकि आप निर्देशिका ( !-d) का संदर्भ नहीं देते हैं और सभी एक्सटेंशन फ़िल्टर अप्रचलित हैं - -fउन्हें पहले ही पकड़ लेना चाहिए।
नील्स केयूरेंटजेस


2

हालांकि पहले से ही उत्तर दिया गया है, और लेखक का इरादा फ्रंट कंट्रोलर टाइप ऐप बनाना है, लेकिन मैं समस्या के लिए शाब्दिक नियम पोस्ट कर रहा हूं। अगर किसी को उसी के लिए समस्या है।

RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L]

ऊपर url के लिए काम करना चाहिए picture.php/Some-text-goes-here/51। अनुक्रमणिका का उपयोग किए बिना। रीडायरेक्ट ऐप के रूप में।


मुझे यह जानने की जरूरत है कि हमें किस URL को href में लिखना है? क्योंकि मैं 404 हो रही है
questionbank
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.