파일을 업로드할 수 있는 PHP 스크립트가 있고 파일을 /tmp에서 test/로 이동하려고 합니다. (상대 경로는 내 프로젝트 폴더에 있습니다. 예를 들어 /var/www/html/myproject/test는 절대 경로입니다. 길). 이런 일이 발생하면 다음 오류가 발생합니다.
move_uploaded_file(test/test.csv): 스트림을 열 수 없습니다: /var/www/html/myproject/import.php, 라인 .php
에서 권한이 거부되었습니다.
이 스크립트는 rwx 권한이 있는 /test 소유권(아파치 소유자와 아파치 그룹 모두 이 디렉터리를 소유함)이 있는 아파치 사용자가 실행합니다.
다음 사항을 확인했습니다.
- safe_mode가 비활성화되었습니다.
- open_basedir이 설정되지 않았습니다.
- file_uploads가 활성화되었습니다.
- upload_max_filesize는 2MB이고 파일 크기는 ~50KB입니다.
- post_max_size는 8MB이고 내 POST 요청은 이에 가깝지 않습니다.
- 상대 경로 대신 절대 경로를 사용하세요.
- is_dir("test/")는 true를 반환합니다.
- is_writable("test/")는 false를 반환합니다.
- PHP 스크립트에서: 인쇄 파일 소유자(이동할 파일), 폴더 소유자(test/), 파일 권한 및 폴더 권한. 파일/폴더 소유자는 Apache로 표시됩니다. 파일 권한은 600이므로 소유자가 읽고 쓸 수 있습니다. 폴더 권한은 755이므로 소유자는 읽기, 쓰기, 실행이 가능합니다.
- ps -aux grep 아파치. Apache 오류 로그의 PID를 Apache 사용자가 소유한 실행 중인 프로세스와 일치시킵니다. 따라서 이는 프로세스가 Apache에서 실행되고 있음을 확인합니다.
- getcwd() 및
__DIR__
모두 올바른 디렉토리 /var/www/html/myproject를 반환합니다.
- dirname(
__FILE__
)은 파일에 대한 올바른 절대 경로를 반환합니다
- file_exists($_FILES['file']['tmp_name'])이 true를 반환하는지 확인하세요
- $_FILES['file']['error'](이동하려는 파일)을 확인하면 0이 반환되며 업로드하는 데 문제가 없습니다.
- is_writable("/tmp")을 사용하여 소스 폴더(/tmp)가 쓰기 가능한지 확인하고 true를 반환합니다.
- test/에서 일시적으로 chmod -R 777을 사용하려고 시도했지만 여전히 권한 거부 및 쓰기 불가능이 표시됩니다.
- 바이러스 백신/EDR이 일시적으로 비활성화되었습니다
- "test/"의 보안 컨텍스트를 확인하세요. 반환 결과는 "unconfined_u:object_r:httpd_sys_content_t:s0"입니다. 이 중 어느 것도 문제가 되지 않습니다(아래 답변에 설명되어 있음).
- 파일 이동을 차단할 수 있는 보안 관련 애플리케이션을 설치했는지 확인하세요. AppArmor, grsecurity, Tomoyo Linux 및 Smack 애플리케이션은 설치되어 있지 않습니다.
- PHP 스크립트의 fopen()/flock() 함수를 사용하여 이동하려는 파일이 잠겨 있지 않은지 확인했습니다.
- is_uploaded_file() 함수를 사용하여 업로드된 파일을 이동하려고 한다는 것을 확인했습니다(이 시점에서 제가 생각할 수 있는 모든 것을 시도하는 것만으로도 미칠 지경이었습니다). 물론 이는 true를 반환합니다.
move_uploaded_file에는 두 개의 매개변수가 필요합니다. 1: 업로드하려는 파일 2: 파일의 절대 경로를 배치합니다 3: 업로드 디렉터리에 적절한 소유권과 권한이 있는지 확인하세요. (참고: Apache를 프록시로 사용하는 경우 디렉터리 소유권은 사용자: apache2 그룹에 속해야 합니다.)
으아악자세히 보기: https://www.php.net/manual/pt_BR/function.move-uploaded-file.php