php file is writable but cannot be deleted - php

I am using this function. is_file and is_writable return true, but when I true to unlink, it gives an error. This is on windows server.
if(is_file($fileToDelete)) {
if(is_writable($fileToDelete)) {
unlink($fileToDelete);
}
}
The file is a PDF document, which I have open. I thought is_writable would return false in this case, but it doesn't.
So how can I tell if a file can be deleted or not?
Thank you

What about doing it the other way around? Just try to delete the file and check whether it is really gone?
#unlink($fileToDelete);
if(is_file($fileToDelete)) {
// file was locked (or permissions error)
}
Not sure whether this is workable in your specific case though, but judging by the code in your question this should be what you want.

Are you using the file? I mean, did you open it by doing fopen($file)?
Do a fclose($file) before trying to delete the file.

For them who don't want to delete the file before the check, the solution is here :
$file = "test.pdf";
if (!is_file($file)) {
print "File doesn't exist.";
} else {
$fh = #fopen($file, "r+");
if ($fh) {
print "File is not opened and seems able to be deleted.";
fclose($fh);
} else {
print "File seems to be opened somewhere and can't be deleted.";
}
}
Simple, and efficient.

Related

Using phpseclib to check if file already exists

I'm trying to create a script that will send across files from one server to another. My script successfully does that as well as checks if the file has something in it or not. My next step is to check whether the file already exists on the server; if the file already exists it does not send and if it does not exist, it does send.
I've tried a few different things and can't seem to get my head around it. How can I get it to check whether the file already exists or not? Any help would be appreciated!
(I had a look at some similar questions but couldn't find anything specific to my issue.)
require('constants.php');
$files = $sftp->nlist('out/');
foreach($files as $file) {
if(basename((string) $file)) {
if(strpos($file,".") > 1) { //Checks if file
$filesize = $sftp->size('out/'.$file); //gets filesize
if($filesize > 1){
if (file_exists('import/'.$file)){
echo $file.' already exists';
}
else {
$sftp->get('out/'.$file, 'import/'.$file); //Sends file over
//$sftp->delete('out/'.$file); //Deletes file from out folder
}
else {
echo $file. ' is empty.</br>';
}
}
}
}
}
EDIT: To try and get this to work, I wrote the following if statement to see if it was finding the file test.php;
if (file_exists('test.txt')){
echo 'True';
} else {
echo 'False';
}
This returned true (a good start) but as soon as I put this into my code, I just get a 500 Internal Server Error (extremely unhelpful). I cannot turn on errors as it is on a server that multiple people use.
I also tried changing the file_exists line to;
if (file_exists('test.txt'))
in the hopes that would work but still didn't work.
Just to clarify, I'm sending the files from the remote server to my local server.
There is a closing curly brace missing right before the second else keyword.
Please try to use a code editor with proper syntax highlighting and code formatting to spot such mistakes on the fly while you are still editing the PHP file.
The corrected and formatted code:
require('constants.php');
$files = $sftp->nlist('out/');
foreach ($files as $file) {
if (basename((string)$file)) {
if (strpos($file, ".") > 1) { //Checks if file
$filesize = $sftp->size('out/' . $file); //gets filesize
if ($filesize > 1) {
if (file_exists('import/' . $file)) {
echo $file . ' already exists';
} else {
$sftp->get('out/' . $file, 'import/' . $file); //Sends file over
}
} else {
echo $file . ' is empty.</br>';
}
}
}
}
Your code checks the file exist in your local server not in remote server.
if (file_exists('import/'.$file)){
echo $file.' already exists';
}
You need to check in remote server using sftp object like
if($sftp->file_exists('import/'.$file)){
echo $file.' already exists';
}
Edit:
Add clearstatcache() before checking file_exists() function as the results of the function get cached.
Refer: file_exists

When file_put_contents fails if the directory is full, a file with size 0 is created. How to avoid that?

When the tmp directory is full, file_put_contents returns FALSE but the file is created with size of 0. file_put_contents should either complete the creation of the file or have no effect at all. For example:
$data = 'somedata';
$temp_name = '/tmp/myfile';
if (file_put_contents($temp_name, $data) === FALSE) {
// the message print that the file could not be created.
print 'The file could not be created.';
}
But when I go to the tmp directory, I can find the file "myfile" created in the directory with size 0. This makes it difficult to maintain. The file should not be created and I would like to see a message or warning the the tmp directory is full. Am I missing anything? And is this normal behaviors?
You are probably missing that if you do the error messages, you need to take care of that scenario, too:
$data = 'somedata';
$temp_name = '/tmp/myfile';
$success = file_put_contents($temp_name, $data);
if ($success === FALSE)
{
$exists = is_file($temp_name);
if ($exists === FALSE) {
print 'The file could not be created.';
} else {
print 'The file was created but '.
'it could not be written to it without an error.';
}
}
This will also allow you to deal with it, like cleaning up if the transaction to write to the temporary file failed, to reset the system back into the state like before.
The problem is that file_put_contents will not necessarily return a boolean value and therefore your condition may not be appropriate you could try:
if(!file_put_contents($temp_name, $data)){
print 'The file could not be created.';
if(file_exists ($temp_name))
unlink($temp_name);
}
hi bro i found the Solution,
i know its old but its maybe help other people like me,
i was search about this code long time.
$data = 'somedata';
$temp_name = '/tmp/myfile';
$success = file_put_contents($temp_name, $data);
if (!$success){
$exists = is_file($temp_name);
if (!$exists) {
print 'The file could not be created.';
} else {
print 'The file was created but '.
'it could not be written to it without an error.';
}
}

How do I create file on server?

Let say I want create file call style.css in /css/ folder.
Example : When I click Save button script will create style.css with content
body {background:#fff;}
a {color:#333; text-decoration:none; }
If server cannot write the file I want show error message Please chmod 777 to /css/ folder
Let me know
$data = "body {background:#fff;}
a {color:#333; text-decoration:none; }";
if (false === file_put_contents('/css/style.css', $data))
echo 'Please chmod 777 to /css/ folder';
You can use the is_writable function to check whether the file is writable or not.
For example:
<?php
$filename = '/path/to/css/style.css';
if (is_writable($filename)) {
echo 'The file is writable';
} else {
echo 'Please chmod 777 to /css/ folder';
}
?>
is the function you may want to use
http://php.net/manual/en/function.fopen.php to open the file
http://php.net/manual/en/function.fwrite.php to write your css
http://php.net/manual/en/function.fclose.php to close the file
or use
http://php.net/manual/en/function.file-put-contents.php just one command to master them all
if you fopen the file and the result of the operation is false then you can't write the file (maybe for permissions, maybe for UID mismatch in safe mode)
file_put_contents (php5 and upper) php calls fopen(), fwrite() and fclose() for you and return false if something id wrong (you should make yourself sure that false is really the boolean value though).
fopen with 'w' flag
<?php
$filename = 'test.txt';
$somecontent = "Add this to the file\n";
// Let's make sure the file exists and is writable first.
if (is_writable($filename)) {
// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.
if (!$handle = fopen($filename, 'a')) {
echo "Cannot open file ($filename)";
exit;
}
// Write $somecontent to our opened file.
if (fwrite($handle, $somecontent) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
echo "Success, wrote ($somecontent) to file ($filename)";
fclose($handle);
} else {
echo "The file $filename is not writable";
}
?>
http://php.net/manual/en/function.fwrite.php | Example 1

No error when creating zip, but it doesn't get created

I wrote this code to create a ZIP file and to save it. But somehow it just doesn't show any error, but it doesn't create a ZIP file either. Here's the code:
$zip = new ZipArchive;
$time = microtime(true);
$res = $zip->open("maps/zips/test_" . $time . ".zip", ZipArchive::CREATE);
if ($res === TRUE) {
echo "RESULT TRUE...";
$zip->addFile("maps/filename.ogz","filename.ogz"); //Sauerbraten map format
$zip->addFromString('how_to_install.txt', 'Some Explanation...');
$zip->close();
$zip_created = true;
echo "FILE ADDED!";
}
What am I doing wrong, and how can I fix it?
Probably apache or php has not got permissions to create zip archives in that directory. From one of the comments on ZipArchice::open:
If the directory you are writing or
saving into does not have the correct
permissions set, you won't get any
error messages and it will look like
everything worked fine... except it
won't have changed!
Instead make sure you collect the
return value of ZipArchive::close().
If it is false... it didn't work.
Add an else clause to your if statement and dump $res to see the results:
if($res === TRUE) {
...
} else {
var_dump($res);
}
There are 2 cases when zip doesn't generate the error.
Make sure every file you are adding to the zip is valid. Even if
one file is not available when zip->close is called then the archive
will fail and your zip file won't be created.
If your folder doesn't
have write permissions zip will not report the error. It will finish
but nothing will be created.
I had an exactly same issue, even when with full writing/reading permissions.
Solved by creating the ".zip" file manually before passing it to ZipArchive:
$zip = new ZipArchive;
$time = microtime(true);
$path = "maps/zips/test_" . $time . ".zip"
touch($path); //<--- this line creates the file
$res = $zip->open($path, ZipArchive::CREATE);
if ($res === TRUE) {
echo "RESULT TRUE...";
$zip->addFile("maps/filename.ogz","filename.ogz"); //Sauerbraten map format
$zip->addFromString('how_to_install.txt', 'Some Explanation...');
$zip->close();
$zip_created = true;
echo "FILE ADDED!";
}
Check out that each of your file exists before calling $zip->addFile otherwise the zip won't be generated and no error message will be displayed.
if(file_exists($fichier->url))
{
if($zip->addFile($fichier->url,$fichier->nom))
{
$erreur_ouverture = false;
}
else
{
$erreur_ouverture = true;
echo 'Open error : '.$fichier->url;
}
}
else
{
echo 'File '.$fichier->url.' not found';
}
break it into steps.
if ($res === TRUE) {
check if file_exist
check if addFile give any error
}
if($zip->close())
{
$zip_created = true;
echo "FILE ADDED!"
}
Check the phpinfo for zip is enabled or not :)
One of the reasons for zip file is not created is due to missing check if you are adding file and not a directory.
if (!$file->isDir())
I found the solution here.

How do I check if a directory is writeable in PHP?

Does anyone know how I can check to see if a directory is writeable in PHP?
The function is_writable doesn't work for folders.
Edit: It does work. See the accepted answer.
Yes, it does work for folders....
Returns TRUE if the filename exists and is writable. The filename argument may be a directory name allowing you to check if a directory is writable.
this is the code :)
<?php
$newFileName = '/var/www/your/file.txt';
if ( ! is_writable(dirname($newFileName))) {
echo dirname($newFileName) . ' must writable!!!';
} else {
// blah blah blah
}
to be more specific for owner/group/world
$dir_writable = substr(sprintf('%o', fileperms($folder)), -4) == "0774" ? "true" : "false";
peace...
You may be sending a complete file path to the is_writable() function. is_writable() will return false if the file doesn't already exist in the directory. You need to check the directory itself with the filename removed, if this is the case. If you do that, is_writable will correctly tell you whether the directory is writable or not. If $file contains your file path do this:
$file_directory = dirname($file);
Then use is_writable($file_directory) to determine if the folder is writable.
I hope this helps someone.
According to the documentation for is_writable, it should just work - but you said "folder", so this could be a Windows issue. The comments suggest a workaround.
(A rushed reading earlier made me think that trailing slashes were important, but that turned out to be specific to this work around).
I've written a little script (I call it isWritable.php) that detects all directories in the same directory the script is in and writes to the page whether each directory is writable or not. Hope this helps.
<?php
// isWritable.php detects all directories in the same directory the script is in
// and writes to the page whether each directory is writable or not.
$dirs = array_filter(glob('*'), 'is_dir');
foreach ($dirs as $dir) {
if (is_writable($dir)) {
echo $dir.' is writable.<br>';
} else {
echo $dir.' is not writable. Permissions may have to be adjusted.<br>';
}
}
?>
stat()
Much like a system stat, but in PHP. What you want to check is the mode value, much like you would out of any other call to stat in other languages (I.E. C/C++).
http://us2.php.net/stat
According to the PHP manual is_writable should work fine on directories.
In my case, is_writable returned true, but when tried to write the file - an error was generated.
This code helps to check if the $dir exists and is writable:
<?php
$dir = '/path/to/the/dir';
// try to create this directory if it doesn't exist
$booExists = is_dir($dir) || (mkdir($dir, 0774, true) && is_dir($dir));
$booIsWritable = false;
if ($booExists && is_writable($dir)) {
$tempFile = tempnam($dir, 'tmp');
if ($tempFile !== false) {
$res = file_put_contents($tempFile, 'test');
$booIsWritable = $res !== false;
#unlink($tempFile);
}
}
this is how I do it:
create a file with file_put_contents() and check the return value, if it is positive (number of written in Bytes) then you can go ahead and do what you have to do, if it is FALSE then it is not writable
$is_writable = file_put_contents('directory/dummy.txt', "hello");
if ($is_writable > 0) echo "yes directory it is writable";
else echo "NO directory it is not writable";
then you can delete the dummy file by using unlink()
unlink('directory/dummy.txt');

Categories