PHP: Can include a file that file_exists() says doesn't exist - php

In my script, I set the include path (so another part of the application can include files too), check that a file exists, and include it.
However, after I set the include path, file_exists() reports that the file does not exist, yet I can still include the same file.
<?php
$include_path = realpath('path/to/some/directory');
if(!is_string($include_path) || !is_dir($include_path))
{
return false;
}
set_include_path(
implode(PATH_SEPARATOR, array(
$include_path,
get_include_path()
))
);
// Bootstrap file is located at: "path/to/some/directory/bootstrap.php".
$bootstrap = 'bootstrap.php';
// Returns "bool(true)".
var_dump(file_exists($include_path . '/' . $bootstrap));
// Returns "bool(false)".
var_dump(file_exists($bootstrap));
// This led me to believe that the include path was not being set properly.
// But it is. The next thing is what puzzles me.
require_once $bootstrap;
// Not only are there no errors, but the file is included successfully!
I can edit the include path and include files without providing the absolute filepath, but I cannot check whether they exist or not. This is really annoying as every time a file that does not exist is called, my application results in a fatal error, or at best a warning (using include_once()).
Turning errors and warnings off is not an option, unfortunately.
Can anyone explain what is causing this behaviour?

file_exists does nothing more than say whether a file exists (and the script is allowed to know it exists), resolving the path relative to the cwd. It does not care about the include path.

Yes Here is the Simplest way to implement this
$file_name = //Pass File name
if ( file_exists($file_name) )
{
echo "Exist";
}
else
{
echo "Not Exist";
}

Related

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');

PHP Include path specifically always at root document

I am vague at understanding the include paths and how they are written out, I know how to set them within the ini file and how to functionally do it set_include_path just not how to get it to be exact each time no matter what.
So I have an admin autoload file that I include in all my headers to register the spl_autoload_register function. I just keep getting errors in my error_log file. It says that
PHP Fatal error: Class 'Configurate' not found in
/home/~username~/public_html/testing_ini.php on line 5
So what I am looking for is how can I set the include path to always be the directory before the public_html directory no matter where I am?
I've tried setting the include path to such
.:/opt/alt/php5/usr/share/pear:/opt/alt/php5/usr/share/phphome/~username~/classes/Configurate.php
But I still get the error. Any help and some tips to understanding this entire thing? I suck at relative paths
As per requested spl_autoload_register function
<?php
$ini = parse_ini_file("configurations.ini",true);
foreach($ini as $section) {
foreach($section as $key=>$value ) {
define("__".strtoupper($key)."__",$value);
}
}
//if(__USERNAME__ == null) {
// header("Location: /setup.php?step=1");
// exit();
//}
spl_autoload_register(function($class) {
try {
if(!file_exists("../classes/{$class}.php")){
throw new Exception("/classes/{$class}.php does not exist error on line ". __LINE__." in file ". realpath(__FILE__));
} else
require_once "../classes/{$class}.php";
} catch (Exception $ex) {
echo $ex->getMessage()."<br>";
echo $ex->getCode();
}
});
getcwd() and many other methods did not work for me. Though I did find this one method that works great for me in any directory.
set_include_path(
dirname( $_SERVER["DOCUMENT_ROOT"] )
);
Hope this helps anyone else out there looking to get outside the document root and using it like I do.

php if file exists include file if not include another file

