2008-12-23 29 views
6

Đây là một vấn đề mà tôi đã chạy vào thời gian gần đây - một apache sai cấu hình trên một máy chủ web. Điều này có nghĩa là tất cả các tập lệnh dựa trên số lần ngắt $_SERVER['DOCUMENT_ROOT']. Cách giải quyết đơn giản nhất mà tôi đã tìm thấy là chỉ cần đặt biến trong một số tệp bao gồm toàn cục được chia sẻ, nhưng đó là một nỗi đau không thể quên nó. Câu hỏi của tôi là, làm cách nào để xác định đúng tài liệu gốc?Làm thế nào để lập trình xác định gốc tài liệu trong PHP?

Ví dụ, trên một máy chủ, các thiết lập là như thế này:

$_SERVER['DOCUMENT_ROOT'] == '/htdocs' 

Rễ tài liệu thật là:

test.example.com -> /data/htdocs/example.com/test 
www.example.com -> /data/htdocs/example.com/www 

Và tôi muốn một kịch bản đó là chạy từ www.example.com/blog/ (trên đường dẫn /data/htdocs/example.com/www/blog) để nhận giá trị chính xác của /data/htdocs/example.com/www.

Mở máy chủ khác, các thiết lập là một chút khác nhau:

$_SERVER['DOCUMENT_ROOT'] == '/srv' 
test.example.com -> /home/virtual_web/example.com/public_html/test 
www.example.com -> /home/virtual_web/example.com/public_html/www 

Có bất kỳ giải pháp này? Hoặc là cách duy nhất đơn giản là không bao giờ dựa vào $_SERVER['DOCUMENT_ROOT'] và sửa tất cả phần mềm mà tôi đang chạy trên trang web của mình? Việc sửa lỗi này ở phía máy chủ không có vẻ là một tùy chọn, tôi chưa gặp phải một máy chủ lưu trữ ở nơi mà cấu hình này được định cấu hình chính xác. Điều tốt nhất tôi nhận được là một tài liệu gốc trỏ đến www.example.com, ít nhất là bên trong open_basedir - họ đã sử dụng một lược đồ đặt tên khác, www.example.com sẽ trỏ đến /u2/www/example_com/data/www/.

Trả lời

2

Dựa trên http://www.helicron.net/php/:

$localpath=getenv("SCRIPT_NAME"); 
$absolutepath=getenv("SCRIPT_FILENAME"); 
$_SERVER['DOCUMENT_ROOT']=substr($absolutepath,0,strpos($absolutepath,$localpath));  

Tôi đã phải thay đổi tên cơ sở/thủ thuật realpath vì nó trả về một chuỗi trống trên máy chủ của tôi. Thay vào đó, tôi sử dụng SCRIPT_FILENAME. Điều này có thể sẽ không hoạt động trên IIS nữa (nhưng các tập lệnh gốc đã sử dụng biến $ _SERVER có thể sẽ không hoạt động).

0

PHP nên được thiết lập thư mục hiện hành với một kịch bản là trong, vì vậy miễn là đó là không bị hỏng, bạn sẽ có thể tìm ra nguồn gốc tài liệu sử dụng $_SERVER['SCRIPT_FILENAME']getcwd(). (Tôi không thể nhớ tất cả các $ _SERVER vars ra khỏi đỉnh đầu của tôi, có thể có một cái gì đó trong phpinfo() đó là hữu ích hơn.)

+0

Một số tập lệnh mà tôi đã cài đặt là "quá thông minh" và biết thư mục nào (liên quan đến thư mục tài liệu lý thuyết) mà chúng được cài đặt và thêm vào thư mục gốc tài liệu (sau khi nhận được từ cơ sở dữ liệu). Tôi vẫn phải sửa đổi mã cho mỗi thư mục để loại bỏ các thư mục ... hay không? –

7

Trong PHP5 có hằng số ma thuật __FILE__ có chứa đường dẫn tuyệt đối của tập tin mà nó xuất hiện. Bạn có thể sử dụng nó kết hợp với dirname để tính toán gốc tài liệu.

