Vấn đềBạn đang cố gắng đóng gói ứng dụng PHP của mình thành một tệp .phar thực thi duy nhất. Bạn chạy tập lệnh build, mong đợi một gói hoàn chỉnh, nhưng quy trình bị treo ngay lập tức. Thay vì nhận được một tệp tin, bạn nhận được một stack trace dài 10 dòng kết thúc bằng ngoại lệ Phar->__construct.
Fatal error: Uncaught UnexpectedValueException: creating archive "project.phar" is disabled by the php.ini setting phar.readonly in /path/to/build-script.php:10
Lỗi này thường xảy ra nhất trong quá trình phát triển local hoặc bên trong các pipeline CI/CD khi tự động hóa việc phân phối các công cụ CLI. Đây là một rào cản phổ biến khi sử dụng các công cụ như Box hoặc các tập lệnh tạo Phar tùy chỉnh.
Tại sao PHP chặn việc tạo PharCấu hình phar.readonly là một công tắc an toàn tích hợp sẵn. PHP đặt giá trị này thành 1 (On) theo mặc định để ngăn các tập lệnh vô tình hoặc cố ý tạo các tệp Phar một cách độc hại. Sự bảo vệ này giúp chặn các cuộc tấn công "Phar Deserialization", nơi tin tặc cố gắng thực thi mã độc ẩn bên trong kho lưu trữ Phar.
Vấn đề là bạn không thể sử dụng ini_set('phar.readonly', 0); bên trong tập lệnh của mình để tắt nó. Vì đây là một thiết lập bảo mật cao, PHP sẽ bỏ qua mọi nỗ lực thay đổi sau khi tập lệnh đã bắt đầu chạy. Bạn phải vô hiệu hóa nó trước khi engine khởi tạo hoàn toàn.
Giải pháp 1: Sử dụng ghi đè dòng lệnh (Cách tốt nhất)Nếu bạn chỉ thỉnh thoảng mới build các bản lưu trữ, đừng thay đổi cài đặt hệ thống chung. Cách an toàn nhất là chỉ vô hiệu hóa hạn chế cho lệnh cụ thể mà bạn đang chạy. Điều này giữ cho hệ thống của bạn an toàn trong khi vẫn cho phép tập lệnh build thực hiện công việc của nó.
Sử dụng cờ -d để thay đổi cấu hình ngay lập tức:
php -d phar.readonly=0 build.phar.php
Dưới đây là chức năng của các thành phần đó:
-d: Yêu cầu PHP xác định một cấu hình tùy chỉnh cho lần thực thi này.-phar.readonly=0: Chuyển chế độ chỉ đọc sang "Off".-build.phar.php: Tên của tập lệnh đóng gói cụ thể của bạn.## Giải pháp 2: Cập nhật php.ini (Khắc phục vĩnh viễn)Trên một máy chủ build chuyên dụng hoặc máy cục bộ nơi bạn build Phar hàng ngày, một thay đổi vĩnh viễn sẽ tiết kiệm thời gian. Trước tiên, bạn cần tìm đúng tệp cấu hình.
Bước 1: Xác định vị trí cấu hình CLI của bạnChạy lệnh này để xem terminal của bạn thực sự đang sử dụng tệp nào:
php --ini
Tìm đường dẫn Loaded Configuration File. Trên Ubuntu, nó thường có dạng /etc/php/8.2/cli/php.ini.
Bước 2: Chỉnh sửa tệpMở tệp đó bằng sudo và trình soạn thảo yêu thích của bạn, chẳng hạn như Nano hoặc Vim:
sudo nano /etc/php/8.2/cli/php.ini
Bước 3: Thay đổi giá trịTìm phần [Phar]. Thay đổi dòng đó thành như thế này:
phar.readonly = Off
Save và thoát. Bạn không cần khởi động lại Apache hoặc Nginx vì thay đổi này chỉ ảnh hưởng đến PHP CLI.
Giải pháp 3: Cách xử lý trong Docker và CI/CDKhi build Phar bên trong container Docker hoặc GitHub Action, bạn không thể chỉnh sửa tệp một cách thủ công. Bạn cần một cách tiếp cận bằng tập lệnh.
Sử dụng DockerfileThêm dòng này vào Dockerfile của bạn để chèn cài đặt trong giai đoạn build image:
RUN echo "phar.readonly=0" >> /usr/local/etc/php/conf.d/docker-php-ext-phar.ini
Sử dụng GitHub ActionsNếu bạn sử dụng action shivammathur/setup-php phổ biến, bạn có thể truyền cài đặt trực tiếp vào tệp YAML workflow của mình:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
ini-values: phar.readonly=0
Kiểm tra bản sửa lỗiXác nhận cài đặt đã hoạt động bằng cách chạy dòng lệnh nhanh này trong terminal của bạn:
php -r "echo 'Readonly is: ' . ini_get('phar.readonly');"
Nếu nó trả về Readonly is: 0, bạn đã sẵn sàng. Bạn cũng có thể chạy tập lệnh kiểm tra tối giản này để đảm bảo đối tượng Phar khởi tạo mà không bị lỗi:
<?php
try {
$p = new Phar('test.phar');
echo "Success: Phar archive initialized.";
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

