2016-05-02 49 views
11

Tôi có một dự án chạy cục bộ trên WampServer. Đó là một cấu trúc giống như MVC; nó ghi lại URL thành index.php?url=$1. Full .htaccess:URL tuyệt đối từ thư mục cơ sở với viết lại

RewriteEngine On 

RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-l 
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L] 

Khi tôi muốn gửi người dùng đến một trang khác sử dụng PHP location: <location> nó không làm điều này đúng vì viết lại (tất cả-mặc dù tôi về mặt kỹ thuật luôn trong index.php).

Ví dụ nếu tôi về http://localhost/project_name/controller/method/ và constructor hoặc phương pháp của bộ điều khiển này cố gắng gửi cho tôi để:

  • header('location: another_controller/method'); gửi cho tôi để http://localhost/project_name/controller/method/another_controller/method/
  • header('location: /another_controller/method'); gửi cho tôi để http://localhost/another_controller/method/

Nhưng tôi muốn gửi cho tôi như thế này:

  • header('location: /another_controller/method'); gửi cho tôi để http://localhost/project_name/another_controller/method/

Bây giờ là giải pháp duy nhất mà tôi đã tìm thấy là:

define('BASE_URL','http://localhost/project_name'); 
header('location: '.BASE_URL.'/another_controller/method/'); 

Nhưng điều này không phải là hoàn hảo hoặc vì nó gây ra tôi phải thay đổi điều này được xác định liên tục BASE_URL bất cứ khi nào tên miền hoặc tên thư mục thay đổi. Tôi cũng có thể tạo một phương thức trong số BaseController tạo URL tuyệt đối, nhưng phương pháp này về cơ bản cũng chỉ cần thêm BASE_URL nữa.

Lưu ý: Vấn đề tương tự không xảy ra với srchref thuộc tính HTML, mà có thể sử dụng đường dẫn tương đối (không có project_name thư mục trong đường dẫn). Tôi không hiểu tại sao. Bởi vì nếu tiêu đề location khiến trình duyệt thêm URL tương đối vào vị trí hiện tại, tại sao nó không có cùng hành vi khi tìm kiếm các tệp .css hoặc .js.

Vậy ... này đặt ra một vài câu hỏi cho tôi:

  1. Tôi sẽ phải vấn đề này nếu tôi có máy ảo?
  2. Cách tốt nhất để giải quyết vấn đề này là gì?
  3. Tốt nhất là chỉ cần có URL tuyệt đối đầy đủ?
  4. Tại sao các thuộc tính srchref của HTML không chia sẻ hành vi này?
+0

bạn có thể thêm một số mã của tệp htaccess của mình không? –

+0

@HarshSanghani Đã thêm. – kgongonowdoe

+2

bạn có thể vui lòng thêm RewriteBase/project_name/sau RewriteEngine trên –

Trả lời

4

Bây giờ là giải pháp duy nhất mà tôi đã tìm thấy là:

define('BASE_URL','http://localhost/project_name'); 
header('location: '.BASE_URL.'/another_controller/method/'); 

Nhưng điều này không phải là hoàn hảo hoặc vì nó khiến tôi phải thay đổi BASE_URL liên tục định nghĩa này bất cứ khi nào miền hoặc thư mục tên thay đổi .

Bạn không cần phải thay đổi hằng số được xác định. Các giá trị này có thể được tìm thấy động.

Ví dụ:

if ($_SERVER['DOCUMENT_ROOT'] == dirname($_SERVER['SCRIPT_FILENAME'])) { 
    define('BASE_PATH', '/'); 
} else { 
    define('BASE_PATH', dirname($_SERVER['SCRIPT_NAME']) . '/'); 
} 

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://'; 
define('BASE_URL', $protocol . $_SERVER['SERVER_NAME'] . BASE_PATH); 

Thêm vào đó, chứ không phải lo lắng về việc có nên chỉ định một URL tuyệt đối hoặc một con đường, bạn có thể quấn chuyển hướng thành một chức năng mà có thể xử lý cả hai:

function redirect($path = null) { 
    if (isset($path)) { 
     if (filter_var($path, FILTER_VALIDATE_URL)) { 
      header('Location: ' . $path); 
     } else { 
      header('Location: ' . BASE_URL . $path); 
     } 
    } else { 
     header('Location: ' . BASE_URL); 
    } 
    exit; 
} 

Cuối cùng, như @HarshSanghani đã đề cập trong các nhận xét, đường dẫn cơ sở trong tệp .htaccesscủa bạn nên khớp với đường cơ sở trong mã của bạn. Vì vậy, nếu BASE_PATH (dựa trên ví dụ trên) kết quả đầu ra /project_name/, sau đó .htaccess của bạn nên chứa nó:

RewriteBase /project_name/ 
2

Để trả lời câu hỏi của bạn:

  1. Nó phụ thuộc vào cách host ảo của bạn sẽ được cấu hình.
  2. Bạn chỉ có thể tạo BASE_URL động của mình: $baseUrl = dirname($_SERVER['SCRIPT_NAME']);. Bằng cách này, bạn sẽ không phải thay đổi bất kỳ mã nào nếu thư mục hoặc tên miền của bạn thay đổi.
  3. Bạn không cần phần tên miền.
  4. html srchref được trình duyệt của bạn giải thích có tính đến thẻ <base> của trang. Tất cả các đường dẫn trên một trang có thẻ <base> được thay đổi theo trình duyệt của bạn.

Tiêu đề HTTP bạn gửi từ máy chủ (để chuyển hướng) không liên quan gì đến trang html bạn gửi và do đó không được cập nhật.

2
  1. Bạn sẽ có vấn đề này nếu bạn có dự án của bạn thiết lập trong thư mục con. Sử dụng các máy chủ ảo sẽ là một cách giải quyết vấn đề nếu bạn muốn thiết lập chúng khi nói, project_name.localhost.
  2. Trong các dự án của tôi, tôi sử dụng biến môi trường để tải một tệp cấu hình khác để phát triển, dàn dựng hoặc sản xuất. Trong trường hợp này, tôi đặt một số $baseUri.
  3. Thực tiễn tốt nhất là sử dụng các url tuyệt đối (bao gồm cả tên miền) cho cả giải pháp của vấn đề này và cho SEO. Về chức năng bạn không cần phần tên miền.
  4. Thẻ src và href thường hoạt động theo cùng một cách, nhưng như Andreas đã đề cập chúng có thể bị ảnh hưởng bởi thẻ cơ sở.
2

Bạn nên chỉ định RewriteBase trong tệp htaccess của mình. Sử dụng đường dẫn tương đối trong các liên kết của bạn và bạn không cần gì hơn.

RewriteBase /project_name/ 
RewriteEngine on 
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC] 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-l 
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L] 
Các vấn đề liên quan