วิธีลบการสอบถามและรับเฉพาะ URL ได้อย่างไร


201

ฉันใช้ PHP เพื่อสร้าง URL ของหน้าปัจจุบัน บางครั้ง URL ในรูปแบบของ

www.mydomian.com/myurl.html?unwantedthngs

ได้รับการร้องขอ ฉันต้องการลบ?และทุกสิ่งที่ตามมา (การสอบถาม) เช่นว่า URL ที่ได้จะกลายเป็น:

www.mydomain.com/myurl.html

รหัสปัจจุบันของฉันคือ:

<?php
function curPageURL() {
    $pageURL = 'http';
    if ($_SERVER["HTTPS"] == "on") {
        $pageURL .= "s";
    }
    $pageURL .= "://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"] . ":" .
            $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    return $pageURL;
}
?>

8
BTW ที่เรียกว่า "สตริงการสืบค้น"
Evan Mulawski

คำตอบ:


577

คุณสามารถใช้strtokเพื่อรับสายก่อนเกิดครั้งแรกของ?

$url = strtok($_SERVER["REQUEST_URI"], '?');

strtok()แสดงให้เห็นถึงเทคนิคที่รัดกุมที่สุดในการแยกสตริงย่อยโดยตรงก่อนที่จะ?ในสตริงการสืบค้น explode()ไม่ตรงเนื่องจากจะต้องสร้างอาเรย์สององค์ประกอบที่จะต้องเข้าถึงองค์ประกอบแรก

เทคนิคอื่น ๆ บางอย่างอาจผิดพลาดเมื่อไม่มีการสืบค้นหรืออาจกลายเป็นสตริงย่อยอื่น ๆ / ไม่ตั้งใจใน url - เทคนิคเหล่านี้ควรหลีกเลี่ยง

การสาธิต :

$urls = [
    'www.example.com/myurl.html?unwantedthngs#hastag',
    'www.example.com/myurl.html'
];

foreach ($urls as $url) {
    var_export(['strtok: ', strtok($url, '?')]);
    echo "\n";
    var_export(['strstr/true: ', strstr($url, '?', true)]); // not reliable
    echo "\n";
    var_export(['explode/2: ', explode('?', $url, 2)[0]]);  // limit allows func to stop searching after first encounter
    echo "\n";
    var_export(['substr/strrpos: ', substr($url, 0, strrpos( $url, "?"))]);  // not reliable; still not with strpos()
    echo "\n---\n";
}

เอาท์พุท:

array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => 'www.example.com/myurl.html',
)
---
array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => false,                       // bad news
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => '',                          // bad news
)
---

24
+1 สำหรับการใช้ $ _SERVER โดยตรงแทนที่จะสร้าง URL ขึ้นใหม่เพื่อแยกวิเคราะห์อีกครั้ง จะให้ +1 อีกถ้าเป็นไปได้เพื่อความกระชับ
ericsoco

8
อ๊ะ - ย้อนกลับอาร์กิวเมนต์เหล่านี้สำหรับ explode () ตัวคั่นจะไปก่อน array_shift(explode('?',$_SERVER["REQUEST_URI"]))
ที่นี่

13
มันจะไม่ส่งคืนบูล (เท็จ) หาก? ไม่มีอยู่ในสตริง แต่จะส่งคืนสตริง
เบ็นซี

4
เยี่ยมมาก! .. มันยังคงส่งคืน URL แม้ว่า?จะไม่ปรากฏ
Harikrishnan

1
@sepehr ฉันไม่เห็นจุดใดที่จะไม่ใช้ฟังก์ชันที่ทำสิ่งที่คุณต้องการและใช้อย่างอื่นและแยกวิเคราะห์ผลลัพธ์ (เช่นรับ [0] หลังจากการระเบิด) (ยกเว้นแน่นอนมีเหตุผลเฉพาะเช่นประสิทธิภาพที่ดีขึ้น ขาดการพึ่งพาที่ไม่จำเป็น ฯลฯ )
Riad

66

ใช้คู่มือ PHP - parse_url ()เพื่อรับชิ้นส่วนที่คุณต้องการ

แก้ไข (ตัวอย่างการใช้งานสำหรับ @Navi Gamage)

คุณสามารถใช้สิ่งนี้:

<?php
function reconstruct_url($url){    
    $url_parts = parse_url($url);
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];

    return $constructed_url;
}

?>

แก้ไข (ตัวอย่างเต็มรูปแบบที่สอง):

ปรับปรุงฟังก์ชั่นเพื่อให้แน่ใจว่าจะแนบรูปแบบและไม่มีข้อความแจ้งให้ทราบล่วงหน้าปรากฏขึ้น:

function reconstruct_url($url){    
    $url_parts = parse_url($url);
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['path'])?$url_parts['path']:'');

    return $constructed_url;
}


$test = array(
    'http://www.mydomian.com/myurl.html?unwan=abc',
    'http://www.mydomian.com/myurl.html',
    'http://www.mydomian.com',
    'https://mydomian.com/myurl.html?unwan=abc&ab=1'
);

foreach($test as $url){
    print_r(parse_url($url));
}       

จะกลับมา:

Array
(
    [scheme] => http
    [host] => www.mydomian.com
    [path] => /myurl.html
    [query] => unwan=abc
)
Array
(
    [scheme] => http
    [host] => www.mydomian.com
    [path] => /myurl.html
)
Array
(
    [scheme] => http
    [host] => www.mydomian.com
)
Array
(
    [path] => mydomian.com/myurl.html
    [query] => unwan=abc&ab=1
)

นี่คือเอาต์พุตจากการส่ง URL ตัวอย่างผ่าน parse_url () โดยไม่มีพารามิเตอร์ที่สอง (สำหรับคำอธิบายเท่านั้น)

และนี่คือผลลัพธ์สุดท้ายหลังจากสร้าง url โดยใช้:

foreach($test as $url){
    echo reconstruct_url($url) . '<br/>';
}   

เอาท์พุท:

http://www.mydomian.com/myurl.html
http://www.mydomian.com/myurl.html
http://www.mydomian.com
https://mydomian.com/myurl.html

ฉันอ่านมัน .. ฉันสับสนนิดหน่อยเพราะถ้าใหม่กับ php.Can คุณช่วยฉันด้วยโค้ด php ข้างต้นได้ไหม?
Navi Gamage

ฉันเพิ่มรหัสนี้หลังบรรทัด 9 $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?"));
Navi Gamage

ล้างส่วนข้อความค้นหาใน URL ... > www.mydomain.com/myurl.html?unwantedthings ผลลัพธ์คือไม่เป็นไร! > www.mydomian.com/myurl.html ทำแล้ว ... แต่เมื่อมันมาพร้อมกับ url ปกติ> www.mydomain.com/myurl.html ผลที่ได้คือไม่มีอะไรว่างเปล่า
Navi Gamage

strrpos () ใน 'www.mydomain.com/myurl.html' จะกลับมาเป็น0 (FALSE casted เป็นบูลีนเพื่อให้ถูกต้องมากขึ้น) ดังนั้น substr ของคุณจะว่างเปล่า ใช้อย่างใดอย่างหนึ่ง : substr () หรือ parse_url () เพราะการใช้ทั้งคู่ไม่มีเหตุผล)
veritas

ฉันหมายถึง FALSE ที่ถูกส่งไปยัง int; D
veritas

54

ทางออกที่ดีที่สุด:

echo parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

ไม่จำเป็นต้องรวมhttp://domain.comของคุณในของคุณหากคุณกำลังส่งแบบฟอร์มไปยังโดเมนเดียวกัน


โปรดทราบว่า parse_url คาดว่าจะมี URL ที่แน่นอนดังนั้นคุณจะได้รับผลลัพธ์ที่ไม่ถูกต้องในบางกรณีเช่นหาก REQUEST_URL ของคุณเริ่มต้นด้วยการทับหลายครั้งติดต่อกัน สิ่งเหล่านั้นจะถูกตีความว่าเป็น URI ที่เกี่ยวข้องกับโปรโตคอล
NikiC

16
$val = substr( $url, 0, strrpos( $url, "?"));

พวกเขาทำตามคำตอบของคุณฉันทำเสร็จแล้วขอบคุณสำหรับความช่วยเหลือของคุณ .. มันล้างส่วนข้อความค้นหาใน URL ...
Navi Gamage

> www.mydomain.com/myurl.html? ผลลัพธ์ที่ไม่ต้องการคือโอเค! > www.mydomian.com/myurl.html เสร็จแล้ว ... แต่เมื่อมันมาพร้อมกับ URL ปกติ> www.mydomain.com/myurl.html ผลที่ได้คือไม่มีอะไร .. ว่างเปล่า
Navi Gamage

