I create one function for delete entry in little file in txt format , the problem it´s when i go delete entry show me this message :
Warning: flock() expects parameter 1 to be resource, boolean given in
The Script Function :
<?php
function delete_entry($name_file_db,$id_entry)
{
$fil_del=file("".$name_file_db."");
$fd=fopen("".$name_file_db."","w");
if (flock($fd,LOCK_EX))
{
ftruncate($fd,0);
fputs($fd,"".$fil_del[0]."");
for($de=1;$de<sizeof($fil_del);$de++)
{
if($de=="".$id_entry."")
{
fputs($fd,"");
}
else
{
fputs($fd,"".$fil_del[$de]."");
}
}
fflush($fd);
flock($fd, LOCK_UN);
fclose($fd);
}
else
{
if($db_activate_msg_bugs=="si")
{
print "Busy File";
}
}
}
?>
I don´t know why no works , i try differents combinations but continue fail
Thank´s Regards
$fd=fopen("".$name_file_db."","w") probably didn't open a file. fopen() returns false if it fails:
Returns a file pointer resource on success, or FALSE on error.
BTW ftruncate() is needless, fopen() in mode w implicitly truncates the file. This does also break your code. The blocked process is truncating your file! Consider using a dedicated lock file or open the file nondeconstructive (e.g. mode c).
Related
how to remove this error is this possible to control this error?
<?php
$file=fopen("welcome.txt","r");
?>
I don't know exactly what you are looking for but you can add condition to check either file exists or not. maybe that'll solve your problem
<?php
if(!file_exists("welcome.txt")) {
die("File not found");
} else {
$file=fopen("welcome.txt","r");
}
?>
In the fopen() manual page we can read (emphasis mine):
Return Values
Returns a file pointer resource on success, or FALSE on failure
Errors/Exceptions
Upon failure, an E_WARNING is emitted.
So:
$file = fopen("welcome.txt","r");
if ($file) {
// Everything's fine
} else {
// Error happened
}
The same happened here.
I just deleted the ".txt" extension from the file and kept the one in the code and it worked.
I want to do a read-modify-write to a file whilst I have an exclusive lock. Clearly I can use flock() and do the sequence fopen, flock, fread, fwrite, flock, fclose, but I my code would look neater if it I could use file_get_contents and file_put_contents. However, I need to lock both processes and I was wondering if was possible to do that using flock "somehow". The danger is, of course, that I'll write something that seems to work but doesnt actually lock anything :-)
as #jonathan said you can use the flag LOCK_EX with file_put_contents but for file_get_contents you can build your own custom function and then use it in your code .
the code below can be a starting point for you:
function fget_contents($path,$operation=LOCK_EX|LOCK_NB,&$wouldblock=0,$use_include_path = false ,$context=NULL ,$offset = 0 ,$maxlen=null){
if(!file_exists($path)||!is_readable($path)){
trigger_error("fget_contents($path): failed to open stream: No such file or directory in",E_USER_WARNING);
return false;
}
if($maxlen<0){
trigger_error("fget_contents(): length must be greater than or equal to zero",E_USER_WARNING);
return false;
}
$maxlen=is_null($maxlen)?filesize($path):$maxlen;
$context=!is_resource($context)?NULL:$context;
$use_include_path=($use_include_path!==false&&$use_include_path!==FILE_USE_INCLUDE_PATH)?false:$use_include_path;
if(is_resource($context))
$resource=fopen($path,'r',(bool)$use_include_path,$context);
else
$resource=fopen($path,'r',(bool)$use_include_path);
$operation=($operation!==LOCK_EX|LOCK_NB&&$operation!==LOCK_SH|LOCK_NB&&$operation!==LOCK_EX&&$operation!==LOCK_SH)?LOCK_EX|LOCK_NB:$operation;
if(!flock($resource,$operation,$wouldblock)){
trigger_error("fget_contents(): the file can't be locked",E_USER_WARNING);
return false;
}
if(-1===fseek($resource,$offset)){
trigger_error("fget_contents(): can't move to offset $offset.The stream doesn't support fseek ",E_USER_WARNING);
return false;
}
$contents=fread($resource,$maxlen);
flock($resource, LOCK_UN);
fclose($resource);
return $contents;
}
for a little explanation :
i just combine the parameters for flock with those for file_get_contents so you just need to read alittle about these two functions to understand the code.However if you don't need advanced usage of this function you can just do
$variable=fget_contents($yourpathhere);
I think this line is the same as :
$variable=file_get_contents($yourpathhere);
Except that fget_contents will actually lock the file according to your flag...
I have the following code:
function lock() {
if($lock = #fopen('lock.txt', 'x')) {
fwrite($lock, getmypid());
fclose($lock);
return true;
}
else {
return false;
}
}
$response = lock();
When I run the code, the file lock.txt is created and the PID is put into the file. However, the function returns false. What in the world is going on?
I need X for fopen because I'm using this function for file locking and control
I took the # off and this is the error that I got:
fopen(lock.txt): failed to open stream: File exists in /xxx on line
22.
The problem is, I know for sure that the file does not exist -- I even went back and deleted it before I ran the code. The code creates the file but still returns false.
I checked to make sure no other code is creating the file. I even waited 30 secs to wait and see if the file reappeared -- it does not appear by itself, it only appears after I execute this code.
The PHP Manual states that for mode 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.
The function is returning false because #fopen('lock.txt', 'x') returns false (the file would already exist), which causes $lock = #fopen('lock.txt', 'x') to evaluate to false, triggering the branch to return false;.
fopen() mode X http://php.net/manual/en/function.fopen.php
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 already exists, the fopen() call will fail by returning FALSE and generating an error of level E_WARNING.
You will see the warning if you don't use # error suppression.
You probably want mode 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.
I am testing my code using little database in txt files. The most important problem that I have found is: when users write at the same time into one file. To solve this I am using flock.
OS of my computer is windows with xampp installed (comment this because i understand flocks works fine over linux no windows) However I need to do this test over linux server.
Actually I have tested my code by loading the same script in 20 windows at the same time. The firsts results works fine, but after test database file appears empty.
My Code :
$file_db=file("test.db");
$fd=fopen("".$db_name."","w");
if (flock($fd, LOCK_EX))
{
ftruncate($fd,0);
for ($i=0;$i<sizeof($file_db);$i++)
{
fputs($fd,"$file_db[$i]"."\n");
}
fflush($fd);
flock($fd, LOCK_UN);
fclose($fd);
}
else
{
print "Db Busy";
}
How it's possible that the script deletes database file content. What is proper way: use flock with fixing of existing code or use some other alternative technique of flock?
I have re-wrote the script using #lolka_bolka's answer and it works. So in answer to your question, the file $db_name could be empty if the file test.db is empty.
ftruncate after fopen with "w" is useless.
file function
Returns the file in an array. Each element of the array corresponds to a line in the file, with the newline still attached. Upon failure, file() returns FALSE.
You do not have to add additional end of line symbol.
flock function
PHP supports a portable way of locking complete files in an advisory way (which means all accessing programs have to use the same way of locking or it will not work).
It means that file function not affected by the lock. It means that $file_db=file("test.db"); could read file while other process somewhere between ftruncate($fd,0); and fflush($fd);. So, you need read file content inside lock.
$db_name = "file.db";
$fd = fopen($db_name, "r+"); // w changed to r+ for getting file resource but not truncate it
if (flock($fd, LOCK_EX))
{
$file_db = file($db_name); // read file contents while lock obtained
ftruncate($fd, 0);
for ($i = 0; $i < sizeof($file_db); $i++)
{
fputs($fd, "$file_db[$i]");
}
fflush($fd);
flock($fd, LOCK_UN);
}
else
{
print "Db Busy";
}
fclose($fd); // fclose should be called anyway
P.S. you could test this script using console
$ for i in {1..20}; do php 'file.php' >> file.log 2>&1 & done
I'm reviewing code that was written by another developer. The code tries to open a file, and sets $canOpen based on success/failure.
$fh = #fopen('files.php', 'a+');
if (!$fh){
fclose($fh);
$canOpen = false;
} else {
$canOpen = true;
}
What I find strange is that it also tries to close the file but only when the open fails if (!$fh). Does this make sense? Shouldn't the close be in the else statement when the file was successfully opened?
No, it makes no sense.
If !$fh is met as a condition, it means the $fh contains boolean FALSE (or possibly, in the event of some weird internal PHP error, NULL). So what you are effectively doing is:
fclose(FALSE);
...which is pointless and will result in an error.
And, if all you're trying to do is populate the $canOpen variable and not do anything useful with the file handle, wouldn't a combination of is_file(), is_readable() and is_writable() suffice?
The only reason one would close an unopened file is if it is for resiliency purposes. For example, always closing the file in the finally block of a try...catch.
In your case, it looks like a coding error.
if you put a var_dump( $fh ) in the true block of your if, you'll find that it's not a resource handle.
The php manual states that fclose takes a resource. Therefore fclose can't be called on a file that can't be opened.
<?php
$fh = #fopen('files.php', 'a+');
if (!$fh){
var_dump( $fh );
fclose($fh); // this will cause an error
$canOpen = false;
} else {
$canOpen = true;
}
No it doesn't make sense, if you cannot open the file you won't need to close it eigther. At this point the filepointer is always open because if the file doesn't exists it will create a file.