본문 바로가기
프로그래밍 놀이터/Web

[PHP] File Manipulation Tutorial

by 돼지왕 왕돼지 2013. 12. 30.
반응형


 PHP, File Manipulation Tutorial 

 

[PHP] File Manipulation Tutorial


=====

파일 열기


$fp = fopen( "$DOCUMENT_ROOT/../orders/orders.txt", "w" );


- $_SERVER['DOCUMENT_ROOT'] 는 웹 문서 트리의 루트를 가르킨다.


- 경로를 나타낼 때, / 를 쓰는 것이 좋다.

  \ 는 윈도우즈에서는 사용할 수 있지만, Linux 에서는 \\ 로 인식시켜야 하기 때문.


- file mode 는 다음과 같다.

r

r+ : 읽고 쓰기 위함.

w

w+ : 읽고 쓰기 위함.

x : 경고 쓰기, 만일 파일이 있을 경우 파일을 열지 않고, fopen() 이 false 를 반환하고 PHP 는 경고

x+ : 파일을 읽고 쓰기 위함.

a : 추가 모드, 파일을 추가 쓰기 위해 연다.

a+ : 파일을 읽고 쓰기 위함.

b : 바이너리 모드, 다른 모드들과 합쳐서 사용한다. 바이너리와 텍스트 파일을 구별하는 경우. 윈도우의 경우 구별이 필요하고, linux 계열에서는 구분하지 않는다. 이 모드는 기본값이다.

t : 텍스트, 다른 모드들과 합쳐서 사용하며, 윈도우즈 시스템에서만 사용한다.


fopen() 으로 FTP 나 HTTP 파일을 열 수도 있다. php.ini 에 있는 allow_url_fopen 이 활성화 되어 있어야 한다. http 로 열 때는 주소마지막에 / 를 반드시 붙여주어야 한다. 예를 들면 http://www.example.com/ ( 최신버전에서는 생략해도 된다. )


파일을 열 때는 에러의 대부분은 권한 문제이다. 권한 없는 파일에 접근하려 하면, ...failed to open stream Permission denied ... 와 같은 에러 메세지가 뜬다.


보통 스크립트는 웹 서버 사용자나 스크립트가 있는 소유자 권한으로 동작한다. 이는 서버 세팅에 따라 달라질 수는 있다.



=====

파일 쓰기


- fwrite() fputs() 를 이용한다. 둘은 동일한 기능을 한다.


fwrite ( resource handle, string string [, int length] )


fwrite() 대신 file_put_contents() 를 사용할 수도 있다.



int file_put_contents( string fileName, string data [, int flags [, resource context]] )


이 함수를 사용하면 fopen() 으로 파일을 먼저 열 필요가 없고, fclose() 로 파일을 닫지 않아도 된다. 이 함수는 PHP5 에서 새로 제공되었다. file_get_contents() 와 한 쌍을 이루며, flags, context 를 이용하여 http, ftp 에 쓸 수도 있다.







=======

파일 내용 읽기


<example>

@$fp = fopen ("$DOCUMENT_ROOT/../orders/orders.txt', 'r' );


if ( !$fp ){

echo '<p><strong> File Open Error </p> </strong>';

exit;

}


while( !feof( $fp ) ){

$buffer = fgets( $fp, 999 );

echo $order.'<br />';

}

fclose( $fp );


fgets 에서 명시한 길이보다 1 바이트 적은 바이트를 읽는다.

예를 들어 위처럼 999 를 적어주면 998 바이트를 읽어들인다.


fgets() 는 일반 텍스트 파일에 유용하다.



string fgetss( resource fp, int length, string [allowable_tags] );


fgetss() 는 읽어들인 문자열에서 PHP 와 HTML 태그를 모두 제거한다. 특정 태그를 남겨두려면 allowable_tags 에 적어준다.



array fgetcsv( resource fp, int length [, string delimiter [, string enclosure]] )


파일에서 읽은 문자열을 구분 문자로 나누어 배열에 저장한다.

입력을 한줄의 문자열이 아닌 변수로 읽어들이고 싶을 때 편리하다.


ex) $order = fgetcsv( $fp, 100, "\t" );


