유용한 함수 file_exists > 개발자팁

개발자팁

개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.

유용한 함수 file_exists 정보

PHP 유용한 함수 file_exists

본문

유용한 함수 file_exists
 
이번에 file_exists 를 다루는 이유는
물론 많이 쓰기도 하지만, 착각하기 쉬운 문제가 있기 때문에
다루었습니다.
 
(PHP 4, PHP 5)
file_exists — Checks whether a file or directory exists

인자로 넘어온 파일이나 디렉토리가 존재하는지 체크합니다.
존재하면 true, 존재하지 않으면 false 를 반환합니다.
함수명만으로 보면 파일이 존재할지 여부만 체크할것 같지만
파일과 디렉토리 모두를 체크합니다.
즉, 인자로 넘어온것이 파일인지 디렉토리 인지 상관없이
존재 유무만 판단하는 것입니다.
 
Description
bool file_exists ( string $filename )
Checks whether a file or directory exists.

일반적인 사용방법에 대한 것은 잘 알것으로 보고
프로그램을 하면서 실수 하기 쉬운 부분의 예를 들고자 합니다.
 
보통 썸네일을 만드는 부분을 처리 하는 소스들을 보면
$save_dir = 'data/' . $bo_table;
if (!file_exists($save_dir)) {
    mkdir($save_dir);
    chmod($save_dir, 0777);
}
...... 썸네일 처리하는 부분 .........
 
와 같이 사용을 많이 합니다.
그냥 언뜻 보기에는 아무런 문제가 없어 보입니다.
그러나...
프로그램 실행 과정중 $bo_table 에 값이 없을 경우가 발생합니다.
결과적으로
$save_dir 에 값은 data/ 입니다.
즉 썸네일 이 원래 생성되고자 하는곳에서 생성되는것이 아니라.
그 상위의 디렉토리에 생성되는 결과를 낳게 됩니다.
즉, 위 소스에선 $bo_table 의 값이 잇는지 없는지 체크 하는 과정이 포함되어야
올바른 프로그램이라 할수 있습니다.
 
또 다른 예로
데이타 디렉토리에 여러가지 디렉토리와 파일을 같이 저장하는 경우.
의도하지 않게 디렉토리 명과 파일명이 겹치는 경우가 있습니다.
이미 데이타 폴더내에 1 이라는 폴더가 존재하는데
파일 1 이 존재하는지 여부를 체크 하여 뭔가를 처리 할 경우
문제가 발생합니다.
위에서 설명 했듯이
file_exists 는 파일인지 디렉토리인지는 상관없이 존재 유무만 체크하는 함수 이므로
존재한다면 true를 반환하기 때문에
그것이 파일인지 디렉토리 인지는 알수가 없습니다.
 
$file_name = '1';
if (!file_exists($file_name)) {
    file_put_contents($file_name, '데이타');
}
$data = file_get_contents($file_name);
.........
 
위의 소스에서 보면
이미 1이라는 디렉토리가 존재하므로 1이라는 데이타 파일을 생성하지 않습니다.
$data = file_get_contents($file_name); 이부분에서도 에러를 발생하게 됩니다.
즉, 체크하고자 하는 대상이 명확하다면
파일일 경우에는 is_file , 디렉토리일 경우에는 is_dir 로서 체크 하는 것이 바람직합니다.
 
가장 많이 일어나는 예는
어떤 특정 경로에 썸네일 파일을 저장하고자 하는데
파일명이 없을때 발생하는 케이스 입니다.
 
파일명은 디비의 특정 테이블에 값이 들어잇고
경로는 고정이라고 햇을때
보통 아래와 같은 식으로 많이 합니다.
 
$save_dir = 'data/files/a';
$save_file = $save_dir . '/' . $row['file_name'];
if (file_exists($save_file)) {
    echo "<img src='$save_file'>";
}
else {
    echo "<img src='noimg.gif'>";
}
 
이것 역시 이상이 없는 소스 처럼 보이지만
$row['file_name'] 에 값이 없다고 생각해보면
체크를 data/files/a/ 로 하게 되어, 존재한다고 파악하고
이미지를 출력하게 됩니다.

가끔 썸네일이 깨져서 출력된다는 식의 문의는 이런경우가 많습니다.
이런 경우 is_file 을 쓰는것이 바람직하다라고 할수 있습니다.
 
참고>
is_file 은 체크하고자 하는 파일이 파일인지 또 존재하는지를 동시에 체크합니다.
is_dir 은 체크하고자 하는 디렉토리가 디렉토리인지 또 존재하는지를 동시에 체크합니다.

 
추천
12

댓글 21개

감사합니다.

사실 글쓰는 낙이라면
많이 읽어주냐 안읽어주냐..... 도 큰거 같아요.

물론 자기 만족도 크지만요.
이전 내용이 좋지 않다거나 잘 못 설명하셨다는 것과는 전혀 다른 얘기입니다.^^

아무래도 저 같은 초보는 그누보드만 접하다보니 그누보드에서 흔히 보여지지 않는 함수는 어떻게 쓰이는지를 몰라 감이 안온다고 해야할까요..
(또 실제 사용할 곳이 없다보니 보고나도 금방 잊어버리게 됩니다.)

흔히 보여지는 for 라던가 비슷한 foreach 같은 것이 저에겐 더 와 닿습니다.
초보 이상의 분들이야 너무 쉬운 함수라지만 초보는 저런거 부터 막히거든요.
그 흔한 preg_replace 조차 100번정도 당해보고(?) 나서야 이제 겨우 대충이나마 사용할 중 아는 정도이니까요^^
아직도 JOIN 같은 건 볼때마다 새롭습니다..;;

