Cách khắc phục lỗi PHP 'open_basedir restriction in effect'

intermediate🐘 PHP2026-04-11| Linux (Ubuntu/CentOS/Debian), PHP-FPM, Nginx, Apache, cPanel, Plesk

Error Message

Warning: file_get_contents(): open_basedir restriction in effect. File is not within the allowed path(s)
#php#quyền truy cập#open-basedir#bảo mật

Sự cố chặn hệ thống lúc 2 giờ sángHãy tưởng tượng bạn vừa hoàn tất việc chuyển một trang web của khách hàng sang một VPS mới. Trang chủ trông thật hoàn hảo, nhưng biểu mẫu liên hệ lại bị lỗi. Bạn kiểm tra nhật ký lỗi và thấy một thông báo quen thuộc nhưng gây khó chịu: open_basedir restriction in effect. Lỗi này chặn đứng mã nguồn của bạn, ngay cả khi các quyền truy cập tệp của bạn có vẻ đã chính xác.

Warning: file_get_contents(): open_basedir restriction in effect. File is not within the allowed path(s)

Điều này xảy ra khi một tập lệnh cố gắng truy cập ra ngoài vùng an toàn (sandbox) được chỉ định của nó. Đây là một tính năng bảo mật ngăn chặn một trang web bị xâm nhập duyệt toàn bộ máy chủ của bạn. Tuy nhiên, nó trở thành một vấn đề lớn khi ứng dụng của bạn cần truy cập vào các tài nguyên dùng chung, tệp phiên làm việc (session files) hoặc các thư mục tạm thời nằm ở nơi khác.

Tại sao PHP lại chặn tệp của bạnHãy coi chỉ thị open_basedir như một vành đai bảo mật. Nó cho PHP biết chính xác những thư mục nào được phép tác động bằng cách sử dụng các hàm như file_get_contents() hoặc include(). Nếu một đường dẫn tệp không nằm trong danh sách cho phép (whitelist) đó, PHP sẽ chặn yêu cầu ngay lập tức. Việc bạn thiết lập tệp thành chmod 777 không quan trọng; chính sách nội bộ của PHP sẽ ghi đè lên các quyền của hệ điều hành.

Bạn thường sẽ gặp phải vấn đề này sau khi:

  • Di chuyển một trang web từ /var/www/html/site1 sang một thư mục gốc mới.- Cố gắng ghi dữ liệu phiên làm việc (session) vào /var/lib/php/sessions.- Truy cập thư viện hình ảnh dùng chung trong /opt/shared/assets/.- Triển khai trên các bảng điều khiển nghiêm ngặt như Plesk hoặc cPanel.## Bước 1: Xác định các hạn chế đang hoạt độngTrước khi bạn bắt đầu thay đổi các tệp cấu hình, bạn cần xem PHP hiện đang cho phép những gì. Hãy tạo một tệp có tên info.php trong thư mục gốc web của bạn:
<?php
phpinfo();
?>

Mở tệp này trong trình duyệt của bạn và tìm kiếm open_basedir. "Local Value" là quy tắc hiện đang ảnh hưởng đến tập lệnh của bạn. Nếu nó ghi no value, đây không phải là vấn đề của bạn. Nếu nó hiển thị một đường dẫn như /var/www/vhosts/example.com/, bất kỳ tệp nào tại /var/www/shared/ sẽ không thể truy cập được.

Cách khắc phục: Cập nhật cấu hình của bạnNơi bạn khắc phục điều này tùy thuộc vào cách máy chủ của bạn được xây dựng. Dưới đây là ba phương pháp phổ biến nhất.

1. Chỉnh sửa php.ini (Khắc phục trên toàn hệ thống)Nếu bạn có quyền truy cập root và muốn thay đổi áp dụng cho toàn bộ máy chủ, hãy chỉnh sửa tệp php.ini chính của bạn. Trên một máy chủ Ubuntu 22.04 tiêu chuẩn chạy PHP 8.2, tệp này thường nằm tại /etc/php/8.2/fpm/php.ini.

# Mở tệp cấu hình
sudo nano /etc/php/8.2/fpm/php.ini