enclosure 는 각각의 필드를 둘러싸는 문자를 지정하는데, 파라미터를 적어주지 않으면 기본적으로 쌍따옴표로 둘러쌓인다.



=======

한번에 파일 전체 읽기


int readfile( string fileName, int [use_include_path[, resource context]] );


파일에서 읽은 입력의 총 길이가 바이트 값으로 리턴된다. 읽으면서 내용이 출력된다.



fpassthru() 는 전달된 파일 포인터의 포인터 위치에서부터 파일의 끝까지 읽는다.

그리고 그 내용을 표준 출력으로 출력한 후 파일을 닫기까지 한다.



file() 은 readfile() 과 같지만, 내용이 출력되지 않고 배열에 저장된다. 편리하긴 하지만 바이너리를 잘 처리하지 못한다.



file_get_contents() 는 PHP 4.3.0 부터 등장했으며, readfile() 과 동일하지만 브라우저에 출력하지 않고 내용을 문자열로 리턴한다. file() 함수와 달리 바이너리를 안전하게 처리한다.



=========

한 글자씩 읽기 : fgetc()

임의의 길이 읽기 : string fread( resource fp, int length );







===========

기타


file_exists( "$DOCUMENT_ROOT/../orders/orders.txt" ) 를 통해 파일 존재유무를 알 수 있다.


filesize( string fileName ) 으로 파일 사이즈를 알 수 있다.


참고로 nl2br 함수는 \n 을 <br /> 로 치환해준다.


unlink( string fileName ) 으로 파일을 지울 수(삭제) 있다.



======

파일 포인터


rewind(), fseek(), ftell() 을 이용해 파일 포인터 위치를 바꿀 수 있다.


rewind() 파일 포인터를 파일 시작점으로 옮긴다.


ftell() 현재 파일 포인터의 위치를 바이트 값으로 return 한다.



int fseek( resource fp, int offset [, int whence] )


fseek() 은 whence 부터 offset 만큼 떨어진 곳에 파일 포인터 fp 를 옮겨놓는다. whence 에 가능한 값은 SEEK_SET ( 파일 처음 ), SEEK_CUR ( 현재 위치 ), SEEK_END ( 파일의 끝 ) 이 있다.



=========

파일에 락 걸기


bool flock( resource fp, int operation [, int &wouldblock] )


wouldblock 은 락을 얻는 과정에서 현재 프로세스가 기다려야 하는지를 알려준다.

가능한 operation 값은 다음과 같다.


LOCK_SH ( 1 ) : 읽기 락. 읽기만 하면 동시에 공유 가능하다.

LOCK_EX ( 2 ) : 쓰기 락. 파일을 공유할 수 없다.

LOCK_UN ( 3 ) : 걸어놓은 락을 푼다.

LOCK_NB ( 4 ) : 락을 걸기 위해 스크립트가 정지하는 것을 막는다.


flock() 은 NFS 나 다른 네트워크 파일 시스템에서는 사용할 수 없고, FAT 과 같이 락을 지원하지 않는 오래된 파일 시스템에서도 사용할 수 없다. 다중 쓰레드 서버 API 를 사용하고 있다면 제대로 동작하지 않을 수도 있다.


따라서 LOCK 에 관해서는 DBMS 를 사용하는 것이 추천된다.







======

파일 사용시의 문제점


1. 파일이 커지면 실행 속도가 느리다.

2. 특정 레코드를 찾는 일이 어렵다.

3. 동시에 파일에 접근하는 문제를 해결하기 어렵다.

4. 파일은 항상 순차적으로 접근하기 때문에 처음부터 끝까지 읽는다. 중간 내용 쿼리와 수정 등이 어렵다.

5. 파일 권한에도 한계가 있어, 데이터에 접근하는 권한 설정이 어렵다.


이들은 DBMS 를 사용하여 해결할 수 있다.






반응형

댓글