check if file exist in folder - php

My script:
$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
if (isset($secret) || !empty($secret)) {
if (file_exists(ROOT . '/intl/codes/' . $secret)) {
unlink(ROOT . '/intl/codes/' . $secret);
$trusted = 'yes';
} else {
$trusted = 'no';
}
}
//$_POST['register'] register details...
}
Is there another way to do it (simplier, etc.)?
If $secret doesn't exist in the /codes/ folder, it produces Warning: unlink Is a directory How to get rid of that?
Why $trusted always gives yes even if the file doesn't exist ?

To delete a directory, you should be using rmdir() instead of unlink().
$secret = check_input($_GET['secret']);
if(isset($_POST['register'])) {
if (!empty($secret)) {
if(file_exists(ROOT . '/intl/codes/' . $secret)) {
rmdir(ROOT . '/intl/codes/' . $secret);
$trusted = 'yes';
} else {
$trusted = 'no';
}
}
//$_POST['register'] register details...
}
Although, there is a serious security risk here! If your check_input() does not properly sanitize $secret, you could rmdir('/intl/codes/../') which is the same as deleting /intl/.
Try something like this:
$allowed = ROOT. '/intl/codes/';
$path = realpath($allowed . check_input($_GET['secret']));
if(strpos($path, $allowed) === 0) { //Check that $path is within allowed directory
if(is_dir($path)) {
rmdir($path);
} else if(file_exists($path)) {
unlink($path);
} else {
echo "File/folder not found";
}
} else {
echo "Untrusted user tried to delete outside of allowed directory";
}

You can use just if (!empty($secret)) - empty() returns TRUE for NULL value as well.
Use if (file_exists(ROOT . '/intl/codes/' . $secret) && !is_dir(ROOT . '/intl/codes/' . $secret)) to check if your file is not a directory and get rid of that warning. If you still wanna remove the directory, use rmdir() function.
file_exists() returns TRUE for directories as well. So, you should also check if the argument is a directory with is_dir() , as i said before.

if (file_exists(ROOT . '/intl/codes/' . $secret)) {
unlink(ROOT . '/intl/codes/' . $secret);
$trusted = 'yes';
} else {
$trusted = 'no';
}
Is there another way to do it (more simplier, etc.)?
No, Only way is to use file_exists
If $secret doesn't exist in /codes/ folder, it produce Warning: unlink Is a directory How get rid of of that?
It seems $secret points to a directory. The execution path reaches to unlink because if part returns true. So it exists. To delete a directory use rmdir()
Why $trusted always give's yes even if file doesn't exist ?
Because unlink deletes it and sets $trusted to yes. When you search after deletion you see it doesn't exist but $trusted contains yes

Obviously your $secret is an empty string, but it's passing your isset() test.
So the directory ROOT . '/intl/codes/' does exist (thus passing file_exists() check), but you can't unlink() the directory (neither is it your intention here).
Make sure that you have something non-empty in $_GET['secret'] and verify your check_input() function.
P.S. You probably should remove isset($secret) part of the condition. !empty($secret) is enough here and it will fix your script.

as stated by php documentation about file_exists():
Checks whether a file or directory exists
My only guess for your question #3 is: You check if file exists and it does. Only, it's not file, it's directory.
as for #2, also as stated by the error message, you can do something like this:
$file_to_check = ROOT . '/intl/codes/' . $secret;
if (file_exists($file_to_check)) {
if( !is_dir( $file_to_check ) )
unlink($file_to_check);
else
rmdir( $file_to_check );
$trusted = 'yes';
}
and for your #1 question, you might one to do something like this:
$secret = input_get($_GET['secret']);
if(isset($_POST['register']) && !empty($secret)) {
$file_to_check = ROOT . '/intl/codes/' . $secret;
if (file_exists($file_to_check)) {
if( !is_dir( $file_to_check ) )
unlink($file_to_check);
else
rmdir( $file_to_check );
$trusted = 'yes';
} else {
$trusted = 'no';
}
}
function input_get($key, $default = ""){
if(!isset($_GET[$key])){
return $default;
} else {
//do input cleanup first, if you want
return $_GET[$key];
}
}
A little bit of explanation:
I don't know what check_input() does, so I created wrapper function for $_GET[] called input_get(). It removes the need to do isset() and also fill in the default value.
I put ROOT . '/intl/codes/' . $secret; into variable $file_to_check so that you don't have to type it again and again.

Related

PHP unlink() Error: "Directory not empty"

