Làm thế nào để loại bỏ chuỗi truy vấn và chỉ nhận được url?


201

Tôi đang sử dụng PHP để xây dựng URL của trang hiện tại. Đôi khi, URL ở dạng

www.mydomian.com/myurl.html?unwantedthngs

được yêu cầu. Tôi muốn xóa ?và mọi thứ theo sau nó (chuỗi truy vấn), sao cho URL kết quả trở thành:

www.mydomain.com/myurl.html

Mã hiện tại của tôi là:

<?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, đó được gọi là "chuỗi truy vấn".
Evan Mulawski

Câu trả lời:


577

Bạn có thể sử dụng strtokđể có được chuỗi trước khi xuất hiện lần đầu tiên của?

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

strtok()đại diện cho kỹ thuật ngắn gọn nhất để trích xuất trực tiếp chuỗi con trước ?chuỗi truy vấn. explode()ít trực tiếp hơn vì nó phải tạo ra một mảng hai phần tử có khả năng mà phần tử đầu tiên phải được truy cập.

Một số kỹ thuật khác có thể bị hỏng khi chuỗi truy vấn bị thiếu hoặc có khả năng đột biến các chuỗi con khác / ngoài ý muốn trong url - những kỹ thuật này nên tránh.

Một cuộc biểu tình :

$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";
}

Đầu ra:

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 để sử dụng trực tiếp $ _SERVER thay vì chỉ xây dựng lại url để phân tích lại. sẽ cho +1 khác nếu có thể, để xử lý.
ericsoco

8
Rất tiếc - đảo ngược các đối số cho explode (), dấu phân cách đi trước. array_shift(explode('?',$_SERVER["REQUEST_URI"]))
ở đây

13
Nó không trả về bool (false) nếu? không có trong chuỗi, nó trả về chuỗi.
Ben C

4
Tuyệt vời! .. Nó vẫn trả lại url ngay cả khi ?không có mặt.
Harikrish Nam

1
@sepehr, tôi chỉ không thấy bất kỳ điểm nào không sử dụng chức năng thực hiện chính xác những gì bạn cần và sử dụng một chức năng khác và phân tích kết quả (ví dụ: nhận [0] sau khi phát nổ) (trừ khi tất nhiên có một lý do cụ thể như hiệu suất tốt hơn , thiếu sự phụ thuộc không cần thiết, vv).
Rịa

66

Sử dụng Hướng dẫn PHP - parse_url () để lấy các phần bạn cần.

Chỉnh sửa (ví dụ sử dụng cho @Navi Gamage)

Bạn có thể sử dụng nó như thế này:

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

    return $constructed_url;
}

?>

Chỉnh sửa (ví dụ đầy đủ thứ hai):

Chức năng được cập nhật để đảm bảo lược đồ sẽ được đính kèm và không có thông báo thông báo nào xuất hiện:

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

Sẽ trở lại:

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
)

Đây là đầu ra từ việc chuyển các url mẫu qua parse_url () không có tham số thứ hai (chỉ để giải thích).

Và đây là đầu ra cuối cùng sau khi xây dựng url bằng cách sử dụng:

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

Đầu ra:

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

Tôi đọc nó..Tôi hơi bối rối vì nếu chưa biết về php. Bạn có thể giúp tôi với mã php ở trên không?
Trò chơi Navi

tôi đã thêm mã này sau dòng 9 $ pageURL = struct ($ pageURL, 0, strrpose ($ pageURL, "?"));
Trò chơi Navi

Nó cắt phần truy vấn trong url ...> www.mydomain.com/myurl.html?unwucetthings kết quả là Được rồi! > www.mydomian.com/myurl.html Xong ... Nhưng khi nó đi kèm với url bình thường> www.mydomain.com/myurl.html kết quả là không có gì..Empty
Navi Gamage

strrpose () trong 'www.mydomain.com/myurl.html' sẽ trả về 0 (FALSE được chuyển thành boolean để chính xác hơn) vì vậy phần nền của bạn sẽ trống. Sử dụng một : chất nền () HOẶC parse_url () vì sử dụng cả hai đều vô nghĩa;)
veritas

Ý tôi là FALSE được chuyển sang int; D
veritas

54

giải pháp tốt nhất:

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

Không cần đưa http://domain.com của bạn vào nếu bạn đang gửi một biểu mẫu cho cùng một tên miền.


Lưu ý rằng parse_url mong đợi một URL tuyệt đối, do đó bạn sẽ nhận được kết quả không chính xác trong một số trường hợp, ví dụ: nếu REQUEST_URL của bạn bắt đầu bằng nhiều dấu gạch chéo liên tiếp. Chúng sẽ được hiểu là một URI liên quan đến giao thức.
NikiC

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

Các bạn theo câu trả lời của bạn Tôi đã hoàn thành..cảm ơn sự giúp đỡ của bạn..Có phần truy vấn trong url ...
Navi Gamage

> www.mydomain.com/myurl.html?unwocateshings kết quả là được! > www.mydomian.com/myurl.html Xong ... Nhưng khi nó đi kèm với url bình thường> www.mydomain.com/myurl.html kết quả là không có gì..Empty
Navi Gamage

Mã php mới code <? Hàm php 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"]; } khác {$ pageURL. = $ _SERVER ["SERVER_NAME"]. $ _ SERVER ["REQUEST_URI"]; $ pageURL = chất nền ($ pageURL, 0, strrpose ($ pageURL, "?")); } trả lại $ pageURL; }?>code
Trò chơi Navi

