PHP에 저장된 임시 파일을 정리하는 올바른 방법은 무엇입니까?

Dec 01 2020

PHP를 사용하여 임시 저장 공간을 정리하는 방법을 찾으려고합니다. cron 작업을 설정할 수 있다는 것을 알고 있지만 PHP 자체에서 수행하는 방법이 있습니까?

사용자가 다운로드 할 수 있도록 생성 된 pdf 파일을 저장하기 위해 임시 저장 폴더를 사용합니다. 3 분 후에는 더 이상 공개적으로 액세스 할 수 없도록 파일을 강제로 만료 시켰습니다. 이제 문제입니다. 파일은 공개적으로 액세스 할 수 없지만 여전히 내 서버에 저장됩니다. 저장소를 정리하기 위해 이와 같은 코드를 작성했습니다.

/** from the main thread */
if (rand(1, 100) <= 5) {
    Reports::clean();
}

/** the clean function */
public static function clean()
{
    $path = static::getStoragePath(); if($dir_handle = opendir($path)) { while (($fileName = readdir($dir_handle)) !== false) { $file = $path . '/' . $fileName;
            
            if (!is_file($file)) continue; // If file is older that 3 minutes delete it if (time() - filemtime($file) > static::$expires) { unlink($file);
            }
        }
        closedir($dir_handle);
    }
}

그래서 이것은 무작위로 저장소를 정리합니다. 대부분 괜찮습니다. 그러나 문제는 저장소 정리가 시작되면 거북이와 같은 요청이 느려지는 것입니다.

그래서 저는 cronjob을 만드는 것을 생각했습니다. 그러나 PHP 자체에서 이것을 수행하는 올바른 방법이 있습니까?

참고 : 저는 slim-4를 사용하고 있으며 cronjob 설정에 대한 전문 지식도 많지 않습니다. 따라서 모든 리소스도 도움이 될 것입니다.

답변

3 MarcinJóźwikowski Dec 01 2020 at 17:04

짧은 대답 : 아니요.

PHP는 어떤 작업도 자체적으로 트리거 할 수 없습니다.

스크립트 (또는 프레임 워크 인 경우 명령)를 만들고 cronjob으로 트리거합니다.

2 MarkusAO Dec 01 2020 at 17:23

구현에서 정리 루틴이 주 스레드에 도달 할 때마다 PDF 디렉토리의 파일 볼륨에 따라 응답에 상당한 지연이 발생할 수 있습니다.

다른 의견 / 답변에서 언급했듯이 크론 작업은 실제로 이것을 처리하는 "표준"방법입니다. 그러나 크론 작업에 액세스 할 수 없거나 단순히 순수한 PHP 솔루션을 선호하는 경우 이미 수행중인 작업을 제외하고 몇 가지 가능한 접근 방식이 있습니다.

  1. 생성 타임 스탬프와 함께 생성 된 파일의 로그를 유지합니다. 정리 루틴이 호출되면 수정 된 시간 검사로 전체 디렉토리 스캔을 수행하는 대신 레코드를 기반으로 삭제하고 레코드에서 삭제 된 항목을 제거하십시오. 레코드를 예를 들어 JSON 파일 또는 CSV / TSV로 저장합니다. 이렇게하면 파일 시스템 액세스가 감소하므로 파일 양이 많은 경우 속도가 크게 향상됩니다.

  2. 정리 지연으로 인해 사용자를 괴롭히지 않으려면 루틴을 사용자 용 파일에서 관리자 전용 파일로 이동하거나 관리자 사용자 확인을 수행하고 정리 빈도 트리거를 조정합니다 (OP에서 1:20) 관리자 사용 빈도와 일치합니다. 이것은 물론 정리 빈도를 줄일 수 있지만 (관리자가 주변에없는 경우) 대중의 부하를 덜어줍니다.

  3. 마지막으로 Cron 씨가되어 가끔씩, 매일 또는 서버 공간이 부족하기 전에 수동으로 정리를 트리거하십시오. 일반적으로 공간이 너무 빡빡하지 않으면 20 페이지 정도 호출 할 때마다 정리할 필요가없는 것 같습니다. 생성 된 PDF의 양, 발생하는 트래픽 또는 서버 리소스에 대해 전혀 모르기 때문에 정리 빈도에 대한 권장 수치를 찾기가 어렵습니다.

TomiL Dec 01 2020 at 21:55

이것은 잘못된 개념 입니다.이 작업에 cronjob 스케줄러 를 사용하십시오. 다음은 폴더 내용이 10MB를 초과하는 경우 / tmp / some_path 폴더의 모든 파일을 삭제하는 bash oneliner입니다 (필요에 따라 수정하십시오).

SIZE=$(du -bs --block-size=1M /tmp/some_path | cut -f1); if [[ $SIZE -gt 10 ]];then echo "Folder '/tmp/some_path' has size ($SIZE MB)."; rm -r /tmp/some_path/*; fi

이 코드를 script.sh에 붙여 넣을 수 있습니다 ( 예 : 상단 에 bash 의 경우 shebang을 포함 #!/bin/bash하고 파일을 실행 가능하게 만듭니다. chmod +x script.sh). 그런 다음 cronjob 스케줄러 (예 :)에 새 줄을 추가하여 매시간 폴더 크기crontab -e확인합니다 .

0 * * * * <path_to_the_script>/script.sh

cronjob에 대한 자세한 내용은 여기에서 찾을 수 있습니다. https://crontab.guru