fopen

(PHP 4, PHP 5, PHP 7, PHP 8)

fopenApre un file o un URL

Descrizione

fopen(
    string $filename,
    string $mode,
    bool $use_include_path = false,
    resource $context = ?
): resource

La funzione fopen() apre un collegamento tra una risorsa, indicata dal parametro filename, ed un flusso.

Elenco dei parametri

filename

Se il parametro filename è nella forma "scheme://...", si assume che sia un URL e PHP cercherà il modulo di gestione del protocollo (detto anche wrapper) per quello schema. Se non vi sono wrapper registrati per il protocollo richiesto, PHP genererà un messaggio per aiutare a trovare potenziali problemi nello script e quindi procede considerando filename come un file normale.

Se PHP ha stabilito che filename indica un file locale, tenterà di aprire detto file come stream. Il file in oggetto dovrà esere accessibile a PHP, occorre, pertanto, assicurarsi che i permessi di accesso del file lo consentano. Se si è attivato open_basedir potrebbero essere applicate ulteriori restrizioni.

Se PHP ha stabilito che filename indica un protocollo registrato, e che tale protocollo è registrato come un URL di rete, PHP verificherà che allow_url_fopen sia abilitato. Se fosse disabilitato, PHP genererà un avviso e la chiamata ad fopen fallirà.

Nota:

L'elenco dei protocolli supportati si trova in Supported Protocols and Wrappers. Alcuni protocolli (indicati anche come wrappers) supportano il context e/o le opzioni del php.ini. Fare riferimento alla pagina specifica del protocollo in uso per avere l'elenco delle opzioni che possono essere utilizzate. (Ad esempio il valore di user_agent del php.ini è utilizzato dal wrapper http).

Sulla piattaforma Windows, fare attenzione effettuando l'escape dei backslash usati nel percorso del file, o utilizzare gli slash.

<?php
$handle 
fopen("c:\\folder\\resource.txt""r");
?>

mode

Il parametro mode indica il tipo di accesso richiesto per il flusso. Esso può essere uno dei seguenti:

Elenco dei possibili valori usati da fopen() per il parametro mode
mode Descrizione
'r' Apre in sola lettura; posiziona il puntatore all'inizio del file.
'r+' Apre in lettura e scrittura; posiziona il puntatore all'inizio del file.
'w' Apre il file in sola scrittura; posiziona il puntatore all'inizio del file e tronca il file alla lunghezza zero. Se il file non esiste, tenta di crearlo.
'w+' Apre in lettura e scrittura; posiziona il puntatore all'inizio del file e tronca il file alla lunghezza zero. Se il file non esiste, tenta di crearlo.
'a' Apre in sola scrittura; posiziona il puntatore alla fine del file. Se il file non esiste, tenta di crearlo. In questa modalità, fseek() non ha effetto, le scritture vengono sempre aggiunte alla fine.
'a+' Apre in lettura e scrittura; posiziona il puntatore alla fine del file. Se il file non esiste, tenta di crearlo. In questa modalità fseek() influisce solo sulla posizione di lettura, le scritture vengono sempre aggiunte alla fine.
'x' Crea ed apre il file in sola scrittura; posiziona il puntatore all'inizio del file. Se il file esiste già, la chiamata a fopen() fallirà restituendo false e verrà generato un errore di livello E_WARNING. Se il file non esiste, si tenterà di crearlo. Questo equivale a specificare i flag O_EXCL|O_CREAT nella sottostante chiamata di sistema a open(2).
'x+' Crea ed apre il file in lettura e scrittura; per il resto ha lo stesso comportamento di 'x'.
'c' Apre il file in sola scrittura. Se il file non esiste, viene creato. Se esiste, non viene né troncato (al contrario di 'w'), né la chiamata a questa funzione fallisce (come nel caso di 'x'). Il puntatore del file è posizionato all'inizio del file. Questo può essere utile se si desidera ottenere un advisory lock (vedere flock()) prima di tentare di modificare il file, poiché l'utilizzo di 'w' potrebbe troncare il file prima che il lock venga ottenuto (se si desidera troncare, può essere usata ftruncate()dopo che il lock viene richiesto).
'c+' Apre il file in lettura e scrittura; per il resto ha lo stesso comportamento di 'c'.
'e' Imposta il flag close-on-exec sul descrittore del file aperto. Disponibile solo per PHP compilato su sistemi conformi a POSIX.1-2008.

Nota:

Differenti famiglie di file system hanno differenti convenzioni di terminatori di riga. Quando si scrive un file di testo e si desidera inserire una interruzione di linea, occorre utilizzare il terminatore appropriato per il sistema operativo utilizzato. I sistemi basati su Unix utilizzano \n come terminatore di riga, i sistemi basati su Windows utilizzano \r\n mentre i sistemi Macintosh (Mac OS Classic) utilizzano \r.

Se si utilizza un errato terminatore di riga quando si scrivono i file, si può verificare che altre applicazioni che aprono questi file abbiano "comportamenti bizzarri".

Windows offre un flag di traduzione della modalità testo ('t') che in modo trasparente converte \n in \r\n mentre si lavora sul file. In contrasto, si può anche usare il flag 'b' per forzare una modalità binaria, nella quale non si ha la conversione dei dati. Per usare questi flag, 'b' oppure 't', devono essere posizionati come ultimo carattere del parametro mode.

La modalità di conversione di default è 'b'. Si può usare la modalità 't' se si lavora con dei file di testo e si utilizza \n per indicare il fine linea negli script, ma ci si aspetta che applicazioni, tipo vecchie versioni di notepad, leggano i file prodotti. In tutti gli altri casi si dovrebbe utilizzare 'b'.

Se non si specifica il flag 'b' quando si lavora con file binari, si possono avere situazioni anomale nei dati, tipo immagini corrotte, e situazioni anomale con i caratteri \r\n.

Nota:

Per la portabilità, è fortemente raccomandato di riscrivere il codice che utilizza o che si avvale del mode 't', così da utilizzare il corretto terminatore di linea invece del 'b' mode.

use_include_path

Il terzo parametro opzionale use_include_path può essere impostato a '1' oppure a true se si desidera cercare il file anche in include_path.

context

Nota: Il supporto per il contesto è stato aggiunto in PHP 5.0.0. Per la descrizione del contesto, fare riferimento a Stream Funzioni.

Valori restituiti

Restituisce una risorsa puntatore a file in caso di successo, o false in caso di fallimento

Errori/Eccezioni

In caso di errore, viene inviato un E_WARNING.

Log delle modifiche

Versione Descrizione
7.0.16, 7.1.2 È stata aggiunta l'opzione 'e'.

Esempi

Example #1 Esempi di fopen()

<?php
$handle 
fopen("/home/rasmus/file.txt""r");
$handle fopen("/home/rasmus/file.gif""wb");
$handle fopen("http://www.example.com/""r");
$handle fopen("ftp://user:password@example.com/somefile.txt""w");
?>

Note

Avviso

Quando si usa SSL, Microsoft IIS viola il protocollo chiudendo la connessione senza inviare un'indicazione close_notify. PHP indicherà questo con un "SSL: Fatal Protocol Error" al raggiungimento della fine dei dati. Per aggirare questo problema, occorre abbassare il livello error_reporting per non includere questi avvisi. PHP 4.3.7 e successivi sono in grado di identificare gli IIS bacati quando si apre lo stream utilizzando il wrapper https:// e disabilitano automaticamente l'avviso. Se si usa fsockopen() per creare un socket ssl://, occorre identificare e sopprimere l'avviso manualmente.

Nota:

Se si dovessero manifestare dei problemi nella lettura o scrittura di file e si sta utilizzando la versione server di PHP, occorre verificare che i file e le directory utilizzate dallo script siano accessibili dal processo del server.

Nota:

Questa funzione può anche avere successo quando filename è una directory. Se non si è sicuri che filename sia un file o una directory, potrebbe essere necessario utilizzare la funzione is_dir() prima di chiamare fopen().

Vedere anche:

add a note add a note

User Contributed Notes 20 notes

up
113
chapman at worldtakeoverindustries dot com
10 years ago
Note - using fopen in 'w' mode will NOT update the modification time (filemtime) of a file like you may expect. You may want to issue a touch() after writing and closing the file which update its modification time. This may become critical in a caching situation, if you intend to keep your hair.
up
3
php-manual at merlindynamics dot com
2 years ago
There is an undocumented mode for making fopen non-blocking (not working on windows). By adding 'n' to the mode parameter, fopen will not block, however if the pipe does not exist an error will be raised.

$fp = fopen("/tmp/debug", "a"); //blocks if pipe does not exist

$fp = fopen("/tmp/debug", "an"); //raises error on pipe not exist
up
21
php at delhelsa dot com
14 years ago
With php 5.2.5 on Apache 2.2.4, accessing files on an ftp server with fopen() or readfile() requires an extra forwardslash if an absolute path is needed.