2
Tôi nghĩ rằng đây là một giải pháp khá ngọt ngào và đơn giản cho vấn đề. Không cần vô số phạm vi hoặc chức năng. Tôi đã sử dụng điều này để có được tên tập tin được gọi hiện tại. $ base = tên cơ sở ($ _ SERVER ['REQUEST_URI']); $ page = đế ($ cơ sở, 0, strrpose ($ cơ sở, "?"));
Cướp

Như Navi đã nêu, câu trả lời này không đáng tin cậy. 3v4l.org/nhVii Nếu chuỗi truy vấn không có trong url, toàn bộ url sẽ bị xóa! Kỹ thuật này không nhận biết thành phần url. Câu trả lời này là không thể.
mickmackusa

9

Cách dễ nhất

$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

Tôi không đồng ý rằng đây là cách dễ nhất. Không, văn bản in đậm không làm cho tuyên bố của bạn hấp dẫn hơn. Câu trả lời này thiếu một lời giải thích.
mickmackusa

@mickmackusa Bạn có thể vui lòng giải thích ý kiến ​​của bạn? Tôi cần giải thích câu trả lời của mình ở đâu? Tôi sẽ biết ơn bạn.
Mukesh Saxena

Tất cả các câu trả lời trên Stackoverflow nên bao gồm một lời giải thích về cách giải pháp hoạt động và lý do tại sao bạn cảm thấy đó là một kỹ thuật lý tưởng. Liên kết đến tài liệu cũng được chào đón. Tôi hoàn toàn hiểu giải pháp của bạn, nhưng nhà nghiên cứu khác có thể không. Các câu trả lời chỉ có mã là giá trị thấp trên Stackoverflow vì chúng làm rất ít để giáo dục / trao quyền cho hàng ngàn nhà nghiên cứu trong tương lai. Về việc không đơn giản nhất - 3v4l.org/RE0GD sẽ là phiên bản đơn giản hơn cho câu trả lời của bạn vì nó có ít biến được khai báo hơn và chỉ thực hiện một thay thế thay vì hai. Câu trả lời được chấp nhận là đơn giản nhất trong tất cả.
mickmackusa

Một sự khác biệt nữa là câu trả lời được chấp nhận cũng quan tâm đến một đoạn có thể, nhưng câu trả lời của bạn thì không. 3v4l.org/ERr4V hoặc tệ hơn là nó có thể chuyển url sang bên trái của chuỗi truy vấn 3v4l.org/L61q1
mickmackusa


4

Bạn có thể sử dụng hàm parse_url trong hàm như thế:

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

2

Bạn co thể thử:

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

2

Nếu bạn muốn nhận đường dẫn yêu cầu ( thông tin thêm ):

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

Nếu bạn muốn xóa truy vấn và (và có thể cả đoạn):

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

Để xóa chuỗi truy vấn khỏi URI yêu cầu, hãy thay thế chuỗi truy vấn bằng một chuỗi trống:

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

Tôi nghĩ rằng sẽ có một vấn đề tiềm năng với www.example.com/myurl.html?.
Earlee

1

Vì tôi xử lý cả URL tương đối và tuyệt đối, tôi đã cập nhật giải pháp của veritas như mã bên dưới.
Bạn có thể thử mình tại đây: 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

cũng có thể sử dụng như sau theo nhận xét thủ công php

$_SERVER['REDIRECT_URL']

Xin lưu ý rằng điều này chỉ hoạt động đối với môi trường PHP nhất định và theo dõi nhận xét dưới đây từ trang đó để biết thêm thông tin;

Mục đích: Tên đường dẫn URL của tệp PHP hiện tại, thông tin đường dẫn là N / A và không bao gồm chuỗi truy vấn URL. Bao gồm dấu gạch chéo hàng đầu.

Hãy cẩn thận: Đây là trước khi URL viết lại (nghĩa là theo URL cuộc gọi ban đầu).

Hãy cẩn thận: Không được đặt trên tất cả các môi trường PHP và chắc chắn chỉ những môi trường có URL viết lại.

Hoạt động trên chế độ web: Có

Hoạt động trên chế độ CLI: Không


0

Thử cái này

$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

Giả sử bạn vẫn muốn nhận URL mà không cần truy vấn (nếu chúng không được đặt), chỉ cần sử dụng một câu lệnh if để kiểm tra strpos:

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

0

Đây là một giải pháp đơn giản nếu bạn đang sử dụng Laravel:

Str::before($request->getRequestUri(), '?')

-3

Thử cái này:

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

hoặc là

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

1
Xin lỗi nhưng điều này là sai - URI có thể được viết lại bởi htaccess - điều này sẽ dẫn đến việc trả lại tên tập lệnh nhưng không phải là URI hiện tại.
Hexodus

Nguy hiểm vì nó có thể bị giả mạo.
tim

xác nhận là sai. giả sử bạn đang viết proxy.php .htaccess chuyển hướng từ các yêu cầu cho các tài nguyên khác nhau, chẳng hạn như index.php, price.php, about.php và tự động xây dựng chế độ xem cho tên được yêu cầu. nếu bạn sử dụng điều này, tập lệnh sẽ luôn thấy proxy.php chứ không phải là tài nguyên được yêu cầu mong muốn mà nó muốn xây dựng.
Dmitry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.