How do I check if a directory is writeable in PHP? - 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');

Related

PHP - Function to read and write a TXT file

I'm making a function on WordPress to get the content of the robots.txt file. If the file doesn't exist, create it with default content. I will use it for my options page. Well, this is my code, it should work almost creating the file, but it doesn't:
function get_robots($robots_file) {
$robots_file = get_home_path() . 'robots.txt'; //The robots file.
$dir = get_home_path(); //The root directory
if(is_file($robots_file)){
$handle = fopen($robots_file, "r");
$robots_content = fread($handle, filesize($robots_file));
fclose($handle);
} else {
$default_content = "User-agent: *\nDisallow:";
chmod($dir, 0777);
$handle = fopen($robots_file, "w+");
$robots_content = fwrite($handle, $default_content);
fclose($handle);
}
chmod($dir, 0744);
return $robots_content;
}
I'm not sure if the problem is is_file, or the fopen($robots_file, "w+" (should it be "r"?) after the else. And I'm not sure about the permissions. Is the 777 needed? Is the 744 the default for the root directory of WordPress?
And I use the return to use it as variable later; I suppose the fopen is already creating the file. Am I right?
Thanks in advance.
The first thing, I would use completely different functions, you have file_put_contents() and file_get_contents() for such simple operations.
So possible simpler solution is:
function get_robots() {
$robots_file = get_home_path() . 'robots.txt'; //The robots file.
if(file_exists($robots_file)){
return file_get_contents($robots_file);
} else {
$default_content = "User-agent: *\nDisallow:";
file_put_contents($robots_file, $default_content);
return $default_content;
}
}
I don't see any point to pass $robots_file as function argument so I removed it. You should check if this code simple works.
I also don't see any reason to change $dir permissions as you showed in your code. It should be rather set manually and you definitely shouldn't change your root directory permission in such function.
EDIT
Because this function uses get_home_path() and this one is available probably only on admin panel you have to do it in different way. You may add the following code to the end of your index.php file:
function get_robots($path)
{
$robots_file = $path . DIRECTORY_SEPARATOR . 'robots.txt'; //The robots file.
if(file_exists($robots_file)){
return file_get_contents($robots_file);
} else {
$default_content = "User-agent: *\nDisallow:";
file_put_contents($robots_file, $default_content);
return $default_content;
}
}
get_robots(getcwd());
(Of course if you want, you may move get_robots() function to some other files.
However you should consider if this is the best approach. You will run this function each time your site will be viewed and it's tiny waste (in fact you will probably want to create robots.txt file just once). You could for example create robots.php file and if you want to run it you can run http://yourwordpressurl/robots.php. It's of course your call.

PHP move uploaded file always error

I post a file by HTML and I want to move it but it always return value false.
here's my code :
$fileName = $_FILES['atc']['name'];
$fileTmp = $_FILES['atc']['tmp_name'];
$newDir = "/home/goes/attachments/" . $fileName;
$a = move_uploaded_file($fileTmp, $newDir);
if ($a==true){
echo "true";
}
else{
echo "false";
}
The destination folder may not be have write permission
Check the content of all of your variables, see if they contain anything (good)
Check if the directory where you want to place the files exists, and is writeable by the webserver (or whoever runs the PHP process).
Is this the script you are calling from your form? Apache only holds the uploaded files for the duration of the called script, after that, the files are deleted if they are not handled by the script.
foreach ($_FILES['atc']['tmp_name'] as $key => $tmp_name){ $path = "home/goes/attachments/" . $fileName";move_uploaded_file($tmp_name, $path);
}

Change folder permission to 777 using PHP temporarily

I have a Video folder on my server which has 755 permission. The problem is: when someone goes to upload video file, it can't be upload into that folder because of permission error.
If I change the permission to 777, then Video can be uploaded. But I don't want to allow the folder permission to 777 for security reason.
Is there any way in PHP to temporary change the permission to 777 while uploading video?
PHP provides a function, chmod() for the task.
Attempts to change the mode of the specified file to that given in mode.
You can put it in an if statement, and if it returns false, you can skip the upload file part.
The usage will be like
if( chmod($path, 0777) ) {
// more code
chmod($path, 0755);
}
else
echo "Couldn't do it.";
As described in the chmod function manual, the $mode must be in octal format - with leading zero, i.e chmod($path, 0777)
There is a way (PHP provides chmod function) but since PHP is not the owner of the folder, you won't be able to change the permission. And I think you are solving the wrong problem. Add webserver and PHP in the same group and give 775 to the folder.
You have to initialize the config for the upload, like this:
$config['remove_spaces'] = FALSE;
$config['upload_path'] = $path;
$this->upload->initialize($config);
$this->load->library('upload', $config);
You can use chmod() function.
For more information, try here
Warning: You cannot undo the file permissions that are changed by the script below. Proceed with extreme caution.
Important: this code should only be used if you remember to delete it immediately after use. As above, its use may put your site into an insecure state.
//replace dirname(__FILE__) with desired folder.
file_fix_directory(dirname(__FILE__));
function file_fix_directory($dir, $nomask = array('.', '..')) {
if (is_dir($dir)) {
// Try to make each directory world writable.
if (#chmod($dir, 0777)) {
echo "Made writable: " . $dir . "";
}
}
if (is_dir($dir) && $handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if (!in_array($file, $nomask) && $file[0] != '.') {
if (is_dir("$dir/$file")) {
// Recurse into subdirectories
file_fix_directory("$dir/$file", $nomask);
}
else {
$filename = "$dir/$file";
// Try to make each file world writable.
if (#chmod($filename, 0666)) {
echo "Made writable: " . $filename . "";
}
}
}
}
closedir($handle);
}
}
or you can use terminal for this
chmod -R 755 public_html/test