쉬운 함수지만 그누보드에 어찌 사용되었는지, 또 어떻게 사용되어지면 더 좋은건지...뭐 이런 강좌가 제 수준엔 "딱"입니다.^^;;

책은 중,고수보다 초보에게 맞게 쓰는 편이 더 많이 팔릴 거 같아요...ㅎㅎㅎ
"그누보드로 활용하는 PHP" 뭐 이런책 나오면 살거 같다는...;;
와.. 정말 깔끔하고 쉽게 정리해 주셨네요..
그 동안 별 구분없이 사용했었는데 함정이 생각보다 많네요..
요즘 공부좀 하려고 인터넷 뒤적이면 창화님 자주뵙는다는..
10년전 사진이라고 올리신거 ㅎㅎ
제가 얼마전까지는 if( file_exists($fn) && is_file($fn) ) {} 이런식의 코딩이 습관이었는데
테스트작업을 로컬에서 usb외장하드로 하다보니 파일이 많은경우, 그리고 파일이 존재하는 경우
카운트가 많은 반복문에서는 부하가 꽤 걸리는듯 하더군요. (is_file()은 캐시가 된다고는 합니다만..)
  보통 호스팅받는 곳의 하드가 빠르니 크게 차이는 없을듯합니다만 확실히 is_file()이 좀 더 부하가 걸리겠네요. 일단 파일이 있으면 다시 파일인지의 여부를 체크할테니까요.. (실질적으로는 is_file()나 file_exists()를 단독으로 사용할때는 별 차이는 없는것 같습니다. 다만 저처럼 두 함수를 같이 사용할때는 차이가 많이 나는듯 합니다.)
  is_file()만으로는 존재여부까지는 알수 없어서 파일명중복을 피하려는 경우에는 file_exists()와 is_file()을 같이 사용해야겠지만 가급적이면 is_file()은 최소화 하는게 좋겠더군요.
유창화님의 예제에서처럼 $bo_table이 없는경우를 미리 예외처리 한다던지,  $save_dir의 파일명부분인 $row['file_name']에 값이 있는지 미리 체크하고 나서 file_exists()로 존재여부를 체크하는 정도가 좋겠지요.
  물론 확실한 무결성을 위해 is_file()을 꼭 써야하는 부분도 있습니다. 파일업로드시에 특정디렉토리에 넣는다 하더라도 그 하위에 또 디렉토리가 있는 경우에는 확실하게 해줘야겠지요. 하지만 이런경우에는 파일이 여러개라도 반복루프가 많진 않을 것이므로 is_file()이 쓰인다 하더라도 크게 지장은 없다고 봐야겠죠.

  제가 스킨자료실에서 가져다쓰는 갤러리게시판에서 썸네일은 data/file/$bo_table/thumb/ 디렉토리에 확장자없이 $wr_id를 파일명으로 넣어주는데요, 글을 수정하거나 등록할때에(write_update.tail.skin.php) 이 파일을 삭제해버리고 list.skin.php에서 file_exists("$thumb_dir/$wr_id")만으로 체크해서 파일이 없으면 썸네일을 생성합니다. (효율성은 write_update.tail.skin.php에서 썸네일생성까지 하는게 제일 좋겠지요;;)
  이처럼 목록같은 반복이 많은 부분에서는 가급적 is_file()의 사용은 자제하고 대신 저장시에 확실하게 체크해주는 습관을 들이는게 좋을것 같습니다.
  쓰다보니 무척 길어졌네요; 제가 벤치마킹같은건 약해서 그런데 누가 확실하게 데이터화 해주실분 안계시려나요.. ^^;
is_file 과 file_exists 는 동시에 쓸필요가 없습니다.

is_file 자체에 파일의 존재유무도 같이 체크합니다.

http://kr.php.net/manual/en/function.is-file.php

중간쯤에

Returns TRUE if the filename exists and is a regular file, FALSE otherwise.
아 그렇군요! 이래서 메뉴얼을 잘 봐야하는거군요. ^^;
그저 함수명만보고 단순하게 파일인지 디렉토린지 구분만 해줄거라 생각하고 디렉토리마져 없으면 에러 뱉을까봐 선행으로 file_exists를 썼었네요.. ㅎㅎ;;
요즘에야 모르는 함수는 중반부 관련함수까지 훑어보지만 예전엔 그런 습관이 없었던지라 대충대충 보고 하다 오랜 습관으로 자리잡혀있었네요. 이너무 영어울렁증땜시.. ㅋ
혹시나 저같은 분이 계실까 싶기도 했고 한페이지에서 많이 쓰이면 아무래도 부하가 걸리는듯해서 남발하지는 말자는 취지에서 썼습니다.
업로드시에 파일명 중복체크는 file_exists()로, 해당파일을 참조할때는 is_file()로 체크하면 되겠지요.
좋은지적 감사합니다. ^^

제가 겪은 경험은 쇼핑몰에서 제품등록시 이미지들을 썸네일로 생성하는데 만들려는 크기보다 작으면 원본이미지를 뿌리면 되겠구나 해서 하드용량을 절약하고자 패스하고 보여줄때 file_exists와 is_file을 써서 썸네일이 있는지 체크했거든요. 메인페이지같은데서는 많은 제품을 뿌리다보니 많이 사용하다 부하가 걸리는 경험을 했었네요.. 그래서 지정사이즈보다 작더라도 일단은 썸네일의 위치에 복사를 해서 제품을 뿌릴때는 파일체크를 전혀 하지 않는 방법으로 바꿨었지요.
참고로 file_exists와 is_file을 microtime으로 살짝 비교해보니 캐시가 되서인지 의외로 is_file이 약간이지만 더 빠른거 같더군요.
전체 64
개발자팁 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT