2013-03-09 2 views
2

PHP nous permet d'utiliser le drapeau x lorsque vous faites fopen:PHP fopen (drapeau x) garanti pour fonctionner seulement une fois?

Créer et ouvert en écriture seule; Placez le pointeur de fichier au début du fichier.

Si le fichier existe déjà, fopen() appeler échouera en retournant FALSE et générer une erreur de niveau E_WARNING .

Si le fichier n'existe pas, essayez de le créer. Cela équivaut à en spécifiant des indicateurs O_EXCL | O_CREAT pour l'appel système open (2) sous-jacent.

Est-ce que cela signifie que peu importe combien de demandes simultanées fopen que nous avons (de différents utilisateurs), il est garanti que le fichier ne sera créé une fois et jamais écrasés?

if ($handle = fopen("part006", "x+b")) { 
    do_some_processing(); 
    echo "You managed to process."; 
    /* 

    can we guarantee that only 1 user (http request) 
    will ever process the function and see the 
    message "you managed to process" ? 

    */ 
} else { 
    echo "You failed to process."; 
} 

Répondre

1

Réponse: Il est garanti que le fichier sera créé uniquement une fois et ne jamais être écrasé, aussi longtemps que d'autres processus utilisent également O_EXCL. Si ce n'est pas le cas, le fichier peut être écrasé. Ainsi, l'ouverture (la création) d'un fichier à l'aide O_EXCL ne signifie pas que le fichier est un peu écriture protégé

Explication: fopen utilise le open syscall sous-jacent. Sur la page de l'homme: man 2 open

O_EXCL

Si O_CREAT et O_EXCL sont, open() doit échouer si le fichier existe. La vérification de l'existence du fichier et de la création du fichier s'il n'existe pas sera atomique par rapport aux autres threads exécutant open() nommant le même nom de fichier dans le même répertoire avec O_EXCL et O_CREAT set. Si O_EXCL et O_CREAT sont définis et que le chemin d'accès nomme un lien symbolique, open() doit échouer et définir errno sur [EEXIST], quel que soit le contenu du lien symbolique. Si O_EXCL est défini et O_CREAT n'est pas défini, le résultat est indéfini.

+0

Est-ce que l'exclusivité est garantie pour Windows? – Pacerier

+0

Je ne suis pas sûr (mais il est probable) .. Essaiera de trouver cette information .. (malheureusement 'man' ne fonctionne pas sur Windows;)) – hek2mgl

+0

@Pacerier Lire une liste de diffusion et il semble que cela ne fonctionnera pas sur les fenêtres. mais je ne suis pas sûr car je n'ai actuellement aucune fenêtre pour tester. pouvez-vous tester? Si cela ne fonctionne pas, alors vous devriez utiliser 'flock()' dans ce but. Ce n'est pas la même chose, mais cela pourrait vous aider (vous ne connaissez pas les besoins de votre application). Notez ma réponse à cette [question] (http://stackoverflow.com/questions/15305296/how-to-use-flock- in-php/15305346 # 15305346) qui est lié 'flock()' et peut aider – hek2mgl