I have the following recursive method to delete a directory and all its sub-directories and files:
protected function _rrmdir($dir)
{
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
if (filetype($dir . '/' . $object) == 'dir') {
_rrmdir($dir . '/' . $object);
} else {
unlink($dir . '/' . $object);
}
}
}
reset($objects);
rmdir($dir);
}
}
On occasion, the get a Warning, "Directory not empty".
The directory is actually created as a temporary holder for files. The files are downloaded from the Internet using the following snippet:
file_put_contents($filename, file_get_contents($file))
After they are downloaded (a write operation), they are then uploaded to a website (a read operation). Once done uploading, the temporary folder and its files are then deleted.
The odd thing is that when I look inside the temporary folder, there are no files there. It's as if the code tried to delete the folder while the last file was in the process of being deleted?
Any ideas what might be wrong and how to resolve it? I need this code to run on Windows and *nix, so a *nix only solution is not an option.
The constant DIRECTORY_SEPARATOR might help you with Windows/Unix compatibility.
For the folder not empty, try this:
protected function _rrmdir($dir)
{
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
if (is_dir($dir . DIRECTORY_SEPARATOR . $object)) {
_rrmdir($dir . DIRECTORY_SEPARATOR . $object);
} else {
if( is_file($dir . DIRECTORY_SEPARATOR . $object) ) {
if(!unlink($dir . DIRECTORY_SEPARATOR . $object)) {
// code in case the file was not removed
}
// wait a bit here?
} else {
// code for debug file permission issues
}
}
}
}
reset($objects);
rmdir($dir);
}
}
It might happen that you try to remove a file which permissions are not at php exec level.
The is_file() method will return FALSE only if no read permissions, mind that write permissions are needed by the execution owner to delete files.

How to loop through parent directories in php?