Bạn có thể đặt một tuyên bố như một sau đây trong một tập tin cấu hình

define ('DOCUMENT_ROOT', dirname(__FILE__)); 

này nên làm các trick

+1

Bí quyết đã sử dụng cả tên tuyệt đối của tệp (hoặc từ hằng số ma thuật, hoặc từ các vars máy chủ) và kết hợp nó với kiến ​​thức về đường dẫn tuyệt đối thực tế đối với gốc tài liệu từ SCRIPT_NAME. –

+3

Từ PHP 5.3, đây cũng là '__DIR__' sử dụng thay cho' dirname (__ FILE __) '. – Michael

+0

Nhưng điều này chỉ trả về thư mục của tệp hiện tại không nhất thiết là thư mục gốc thực của máy chủ web. – Chuck

3

Không cần phải sửa đổi tất cả các kịch bản.

Bạn có thể chạy tệp PHP trước khi bất kỳ tập lệnh nào được chạy bằng cách sử dụng auto_prepend_file.

$_SERVER chỉ là một mảng, bạn có thể sửa đổi và đặt chính xác $_SERVER['DOCUMENT_ROOT'].

+0

Đó là kindof vô dụng để chạy kịch bản đó trên * mỗi lần chạy. – SchizoDuckie

+0

Đó là kindof useless để chạy mà kịch bản trên * mỗi * chạy. Xử lý tốt hơn bằng một số .htaccess thay vì đặt nó. – SchizoDuckie

+0

Bạn có thể sử dụng php_value trong .htaccess để đặt auto_prepend_file, nhưng tác giả của câu hỏi đã đề cập đến máy chủ IIS mà tôi cho rằng không hỗ trợ điều này. – Kornel

0

Tại sao không yêu cầu máy chủ web của bạn cấu hình máy chủ của mình chính xác?

những thứ này có xu hướng nán lại âm thầm trong mã của bạn và không bao giờ bị xóa (nhưng vẫn hoạt động) cho đến khi ai đó cuối cùng sửa máy chủ. Tất cả mọi thứ sẽ phá vỡ một lần nữa.

Hoặc, di chuyển nội dung của bạn tới một máy chủ sẽ hoạt động. Nếu điều này bị hỏng, ai biết bạn sẽ tìm thấy gì tiếp theo.

+0

Tôi không chắc chắn nếu nó có thể cấu hình máy chủ một cách chính xác, nó có vẻ là một vấn đề với mod_vhost_alias (theo một bình luận trên http://www.webmasterworld.com/apache/3640691.htm). –

2

Đây là một trong những lý do tại sao mọi người hút mọi thứ thông qua bootstrap /index.php bằng cách sử dụng htaccess và/hoặc chuỗi truy vấn. Bạn có thể sử dụng thủ thuật dirname(__FILE__) được lưu ý ở trên và nhận cơ sở công khai của ứng dụng theo cách đó.

Nếu bạn quá xa để chuyển sang một mục nhập, một điều tôi thấy mọi người làm là có tiêu đề chung cho tập lệnh của họ, đi lên cây thư mục để tìm tệp duy nhất dir cơ sở:

function findAppBase($dir) { 
    if(file_exists("$dir/unique_file.txt")) { 
     return $dir; 

    return findAppBase(dirname($dir)); 
} 

$base = findAppBase(dirname(__FILE__)); 

đó là mã chưa được thử nghiệm, và có thể có một cách tinh quái bằng cách sử dụng VAR trong $_ENV hoặc $_SERVER rằng sẽ làm những gì bạn muốn ...

+0

Rất may, đây không phải là vấn đề, tôi chỉ có một điểm vào duy nhất. Nó chỉ là tôi chạy cùng một phần mềm trên nhiều tên miền và máy chủ, và tôi phải sửa nó cho mỗi tên miền. Tôi muốn gửi một bản sửa lỗi ngược dòng vì vậy tôi không phải quan tâm đến nó nữa. –

Các vấn đề liên quan