Skip to content

PHP

Giới thiệu và license

PHP là ngôn ngữ kịch bản (script) dùng để sinh nội dung động cho web. PHP không phải web server: web server (lighttpd, Nginx, BusyBox httpd) nhận request HTTP, tự trả file tĩnh, còn request tới file .php thì chuyển sang trình thông dịch PHP, nhận kết quả và gửi lại cho trình duyệt.

Trình duyệt ──HTTP──► Web server (lighttpd / Nginx)
                         │  file tĩnh: tự trả về
                         │  file .php: chuyển tiếp (CGI / FastCGI)
                         ▼
                      PHP (php-cgi / PHP-FPM) ──► chạy script, đọc cấu hình, gọi lệnh hệ thống...

License: PHP License v3.01 (permissive, kiểu BSD). Kiểm tra lại license của phiên bản đang dùng và của từng extension đi kèm.

SAPI: các cách chạy PHP

SAPI (Server API) là lớp giao tiếp giữa PHP và môi trường chạy nó. Khi build PHP cho thiết bị nhúng cần chọn SAPI phù hợp:

SAPI Cơ chế Dùng với Ghi chú
cli Chạy script từ dòng lệnh (php script.php) Shell, cron Có web server dựng sẵn php -S, chỉ dùng khi phát triển
cgi (php-cgi) CGI: mỗi request một tiến trình mới; hoặc chạy liên tục ở chế độ FastCGI BusyBox httpd, lighttpd Đơn giản; lighttpd có thể tự khởi tạo php-cgi
fpm (PHP-FPM) FastCGI Process Manager: daemon riêng quản lý pool tiến trình PHP lighttpd, Nginx Kiểm soát số tiến trình và RAM tốt nhất
apache2handler (mod_php) PHP chạy trong tiến trình Apache Apache Hiếm gặp trên thiết bị nhúng

Kích thước và tài nguyên sử dụng

PHP nặng hơn nhiều so với lighttpd: binary cỡ vài MB, mỗi tiến trình PHP chiếm thêm vài MB RAM tùy extension được bật. Những yếu tố ảnh hưởng chính:

  • Số extension được build (mỗi extension kéo thêm thư viện phụ thuộc như libxml2, OpenSSL, SQLite).
  • Số tiến trình PHP chạy đồng thời (PHP-FPM: pm.max_children).
  • OPcache: giảm CPU vì không phải biên dịch lại script mỗi request, nhưng chiếm thêm bộ nhớ chia sẻ.

Build / cross-compile

Yocto

Recipe php nằm trong layer meta-openembedded/meta-oe, tách thành nhiều package theo SAPI:

# bblayers.conf: thêm meta-openembedded/meta-oe
IMAGE_INSTALL:append = " php-fpm"     # hoặc php-cgi, php-cli

Bật/tắt extension qua PACKAGECONFIG trong bbappend:

# php_%.bbappend
PACKAGECONFIG = "sqlite3 openssl"

Petalinux

Buildroot

BR2_PACKAGE_PHP=y
BR2_PACKAGE_PHP_SAPI_FPM=y        # hoặc _CGI, _CLI, _CLI_CGI
BR2_PACKAGE_PHP_EXT_SQLITE=y      # chỉ bật extension cần dùng

Cấu hình mẫu

PHP-FPM cho thiết bị ít RAM

; /etc/php-fpm.d/www.conf (đường dẫn tùy bản phân phối)
[www]
user  = www-data
group = www-data
listen = /run/php-fpm.sock
listen.owner = www-data
listen.group = www-data

; ondemand: chỉ tạo worker khi có request, tự dừng khi rảnh
pm = ondemand
pm.max_children = 2
pm.process_idle_timeout = 30s
pm.max_requests = 200

php.ini

memory_limit = 16M
expose_php = Off
display_errors = Off
log_errors = On

opcache.enable = 1
opcache.memory_consumption = 8

Tích hợp với web server

lighttpd

Kết nối tới PHP-FPM qua Unix socket:

server.modules += ( "mod_fastcgi" )

fastcgi.server = ( ".php" =>
    (( "socket" => "/run/php-fpm.sock" ))
)

Hoặc để lighttpd tự khởi tạo php-cgi, không cần PHP-FPM:

fastcgi.server = ( ".php" =>
    (( "bin-path"  => "/usr/bin/php-cgi",
       "socket"    => "/tmp/php.socket",
       "max-procs" => 1,
       "bin-environment" => ( "PHP_FCGI_CHILDREN" => "2" )
    ))
)

Xem thêm lighttpd.

Nginx

location ~ \.php$ {
    try_files $uri =404;          # không chuyển file không tồn tại sang PHP
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php-fpm.sock;
}

Xem thêm Nginx.

BusyBox httpd

BusyBox httpd chỉ hỗ trợ CGI. Có thể khai báo trình thông dịch cho đuôi .php trong httpd.conf:

*.php:/usr/bin/php-cgi

Bảo mật

Web UI trên thiết bị nhúng thường gọi lệnh hệ thống (đổi IP, reboot, nâng cấp firmware), nên lỗi command injection là rủi ro lớn nhất:

  • Luôn dùng escapeshellarg() cho tham số đưa vào exec() / shell_exec(), và kiểm tra giá trị đầu vào theo danh sách cho phép.
  • Chạy PHP dưới user không phải root; chỉ cấp quyền cho đúng những lệnh cần thiết (ví dụ qua sudoers giới hạn lệnh).
  • Tắt display_errors và expose_php trên sản phẩm.
  • Với Nginx, dùng try_files $uri =404 để tránh chuyển file không phải .php sang PHP thực thi.

Thiết lập HTTPS xem tại TLS.

Debug và tuning

  • Kiểm tra cấu hình PHP-FPM: php-fpm -t.
  • Xem SAPI, extension và file php.ini đang dùng: php -i, php -m.
  • Bật pm.status_path = /status trong PHP-FPM để theo dõi số worker đang chạy.
  • Bật slowlog và request_slowlog_timeout để tìm script chạy chậm.

Tài liệu tham khảo