Я использую PHP 7.2 fpm с lighttpd / 1.4.53 на Raspbian. Моя цель - загрузить файлы изображений через HTTP POST. Но все, что я отправляю в сценарий, суперглобальные переменные $ _POST, $ _FILES, $ _REQUEST - это просто пустые массивы. Однако $ _SERVER возвращает правильно заполненный массив. То же самое и $ _GET, если к URL-адресу добавлены какие-либо параметры.
Вот что я использую для тестирования:
<?php
$outhandle = fopen("logfile.txt", "a");
fputs($outhandle, print_r($_FILES, true) . "\n");
fputs($outhandle, print_r($_REQUEST, true) . "\n");
fputs($outhandle, print_r($_GET, true) . "\n");
fputs($outhandle, print_r($_POST, true) . "\n");
fputs($outhandle, print_r($_SERVER, true) . "\n");
и вот результат:
Array
(
)
Array
(
)
Array
(
)
Array
(
)
Array
(
[USER] => www-data
[HOME] => /var/www
[CONTENT_TYPE] => image/jpeg
[HTTP_CONTENT_LENGTH] => 2879609
[HTTP_CONNECTION] => keep-alive
[HTTP_ACCEPT_ENCODING] => gzip, deflate, br
[HTTP_HOST] => 192.168.10.2
[HTTP_POSTMAN_TOKEN] => dfeea482-03cf-4b87-b088-3e727d9ed537
[HTTP_ACCEPT] => */*
[HTTP_USER_AGENT] => PostmanRuntime/7.26.1
[REMOTE_PORT] => 54820
[REMOTE_ADDR] => 192.168.10.162
[SERVER_NAME] => 192.168.10.2
[SERVER_ADDR] => 192.168.10.2
[SERVER_PORT] => 80
[REQUEST_SCHEME] => http
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_SOFTWARE] => lighttpd/1.4.53
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => POST
[DOCUMENT_ROOT] => /var/www/html
[SCRIPT_FILENAME] => /var/www/html/upload.php
[SCRIPT_NAME] => /upload.php
[REDIRECT_STATUS] => 200
[REQUEST_URI] => /upload.php
[QUERY_STRING] =>
[CONTENT_LENGTH] => 2879609
[FCGI_ROLE] => RESPONDER
[PHP_SELF] => /upload.php
[REQUEST_TIME_FLOAT] => 1593803808.1838
[REQUEST_TIME] => 1593803808
)
Обратите внимание, что CONTENT_LENGTH составляет около 2,8 МБ (также пробовал файлы гораздо меньшего размера, тот же результат), это запрос POST, который я отправил через Postman. Я нашел несколько предложений в Интернете, все они относятся к настройкам в файле php.ini, но ни одно из них не решило проблему:
upload_max_filesize = 8M
max_file_uploads = 20
request_order = "GP"
variables_order = "GPCS"
Я предполагаю, что произошла некоторая неправильная конфигурация, но я понятия не имею, что я пропустил? Вот и файл конфигурации lighttpd:
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_redirect",
)
server.document-root = "/var/www/html"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
server.port = 80
# strict parsing and normalization of URL for consistency and security
# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails
# (might need to explicitly set "url-path-2f-decode" = "disable"
# if a specific application is encoding URLs inside url-path)
server.http-parseopts = (
"header-strict" => "enable",# default
"host-strict" => "enable",# default
"host-normalize" => "enable",# default
"url-normalize-unreserved"=> "enable",# recommended highly
"url-normalize-required" => "enable",# recommended
"url-ctrls-reject" => "enable",# recommended
"url-path-2f-decode" => "enable",# recommended highly (unless breaks app)
#"url-path-2f-reject" => "enable",
"url-path-dotseg-remove" => "enable",# recommended highly (unless breaks app)
#"url-path-dotseg-reject" => "enable",
#"url-query-20-plus" => "enable",# consistency in query string
)
index-file.names = ( "index.php", "index.html" )
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )
# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.conf.pl"
include "/etc/lighttpd/conf-enabled/*.conf"
#server.compat-module-load = "disable"
server.modules += (
"mod_compress",
"mod_dirlisting",
"mod_staticfile",
)
Я понял, что это не проблема с lighttpd. Фактически, эти суперглобальные переменные заполняются только тогда, когда запрос POST отправляется через веб-форму. Чтобы получить опубликованные файлы из другого запроса, нужно прочитать содержимое ввода php: //, как здесь:
file_put_contents($path_to_destination_file, file_get_contents('php://input'));
Я не знаю, как это должно работать с несколькими файлами, но сейчас это не проблема.