PHP의 고유하고 임시 파일 이름?
일부 파일을 PDF로 변환 한 다음 이메일에 첨부해야합니다. 나는 이메일쪽에 Pear Mail을 사용하고 있으며 괜찮습니다 (대부분-여전히 몇 가지 문제를 해결하고 있음).하지만 이것의 일부로 임시 파일을 만들어야합니다. 이제 tempnam () 함수를 사용할 수 있지만 파일 시스템에 파일을 생성하는 것처럼 들립니다.
동일한 사용자가 스크립트를 두 번 이상 호출하는 동일한 스크립트를 실행하는 다른 사람과 충돌하지 않는 임시 파일 시스템의 이름 ( sys_get_temp_dir () 사용)을 원합니다 .
제안?
나는 과거에 uniqid ()를 사용하여 고유 한 파일 이름을 생성했지만 실제로 파일을 생성하지는 않았습니다.
$filename = uniqid(rand(), true) . '.pdf';
첫 번째 매개 변수는 원하는대로 지정할 수 있지만 여기서는 rand ()를 사용하여 좀 더 무작위로 만들었습니다. 집합 접두사를 사용하면 시스템의 다른 임시 파일과의 충돌을 더욱 방지 할 수 있습니다.
$filename = uniqid('MyApp', true) . '.pdf';
거기에서 파일을 만듭니다. 다른 모든 것이 실패하면 while 루프에 넣고 작동하는 것을 얻을 때까지 계속 생성하십시오.
while (true) {
$filename = uniqid('MyApp', true) . '.pdf';
if (!file_exists(sys_get_temp_dir() . $filename)) break;
}
진지하게, tempnam ()을 사용하십시오. 예, 이렇게하면 파일이 생성되지만 이는 시스템의 다른 프로세스가 파일 이름을 "도용"하여 프로세스가 원하지 않는 파일을 덮어 쓰는 것을 방지하기 위해 고안된 매우 의도적 인 보안 조치입니다.
즉, 다음 순서를 고려하십시오.
- 임의의 이름을 생성합니다.
- 파일 시스템이 존재하지 않는지 확인합니다. 그렇다면 이전 단계를 반복하십시오.
- 또 다른 사악한 프로세스는 Mr Evil이 실수로 덮어 쓰도록 요청한 파일에 대한 하드 링크와 동일한 이름의 파일을 만듭니다.
- 쓰기 모드에서 기존 파일을 여는 것이 아니라 파일을 만들고 있다고 생각하고 파일을 열고 쓰기 시작합니다.
- 중요한 것을 덮어 썼습니다.
PHP의 tempnam ()은 실제로 시스템의 mkstemp를 내부에서 호출합니다 (리눅스를위한 것입니다 ... 다른 OS를 "모범 사례"함수로 대체). 다음과 같은 프로세스를 거칩니다.
- 파일 이름 선택
- 다른 사람이 소유하지 않은 파일을 제거하지 못하도록하는 디렉토리 내부에 제한적인 권한으로 파일을 만듭니다 (이것이 고정 비트가 / var / tmp 및 / tmp에서 수행하는 작업입니다).
- 생성 된 파일에 여전히 제한적인 권한이 있는지 확인합니다.
- 위의 방법 중 하나라도 실패하면 다른 이름으로 다시 시도하십시오.
- 생성 된 파일 이름을 반환합니다.
이제 이러한 모든 작업을 직접 수행 할 수 있지만 "적절한 기능"이 보안 임시 파일을 생성하는 데 필요한 모든 작업을 수행하고 거의 항상 빈 파일을 생성해야하는 이유입니다.
예외 :
- 프로세스 만 파일을 생성 / 삭제할 수있는 디렉토리에 임시 파일을 생성합니다.
- 프로세스 만 파일을 생성 / 삭제할 수 있는 임의로 생성 된 임시 디렉토리 를 만듭니다.
고유 한 파일 이름을 생성하기 위해 날짜 및 시간의 일부를 사용할 수 있습니다. 이렇게하면 두 번 이상 호출 될 때 중복되지 않습니다.
파일 이름에 uuid를 사용하는 것이 좋습니다. uniqid 기능을 고려하십시오. http://php.net/uniqid
@Lusid
최대 실행 시간의 장애 조치 (failover) 에 대한 응답을 기반으로하는 또 다른 대안 :
//////////// Max exectution time of 10 seconds.
$maxExecTime = time() + 10;
$isUnique = false;
while (time() !== $maxExecTime) {
//////////// Unique file name
$uniqueFileName = uniqid(mt_rand(), true) . '.pdf';
if (!file_exists(sys_get_temp_dir() . $uniqueFileName)){
$isUnique = true;
break;
}
}
if($isUnique){
//////////// Save your file with your unique name
}else{
//////////// Time limit was exceeded without finding a unique name
}
노트 :
나는 첫 번째 기능을 사용 하고 두 번째 ( ) 보다 빠르기 때문에
mt_rand
대신 사용하는 것을 선호합니다 .rand
Mersenne Twister algorithm
LCG
더 많은 정보:
- http://php.net/manual/en/function.uniqid.php
- http://php.net/manual/en/function.mt-rand.php
- http://php.net/manual/en/function.time.php
http://www.php.net/tempnam PHP 기능 사용을 권장합니다 .
$file=tempnam('tmpdownload', 'Ergebnis_'.date(Y.m.d).'_').'.pdf';
echo $file;
/var/www/html/tmpdownload/Ergebnis_20071004_Xbn6PY.pdf
<?php
$temp = tmpfile();
fwrite($temp, "writing to tempfile");
fseek($temp, 0);
echo fread($temp, 1024);
fclose($temp); // this removes the file
?>
내 생각은 재귀 함수를 사용하여 파일 이름이 있는지 확인하고 존재하는 경우 다음 정수로 반복하는 것입니다.
function check_revision($filename, $rev){
$new_filename = $filename."-".$rev.".csv";
if(file_exists($new_filename)){
$new_filename = check_revision($filename, $rev++);
}
return $new_filename;
}
$revision = 1;
$filename = "whatever";
$filename = check_revision($filename, $revision);
사용자 ID와 함께 Unix 타임 스탬프를 더 잘 사용하십시오.
$filename='file_'.time().'_'.$id.'.jepg';
function gen_filename($dir) {
if (!@is_dir($dir)) {
@mkdir($dir, 0777, true);
}
$filename = uniqid('MyApp.', true).".pdf";
if (@is_file($dir."/".$filename)) {
return $this->gen_filename($dir);
}
return $filename;
}
참조 URL : https://stackoverflow.com/questions/460164/unique-and-temporary-file-names-in-php
'programing' 카테고리의 다른 글
문자열이 날짜인지 확인하는 기능 (0) | 2021.01.16 |
---|---|
* ngFor를 사용하여 객체 키를 반복하는 방법 (0) | 2021.01.16 |
클로저에서 숫자를 구문 분석하는 가장 쉬운 방법은 무엇입니까? (0) | 2021.01.16 |
IO 용 GoF 데코레이터 패턴의 사용 사례 및 예 (0) | 2021.01.16 |
Android에서 문자열에 새 줄을 삽입하는 방법 (0) | 2021.01.16 |