i.e., if a file called bullbes.txt is stored under /var/school/ on ftp server example.com and you're trying to access it with user blossom and password buttercup, the url would be:

ftp://blossom:buttercup@example.com//var/school/bubbles.txt

Note the two forwardslashes. It looks like the second one is needed so the server won't interpret the path as relative to blossom's home on townsville.
up
6
petepostma-deletethis at gmail dot com
5 years ago
The verbal descriptions take a while to read through to get a feel for the expected results for fopen modes. This csv table can help break it down for quicker understanding to find which mode you are looking for:

Mode,Creates,Reads,Writes,Pointer Starts,Truncates File,Notes,Purpose
r,,y,,beginning,,fails if file doesn't exist,basic read existing file
r+,,y,y,beginning,,fails if file doesn't exist,basic r/w existing file
w,y,,y,beginning+end,y,,"create, erase, write file"
w+,y,y,y,beginning+end,y,,"create, erase, write file with read option"
a,y,,y,end,,,"write from end of file, create if needed"
a+,y,y,y,end,,,"write from end of file, create if needed, with read options"
x,y,,y,beginning,,fails if file exists,"like w, but prevents over-writing an existing file"
x+,y,y,y,beginning,,fails if file exists,"like w+, but prevents over writing an existing file"
c,y,,y,beginning,,,open/create a file for writing without deleting current content
c+,y,y,y,beginning,,,"open/create a file that is read, and then written back down"
up
3
Anon.
1 year ago
/***** GENTLE REMINDER *****/
Really important. Do NOT use the "w" flag unless you want to delete everything in the file.
up
4
durwood at speakeasy dot NOSPAM dot net
16 years ago
I couldn't for the life of me get a certain php script working when i moved my server to a new Fedora 4 installation. The problem was that fopen() was failing when trying to access a file as a URL through apache -- even though it worked fine when run from the shell and even though the file was readily readable from any browser.  After trying to place blame on Apache, RedHat, and even my cat and dog, I finally ran across this bug report on Redhat's website:

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=164700

Basically the problem was SELinux (which I knew nothing about) -- you have to run the following command in order for SELinux to allow php to open a web file:

/usr/sbin/setsebool httpd_can_network_connect=1

To make the change permanent, run it with the -P option:

/usr/sbin/setsebool -P httpd_can_network_connect=1

Hope this helps others out -- it sure took me a long time to track down the problem.
up
5
ideacode
17 years ago
Note that whether you may open directories is operating system dependent. The following lines:

<?php
// Windows ($fh === false)
$fh = fopen('c:\\Temp', 'r');

// UNIX (is_resource($fh) === true)
$fh = fopen('/tmp', 'r');
?>

demonstrate that on Windows (2000, probably XP) you may not open a directory (the error is "Permission Denied"), regardless of the security permissions on that directory.

On UNIX, you may happily read the directory format for the native filesystem.
up
8
info at b1g dot de
16 years ago
Simple class to fetch a HTTP URL. Supports "Location:"-redirections. Useful for servers with allow_url_fopen=false. Works with SSL-secured hosts.

<?php
#usage:
$r = new HTTPRequest('http://www.example.com');
echo
$r->DownloadToString();