# Tìm kiếm open_basedir. 
# Để cho phép truy cập vào một thư mục mới, hãy thêm nó vào danh sách:
open_basedir = "/var/www/vhosts/mysite/:/tmp/:/var/www/shared/"

Mẹo nhỏ: Sử dụng dấu hai chấm (:) để phân tách các đường dẫn trên Linux. Các máy chủ Windows yêu cầu dấu chấm phẩy (;).

2. Cấu hình PHP-FPM Pool (Tốt nhất cho Nginx)Các hệ thống hiện đại thường bỏ qua tệp php.ini toàn cục để ưu tiên các cài đặt riêng cho từng pool. Điều này phổ biến nếu bạn lưu trữ nhiều trang web trên một máy chủ. Bạn sẽ cần chỉnh sửa tệp .conf cụ thể cho trang web của mình.

# Tìm cấu hình pool của bạn (thường là www.conf)
sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Tìm dòng chứa php_admin_value[open_basedir]. Nếu không có, hãy thêm nó vào cuối tệp:

php_admin_value[open_basedir] = /var/www/vhosts/mysite/:/tmp/:/custom/path/

Sau khi lưu, hãy khởi động lại dịch vụ để áp dụng các thay đổi:

sudo systemctl restart php8.2-fpm

3. Apache VirtualHostNếu bạn sử dụng Apache với mod_php, bạn có thể thiết lập hạn chế bên trong khối VirtualHost của trang web. Cách này sạch sẽ hơn so với việc thay đổi toàn cục.

<Directory /var/www/vhosts/mysite>
    php_admin_value open_basedir "/var/www/vhosts/mysite/:/tmp/"
</Directory>

Xử lý trên các bảng điều khiển (cPanel & Plesk)Nếu bạn sử dụng một bảng điều khiển, các chỉnh sửa tệp thủ công thường bị ghi đè bởi giao diện người dùng (GUI). Thay vào đó, hãy sử dụng các cài đặt có sẵn:

  • Plesk: Đi tới PHP Settings. Tìm trường open_basedir và thêm đường dẫn tùy chỉnh của bạn vào cuối chuỗi hiện có.- cPanel: Đi tới PHP Selector > Options. Tìm mục open_basedir và nhập các đường dẫn cần thiết của bạn.## Xác minh: Xác nhận việc khắc phụcĐừng chỉ giả định rằng nó hoạt động. Hãy chạy một tập lệnh kiểm tra nhỏ để xác minh rằng PHP hiện có thể "nhìn thấy" thư mục đích:
<?php
$path = '/var/www/shared/data.txt';
if (is_readable($path)) {
    echo "Thành công: PHP có thể truy cập tệp.";
} else {
    echo "Thất bại: Truy cập bị từ chối. Giới hạn hiện tại: " . ini_get('open_basedir');
}

Kiểm tra cuối cùng về quyền truy cập trên LinuxĐôi khi, việc khắc phục open_basedir lại làm lộ ra vấn đề thứ hai: quyền truy cập tệp tiêu chuẩn của Linux. Ngay cả khi PHP được phép xem một thư mục, người dùng hệ thống (như www-data) vẫn cần quyền đọc.

Khi tính toán các quyền cho các cây thư mục phức tạp, tôi thường sử dụng một Công cụ tính toán quyền Unix. Nó giúp bạn hình dung những gì chmod 755 thực sự thực hiện đối với Chủ sở hữu, Nhóm và Những người khác. Điều này đảm bảo bạn không vô tình để một thư mục có quyền ghi cho tất cả mọi người (777) chỉ để giải quyết một lỗi đường dẫn.

Danh sách kiểm tra tóm tắt- Tìm đường dẫn chính xác đang bị chặn từ nhật ký lỗi của bạn.- Kiểm tra phpinfo() để xác định hạn chế đang hoạt động.- Cập nhật đường dẫn trong php.ini, PHP-FPM pool của bạn hoặc Bảng điều khiển.- Luôn bao gồm /tmp/ để tránh làm gián đoạn việc tải lên tệp.- Khởi động lại PHP-FPM hoặc Apache.- Xác minh quyền truy cập bằng cách sử dụng is_readable().

Related Error Notes