What PHP function(s) should I use to cut off the end of a string?

I have a filename stored with the directory as a value.
Ex. /var/www/remove_this.php
In my PHP script I want to remove everthing after the last '/', so I can use mkdir on this path without creating a directory from the filename also.
There are so many string editing functions, I don't know a good approach. Thanks!
dirname() will return you the directory part of the path
Use pathinfo() to get info about the file itself.
$file = '/var/www/remove_this.php';
$pathinfo = pathinfo($file);
$dir = $pathinfo['dirname']; // '/var/www/'
You could use string functions, but for this case PHP has some smarter directory functions:
$dir = dirname('/var/www/remove_this.php'); // /var/www
pathinfo is an excellent one as well.
<?php
$file="/var/www/remove_this.php";
$folder=dirname($var);
if (!file_exsts($folder))
{
if (mkdir($folder,777,true))
{
echo "Folder created\n";
} else
{
echo "Folder creation failed\n";
}
} else
{
echo "Folder exists already\n";
}
?>

How to test if a directory already exist in PHP?

How can i test if a directory already exist and if not create one in PHP?
Try this:
$filename = "/tmp";
if (!file_exists($filename))
echo $filename, " does not exist";
elseif (!is_dir($filename))
echo $filename, " is not a directory";
else
echo "Directory ", $filename, " already exists";
file_exists checks if the path/file exists and is_dir checks whether the given filename is a directory.
Edit:
to create the directory afterwards, call
mkdir($filename);
To expand on the answer above based on the questioner's comments:
$filename = "/tmp";
if (!is_dir($filename)) {
mkdir($filename);
}
You need to use mkdir() to actually make the directory.
Try this:
$dir = "/path/to/dir";
if(is_dir($dir) == false)
mkdir($dir);
If you want the complete path the be created (if not present), set recusive parameter to true.
See documentation of mkdir for more information.
Use This:
if(file_exists("Directory path") && is_dir("Directory path"))
{
//Your Code;
}

Categories