class
HTTPRequest
{
    var
$_fp;        // HTTP socket
   
var $_url;        // full URL
   
var $_host;        // HTTP host
   
var $_protocol;    // protocol (HTTP/HTTPS)
   
var $_uri;        // request URI
   
var $_port;        // port
   
    // scan url
   
function _scan_url()
    {
       
$req = $this->_url;
       
       
$pos = strpos($req, '://');
       
$this->_protocol = strtolower(substr($req, 0, $pos));
       
       
$req = substr($req, $pos+3);
       
$pos = strpos($req, '/');
        if(
$pos === false)
           
$pos = strlen($req);
       
$host = substr($req, 0, $pos);
       
        if(
strpos($host, ':') !== false)
        {
            list(
$this->_host, $this->_port) = explode(':', $host);
        }
        else
        {
           
$this->_host = $host;
           
$this->_port = ($this->_protocol == 'https') ? 443 : 80;
        }
       
       
$this->_uri = substr($req, $pos);
        if(
$this->_uri == '')
           
$this->_uri = '/';
    }
   
   
// constructor
   
function HTTPRequest($url)
    {
       
$this->_url = $url;
       
$this->_scan_url();
    }
   
   
// download URL to string
   
function DownloadToString()
    {
       
$crlf = "\r\n";
       
       
// generate request
       
$req = 'GET ' . $this->_uri . ' HTTP/1.0' . $crlf
           
.    'Host: ' . $this->_host . $crlf
           
.    $crlf;
       
       
// fetch
       
$this->_fp = fsockopen(($this->_protocol == 'https' ? 'ssl://' : '') . $this->_host, $this->_port);
       
fwrite($this->_fp, $req);
        while(
is_resource($this->_fp) && $this->_fp && !feof($this->_fp))
           
$response .= fread($this->_fp, 1024);
       
fclose($this->_fp);
       
       
// split header and body
       
$pos = strpos($response, $crlf . $crlf);
        if(
$pos === false)
            return(
$response);
       
$header = substr($response, 0, $pos);
       
$body = substr($response, $pos + 2 * strlen($crlf));
       
       
// parse headers
       
$headers = array();
       
$lines = explode($crlf, $header);
        foreach(
$lines as $line)
            if((
$pos = strpos($line, ':')) !== false)
               
$headers[strtolower(trim(substr($line, 0, $pos)))] = trim(substr($line, $pos+1));
       
       
// redirection?
       
if(isset($headers['location']))
        {
           
$http = new HTTPRequest($headers['location']);
            return(
$http->DownloadToString($http));
        }
        else
        {
            return(
$body);
        }
    }
}
?>
up
1
k-gun at git dot io
2 years ago
Seems not documented here but keep in mind, when $filename contains null byte (\0) then a TypeError will be thrown with message such;

TypeError: fopen() expects parameter 1 to be a valid path, string given in ...
up
3
ceo at l-i-e dot com
16 years ago
If you need fopen() on a URL to timeout, you can do like:
<?php
  $timeout
= 3;
 
$old = ini_set('default_socket_timeout', $timeout);
 
$file = fopen('http://example.com', 'r');
 
ini_set('default_socket_timeout', $old);
 
stream_set_timeout($file, $timeout);
 
stream_set_blocking($file, 0);
 
//the rest is standard
?>
up
2
keithm at aoeex dot NOSPAM dot com
21 years ago
I was working on a consol script for win32 and noticed a few things about it.  On win32 it appears that you can't re-open the input stream for reading, but rather you have to open it once, and read from there on.  Also, i don't know if this is a bug or what but it appears that fgets() reads until the new line anyway.  The number of characters returned is ok, but it will not halt reading and return to the script.  I don't know of a work around for this right now, but i'll keep working on it.

This is some code to work around the close and re-open of stdin.

<?php
function read($length='255'){
    if (!isset(
$GLOBALS['StdinPointer'])){
       
$GLOBALS['StdinPointer']=fopen("php://stdin","r");
    }
   
$line=fgets($GLOBALS['StdinPointer'],$length);
    return
trim($line);
}
echo
"Enter your name: ";
$name=read();
echo
"Enter your age: ";
$age=read();
echo
"Hi $name, Isn't it Great to be $age years old?";
@
fclose($StdinPointer);
?>
up
1
php at richardneill dot org
11 years ago
fopen() will block if the file to be opened is a fifo. This is true whether it's opened in "r" or "w" mode.  (See man 7 fifo: this is the correct, default behaviour; although Linux supports non-blocking fopen() of a fifo, PHP doesn't).
The consequence of this is that you can't discover whether an initial fifo read/write would block because to do that you need stream_select(), which in turn requires that fopen() has happened!
up
2
dan at cleandns dot com
18 years ago
<?php
#going to update last users counter script since
#aborting a write because a file is locked is not correct.

$counter_file = '/tmp/counter.txt';
clearstatcache();
ignore_user_abort(true);     ## prevent refresh from aborting file operations and hosing file
if (file_exists($counter_file)) {
  
$fh = fopen($counter_file, 'r+');
    while(
1) {
      if (
flock($fh, LOCK_EX)) {
        
#$buffer = chop(fgets($fh, 2));
        
$buffer = chop(fread($fh, filesize($counter_file)));
        
$buffer++;
        
rewind($fh);
        
fwrite($fh, $buffer);
        
fflush($fh);
        
ftruncate($fh, ftell($fh));    
        
flock($fh, LOCK_UN);
         break;
      }
   }
}
else {
  
$fh = fopen($counter_file, 'w+');
  
fwrite($fh, "1");
  
$buffer="1";
}
fclose($fh);

print
"Count is $buffer";