I am trying to include a file if it exists, if the file doesn't exist i would like it to include another file instead.
I have the following code which seems to work correctly, The only problem with my code is if the file does exist then it displays them both.
I would like to only include
include/article.php
if
include/'.$future.'.php
doesn't exist.
if
include/'.$future.'.php
exists i don't want to include
include/article.php
<?php
$page = $_GET['include'];
if (file_exists('include/'.$future.'.php')){
include('include/'.$future.'.php');
}
else{
include('include/article.php');
}
?>
Your variable $future was never even defined, so how is it ever being included? I think you meant for $page and $future to be the same variable. Also including a file specified by the user in a get request doesn't make much sense to begin with, but is probably also a security risk.
Perhaps this is what you need?
Make sure any variable you're going to use IS defined before you'll
use the variable...
<?php
$page = ''; // show emptyness is there is nothing dome below
$page = isset($_GET['include']); // Do you have a variable in your URL that IS called "include" and is the include variable set? for example: http://www.example.com/index.php?include=....... you might want to check for empty value and write a default value as well but I didn't here ;)
// REMEMBER: $future must be defined BEFORE this line!
if (file_exists('include/' . $future . '.php') && is_file('include/' . $future . '.php')){ // file exists on server: true/false and is it a file or a directory? If Directory it will NOT be included as I used is_file()!
include('include/' . $future . '.php');
}elseif{
(file_exists('include/article.php') && is_file('include/article.php')){
include 'include/article.php';
}else{
echo 'WOW, No article found! You just found a error...<br />We will repair all errors ASAP! Thank you for visiting us...';
}
?>

How to sequentially rename files in a folder using PHP?

I have files in a folder called 'thumbs'. They have names based on how they were named / renamed by their original authors. I would like to rename them to be two digit sequentially and I managed to find this PHP code:
function sequentialImages($path, $sort=false) {
$i = 1;
$files = glob($path."/{*.gif,*.jpg,*.jpeg,*.png}",GLOB_BRACE|GLOB_NOSORT);
if ( $sort !== false ) {
usort($files, $sort);
}
$count = count($files);
foreach ( $files as $file ) {
$newname = str_pad($i, strlen($count)+1, '0', STR_PAD_LEFT);
$ext = substr(strrchr($file, '.'), 1);
$newname = $path.'/'.$newname.'.'.$ext;
if ( $file != $newname ) {
rename($file, $newname);
}
$i++;
}
}
The php to execute this code is called 'rename.php' and it is found in a folder called 'admin'.
Therefore they are as follows
'admin' folder (contains rename.php')
'thumbs' folder (contains images with random names)
Both folders are on the same level.
How can I execute 'rename.php' if both are in different folders.
I tried to include $path = '../thumbs'; but it did not function.
Why isn't not working please?
I think I would start by checking if you're actually getting any errors reported at all. Since you're saying that you only get a blank page without any errors it could be as simple as enabling error reporting to see what actually goes wrong.
If, for instance, PHP doesn't have write access to the thumbs-folder you'll probably get a bunch of warnings when you try to rename the files. Check your php.ini and make sure that display_errors = On, run the script again and check if you get any helpful error messages.
Not sure if that helps you (or if display_errors is already set to on), but that would be the first step that I would try, which hopefully gives you a little more details about what's going wrong.
At the top of your function add:
if( !is_dir($path) ) {
die("error: $path is not a valid directory.");
// or whatever error handling method you prefer
}
If, for some reason, parent paths are disabled on your server, or if there is some other issue with the path, you will be notified here.
If that works fine, then step through your code and make sure that everything is as you expect it to be. eg: $files has the contents you expect, $newname is formatted properly, rename() is not returning false which indicates an error likely due to permissions, etc...
$path = realpath(__DIR__ . '/..') . '/thumbs';
realpath() function: http://php.net/manual/en/function.realpath.php
DIR (and other magic constants): http://php.net/manual/en/language.constants.predefined.php

Deleting files in higher directory

I'm having problems deleting a file from a higher directory, I found this post and tried it but no luck....:
gotdalife at gmail dot com 25-Sep-2008
02:04
To anyone who's had a problem with the
permissions denied error, it's
sometimes caused when you try to
delete a file that's in a folder
higher in the hierarchy to your
working directory (i.e. when trying to
delete a path that starts with "../").
So to work around this problem, you
can use chdir() to change the working
directory to the folder where the file
you want to unlink is located.
<?php
> $old = getcwd(); // Save the current directory
> chdir($path_to_file);
> unlink($filename);
> chdir($old); // Restore the old working directory ?>
here is the code that I currently have:
session_start();
if (!isset($_SESSION['agent']) OR ($_SESSION['agent'] !=md5($_SERVER['HTTP_USER_AGENT']))){
require_once ('includes/login_functions.inc.php');
$url = absolute_url();
header("Location: $url");
exit();
}
$folder = $_GET['folder'];
$filename = $_GET['name'];
$path = "../gallery/photos/$folder";
if (isset($_POST['submitted'])) {
if ($_POST['sure'] == 'Yes') {
$old = getcwd(); // Save the current directory
chdir($path);
unlink($filename);
chdir($old); // Restore the old working directory
}
else{
echo '<p>The photo has NOT been deleted.</p>';
}
}
I'm getting the error message :
Warning: unlink() [function.unlink]:
No error in
J:\xampp\htdocs\bunker\admin\delete_file.php
on line 37
line 37 being:
unlink($filename);
can anybody see what I've done wrong?
I always use absolute filepath names.
I'd define the filedir as a constant in your config, then concatenate so you have an absolute filepath, then make a call to unlink().
Btw: I hope you know your code is highly insecure.
See here:
http://bugs.php.net/bug.php?id=43511
and here
http://php.bigresource.com/Track-php-03TimDKO/
http://www.phpbuilder.com/board/showthread.php?t=10357994
Though I wouldnt recommend doing this, as per the comments above. Is there the option for a different approach?

Categories