ใหม่โค้ด php code <? php ฟังก์ชั่น curPageURL () {$ pageURL = 'http'; if ($ _SERVER ["HTTPS"] == "กับ") {$ pageURL. = "s";} $ pageURL. = ": //"; if ($ _SERVER ["SERVER_PORT"]! = "80") {$ pageURL. = $ _SERVER ["SERVER_NAME"]. ":". $ _ SERVER ["SERVER_PORT"]; $ _ SERVER ["REQUEST_URI"]; } else {$ pageURL. = $ _SERVER ["SERVER_NAME"]. $ _ SERVER ["REQUEST_URI"]; $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?")); } ส่งคืน $ pageURL; }?>code
Navi Gamage

2
ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่ค่อนข้างง่ายและหวาน ไม่จำเป็นต้องโหลดขอบเขตหรือฟังก์ชั่น ฉันใช้สิ่งนี้เพื่อรับชื่อไฟล์ปัจจุบัน $ base = basename ($ _ SERVER ['REQUEST_URI']); $ page = substr ($ base, 0, strrpos ($ base, "?"));
Rob

ตามที่ระบุไว้โดย Navi คำตอบนี้ไม่น่าเชื่อถือ 3v4l.org/nhVii หากข้อความค้นหาขาดใน url URL ทั้งหมดจะถูกลบออก! เทคนิคนี้ไม่ได้เป็นองค์ประกอบที่รับรู้ คำตอบนี้ไม่เหมาะสม
mickmackusa

9

วิธีที่ง่ายที่สุด

$url = 'https://www.youtube.com/embed/ROipDjNYK4k?rel=0&autoplay=1';
$url_arr = parse_url($url);
$query = $url_arr['query'];
print $url = str_replace(array($query,'?'), '', $url);

//output
https://www.youtube.com/embed/ROipDjNYK4k

ฉันไม่เห็นด้วยว่านี่เป็นวิธีที่ง่ายที่สุด ไม่ตัวหนาไม่ได้ทำให้คำสั่งของคุณน่าสนใจยิ่งขึ้น คำตอบนี้ไม่มีคำอธิบาย
mickmackusa

@mickmackusa คุณช่วยอธิบายความคิดเห็นของคุณได้ไหม? ฉันต้องอธิบายคำตอบของฉันที่ไหน ฉันจะขอบคุณคุณ
Mukesh Saxena

คำตอบทั้งหมดเกี่ยวกับ Stackoverflow ควรมีคำอธิบายว่าโซลูชันทำงานอย่างไรและทำไมคุณถึงรู้สึกว่ามันเป็นเทคนิคในอุดมคติ ลิงค์ไปยังเอกสารยังยินดีต้อนรับ ฉันเข้าใจวิธีการแก้ปัญหาของคุณ แต่นักวิจัยคนอื่นอาจไม่ คำตอบที่ใช้รหัสเท่านั้นมีค่าต่ำใน Stackoverflow เพราะทำน้อยมากเพื่อให้ความรู้ / ให้อำนาจนักวิจัยในอนาคตหลายพันคน เกี่ยวกับการไม่ง่ายที่สุด - 3v4l.org/RE0GDจะเป็นคำตอบที่ง่ายกว่าเพราะมีตัวแปรที่ประกาศน้อยกว่าและทำการแทนที่เพียงครั้งเดียวแทนที่จะเป็นสองคำ คำตอบที่ยอมรับนั้นง่ายที่สุดของทั้งหมด
mickmackusa

ความแตกต่างอีกอย่างก็คือคำตอบที่ได้รับการยอมรับจะดูแลส่วนที่เป็นไปได้ แต่คุณจะไม่ 3v4l.org/ERr4V หรือแย่กว่านั้นอาจทำให้ URL ไปทางซ้ายของการสอบถาม 3v4l.org/L61q1
mickmackusa

7

คุณจะต้องใช้ PHP เวอร์ชัน 5.4 เป็นอย่างน้อยในการใช้งานโซลูชันนี้โดยไม่ต้องแปลงเป็นตัวแปรในหนึ่งบรรทัดและต่อกันในบรรทัดถัดไป

$_SERVER["HTTP_HOST"].explode('?', $_SERVER["REQUEST_URI"], 2)[0];

ตัวแปรเซิร์ฟเวอร์: http://php.net/manual/en/reserved.variables.server.php การ
ยกเลิกการอ้างอิงอาร์เรย์: https://wiki.php.net/rfc/functionarraydereferencing


4

คุณสามารถใช้การสร้าง parse_url ในฟังก์ชันดังนี้:

$baseUrl = $_SERVER['SERVER_NAME'] . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

2

คุณสามารถลอง:

<?php
$this_page = basename($_SERVER['REQUEST_URI']);
if (strpos($this_page, "?") !== false) $this_page = reset(explode("?", $this_page));
?>

2

หากคุณต้องการขอเส้นทาง ( ข้อมูลเพิ่มเติม ):

echo parse_url($_SERVER["REQUEST_URI"])['path']

หากคุณต้องการลบข้อความค้นหาและ (และอาจจะเป็นส่วน ๆ ด้วย):

function strposa($haystack, $needles=array(), $offset=0) {
        $chr = array();
        foreach($needles as $needle) {
                $res = strpos($haystack, $needle, $offset);
                if ($res !== false) $chr[$needle] = $res;
        }
        if(empty($chr)) return false;
        return min($chr);
}
$i = strposa($_SERVER["REQUEST_URI"], ['#', '?']);
echo strrpos($_SERVER["REQUEST_URI"], 0, $i);

1

ในการลบสตริงเคียวรีออกจาก URI คำขอให้แทนที่สตริงเคียวรีด้วยสตริงว่าง:

function request_uri_without_query() {
    $result = $_SERVER['REQUEST_URI'];
    $query = $_SERVER['QUERY_STRING'];
    if(!empty($query)) {
        $result = str_replace('?' . $query, '', $result);
    }
    return $result;
}

www.example.com/myurl.html?ผมคิดว่าจะมีปัญหาที่อาจเกิดกับ
Earlee

1

เนื่องจากฉันจัดการกับทั้ง URL แบบสัมพัทธ์และสัมบูรณ์ฉันจึงอัปเดตโซลูชันของ veritas เช่นรหัสด้านล่าง
คุณสามารถลองด้วยตัวเองได้ที่นี่: https://ideone.com/PvpZ4J

function removeQueryStringFromUrl($url) {
    if (substr($url,0,4) == "http") {
        $urlPartsArray = parse_url($url);
        $outputUrl = $urlPartsArray['scheme'] . '://' . $urlPartsArray['host'] . ( isset($urlPartsArray['path']) ? $urlPartsArray['path'] : '' );
    } else {
        $URLexploded = explode("?", $url, 2);
        $outputUrl = $URLexploded[0];
    }
    return $outputUrl;
}

1

สามารถใช้ดังต่อไปนี้ตามความคิดเห็นด้วยตนเอง php

$_SERVER['REDIRECT_URL']

โปรดทราบว่านี่ใช้งานได้เฉพาะในบางสภาพแวดล้อม PHP เท่านั้นและทำตามความคิดเห็นต่อจากหน้านั้นสำหรับข้อมูลเพิ่มเติม

วัตถุประสงค์: ชื่อเส้นทาง URL ของไฟล์ PHP ปัจจุบันชื่อพา ธ คือ N / A และไม่รวมสตริงการสืบค้น URL รวมถึงการเฉือนชั้นนำ

Caveat: สิ่งนี้อยู่ก่อนการเขียน URL ใหม่ (เช่นเป็นไปตาม URL การโทรเดิม)

Caveat: ไม่ได้ตั้งค่าในทุกสภาพแวดล้อมของ PHP และเฉพาะกับการเขียน URL เท่านั้น

ทำงานบนโหมดเว็บ: ใช่

ใช้งานได้ในโหมด CLI: ไม่


0

ลองสิ่งนี้

$url_with_querystring = 'www.mydomian.com/myurl.html?unwantedthngs';
$url_data = parse_url($url_with_querystring);
$url_without_querystring = str_replace('?'.$url_data['query'], '', $url_with_querystring);

0

สมมติว่าคุณยังคงต้องการรับ URL โดยไม่มี args ของแบบสอบถาม (หากยังไม่ได้ตั้งค่า) ให้ใช้คำสั่งย่อเพื่อตรวจสอบกับstrpos:

$request_uri = strpos( $_SERVER['REQUEST_URI'], '?' ) !== false ? strtok( $_SERVER["REQUEST_URI"], '?' ) : $_SERVER['REQUEST_URI'];


-3

ลองสิ่งนี้:

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']

หรือ

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']

1
ขออภัย แต่เป็นความผิด - URI สามารถเขียนใหม่ได้โดย htaccess - ซึ่งจะทำให้ชื่อสคริปต์กลับมา แต่ไม่ใช่ URI ปัจจุบัน
Hexodus

เป็นอันตรายเนื่องจากสามารถปลอมแปลงได้
ทิม

ยืนยันผิด สมมติว่าคุณกำลังเขียน proxy.php ซึ่งเป็น. htaccess เปลี่ยนเส้นทางไปยังจากการร้องขอทรัพยากรต่าง ๆ เช่น index.php, prices.php, about.php และสร้างมุมมองแบบไดนามิกสำหรับชื่อที่ร้องขอ หากคุณใช้สิ่งนี้สคริปต์จะเห็น proxy.php มากกว่าทรัพยากรที่ต้องการที่ต้องการสร้าง
Dmitry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.