?>
up
1
apathetic012 at gmail dot com
9 years ago
a variable $http_response_header is available when doing the fopen(). Which contains an array of the response header.
up
0
etters dot ayoub at gmail dot com
4 years ago
This functions check recursive permissions and recursive existence parent folders, before creating a folder. To avoid the generation of errors/warnings.

/**
* This functions check recursive permissions and recursive existence parent folders,
* before creating a folder. To avoid the generation of errors/warnings.
*
* @return bool
*     true folder has been created or exist and writable.
*     False folder not exist and cannot be created.
*/
function createWritableFolder($folder)
{
    if (file_exists($folder)) {
        // Folder exist.
        return is_writable($folder);
    }
    // Folder not exit, check parent folder.
    $folderParent = dirname($folder);
    if($folderParent != '.' && $folderParent != '/' ) {
        if(!createWritableFolder(dirname($folder))) {
            // Failed to create folder parent.
            return false;
        }
        // Folder parent created.
    }

    if ( is_writable($folderParent) ) {
        // Folder parent is writable.
        if ( mkdir($folder, 0777, true) ) {
            // Folder created.
            return true;
        }
        // Failed to create folder.
    }
    // Folder parent is not writable.
    return false;
}

/**
* This functions check recursive permissions and recursive existence parent folders,
* before creating a file/folder. To avoid the generation of errors/warnings.
*
* @return bool
*     true has been created or file exist and writable.
*     False file not exist and cannot be created.
*/
function createWritableFile($file)
{
    // Check if conf file exist.
    if (file_exists($file)) {
        // check if conf file is writable.
        return is_writable($file);
    }

    // Check if conf folder exist and try to create conf file.
    if(createWritableFolder(dirname($file)) && ($handle = fopen($file, 'a'))) {
        fclose($handle);
        return true; // File conf created.
    }
    // Inaccessible conf file.
    return false;
}
up
1
splogamurugan at gmail dot com
11 years ago
While opening a file with multibyte data (Ex: données multi-octets), faced some issues with the encoding. Got to know that it uses  windows-1250. Used iconv to convert it to UTF-8 and it resolved the issue. 

<?php
function utf8_fopen_read($fileName) {
   
$fc = iconv('windows-1250', 'utf-8', file_get_contents($fileName));
   
$handle=fopen("php://memory", "rw");
   
fwrite($handle, $fc);
   
fseek($handle, 0);
    return
$handle;
}
?>

Example usage:

<?php
$fh
= utf8_fopen_read("./tpKpiBundle.csv");
while ((
$data = fgetcsv($fh, 1000, ",")) !== false) {
    foreach (
$data as $value) {
        echo
$value . "<br />\n";
    }
}
?>

Hope it helps.
up
1
ken dot gregg at rwre dot com
18 years ago
PHP will open a directory if a path with no file name is supplied. This just bit me. I was not checking the filename part of a concatenated string.

For example:

<?php
$fd
= fopen('/home/mydir/' . $somefile, 'r');
?>

Will open the directory if $somefile = ''

If you attempt to read using the file handle you will get the binary directory contents. I tried append mode and it errors out so does not seem to be dangerous.

This is with FreeBSD 4.5 and PHP 4.3.1. Behaves the same on 4.1.1 and PHP 4.1.2. I have not tested other version/os combinations.
up
1
flobee
16 years ago
download: i need a function to simulate a "wget url" and do not buffer the data in the memory to avoid thouse problems on large files:
<?php
function download($file_source, $file_target) {
       
$rh = fopen($file_source, 'rb');
       
$wh = fopen($file_target, 'wb');
        if (
$rh===false || $wh===false) {
// error reading or opening file
          
return true;
        }
        while (!
feof($rh)) {
            if (
fwrite($wh, fread($rh, 1024)) === FALSE) {
                  
// 'Download error: Cannot write to file ('.$file_target.')';
                  
return true;
               }
        }
       
fclose($rh);
       
fclose($wh);
       
// No error
       
return false;
    }
?>
up
-2
kasper at webmasteren dot eu
10 years ago
"Do not use the following reserved device names for the name of a file:
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1,
LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names
followed immediately by an extension; for example, NUL.txt is not recommended.
For more information, see Namespaces"
it is a windows limitation.
see:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
up
-4
sean downey
14 years ago
when using ssl / https on windows i would get the error:
"Warning: fopen(https://example.com): failed to open stream: Invalid argument in someSpecialFile.php on line 4344534"

This was because I did not have the extension "php_openssl.dll" enabled.

So if you have the same problem, goto your php.ini file and enable it :)
To Top