Nice programing

PHP에서 fopen 모드 "r +"와 "rw +"의 차이점은 무엇입니까?

nicepro 2020. 12. 25. 22:57
반응형

PHP에서 fopen 모드 "r +"와 "rw +"의 차이점은 무엇입니까?


Stack Overflow의 많은 답변은를 사용 fopen($file, "rw+")하지만 매뉴얼 에는 "rw+"모드 가 나열되어 있지 않고 "r+"모드 (또는 "w+"모드) 만 있습니다.

그래서 모드가 무엇"rw+"fopen($file, "rw+""r+" 을하는지 궁금 합니다. 또는 의 차이점은 무엇입니까 ? "rw+"모드 에 대한 문서가 없기 때문에 이것을 묻습니다 .

한 가지 접근 방식은 모드가 추가적 이라는 것을 고려하는 것이지만 fopen매뉴얼 페이지 에서 모드 결합에 대한 언급을 찾을 수 없습니다 (게다가 이미 읽을 수있는 경우 "r"결합하는 의미는 무엇 입니까?). 그러나 가장 중요한 것은 모드가 파일을 자르는 반면 파일을 자르지 는 않는다는 것입니다 (따라서 추가 할 수 없음). Stack Overflow 사용자가 사용 함에도 불구하고 아마도 모드 가 없을 것입니다 . 모드가 === 로 보이기 때문에 파서가 "w"문자를 무시하기 때문에 작동 할 수 있습니다. ?"w+""w+"w+rw+rw+rw+r+

내 질문에 명확히하기 위해 : 무엇 "rw+"모드 , 즉, 어떻게 다른 모드의 차이점은 무엇입니까? 댓글에서 두 가지 답변 만 받았습니다. 문서를 확인해야한다는 것 (이미 확인하고 다시 확인했습니다)과 같지 "w+"않다는 잘못된 답변 입니다. "w+"파일을 자르지 만 "rw+"그렇지 않습니다.

다음은 테스트 용 스크립트입니다 ( w+파일 잘리는 것을 증명 하지만 rw+그렇지 않음).

<?php 
$file = "somefile"; 
$fileOpened = fopen($file, "w"); 
fwrite($fileOpened, "0000000000000000000"); 
fclose($fileOpened);  

$fileOpened = fopen($file, "rw+"); 
fwrite($fileOpened, "data"); 
fclose($fileOpened); 
$fileOpened = fopen($file, "r"); 
$output = fgets($fileOpened); 
echo "First, with 'rw+' mode:<br>".$output; 

$fileOpened = fopen($file, "w+"); 
fwrite($fileOpened, "data"); 
fclose($fileOpened); 
$fileOpened = fopen($file, "r"); 
$output = fgets($fileOpened); 
echo "<br><br><br>Now with only 'w+' mode:<br>".$output; 
?>

나는 당신이 이것을 거의 이해했다고 생각합니다. 나는 추측하지만 권위있는 대답을 원합니다.

문서에 언급되지 않은 것은 사실입니다 "rw+". 그러나 더 나은 것이 있습니다 : PHP 소스 코드 !


래빗 홀

PHP 개발자를위한 PHP의 소스 코드 시리즈 ( Part 1 , Part 2 , Part 3 , Part 4 )를 찾을 때까지 소스 코드를 탐색하는 데 어려움을 겪었습니다 . 나는 두 사이트 사이의 링크가 점프한다는 것을 알고 있습니다. 그 시리즈는 그렇게 유행합니다. 그건 그렇고, 발표 된 Part 5를 찾지 못했습니다.

참고 :이 기사는 오래되었으며 PHP 5.4에 대해 이야기하고 있습니다.

fopen실제로 무엇을하는지 보자 ... 토끼 굴에 빠지자 ...

먼저 함수 정의를 살펴 봅니다 (위 링크 된 파트 2의 조언에 따라 찾았습니다). 나는 그것이 php_stream_open_wrapper_ex내가 다른 곳 에서 찾은 것을 사용 _php_stream_open_wrapper_ex하는 것을 알아 차렸고 , 그것은 우리가 stream.c 에서 찾은 것을 사용한다 .

무엇 _php_stream_open_wrapper_exmode합니까? 에 전달합니다stream_opener .

의 정의를 찾으면 php_streams.hstream_opener 형식 php_stream_wrapper_ops으로 이동했습니다 .

유형의 용도를 검색php_stream_wrapper_ops 하면 plain_wrapper.c 로 연결 되었습니다 .

실제로 php_stream_wrapper_ops다른 것을 열 수 있는 많은 초기화가 있습니다. php_fopen_wrapper.c는 php_stream_wrapper_opswhere stream_openeris 초기화되어 있기 때문에 살펴보고 php_plain_files_stream_opener있습니다.

우리는 거기에 가고 있습니다 ...

php_plain_files_stream_opener이다 동일한 파일에서 더 아래로 . 에 위임합니다php_stream_fopen_rel .

php_streams.hphp_stream_fopen_rel를 사용하여 정의합니다_php_stream_fopen . 어느 것 plain_wrapper.c 다시 .

마지막으로, _php_stream_fopen호출합니다php_stream_parse_fopen_modes . 문자열을 받아 몇 가지 플래그를 출력합니다.


이상한 나라

살펴 보겠습니다 php_stream_parse_fopen_modes.

PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags)
{
    int flags;

    switch (mode[0]) {
        case 'r':
            flags = 0;
            break;
        case 'w':
            flags = O_TRUNC|O_CREAT;
            break;
        case 'a':
            flags = O_CREAT|O_APPEND;
            break;
        case 'x':
            flags = O_CREAT|O_EXCL;
            break;
        case 'c':
            flags = O_CREAT;
            break;
        default:
            /* unknown mode */
            return FAILURE;
    }

    if (strchr(mode, '+')) {
        flags |= O_RDWR;
    } else if (flags) {
        flags |= O_WRONLY;
    } else {
        flags |= O_RDONLY;
    }

#if defined(O_CLOEXEC)
    if (strchr(mode, 'e')) {
        flags |= O_CLOEXEC;
    }
#endif

#if defined(O_NONBLOCK)
    if (strchr(mode, 'n')) {
        flags |= O_NONBLOCK;
    }
#endif

#if defined(_O_TEXT) && defined(O_BINARY)
    if (strchr(mode, 't')) {
        flags |= _O_TEXT;
    } else {
        flags |= O_BINARY;
    }
#endif

    *open_flags = flags;
    return SUCCESS;
}

추상의 경우 다음 작업을 수행합니다 (세부 사항 무시).

  1. 그것은 제 문자 얻어 mode그이면 검사 r, w, a, x, c. 이들 중 하나를 인식하면 적절한 플래그를 설정합니다. 그렇지 않으면 FAILURE.

  2. 그것은을 찾습니다 +문자열의 어딘가에하고 적절한 플래그를 설정합니다.

  3. 문자열에서 e, nt(전 처리기 지시문에 따라 다름)를 찾고 적절한 플래그를 설정합니다.

  4. 반환 SUCCESS.


현실 세계로 돌아 가기

질문 :

PHP에서 fopen 모드 "r +"와 "rw +"의 차이점은 무엇입니까?

Nothing. PHP only cares that the string starts with "r" and has a "+". The "w" is ignored.

Final note: While it is tempting to play with it and write stuff like "read+", be careful with that, because those letter could someday have some meaning. It would not be forward compatible. In fact, in some context, "e" already has a meaning. Instead, I suggest, sticking to the documentation.


Thanks for the excuse to give a look at the PHP source code.

ReferenceURL : https://stackoverflow.com/questions/43797180/what-is-the-difference-between-fopen-modes-r-and-rw-in-php

반응형