php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78850 PHP Version 7.2.3 - fseek
Submitted: 2019-11-21 09:51 UTC Modified: 2019-11-22 09:53 UTC
From: david dot wildermoth at yandex dot com Assigned:
Status: Not a bug Package: Filesystem function related
PHP Version: 7.2.24 OS: Widows 10
Private report: No CVE-ID: None
 [2019-11-21 09:51 UTC] david dot wildermoth at yandex dot com
Description:
------------
---
https://www.php.net/manual/en/function.fseek.php
---

This "fseek" coding has a malfunction:-

$record = fopen("C:xampp/htdocs/application/views/record.php", "r+");
fseek($record, 200); //fseek malfunctions
$gm = gmdate("\nd M Y H:i T");
fwrite($record, $gm);
$ad = (" - $advertiser") . "<br>";
fwrite($record, $ad);

That producers a result similar to the following:-

21 Nov 2019 - 14:38 GMT - chris<br>

Which is 35 bytes or thereabouts. That is OK for the first record, but if there exists a previous record, then that previous record will be overwritten which is what I don't want.

If I advance (by white space) a previous record by about 35-40 bytes the new record will print plus consume an additional 35 odd bytes, and that previous record moves 35 bytes closer to the new record. I want to avoid that extra consumption.

I want the output to consume only the bytes of its length, no more.

If I insert "a" which takes the pointer to the end, everything works but the output is "recent at the bottom" whereas I want "recent at the top" hence using "r+" and "fseek".

I have read the PHP manual on fseek() and fwrite() and others but there is nothing suggesting a consumption limitation, or similar. I've also tried various addins but nothing has worked.


Expected result:
----------------
I want the output to consume only the bytes of its length, no more.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-11-21 09:54 UTC] requinix@php.net
-Status: Open +Status: Not a bug -Package: Program Execution +Package: Filesystem function related
 [2019-11-21 09:54 UTC] requinix@php.net
If you are not appending to the end of the file then you are overwriting. That's how files work. There is no way to insert at the beginning or in the middle of a file.

If you want to prepend your records then
a) load the entire file into memory, prepend, and write it all back out, or
b) write the new record to a temporary file, append the old file into it, and rename the new file onto the old one
 [2019-11-21 10:16 UTC] david dot wildermoth at yandex dot com
"There is no way to insert at the beginning or in the middle of a file." That statement appears to be incorrect.

https://www.php.net/manual/en/function.fseek.php

Sets the file position indicator for the file referenced by handle. The new position, measured in bytes from the beginning of the file, is obtained by adding offset to the position specified by whence.

The coding that I submitted does insert in the middle of the file. The "bug" I'm reporting inserts white space in addition to the output which is what I want to delete.
 [2019-11-21 17:31 UTC] requinix@php.net
You cannot *insert* into the file. You can *overwrite*.

Open up your favorite text editor. Pull open any file you like and put the cursor somewhere in the middle. Then turn on your editor's overwrite/overtype mode (probably Ins key) and start typing. That's what fseek-ing into the middle and fwrite-ing will do, except it will overwrite newlines as well.
 [2019-11-22 07:55 UTC] david dot wildermoth at yandex dot com
Please tell me something I don't know. I want insert and no overwrite.

fseek() determines the pointer position. fopen determines truncate or append and also pointer position. "fopen" appears to be the root of my problem, and not "fseek" as I first thought.

https://www.php.net/manual/en/function.fopen.php
'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.

Is it possible to have a mode similar to 'a' as follows?
Open for writing only; place the file pointer at the beginning of the file. If the file does not exist, attempt to create it. In this mode, fseek() to be effective, writes are always appended.

If I knew where to amend coding in PHP, I could probably fix this myself.
 [2019-11-22 09:53 UTC] cmb@php.net
Inserting something into a file is a very expensive operation,
since everything that follows the insertion position would have to
be moved.  This is why this operation is not available; if you
need it, you have to move the existing contents yourself.
 [2019-11-22 10:09 UTC] david dot wildermoth at yandex dot com
Please advise the path to "fopen" and "fwrite" and I'll attempt to fix the problem?

And if it works I'll share it as no doubt others will want to insert & no overwrite.
 [2019-11-23 01:20 UTC] david dot wildermoth at yandex dot com
If it is an expensive operation to insert, then it will probably be less expensive to modify an existing mode such as "x" or "c", which would be more useful to the wider community.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Dec 02 22:01:23 2020 UTC