how to check if .exe file exists in php - php

Hi there is there any way to check if .exe file exists on a given path or not.
I have installation of ImageMagic. I have a path of convert.exe of Image Magic. I need to check that in given path the convert.exe exists or not. I have implemented
$settingFileContent = file_get_contents($settingFilePath);
// print_r($settingFileContent);
$allPaths = unserialize(stripslashes($settingFileContent));
if (isset($allPaths['IMAGE_CONVERT_EXE'])) {
//cho $allPaths['IMAGE_CONVERT_EXE'];
if (file_exists($allPaths['IMAGE_CONVERT_EXE'])) {
$analysisResultObj->level = ENUM_SUCCESS;
} else {
$analysisResultObj->level = ENUM_ERROR;
$analysisResultObj->infoText = "Image Magic convert.ext has wrong path";
Logger::getLogger('Application')->error('Image Magic convert.ext has wrong path');
}
}
I can change the value of $allPaths['IMAGE_CONVERT_EXE'] in file. When I change to wrong value even in that condition it returns true.

Based on the documentation comment specifically about PHP on Windows I'm guessing (and let's be clear: everything in PHP is a guess) try this:
$file = 'd:/somfolder/imagemagic/convert.ext'
if(file_exists($file)) {
// should be false
}
Based on your actual code have you tried:
$file = $allPaths['IMAGE_CONVERT_EXE'];
if(file_exists($file)) {
// should be false
}
Looking at the documentation someone commented about having this same problem on Windows and being unable to return the correct result when concatenating string values. While you are not concatenating string values together its at least worth a shot to make sure there isn't something else strange going on.

To me it sounds like you're trying to get wether or not the Imagemagick extension exists. PHP provides ways for doing just that thus eliminating your extrapolated and insane approach all together.
<?php
echo extension_loaded('imagick');
?>
Additionally, you can get an idea of your installed extensions via
<?php
print_r(get_loaded_extensions());
?>

Related

php file_exists() only works once in the same function

I have a php function that renames two separate image files from a temporary to permanent path after first confirming that the temporary path exists.
When it checks for the fist file it works fine but, for some reason, the second file never passes the if(file_exists()) even though I can confirm with 100% certainty that the file path being checked does, in fact, exist.
The image files have different names but the codes are otherwise structured exactly the same so I can't see why one would work and the other wouldn't.
if(file_exists('temp/'.strtolower($option['image1']))){
$path1 = 'images/'.strtolower($option['image1']); // upload directory
$tmp1 = 'temp/'.strtolower($option['image1']);
if(rename($tmp1, $path1)){
$error = 0;
}else{
$error = 4;
}
}
if(file_exists('temp/'.strtolower($option['image2']))){
$path2 = 'images/'.strtolower($option['image2']); // upload directory
$tmp2 = 'temp/'.strtolower($option['image2']);
if(rename($tmp2, $path2)){
$error = 0;
}else{
$error = 5;
}
}
Is there an issue with calling file_exists() twice? How else can I check for both paths?
Edit
As per Marco-A's suggestion, I added clearstatcache(); between the two if/then blocks and it worked like a charm.
The only two possibilities (if you're absolutely sure the file path exists) I'm seeing are either 1.) a stat cache problem (you can clear the cache with clearstatcache) or 2.) a permission issue. Consider this:
$ touch /tmp/locked/file
$ php is_file_test.php
$ bool(true)
$ chmod -x /tmp/locked
$ php is_file_test.php
$ bool(false)
So it might be, that the parent directory of that file doesn't have the x (executable) permission bit set. This prevents any process from iterating and accessing the directory's content.
The uploaded file names can have uppercase characters. If you use strtolower in the file_exists function, you probably wouldn't be looking for the original file path.
if(file_exists('temp/' . strtolower($option['image']))){
// ...
}
Should be changed to:
if(file_exists('temp/' . $option['image'])){
// ...
}

How to echo error message if include can't find the file

I use a php script to include another php file. When someone goes to the index.php with the wrong string, I want it to show on the screen an error message.
How do I make it show a custom error message like "You have used the wrong link. Please try again."?
Here is what I am doing now...
Someone comes to the URL like this...
http://example.com/?p=14
That would take them to the index.php file and it would pick up p. In the index.php script it then uses include ('p'.$p.'/index.php'); which finds the directory p14 and includes the index.php file in that directory.
I am finding people, for what ever reason, are changing the p= and making it something that is not a directory. I want to fight against that and just show an error if they put anything else in there. I have too many directories and will be adding more so I can't just us a simple if ($p != '14'){echo "error";} I would have to make about 45 of those.
So what is a simple way for me to say.... "If include does not work then echo "error";"?
$filename = 'p'.$p.'/index.php';
Solution1:
if(!#include($filename)) throw new Exception("Failed to include ".$filename);
Solution2: Use file_exists - this checks whether a file or directory exists, so u can just check for directory as well
if (!file_exists($filename)) {
echo "The file $filename does not exist";
}
You should never use this include solution, because it can be vulnerable to code injection.
Even using file_exists is not a good solution, because the attacker can try some files in your server that was not properly secured and gain access to them.
You should use a white list: a dictionary containing the files that the user can include referenced by an alias, like this:
$whiteList = array(
"page1" => "/dir1/file1.php",
"page2" => "/dirabc/filexyz.php"
)
if (array_key_exists($p, $whiteList)) {
include_once($whiteList[$p]);
} else {
die("wrong file");
}
In this way you do no expose the server files structure to the web and guarantee that only a file allowed by you can be included.
You must sanitize the $p before using it:
$p = filter_input(INPUT_GET, "p", FILTER_SANITIZE_STRING);
But depending on the keys that you use in the dictionary, other filters should be used... look at the reference.
if(!file_exists('p'.$p.'/index.php')) die('error');
require_once('p'.$p.'/index.php');

file_exists() returns false, but the file DOES exist

I'm having a very weird issue with file_exists(). I'm using this function to check if 2 different files in the same folders do exist. I've double-checked, they BOTH do exist.
echo $relative . $url['path'] . '/' . $path['filename'] . '.jpg';
Result: ../../images/example/001-001.jpg
echo $relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension'];
Result: ../../images/example/001-001.PNG
Now let's use file_exists() on these:
var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.jpg'));
Result: bool(false)
var_dump(file_exists($relative . $url['path'] . '/' . $path['filename'] . '.' . $path['extension']));
Result: bool(true)
I don't get it - both of these files do exist. I'm running Windows, so it's not related to a case-sensitive issue. Safe Mode is off.
What might be worth mentioning though is that the .png one is uploaded by a user via FTP, while the .jpg one is created using a script. But as far as I know, that shouldn't make a difference.
Any tips?
Thanks
file_exists() just doesn't work with HTTP addresses.
It only supports filesystem paths (and FTP, if you're using PHP5.)
Please note:
Works :
if (file_exists($_SERVER['DOCUMENT_ROOT']."/folder/test.txt")
echo "file exists";
Does not work:
if (file_exists("www.mysite.com/folder/test.txt")
echo "file exists";
Results of the file_exists() are cached, so try using clearstatcache(). If that not helped, recheck names - they might be similar, but not same.
I found that what works for me to check if a file exists (relative to the current php file it is being executed from) is this piece of code:
$filename = 'myfile.jpg';
$file_path_and_name = dirname(__FILE__) . DIRECTORY_SEPARATOR . "{$filename}";
if ( file_exists($file_path_and_name) ){
// file exists. Do some magic...
} else {
// file does not exists...
}
Just my $.02: I just had this problem and it was due to a space at the end of the file name. It's not always a path problem - although that is the first thing I check - always. I could cut and paste the file name into a shell window using the ls -l command and of course that locates the file because the command line will ignore the space where as file_exists does not. Very frustrating indeed and nearly impossible to locate were it not for StackOverflow.
HINT: When outputting debug statements enclose values with delimiters () or [] and that will show a space pretty clearly. And always remember to trim your input.
It's because of safe mode. You can turn it off or include the directory in safe_mode_include_dir. Or change file ownership / permissions for those files.
php.net: file_exists()
php.net: safe mode
Try using DIRECTORY_SEPARATOR instead of '/' as separator. Windows uses a different separator for file system paths (backslash) than Linux and Unix systems.
A very simple trick is here that worked for me.
When I write following line, than it returns false.
if(file_exists('/my-dreams-files/'.$_GET['article'].'.html'))
And when I write with removing URL starting slash, then it returns true.
if(file_exists('my-dreams-files/'.$_GET['article'].'.html'))
I have a new reason this happens - I am using PHP inside a Docker container with a mounted volume for the codebase which resides on my local host machine.
I was getting file_exists == FALSE (inside Composer autoload), but if I copied the filepath into terminal - it did exist! I tried the clearstatche(), checked safe-mode was OFF.
Then I remembered the Docker volume mapping: the absolute path on my local host machine certainly doesn't exist inside the Docker container - which is PHP's perspective on the world.
(I keep forgetting I'm using Docker, because I've made shell functions which wrap the docker run commands so nicely...)
It can also be a permission problem on one of the parent folders or the file itself.
Try to open a session as the user running your webserver and cd into it. The folder must be accessible by this user and the file must be readable.
If not, php will return that the file doesn't exist.
have you tried manual entry. also your two extensions seem to be in different case
var_dump(file_exists('../../images/example/001-001.jpg'));
var_dump(file_exists('../../images/example/001-001.PNG'));
A custom_file_exists() function inspired by #Timur, #Brian, #Doug and #Shahar previous answers:
function custom_file_exists($file_path=''){
$file_exists=false;
//clear cached results
//clearstatcache();
//trim path
$file_dir=trim(dirname($file_path));
//normalize path separator
$file_dir=str_replace('/',DIRECTORY_SEPARATOR,$file_dir).DIRECTORY_SEPARATOR;
//trim file name
$file_name=trim(basename($file_path));
//rebuild path
$file_path=$file_dir."{$file_name}";
//If you simply want to check that some file (not directory) exists,
//and concerned about performance, try is_file() instead.
//It seems like is_file() is almost 2x faster when a file exists
//and about the same when it doesn't.
$file_exists=is_file($file_path);
//$file_exists=file_exists($file_path);
return $file_exists;
}
This answer may be a bit hacky, but its been working for me -
$file = 'path/to/file.jpg';
$file = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/'.$file;
$file_headers = #get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}else{
$exists = true;
}
apparently $_SERVER['REQUEST_SCHEME'] is a bit dicey to use with IIS 7.0 + PHP 5.3 so you could probably look for a better way to add in the protocol.
I found this answer here http://php.net/manual/en/function.file-exists.php#75064
I spent the last two hours wondering what was wrong with my if statement: file_exists($file) was returning false, however I could call include($file) with no problem.
It turns out that I didn't realize that the php include_path value I had set in the .htaccess file didn't carry over to file_exists, is_file, etc.
Thus:
<?PHP
// .htaccess php_value include_path '/home/user/public_html/';
// includes lies in /home/user/public_html/includes/
//doesn't work, file_exists returns false
if ( file_exists('includes/config.php') )
{
include('includes/config.php');
}
//does work, file_exists returns true
if ( file_exists('/home/user/public_html/includes/config.php') )
{
include('includes/config.php');
}
?>
Just goes to show that "shortcuts for simplicity" like setting the include_path in .htaccess can just cause more grief in the long run.
In my case, the problem was a misconception of how file_exists() behaves with symbolic links and .. ("dotdot" or double period) parent dir references. In that regard, it differs from functions like require, include or even mkdir().
Given this directory structure:
/home/me/work/example/
www/
/var/www/example.local/
tmp/
public_html -> /home/me/work/example/www/
file_exists('/var/www/example.local/public_html/../tmp/'); would return FALSE even though the subdir exists as we see, because the function traversed up into /home/me/work/example/ which does not have that subdir.
For this reason, I have created this function:
/**
* Resolve any ".." ("dotdots" or double periods) in a given path.
*
* This is especially useful for avoiding the confusing behavior `file_exists()`
* shows with symbolic links.
*
* #param string $path
*
* #return string
*/
function resolve_dotdots( string $path ) {
if (empty($path)) {
return $path;
}
$source = array_reverse(explode(DIRECTORY_SEPARATOR, $path));
$balance = 0;
$parts = array();
// going backwards through the path, keep track of the dotdots and "work
// them off" by skipping a part. Only take over the respective part if the
// balance is at zero.
foreach ($source as $part) {
if ($part === '..') {
$balance++;
} else if ($balance > 0) {
$balance--;
} else {
array_push($parts, $part);
}
}
// special case: path begins with too many dotdots, references "outside
// knowledge".
if ($balance > 0) {
for ($i = 0; $i < $balance; $i++) {
array_push($parts, '..');
}
}
$parts = array_reverse($parts);
return implode(DIRECTORY_SEPARATOR, $parts);
}
I just encountered this same problem and I solved it in a mysterious way. After inserting a a filepath I copied from Windows File explorer. file_exists() keeps returning false continuously, but if I copy same path from VSCode editor it works perfectly.
After dumping variables with var_dump($path); I noticed something mysterious.
For path I copied from file explorer it shows length 94.
For path I copied from VSCode Editor it shows length 88.
Both path look same length on my code Editor.
My suggestion: if string contain hidden characters, it may fail and not work.

PHP file_exists($var) not working

I'm trying to write some code on my notebook and am using the xampp environment. I have the following piece of code:
class A {
...
foreach ($blocks as $block) {
$block = 'dir/dir2/' . $block;
}
if (file_exists($block) == true) {
$var .= file_get_contents($block);
}
}
When I echo the $block variable in the foreach loop, it gives back the path to the files. However, the file_exists function always returns false. Could you please help me figure out what's wrong here?
file_exists purpose is to check if the supplied file exists. It's returning false. This means that the your file doesn't exist where php is looking. php might be looking in a different area than you expect. Looks like it's time for some debugging.
Run this to figure out where php is looking.
echo "current working directory is -> ". getcwd();
Is that where you want php to look? If not then change the directory php is looking in with the chdir function.
$searchdirectory = "c:\path\to\your\directory"; //use unix style paths if necessary
chdir($searchdirectory);
Then run your function (note: I flipped the slashes to backslashes in order to be consistent with windows style paths.)
class A {
...
//change working directory
$searchdirectory = "c:\path\to\your\directory"; //use unix style paths if necessary
chdir($searchdirectory);
foreach ($blocks as $block) {
$block = 'dir\dir2\' . $block;
if (file_exists($block) == true) {
$var .= file_get_contents($block);
}
}
}
Quoting someones comment on the php file_exists manual page,
Be aware: If you pass a relative path
to file_exists, it will return false
unless the path happens to be relative
to the "current PHP dir" (see chdir()
).
In other words, if your path is relative to the current files directory, you should append dirname(__FILE__) to your relative paths, or as of PHP 5.3, you can just use __DIR__.
It may be too late but just found its solution after banging my head for last 2 hrs. In case you are using windows, it hides file name extension by default. So a.txt will be displayed as a and the file which is displayed as a.txt is actually a.txt.txt . To view file extensions go to
Control Panel -> Appereances And Personalization -> Folder Option -> View
and uncheck hide file name extension. Now you can see the true name which is to be used in file_exists().
You are mixing slashes, this one drove me nuts.
Here is the solution:
echo getcwd();
$searchimg = getcwd().'\\public\\images\\pics\\'.$value['name'].'.'.$value['ext'];
You will need to quote the slashes like that all the way to the picture :)
As far as I see, you are using file_exists outside the foreach loop. Hence the $block variable is not bound at the time.
EDIT: actually it is still bound to the last value in your collection.
Do you intend to check file_exists() inside the foreach loop?
class A {
...
foreach ($blocks as $block) {
$block = 'dir/dir2/' . $block;
// Inside the loop
if (file_exists($block) == true) {
$var .= file_get_contents($block);
}
}
}
i guess that the check of file_exists work a bit different from opening with file_get_contents. so i maye it could be one of these problems:
file_exists: returns FALSE if inaccessible due to safe mode restrictions
file_exists: for checking it uses the real UID/GID and not the effective rights
file_get_contents: uses a protocol with file_exists does not know..
maybe it helps you further! good luck
If you use a variable for your file, make sure that there are no blank space at the end. I went mad until i found the solution : removing blank with trim(). See below.
if file_exists(trim($Filename))

PHP file uploading trouble

I'm having an extremely weird problem with a PHP script of mine.
I'm uploading a couple of files and having PHP put them all in one folder.
I've have trouble with random files being sent and random ones not being sent. So I debugged it and I got a very weird result from the $_FILES[] array.
I tried it with 3 files.
$_FILES["addFile"]["name"] Holds the names of the 3 files.
You'd expect $_FILES["addFile"]["tmp_name"] to hold the 3 temporary names that PHP uses to copy the files, but it doesn't. It holds just one name. The other 2 are empty strings, which generate an error whilst uploading(which I supress from being displayed)
This is very odd. I've tried mulitple situations and it just keeps on happening.
This must be something in my settings or perhaps even my code.
Here's my code:
$i = 0;
if (!empty($_FILES['addFile'])) {
foreach($_FILES['addFile'] as $addFile) {
$fileToCopy = $_FILES["addFile"]["tmp_name"][$i];
$fileName = $_FILES["addFile"]["name"][$i];
$i++;
if(!empty($fileToCopy)){
$copyTo = $baseDir."/".$fileName;
#copy($fileToCopy, $copyTo) or die("cannot copy ".$fileToCopy." to ".$copyTo);
}
}
exit(0);
}
Since the tmp_name is empty, the if-value will be false so it's gonna skip the die() function.
Does anybody know what might be causing this?
further info: I'm using Windows XP, running WAMP server. Never had this problem before and I can acces all maps from which I've tried to upload. Security settings of windows can't be the issue I think.
I'm sorry but it seams to me that you are trying to upload all 3 files with the same variable name? Is this right?
But this will not work because they will overwrite each other.
I think the better an cleaner way it would be to use something like
$i = 0;
foreach($_FILES['addFile'.$i] as $addFile) {
if(!empty($addFiles) {
move_uploaded_file($addFile['temp_name'], 'YOUR DIRECTORY');
}
$i++;
}
Relevent, but probably not going to help: but move_uploaded_file is a (slightly) better way to handle uploaded files than copy.
Are any of the files large? PHP has limits on the filesize and the time it can take to upload them ...
Better to send you here than attempt to write up what it says:
http://uk3.php.net/manual/en/features.file-upload.common-pitfalls.php
Your loop logic is incorrect. You are using a foreach loop on the file input name directly, which stores several properties that are of no interest to you ('type','size', etc).
You should get the file count from the first file and use it as the loop length:
if (!empty($_FILES['addFile']) && is_array($_FILES['addFile']['name'])) {
$length = count($_FILES['addFile']['name']);
for($i = 0; $i < $length; $i++) {
$result = move_uploaded_file($_FILES['addFile']['tmp_name'][$i],$baseDir."/" . $_FILES['addFile']['name'][$i]);
if($result === false) {
echo 'File upload failed. The following error has occurred: ' . $_FILES['addFile']['error'][$i];
}
}
}
Check the error code if you are still having problems, it should provide all the information you need to debug it.

Categories