Php fopen не открывает файл
I'm want to read a simple string from a text file which is around 3-4 mb but fopen() fails ("can't open file" from die() is called). Here's the code:
STOP upvoting these 2 nonsense comments. One have to check certain error message, not to tell fortunes. There are helluvalot of other reasons beside these 2.
5 Answers 5
Have you firstly checked to see if the file exists?
I changed my file permissions to 777 and after adding the clearstatcache method my script started working.
THere is a missing close parentheses, but editing won't allow on a single character change :( if (!file_exists("/my/path/to/file.txt"))
you have to add to your code this line
and ALWAYS keep this line in ALL your codes
and also this line
and keep this line only on development server.
while on the production it should be changed to
By doing this you will not need Stackoverflow assistance in reading the now obvious error messages.
Change that second line to:
and see what it outputs as the cause.
@Col: I'm not a big fan of dying either but the brief is to find out why the call is failing, not to re-architect all the code :-)
If you're going to go through and remove all the die statement, that is rearchitecting. We have no idea how many thousands of those beasties may exist :-) The changing of the argument to this particular die is the minimal-impact change required to deliver the needed information.
Actually it's you who asking him to rewrite all die statements. While I am only asking to turn error_reporting on.
There's no point discussing it to death, @Col, I suspect we'll have to agree to disagree. I'm asking to only change the one particular die that information is needed on. Once the information is gathered, the OP is free to do what they want (change it back, change them all, remove them all, whatever). The art of minimal impact discovery is a vital one to debugging, especially in the field, and it's for that reason I put forward this answer.
fopen() binds a named resource, specified by filename , to a stream.
Ошибки
В случае неудачного завершения работы генерируется ошибка уровня E_WARNING .
User Contributed Notes 36 notes
Just a note for those who face problems on names containing spaces (e.g. "test test.pdf").
In the examples (99% of the time) you can find
header('Content-Disposition: attachment; filename='.basename($file));
but the correct way to set the filename is quoting it (double quote):
header('Content-Disposition: attachment; filename="'.basename($file).'"' );
flobee.at.gmail.dot.com shared "readfile_chunked" function. It does work, but you may encounter memory exhaustion using "fread". Meanwhile "stream_copy_to_stream" seems to utilize the same amount of memory as "readfile". At least, when I was testing "download" function for my https://github.com/Simbiat/HTTP20 library on 1.5G file with 256M memory limitation that was the case: "fread" I got peak memory usage of ~240M, while with "stream_copy_to_stream" - ~150M.
It does not mean that you can fully escape memory exhaustion, though: if you are reading too much at a time, you can still encounter it. That is why in my library I use a helper function ("speedLimit") to calculate whether selected speed limit will fit the available memory (while allowing some headroom).
You can read comments in the code itself for more details and raise issues for the library, if you think something is incorrect there (especially since it's WIP at the moment of writing this), but so far I am able to get consistent behavior with it.
if you need to limit download rate, use this code
$local_file = 'file.zip' ;
$download_file = 'name.zip' ;
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5 ;
if( file_exists ( $local_file ) && is_file ( $local_file ))
header ( 'Cache-control: private' );
header ( 'Content-Type: application/octet-stream' );
header ( 'Content-Length: ' . filesize ( $local_file ));
header ( 'Content-Disposition: filename=' . $download_file );
flush ();
$file = fopen ( $local_file , "r" );
while(! feof ( $file ))
// send the current file part to the browser
print fread ( $file , round ( $download_rate * 1024 ));
// flush the content to the browser
flush ();
// sleep one second
sleep ( 1 );
>
fclose ( $file );>
else die( 'Error: The file ' . $local_file . ' does not exist!' );
>
regarding php5:
i found out that there is already a disscussion @php-dev about readfile() and fpassthru() where only exactly 2 MB will be delivered.
so you may use this on php5 to get lager files
function readfile_chunked ( $filename , $retbytes = true ) $chunksize = 1 *( 1024 * 1024 ); // how many bytes per chunk
$buffer = '' ;
$cnt = 0 ;
// $handle = fopen($filename, 'rb');
$handle = fopen ( $filename , 'rb' );
if ( $handle === false ) return false ;
>
while (! feof ( $handle )) $buffer = fread ( $handle , $chunksize );
echo $buffer ;
if ( $retbytes ) $cnt += strlen ( $buffer );
>
>
$status = fclose ( $handle );
if ( $retbytes && $status ) return $cnt ; // return num. bytes delivered like readfile() does.
>
return $status ;
My script working correctly on IE6 and Firefox 2 with any typ e of files (I hope :))
function DownloadFile($file) < // $file = include path
if(file_exists($file)) header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
>
Run on Apache 2 (WIN32) PHP5
To avoid the risk of choosing themselves which files to download by messing with the request and doing things like inserting "../" into the "filename", simply remember that URLs are not file paths, and there's no reason why the mapping between them has to be so literal as "download.php?file=thingy.mpg" resulting in the download of the file "thingy.mpg".
It's your script and you have full control over how it maps file requests to file names, and which requests retrieve which files.
But even then, as ever, never trust ANYTHING in the request. Basic first-day-at-school security principle, that.
Always using MIME-Type 'application/octet-stream' is not optimal. Most if not all browsers will simply download files with that type.
If you use proper MIME types (and inline Content-Disposition), browsers will have better default actions for some of them. Eg. in case of images, browsers will display them, which is probably what you'd want.
To deliver the file with the proper MIME type, the easiest way is to use:
header('Content-Type: ' . mime_content_type($file));
header('Content-Disposition: inline; filename="'.basename($file).'"');
A note on the smartReadFile function from gaosipov:
Change the indexes on the preg_match matches to:
$begin = intval($matches[1]);
if( !empty($matches[2]) ) $end = intval($matches[2]);
>
Otherwise the $begin would be set to the entire section matched and the $end to what should be the begin.
See preg_match for more details on this.
To anyone that's had problems with Readfile() reading large files into memory the problem is not Readfile() itself, it's because you have output buffering on. Just turn off output buffering immediately before the call to Readfile(). Use something like ob_end_flush().
To avoid errors,
just be careful whether slash "/" is allowed or not at the beginning of $file_name parameter.
In my case, trying to send PDF files thru PHP after access-logging,
the beginning "/" must be removed in PHP 7.1.
$size = filesize ( $location );
$time = date ( 'r' , filemtime ( $location ));
$begin = 0 ;
$end = $size ;
header ( "Content-Type: $mimeType " );
header ( 'Cache-Control: public, must-revalidate, max-age=0' );
header ( 'Pragma: no-cache' );
header ( 'Accept-Ranges: bytes' );
header ( 'Content-Length:' .( $end - $begin ));
header ( "Content-Range: bytes $begin - $end / $size " );
header ( "Content-Disposition: inline; filename= $filename " );
header ( "Content-Transfer-Encoding: binary\n" );
header ( "Last-Modified: $time " );
header ( 'Connection: close' );
$cur = $begin ;
fseek ( $fm , $begin , 0 );
smartReadFile ( "/tmp/filename" , "myfile.mp3" , "audio/mpeg" )
?>
It can be slow for big files to read by fread, but this is a single way to read file in strict bounds. You can modify this and add fpassthru instead of fread and while, but it sends all data from begin --- it would be not fruitful if request is bytes from 100 to 200 from 100mb file.
When using the readfile_chunked function noted here with files larger than 10MB or so I am still having memory errors. It's because the writers have left out the all important flush() after each read. So this is the proper chunked readfile (which isn't really readfile at all, and should probably be crossposted to passthru(), fopen(), and popen() just so browsers can find this information):
function readfile_chunked ( $filename , $retbytes = true ) <
$chunksize = 1 *( 1024 * 1024 ); // how many bytes per chunk
$buffer = '' ;
$cnt = 0 ;
// $handle = fopen($filename, 'rb');
$handle = fopen ( $filename , 'rb' );
if ( $handle === false ) <
return false ;
>
while (! feof ( $handle )) <
$buffer = fread ( $handle , $chunksize );
echo $buffer ;
ob_flush ();
flush ();
if ( $retbytes ) <
$cnt += strlen ( $buffer );
>
>
$status = fclose ( $handle );
if ( $retbytes && $status ) <
return $cnt ; // return num. bytes delivered like readfile() does.
>
return $status ;
>
?>
All I've added is a flush(); after the echo line. Be sure to include this!
If you are lucky enough to not be on shared hosting and have apache, look at installing mod_xsendfile.
This was the only way I found to both protect and transfer very large files with PHP (gigabytes).
It's also proved to be much faster for basically any file.
Available directives have changed since the other note on this and XSendFileAllowAbove was replaced with XSendFilePath to allow more control over access to files outside of webroot.
Download the source.
Install with: apxs -cia mod_xsendfile.c
Then to use it in your script:
$file = '/tmp/blah/foo.iso' ;
$download_name = basename ( $file );
if ( file_exists ( $file )) header ( 'Content-Type: application/octet-stream' );
header ( 'Content-Disposition: attachment; filename=' . $download_name );
header ( 'X-Sendfile: ' . $file );
exit;
>
?>
Just a note: If you're using bw_mod (current version 0.6) to limit bandwidth in Apache 2, it *will not* limit bandwidth during readfile events.
Instead of using
header ( 'Content-Type: application/force-download' );
?>
use
header ( 'Content-Type: application/octet-stream' );
?>
Some browsers have troubles with force-download.
Using pieces of the forced download script, adding in MySQL database functions, and hiding the file location for security was what we needed for downloading wmv files from our members creations without prompting Media player as well as secure the file itself and use only database queries. Something to the effect below, very customizable for private access, remote files, and keeping order of your online media.
switch ($file_extension) <
case "wmv": $ctype="video/x-ms-wmv"; break;
default: $ctype="application/force-download";
>
// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: video/x-ms-wmv");
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".@filesize($filename));
set_time_limit(0);
@readfile("$fileurl") or die("File not found.");
$donwloaded = "downloads + 1";
if ($_GET["hit"]) <
mysql_query("UPDATE ibf_movies SET downloads = $donwloaded WHERE ");
If you are looking for an algorithm that will allow you to download (force download) a big file, may this one will help you.
$filename = "file.csv";
$filepath = "/path/to/file/" . $filename;
// Close sessions to prevent user from waiting until
// download will finish (uncomment if needed)
//session_write_close();
set_time_limit(0);
ignore_user_abort(false);
ini_set('output_buffering', 0);
ini_set('zlib.output_compression', 0);
$chunk = 10 * 1024 * 1024; // bytes per chunk (10 MB)
$fh = fopen($filepath, "rb");
if ($fh === false) <
echo "Unable open file";
>
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
// Repeat reading until EOF
while (!feof($fh)) <
echo fread($handle, $chunk);
ob_flush(); // flush output
flush();
>
A mime-type-independent forced download can also be conducted by using:
(. )
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // some day in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-type: application/x-download");
header("Content-Disposition: attachment; filename=");
header("Content-Transfer-Encoding: binary");
?>
Remember if you make a "force download" script like mentioned below that you SANITIZE YOUR INPUT!
I have seen a lot of download scripts that does not test so you are able to download anything you want on the server.
Test especially for strings like ".." which makes directory traversal possible. If possible only permit characters a-z, A-Z and 0-9 and make it possible to only download from one "download-folder".
In the C source, this function simply opens the path in read+binary mode, without a lock, and uses fpassthru()
If you need a locked read, use fopen(), flock(), and then fpassthru() directly.
I have noticed some unusual behavior with Internet Explorer 6 that’s worth taking note of. I have a link on my site to a script that outputs an XML file to the browser with the below code:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
@readfile($file);
When the popular IE setting “Reuse Window for Launching Shortcuts” is unchecked (access this setting in the Tools Menu > Internet Options > Advanced Tab) this script will output the file to the browser and open it in a different window if the user clicks the open button on the IE prompt. However, if this setting is checked, and browser windows are being re-used, then it will open up on top of the page where the link was clicked to access the script.
If I instead set the html link target option to be “_blank”, the script will open up in a new window as expected if the “Reuse Window for Launching Shortcuts” is checked. But, if the setting is unchecked, the output XML file will open up in a new window and there will be another blank window also open that has the address of the script, in addition to our original window.
This is far from ideal, and there is no way of knowing whether users have this option checked or not. We are stuck with the distinct possibility of half of our visitors seeing either an annoying third blank window being opened or the script writing over their original window, depending on their “Reuse Window for Launching Shortcuts” setting.
That is one way to do it, however this is avoidable. For example in Zend Framework you could do
// Action controller
public function someAction ()
$response = $this -> _response ;
// Disable view and layout rendering
$this -> _helper -> viewRenderer -> setNoRender ();
$this -> _helper -> layout ()-> disableLayout ();
// Process the file
$file = 'whatever.zip' ;
$bits = @ file_get_contents ( $file );
if( strlen ( $bits ) == 0 ) $response -> setBody ( 'Sorry, we could not find requested download file.' );
>
else $response -> setHeader ( 'Content-type' , 'application/octet-stream' , true );
$response -> setBody ( $bits );
>
>
If you guys know how to judge the return values of function "stat", in order to avoid using "is_file" or "is_readable" (or "is_dir"), please let me know or just write it here.
If you don't have to do anything special on 404, "header('HTTP/1.x xxx xxxxx');" can be inside of the function.
$stat = @ stat ( $filename );
$etag = sprintf ( '%x-%x-%x' , $stat [ 'ino' ], $stat [ 'size' ], $stat [ 'mtime' ] * 1000000 );
header ( 'Expires: ' );
header ( 'Cache-Control: ' );
header ( 'Pragma: ' );
в рамках ведения журнала приложение, которое я пытаюсь открыть локальный файл, и если файл еще не существует, создать новый. Вот что у меня есть:
Я дважды проверил, и /logs каталог chmod 0777, и я даже пошел дополнительный шаг chown'ING его apache:apache для хорошей меры. Тем не менее, когда скрипт открывает файл, он дает мне предупреждение о том, что файл не существует, и бомбит. Файл никогда не создается.
Я нужно подавить fopen() предупреждение, чтобы заставить его создать файл?
когда вы работаете с путями в PHP, контекст имеет большое значение. Если вы работаете с URL-адресами в контексте перенаправления , корневой каталог ( ' / ' ) ссылается на корневой каталог вашего домена. То же самое касается путей для связывания файлов или изображений и директив include и require.
однако, когда вы имеете дело с командами файловой системы, такими как fopen корневой каталог ('/') является корневая система. Не ваш домен root.
или вы можете использовать $_SERVER['DOCUMENT_ROOT'] как предложено в других ответах для доступа к сохраненному значению вашего сервера для пути к корню документа. The /var/www часть.
вы также можете использовать __DIR__ магическая константа в некоторых случаях. Обратите внимание, что __DIR__ будет каталогом, в котором находится текущий файл, который не обязательно совпадает с корнем вашего приложения. Так, например, если корень вашего приложения /var/www/application и вы работаете в /var/www/application/src/controllers/my_controller.php , потом __DIR__ будет /var/www/application/src/controllers . см. здесь, в документации по PHP.
вы пробовали это?
сервер, на котором вы работаете, мог бы посадить вас в тюрьму только для работы в каталоге phpapp и его подкаталогах.
один из способов обойти эту проблему в UBUNTU 14.04 - щелкнуть правой кнопкой мыши по каталогу, где находится файл, и изменить разрешения "другие" на "создание и удаление файлов".
вы всегда можете открыть файл с помощью just "a" , Он также создаст новый файл.
Не нужно ставить условие.
однако основной проблемой вашего кода является понимание разницы между физической файловой системой и виртуальным веб-сервером, что уже было прекрасно объяснено.
путь к файлу должен быть с корневым сервером. Я мог бы достичь этого, используя функцию phpinfo() метод внутри документа, который я хотел знать. Поэтому при использовании phpinfo () вы увидите информационный документ. Если вы найдете для _SERVER ["SCRIPT_FILENAME"] вы увидите абсолютный путь к вашему файлу.
Я надеюсь, что это поможет кому-то.
Не забудьте убедиться, что SELinux не блокирует вас.
Примечание:
чтобы сделать этот пакет активной политики, выполните:
Смотрите также
- fpassthru() - Выводит все оставшиеся данные из файлового указателя
- file() - Читает содержимое файла и помещает его в массив
- fopen() - Открывает файл или URL
- include - include
- require - require
- virtual() - Выполняет подзапрос Apache
- file_get_contents() - Читает содержимое файла в строку
Примечания
Замечание:
readfile() сама по себе не приводит к каким-либо проблемам с памятью, даже при отправке больших файлов. При возникновении ошибки превышения памяти убедитесь, что буферизация вывода отключена с помощью ob_get_level() .
Для этой функции вы можете использовать URL в качестве имени файла, если была включена опция fopen wrappers. Смотрите более подробную информацию об определении имени файла в описании функции fopen() . Смотрите также список поддерживаемых обёрток URL, их возможности, замечания по использованию и список предопределённых констант в разделе Поддерживаемые протоколы и обёртки.
Parameters
If filename is of the form "scheme://. ", it is assumed to be a URL and PHP will search for a protocol handler (also known as a wrapper) for that scheme. If no wrappers for that protocol are registered, PHP will emit a notice to help you track potential problems in your script and then continue as though filename specifies a regular file.
If PHP has decided that filename specifies a local file, then it will try to open a stream on that file. The file must be accessible to PHP, so you need to ensure that the file access permissions allow this access. If you have enabled open_basedir further restrictions may apply.
If PHP has decided that filename specifies a registered protocol, and that protocol is registered as a network URL, PHP will check to make sure that allow_url_fopen is enabled. If it is switched off, PHP will emit a warning and the fopen call will fail.
On the Windows platform, be careful to escape any backslashes used in the path to the file, or use forward slashes.
The mode parameter specifies the type of access you require to the stream. It may be any of the following:
mode | Description |
---|---|
'r' | Open for reading only; place the file pointer at the beginning of the file. |
'r+' | Open for reading and writing; place the file pointer at the beginning of the file. |
'w' | Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it. |
'w+' | Open for reading and writing; otherwise it has the same behavior as 'w' . |
'a' | Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create it. In this mode, fseek() has no effect, writes are always appended. |
'a+' | Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it. In this mode, fseek() only affects the reading position, writes are always appended. |
'x' | Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the fopen() call will fail by returning false and generating an error of level E_WARNING . If the file does not exist, attempt to create it. This is equivalent to specifying O_EXCL|O_CREAT flags for the underlying open(2) system call. |
'x+' | Create and open for reading and writing; otherwise it has the same behavior as 'x' . |
'c' | Open the file for writing only. If the file does not exist, it is created. If it exists, it is neither truncated (as opposed to 'w' ), nor the call to this function fails (as is the case with 'x' ). The file pointer is positioned on the beginning of the file. This may be useful if it's desired to get an advisory lock (see flock() ) before attempting to modify the file, as using 'w' could truncate the file before the lock was obtained (if truncation is desired, ftruncate() can be used after the lock is requested). |
'c+' | Open the file for reading and writing; otherwise it has the same behavior as 'c' . |
'e' | Set close-on-exec flag on the opened file descriptor. Only available in PHP compiled on POSIX.1-2008 conform systems. |
Note:
Different operating system families have different line-ending conventions. When you write a text file and want to insert a line break, you need to use the correct line-ending character(s) for your operating system. Unix based systems use \n as the line ending character, Windows based systems use \r\n as the line ending characters and Macintosh based systems (Mac OS Classic) used \r as the line ending character.
If you use the wrong line ending characters when writing your files, you might find that other applications that open those files will "look funny".
Windows offers a text-mode translation flag ( 't' ) which will transparently translate \n to \r\n when working with the file. In contrast, you can also use 'b' to force binary mode, which will not translate your data. To use these flags, specify either 'b' or 't' as the last character of the mode parameter.
The default translation mode is 'b' . You can use the 't' mode if you are working with plain-text files and you use \n to delimit your line endings in your script, but expect your files to be readable with applications such as old versions of notepad. You should use the 'b' in all other cases.
If you specify the 't' flag when working with binary files, you may experience strange problems with your data, including broken image files and strange problems with \r\n characters.
Note:
For portability, it is also strongly recommended that you re-write code that uses or relies upon the 't' mode so that it uses the correct line endings and 'b' mode instead.
Note: The mode is ignored for php://output , php://input , php://stdin , php://stdout , php://stderr and php://fd stream wrappers.
The optional third use_include_path parameter can be set to '1' or true if you want to search for the file in the include_path, too.
fopen() закрепляет именованный ресурс, указанный в аргументе filename , за потоком.
Возвращаемые значения
Возвращает количество прочитанных из файла байт в случае успешного выполнения или false в случае возникновения ошибки
Список параметров
Если filename передан в форме "scheme://. ", он считается URL и PHP проведёт поиск обработчика протокола (также известного как "обёртка") для этой схемы. Если ни одна обёртка не закреплена за протоколом, PHP выдаст замечание, чтобы помочь вам отследить потенциальную проблему в вашем скрипте и затем продолжит выполнение, как если бы filename указывал на обыкновенный файл.
Если PHP установлено, что filename указывает на локальный файл, тогда выполняется попытка открыть поток к этому файлу. Файл должен быть доступен PHP, так что вам следует убедиться, что права доступа на файл это разрешают. Если вы включили open_basedir, то накладываются дальнейшие ограничения.
На платформе Windows, необходимо экранировать все обратные слеши в пути к файлу или использовать прямые слеши.
Параметр mode указывает тип доступа, который вы запрашиваете у потока. Он может быть одним из следующих вариантов:
mode | Описание |
---|---|
'r' | Открывает файл только для чтения; помещает указатель в начало файла. |
'r+' | Открывает файл для чтения и записи; помещает указатель в начало файла. |
'w' | Открывает файл только для записи; в противном случае ведёт себя так же, как и 'w+' . |
'w+' | Открывает файл для чтения и записи; помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует - пытается его создать. |
'a' | Открывает файл только для записи; помещает указатель в конец файла. Если файл не существует - пытается его создать. В данном режиме функция fseek() не применима, записи всегда добавляются в конец. |
'a+' | Открывает файл для чтения и записи; помещает указатель в конец файла. Если файл не существует - пытается его создать. В данном режиме функция fseek() влияет только на позицию чтения, записи всегда добавляются в конец. |
'x' | Создаёт и открывает только для записи; помещает указатель в начало файла. Если файл уже существует, вызов fopen() закончится неудачей, вернёт false и выдаст ошибку уровня E_WARNING . Если файл не существует, попытается его создать. Это эквивалентно указанию флагов O_EXCL|O_CREAT для внутреннего системного вызова open(2) . |
'x+' | Создаёт и открывает для чтения и записи; в остальном имеет то же поведение, что и 'x' . |
'c' | Открывает файл только для записи. Если файл не существует, то он создаётся. Если же файл существует, то он не обрезается (в отличие от 'w' ), и вызов к этой функции не вызывает ошибку (также как и в случае с 'x' ). Указатель на файл будет установлен на начало файла. Это может быть полезно при желании заблокировать файл (смотрите flock() ) перед изменением, так как использование 'w' может обрезать файл ещё до того как была получена блокировка (если вы желаете обрезать файл, можно использовать функцию ftruncate() после запроса на блокировку). |
'c+' | Открывает файл для чтения и записи; в остальном имеет то же поведение, что и 'c' . |
'e' | Установить флаг close-on-exec (закрыть при запуске) на открытый файловый дескриптор. Доступно только в PHP скомпилированном на системах поддерживающих POSIX.1-2008. |
Замечание:
Разные семейства операционных систем имеют разные соглашения относительно окончания строк. Когда вы пишете текст и хотите вставить разрыв строки, вы должны использовать правильные символы (или символ) для вашей операционной системы. Системы семейства Unix используют \n в качестве символа конца строки, системы семейства Windows используют \r\n в качестве символов окончания строки и системы семейства Macintosh (Mac OS Classic) используют \r в качестве символа конца строки.
Если вы используете неверный символ конца строки при редактировании файлов, вы можете обнаружить, что при открытии эти файлы "странно выглядят".
Windows предлагает флаг режима текстовой трансляции ( 't' ), который автоматически переведёт \n в \r\n во время работы с файлом. И наоборот - вы также можете использовать 'b' , чтобы принудительно включить бинарный режим, в котором ваши данные не будут преобразовываться. Чтобы использовать эти режимы, укажите 'b' или 't' последней буквой параметра mode .
Флагом трансляции по умолчанию является 'b' . Вы можете использовать режим 't' , если работаете с текстовыми файлами и используете \n для обозначения конца строки в вашем скрипте, но при этом предполагаете, что ваши файлы будут использоваться в таких приложениях, как "Блокнот" (в устаревших версиях). Во всех остальных случаях используйте флаг 'b' .
Если вы укажете флаг 't' во время работы с бинарными файлами, вы можете столкнуться со странными проблемами с вашими данными, включая повреждённые файлы изображений и проблемы с символами \r\n .
Замечание:
Опять же из соображений портируемости крайне рекомендуется переписать старый код, который полагается на режим 't' , чтобы вместо этого он использовал правильные концы строк и режим 'b' .
Замечание: Параметр mode игнорируется при работе с обёртками потока php://output , php://input , php://stdin , php://stdout , php://stderr и php://fd .
Необязательный третий параметр use_include_path может быть установлен в '1' или true , если вы также хотите провести поиск файла в include_path.
Если вы хотите, чтобы использовался поиск файла в include_path, установите этот параметр в true .
Примеры
Результатом выполнения данного примера будет что-то подобное:
Читайте также: