58 votes

Quelle est la différence entre les modes fopen "r +" et "rw +" en PHP?

Beaucoup de réponses ici dans le Débordement de la Pile utilisation fopen($file, "rw+"), mais le manuel n'est pas de la liste de l' "rw+" mode, il n'y a qu'à l' "r+" (ou "w+" mode).

Alors je me demandais, quel est le "rw+" mode? Quelle est la différence entre fopen($file, "rw+" ou "r+"? Je vous pose cette question car il n'y a pas de documentation sur l' "rw+" mode.

Une approche consiste à considérer que les modes sont des additifs, mais je ne pouvais pas trouver aucune mention de la combinaison de modes dans l' fopen page de manuel (d'ailleurs, quel est le sens de la combinaison de "r" avec "w+", si "w+" déjà fait-elle lisible?). Mais le plus important, w+ mode tronque le fichier rw+ ne pas tronquer (par conséquent, ils ne peuvent pas être additif). Probablement il n'y a pas d' rw+ mode, en dépit de son utilisation par Débordement de Pile utilisateurs. Ça marche peut-être parce que l'analyseur ignore le "w" lettre", comme l' rw+ mode semble être === r+?

Pour préciser ma question: quel est le "rw+" mode, qui est, comment est-il différent des autres modes de transport? Je n'ai reçu que deux réponses dans les commentaires: soit que je devrais vérifier les documents (j'ai déjà vérifié et re-vérifié) et une mauvaise réponse, qui a dit qu'il est égal à "w+" (n'est pas). "w+" tronque le fichier "rw+" ne le fait pas.

Voici un script pour tester (il s'avère qu' w+ tronque le fichier, mais rw+ qui ne marche pas):

<?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; 
?>

69voto

Theraot Points 5174

Je pense que vous avez assez bien compris cela. Bien que je pense que, vous voulez une réponse faisant autorité.

Il est vrai que la documentation ne mentionne pas le "rw+". Pourtant, il y a quelque chose de mieux: le code source PHP!


Le Trou De Lapin

J'ai eu un moment difficile essayer de naviguer dans le code source que j'ai découvert la série d'article de PHP Code Source Pour les Développeurs PHP (Partie 1, Partie 2, Partie 3, Partie 4). Je sais que les liens de saut entre les deux sites, cette série c'est de la hanche comme ça. En passant, je n'ai pas trouvé l'annonce de la Partie 5.

Note: Ces articles sont vieux, ils parlent de PHP 5.4.

Voyons ce qu' fopen en fait... nous laisser tomber dans le trou de lapin...

Tout d'abord nous regardons la définition de la fonction (que j'ai découvert en suivant les conseils de la partie 2 ci-dessus). Je remarque qu'il utilise php_stream_open_wrapper_ex, j'ai trouvé d'ailleurs, il utilise juste _php_stream_open_wrapper_ex que nous trouvons dans le flux.c.

Qu'est - _php_stream_open_wrapper_ex faire avec mode? Il les transmet stream_opener.

La recherche de la définition de l' stream_opener m'a pris du type php_stream_wrapper_ops dans php_streams.h.

La recherche pour les utilisations de type php_stream_wrapper_ops plomb-moi de plain_wrapper.c.

Il ya effectivement beaucoup d'initialisation de php_stream_wrapper_ops qui permettent d'ouvrir des choses différentes. Nous sommes à la recherche à php_fopen_wrapper.c parce qu'il a une initialisation de php_stream_wrapper_opsstream_opener est php_plain_files_stream_opener.

Nous y arrivons...

php_plain_files_stream_opener est plus bas dans le même fichier. Il délègue à d' php_stream_fopen_rel.

php_streams.h définit php_stream_fopen_rel par l'aide d' _php_stream_fopen. Qui est de retour sur plain_wrapper.c.

Enfin, _php_stream_fopen des appels php_stream_parse_fopen_modes. Qui va prendre la corde et la sortie des drapeaux, Yay!


Pays des merveilles

Laissez-nous jeter un oeil à l' 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;
}

Pour résumé, c'est ce qu'il fait (en ignorant les détails):

  1. Il prend le premier caractère de l' mode et vérifie si il est r, w, a, x, c. Si elle reconnaît l'un de ceux-ci, il définit l'indicateur approprié. Sinon, nous avons un FAILURE.

  2. Il semble pour l' + quelque part dans la chaîne et définit les indicateurs.

  3. Il semble pour l' e, n et t (selon les Directives de Préprocesseur) quelque part dans la chaîne et définit les indicateurs.

  4. De retour SUCCESS.


De retour dans le monde réel

Vous avez demandé:

Quelle est la différence entre fopen en mode "r+" et "rw+" en PHP?

Rien. PHP ne se soucie que la chaîne commence par "r" et a un "+". L' "w" est ignoré.

Dernière remarque: il est tentant de jouer avec elle et écrire des trucs comme "read+", être prudent, parce que ceux de la lettre pourrait un jour avoir une signification. Il ne serait pas compatible. En fait, dans un certain contexte, "e" a déjà une signification. Au lieu de cela, je suggère, s'en tenir à la documentation.


Merci pour l'excuse à donner un coup d'oeil au code source PHP.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X