我想在PHP中實現不區分大小寫的file_exists函數的最快方法。我最好的辦法是枚舉目錄中的文件並執行strtolower()到strtolower()比較,直到找到匹配項爲止?PHP案件不敏感版本file_exists()
回答
我用評論的來源來創建這個功能。如果找到則返回完整路徑文件,否則返回FALSE。
對文件名中的目錄名稱不區分大小寫。
function fileExists($fileName, $caseSensitive = true) {
if(file_exists($fileName)) {
return $fileName;
}
if($caseSensitive) return false;
// Handle case insensitive requests
$directoryName = dirname($fileName);
$fileArray = glob($directoryName . '/*', GLOB_NOSORT);
$fileNameLowerCase = strtolower($fileName);
foreach($fileArray as $file) {
if(strtolower($file) == $fileNameLowerCase) {
return $file;
}
}
return false;
}
總是返回完整的文件名不是很好嗎?當找到匹配時,有時會得到一個布爾值,有時候會是一條有用的路徑,這有點奇怪。 – 2010-10-19 06:15:15
如果文件不存在,你會返回什麼? O_o – Jonathan 2013-11-28 13:44:15
我認爲'fileExists'函數應該返回'true',如果文件存在:) – 2014-10-29 14:47:27
在Unix中,文件名是區分大小寫的,因此您將無法執行不區分大小寫的存在檢查而不列出目錄的內容。
對於純粹的PHP實現,是的。在the comments for the file_exists
function中有一個例子。
另一種選擇是在不區分大小寫的文件系統上運行腳本。
謝謝!在我的回答中結束了使用。 – 2010-10-19 02:31:34
您的方法有效。
或者,您可以使用glob
獲取陣列中當前工作目錄中的所有文件和目錄的列表,使用array_map
將strtolower
應用於每個元素,然後使用in_array
檢查您的文件(在應用strtolower
後)是否存在於陣列中。
當我們從IIS遷移到apache時,遇到了同樣的問題。下面是我鞭打的一塊。它將正確的路徑作爲字符串返回或爲false。
function resolve_path($path)
{
$is_absolute_path = substr($path, 0, 1) == '/';
$resolved_path = $is_absolute_path ? '/' : './';
$path_parts = explode('/', strtolower($path));
foreach ($path_parts as $part)
{
if (!empty($part))
{
$files = scandir($resolved_path);
$match_found = FALSE;
foreach ($files as $file)
{
if (strtolower($file) == $part)
{
$match_found = TRUE;
$resolved_path .= $file . '/';
}
}
if (!$match_found)
{
return FALSE;
}
}
}
if (!is_dir($resolved_path) && !is_file($resolved_path))
{
$resolved_path = substr($resolved_path, 0, strlen($resolved_path) - 1);
}
$resolved_path = $is_absolute_path ? $resolved_path : substr($resolved_path, 2, strlen($resolved_path));
return $resolved_path;
}
$relative_path = substr($_SERVER['REQUEST_URI'], 1, strlen($_SERVER['REQUEST_URI']));
$resolved_path = resolve_path($relative_path);
if ($resolved_path)
{
header('Location: http://' . $_SERVER['SERVER_NAME'] . '/' . $resolved_path);
die();
}
我提高了John Himmelman
的功能,並提出了這一點:
suppose that i have a catch system \iMVC\kernel\caching\fileCache
function resolve_path($path)
{
# check if string is valid
if(!strlen($path)) return FALSE;
# a primary check
if(file_exists($path)) return $path;
# create a cache signiture
$cache_sig = __METHOD__."@$path";
# open the cache file
$fc = new \iMVC\kernel\caching\fileCache(__CLASS__);
# check cache file and validate it
if($fc->isCached($cache_sig) && file_exists($fc->retrieve($cache_sig)))
{
# it was a HIT!
return $fc->retrieve($cache_sig);
}
# if it is ab
$is_absolute_path = ($path[0] == DIRECTORY_SEPARATOR);
# depart the path
$path_parts = array_filter(explode(DIRECTORY_SEPARATOR, strtolower($path)));
# normalizing array's parts
$path_parts = count($path_parts)? array_chunk($path_parts, count($path_parts)) : array();
$path_parts = count($path_parts[0])?$path_parts[0]:array();
# UNIX fs style
$resolved_path = $is_absolute_path ? DIRECTORY_SEPARATOR : ".";
# WINNT fs style
if(string::Contains($path_parts[0], ":"))
{
$is_absolute_path = 1;
$resolved_path = $is_absolute_path ? "" : ".".DIRECTORY_SEPARATOR;
}
# do a BFS in subdirz
foreach ($path_parts as $part)
{
if (!empty($part))
{
$target_path = $resolved_path.DIRECTORY_SEPARATOR.$part;
if(file_exists($target_path))
{
$resolved_path = $target_path;
continue;
}
$files = scandir($resolved_path);
$match_found = FALSE;
foreach ($files as $file)
{
if (strtolower($file) == $part)
{
$match_found = TRUE;
$resolved_path = $resolved_path.DIRECTORY_SEPARATOR.$file;
break;
}
}
if (!$match_found)
{
return FALSE;
}
}
}
# cache the result
$fc->store($target_path, $resolved_path);
# retrun the resolved path
return $resolved_path;
}
我調整功能更加律位。猜這更好的使用
function fileExists($fileName, $fullpath = false, $caseInsensitive = false)
{
// Presets
$status = false;
$directoryName = dirname($fileName);
$fileArray = glob($directoryName . '/*', GLOB_NOSORT);
$i = ($caseInsensitive) ? "i" : "";
// Stringcheck
if (preg_match("/\\\|\//", $fileName)) // Check if \ is in the string
{
$array = preg_split("/\\\|\//", $fileName);
$fileName = $array[ count($array) -1 ];
}
// Compare String
foreach ($fileArray AS $file)
{
if(preg_match("/{$fileName}/{$i}", $file))
{
$output = "{$directoryName}/{$fileName}";
$status = true;
break;
}
}
// Show full path
if($fullpath && $status)
$status = $output;
// Return the result [true/false/fullpath (only if result isn't false)]
return $status;
}
已經發現此頁面的快速谷歌我以前Kirk
的解決方案,但是它的速度慢,如果你把它放在同一個目錄多次,或在具有許多文件的目錄這是由於它每次遍歷所有的文件,所以我優化了一點:
function fileExists($fileName) {
static $dirList = [];
if(file_exists($fileName)) {
return true;
}
$directoryName = dirname($fileName);
if (!isset($dirList[$directoryName])) {
$fileArray = glob($directoryName . '/*', GLOB_NOSORT);
$dirListEntry = [];
foreach ($fileArray as $file) {
$dirListEntry[strtolower($file)] = true;
}
$dirList[$directoryName] = $dirListEntry;
}
return isset($dirList[$directoryName][strtolower($fileName)]);
}
我放棄了標誌檢查不區分大小寫,因爲我認爲你只是使用file_exists
如果你沒」 t需要這種行爲,所以國旗似乎是多餘的。我也希望如果你做的事情不是一個簡單的腳本,你想把它變成一個類,以更好地控制目錄列表緩存,例如,重置它,但這超出了我所需要的範圍,如果你需要它,這應該是微不足道的。
這個問題已經過了幾年了,但它與重複項相關,所以這裏是一個簡單的方法。
返回false
如果在任何情況下$filename
沒有在$path
或3210返回的第一個文件的實際文件名中發現,如果它在任何情況下被發現:
$result = current(preg_grep("/$filename$/i", glob("$path/*")));
取出current()
全部歸還匹配文件。這對於區分大小寫的文件系統很重要,因爲IMAGE.jpg
和image.JPG
都可以存在。
我的調整方案,獨立於操作系統,case-insensitive realpath()
替代,覆蓋整個路徑,命名爲realpathi()
:
/**
* Case-insensitive realpath()
* @param string $path
* @return string|false
*/
function realpathi($path)
{
$me = __METHOD__;
$path = rtrim(preg_replace('#[/\\\\]+#', DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR);
$realPath = realpath($path);
if ($realPath !== false) {
return $realPath;
}
$dir = dirname($path);
if ($dir === $path) {
return false;
}
$dir = $me($dir);
if ($dir === false) {
return false;
}
$search = strtolower(basename($path));
$pattern = '';
for ($pos = 0; $pos < strlen($search); $pos++) {
$pattern .= sprintf('[%s%s]', $search[$pos], strtoupper($search[$pos]));
}
return current(glob($dir . DIRECTORY_SEPARATOR . $pattern));
}
與水珠[nN][aA][mM][eE]
模式搜索文件名似乎是更快的解決方案
其他答案可能在大型文件系統(需要搜索大量文件)上非常耗費資源。創建一個包含所有文件名的臨時表(如有必要,請使用完整路徑)可能很有用。然後做一個類似的條件搜索該表以獲取任何實際情況。
SELECT actual_file_name
FROM TABLE_NAME
WHERE actual_file_name LIKE 'filename_i_want'
//will resolve & print the real filename
$path = "CaseInsensitiveFiLENAME.eXt";
$dir = "nameOfDirectory";
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if (strtolower($path) == strtolower($entry)){
echo $entry ;
}}
closedir($handle);
}
今天這個跨越剛跑,但不喜歡任何這裏的答案,所以我想我會加入我的解決方案(使用SPL和正則表達式迭代器)
function _file_exists($pathname){
try{
$path = dirname($pathname);
$file = basename($pathname);
$Dir = new \FilesystemIterator($path, \FilesystemIterator::UNIX_PATHS);
$regX = new \RegexIterator($Dir, '/(.+\/'.preg_quote($file).')$/i', \RegexIterator::MATCH);
foreach ($regX as $p) return $p->getPathname();
}catch (\UnexpectedValueException $e){
//invalid path
}
return false;
}
我使用它的方式是這樣的:
$filepath = 'path/to/file.php';
if(false !== ($filepath = _file_exists($filepath))){
//do something with $filepath
}
這樣它將使用內置的第一個,如果失敗它將使用ins並且將適當的外殼分配給$filepath
變量。
- 1. 蛋糕PHP案例不敏感查找
- 2. Mac上file_exists()的大小寫敏感度?
- 3. 案例敏感和不敏感像SQLite的
- 4. PHP不敏感取代
- 5. DB2案例敏感性
- 6. 版本敏感已廢棄屬性
- 7. Django:icontains案件對於unicode很敏感
- 8. 爲什麼MySQL是不是辦案敏感案件
- 9. UI選擇案例不敏感
- 10. Alfresco javascript搜索不敏感的案例
- 11. lucene案例不敏感排序搜索
- 12. 案例在軌道不敏感
- 13. 案例不敏感的替換(映射)
- 14. Array.indexOf不敏感
- 15. 如何製作不敏感的文本輸入案例?
- 16. 在Apache案例中使文件夾不敏感使用.htaccess
- 17. Diacritic敏感搜索PHP
- 18. 大寫敏感的php mac
- 19. AngularJS路由案例敏感性
- 20. XML元素案例敏感的問題
- 21. 如何使SqlCeCommand案例敏感?
- 22. 如何使案例在敏感的LINQ
- 23. vim的情況下,敏感不敏感的搜索替換
- 24. MonoDevelop的小部件不敏感StateType
- 25. PHP file_exists
- 26. Hiberate:HQL Case不敏感搜索
- 27. Gui變得不太敏感
- 28. 的tableview不那麼敏感
- 29. IOS case不敏感比較
- 30. AS3的replaceAll不敏感
事情是,file_exists不區分大小寫 – Dwza 2014-02-03 15:59:34
-1 - 這需要澄清。這是否適用於區分大小寫的文件系統。如果不是這樣,問題就是廢話,因爲PHP的'file_exists()'對大小寫不敏感的文件系統上的文件不區分大小寫。 – danorton 2014-03-28 19:54:24