Как проверить, существует ли файл без расширения в PHP?

Я не хочу указывать в ссылке расширение файла ".php". Но когда я это делаю, я не могу успешно проверить, существует ли файл, указанный в ссылке, или нет. Это связано с тем, что встроенная в PHP функция "file_exists" учитывает расширение .php. И даже это не работает:

файл_существует($файл.".php");

В любом случае, есть ли способ выполнить следующую работу, не указывая расширение php в ссылках html:

<a href="?file=dude">Some File</a>

<?php

$file = $_GET['file'];

if(file_exists($file.".php"))
{
     include($file.".php");
}
else
     include("404.php");


?>

person Johny    schedule 08.02.2010    source источник
comment
Предполагая, что $file.php доступен в include_path или существует в том же каталоге, что и запущенный скрипт, ваш код должен работать.   -  person Kevin    schedule 08.02.2010


Ответы (4)


Ваш пример должен работать нормально (Я снова удалил предыдущий, как в EDIT 2), при условии, что файл находится в текущем рабочем каталоге (с этого момента я буду сокращать его до cwd).

EDIT
Извините, о чем я думал. Ваш пример, конечно, не работает, потому что file_exists() должен быть указан полный путь к файлу. Поэтому добавьте к файлу каталог, из которого вы хотите извлечь файлы. Тем не менее, мое предупреждение о санации, внесении в белый список и т. д. остается в силе.
КОНЕЦ РЕДАКТИРОВАНИЯ

РЕДАКТИРОВАТЬ 2
Ничего себе, извините, я сильно напортачил. file_exists() должно нормально работать с относительными путями. Глядя на документацию, она предупреждает об ограничениях безопасного режима. Возможно, это применимо к вашей ситуации, я не знаю.
КОНЕЦ РЕДАКТИРОВАНИЯ 2

Вы можете проверить, что такое cwd с помощью getcwd(). При нормальных обстоятельствах cwd совпадает с точкой входа вашего приложения. Итак, если, например, /usr/www/your_site_root/index.php — это точка входа, то /usr/www/your_site_root/ — это cwd.

Поэтому файлы, которые вы пытаетесь включить в свои примеры, должны находиться в указанном каталоге.

Небольшой совет:
Возможно, вы уже знаете об этом, но ваш пример не очень безопасен. Вы никоим образом не очищаете ввод от пользователя (в данном случае $_GET[ 'file' ]). Таким образом, посетитель сможет включать все виды файлов php с нежелательными результатами.

Поэтому я советую вам вести белый список файлов, которые разрешено загружать. Что-то типа:

<?php

$whiteList = array(
    'dude',
    'chick',
    'mom'
);

// and just to be safe, you should probably strip stuff like ../ etc. here too.
$requestedFileBaseName = $_GET[ 'file' ];

if( !in_array( $requestedFileBaseName, $whileList ) )
{
    include( '404.php' );
}
else
{
    include( $requestedFileBaseName . '.php' );
}
person Decent Dabbler    schedule 08.02.2010
comment
Уверены ли вы? Я только что протестировал file_exists() локально, и он работает без полного пути. - person Kevin; 08.02.2010
comment
@Kevin: да, это была оплошность с моей стороны, извини. Я тоже проверил это на себе, и это действительно работает. Спасибо, что указали на это в любом случае. - person Decent Dabbler; 08.02.2010
comment
«чувак», «телка», «мама». Звучит как вечеринка. - person Scarface; 05.07.2011

Попробуйте переписать URL, добавьте это в свой файл .htaccess:

RewriteCond %{DOCUMENT_ROOT}/$1.php -f 
RewriteRule ^/(([^/]+/)*[^.]+)$ /$1.php [L]
person David Aleu    schedule 08.02.2010

Используйте функцию PHP glob, чтобы предотвратить указание расширения .php. Однако это может привести к проблемам с безопасностью:

http://ar2.php.net/glob

glob($file . ".*")
person Johnco    schedule 08.02.2010

использовать :

$file = dirname(__FILE__).'/../relativepathfromcurrentscript/'.$_GET['file'].'.php';
person useless    schedule 08.02.2010