There are all these resources for recursively looping through sub directories, but I haven't found ONE that shows how to do the opposite.
This is what I want to do...
<?php
// get the current working directory
// start a loop
// check if a certain file exists in the current directory
// if not, set current directory as parent directory
// end loop
So, in other words, I'm searching for a VERY specific file in the current directory, if it doesn't exist there, check it's parent, then it's parent, etc.
Everything I've tried just feels ugly to me. Hopefully someone has an elegant solution to this.
Thanks!
Try to create a recursive function like this
function getSomeFile($path) {
if(file_exists($path) {
return file_get_contents($path);
}
else {
return getSomeFile("../" . $path);
}
}
The easiest way to do this would be using ../ this will move you to the folder above. You can then get a file/folder list for that directory. Don't forget that if you check children of the directory above you then you're checking your siblings. If you just want to go straight up the tree then you can simply keep stepping up a directory until you hit root or as far as you are permitted to go.
<?php
$dir = '.';
while ($dir != '/'){
if (file_exists($dir.'/'. $filename)) {
echo 'found it!';
break;
} else {
echo 'Changing directory' . "\n";
$dir = chdir('..');
}
}
?>
Modified mavili 's code:
function findParentDirWithFile( $file = false ) {
if ( empty($file) ) { return false; }
$dir = '.';
while ($dir != '/') {
if (file_exists($dir.'/'. $file)) {
echo 'found it!';
return $dir . '/' . $file;
break;
} else {
echo 'Changing directory' . "\n";
chdir('..');
$dir = getcwd();
}
}
}

Checking if file exists

I have a piece of code that checks whether an image exists in the file system and if so, displays it.
if (file_exists(realpath(dirname(__FILE__) . $user_image))) {
echo '<img src="'.$user_image.'" />';
}
else {
echo "no image set";
}
If I echo $user_image out, copy and paste the link into the browser, the image is there.
However, here, the 'no image set' is always being reached.
The $user_image contents are http://localhost:8888/mvc/images/users/1.jpg
Some of these functions not needed?
Any ideas?
Broken code or a better way of doing it (that works!)?
Beside #hek2mgl answer which i think is correct, i also think you should switch to is_file() instead of file_exists().
Also, you can go a bit further like:
if(is_file(dirname(__FILE__). '/' . $user_image) && false !== #getimagesize(dirname(__FILE__) . '/'. $user_image)) {
// image is fine
} else {
// it isn't
}
L.E:1
Oh great, now you are telling us what $user_image contains? Couldn't you do it from the start, could you?
So you will have to:
$userImagePath = parse_url($user_image, PHP_URL_PATH);
$fullPath = dirname(__FILE__) . ' / ' . $userImagePath;
if($userImagePath && is_file($fullPath) && false !== #getimagesize($fullPath)) {
// is valid
}else {
// it isn't
}
L.E: 2
Also, storing the entire url is not a good practice, what happens when you switch domain names? Try to store only the relative path, like /blah/images/image.png instead of http://locathost/blah/images/image.png
You missed the directory separator / between path and filename. Add it:
if (file_exists(realpath(dirname(__FILE__) . '/' . $user_image))) {
Note that dirname() will return the directory without a / at the end.

How to use Unlink() function

I'm trying to use PHP unlink() function to delete away the specific document in the folder. That particular folder has already been assigned to full rights to the IIS user.
Code:
$Path = './doc/stuffs/sample.docx';
if (unlink($Path)) {
echo "success";
} else {
echo "fail";
}
It keep return fail. The sample.docx does reside on that particular path. Kindly advise.
I found this information in the comments of the function unlink()
Under Windows System and Apache, denied access to file is an usual
error to unlink file. To delete file you must to change the file's owner.
An example:
chown($tempDirectory . '/' . $fileName, 666); //Insert an Invalid UserId to set to Nobody Owern; 666 is my standard for "Nobody"
unlink($tempDirectory . '/' . $fileName);
So try something like this:
$path = './doc/stuffs/sample.docx';
chown($path, 666);
if (unlink($path)) {
echo 'success';
} else {
echo 'fail';
}
EDIT 1
Try to use this in the path:
$path = '.'
. DIRECTORY_SEPARATOR . 'doc'
. DIRECTORY_SEPARATOR . 'stuffs'
. DIRECTORY_SEPARATOR . 'sample.docx';
Try this:
$Path = './doc/stuffs/sample.docx';
if (file_exists($Path)){
if (unlink($Path)) {
echo "success";
} else {
echo "fail";
}
} else {
echo "file does not exist";
}
If you get file does not exist, you have the wrong path. If not, it may be a permissions issue.
This should work once you are done with the permission issue. Also try
ini_set('display_errors', 'On');
That will tell you whats wrong
define("BASE_URL", DIRECTORY_SEPARATOR . "book" . DIRECTORY_SEPARATOR);
define("ROOT_PATH", $_SERVER['DOCUMENT_ROOT'] . BASE_URL);
$path = "doc/stuffs/sample.docx";
if (unlink(ROOT_PATH . $Path)) {
echo "success";
} else {
echo "fail";
}
// http://localhost/book/doc/stuffs/sample.docx
// C:/xampp/htdocs\book\doc/stuffs/sample.docx
You need the full file path to the file of interest. For example: C:\doc\stuff\sample.docx. Try using __DIR__ or __FILE__ to get your relative file position so you can navigate to the file of interest.

Error shown even if directory already exists

I am making a intranet customer manager in PHP. For each customer a directory is created for the shop to add files into. What my script is supposed do is if no directory exists create it, if it does exists dont create it.
What is actually happening is if the directory already exists I am getting the following error :
Warning: mkdir() [function.mkdir]: File exists in C:\server2go\server2go\htdocs\customermgr\administrator\components\com_chronoforms\form_actions\custo m_code\custom_code.php(18) : eval()'d code on line 14
So what is happening it is trying to create it anyway, even though the if statement should stop it ?, im confused on what I am doing wrong :-S .
<?php
$customerID = $_GET['cfid'];
$directory = "/customer-files/$customerID";
if(file_exists($directory) && is_dir($directory)) {
}
else {
$thisdir = getcwd();
mkdir($thisdir ."/customer-files/$customerID" , 0777); }
?>
Replace:
if(file_exists($directory) && is_dir($directory)) {
with:
$thisdir = getcwd();
if(file_exists($thisdir.$directory) && is_dir($thisdir.$directory)) {
or better:
<?php
$customerID = $_GET['cfid'];
$directory = "./customer-files/$customerID";
if(file_exists($directory) && is_dir($directory)) {
}
else {
mkdir($directory , 0777); }
?>
Just took a short look but i would try this:
$directory = $thisdir . "/customer-files/$customerID";
and remove $thisdir from mkdir();
also you should move your $thisdir before the $directory declaration
The function file_exists() does not use relative paths, where is_dir() can. So instead, use the common denominator and pass an absolute path to these functions. Additionally you can move the call to getcwd() into the $directory assignment and reuse $directory later for creating the directory.
<?php
$customerID = $_GET['cfid'];
// Get full path to directory
$directory = getcwd() . "/customer-files/$customerID";
if(file_exists($directory) && is_dir($directory)) {
// Do nothing
}
else {
// Directory doesn't exist, make it
mkdir($directory , 0777); }
}
?>

Categories