Tôi đang cố gắng nghĩ cách nhanh nhất để triển khai hàm file_exists không phân biệt dạng chữ trong PHP. Tôi có đặt cược tốt nhất để liệt kê tệp trong thư mục và thực hiện một phép so sánh strtolower() với strtolower() cho đến khi tìm thấy một kết quả phù hợp không?Phiên bản PHP không phân biệt chữ hoa chữ thường của file_exists()
Trả lời
Tôi đã sử dụng nguồn từ nhận xét để tạo chức năng này. Trả về tệp đường dẫn đầy đủ nếu được tìm thấy, FALSE nếu không.
Không hoạt động không phân biệt chữ hoa chữ thường trên tên thư mục trong tên tệp.
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;
}
Sẽ không hay khi LUÔN trả lại tên đầy đủ? Thật kỳ lạ khi đôi khi có được một con đường boolean và đôi khi là một con đường hữu ích khi tìm thấy một trận đấu. –
bạn sẽ trả lại gì nếu tệp không tồn tại? O_o – Jonathan
Tôi nghĩ rằng 'fileExists' chức năng nên trả về' true', nếu tập tin tồn tại :) –
Trong tên tệp Unix phân biệt chữ hoa chữ thường, vì vậy bạn sẽ không thể thực hiện kiểm tra sự tồn tại phân biệt chữ hoa chữ thường mà không liệt kê nội dung của thư mục.
Để thực hiện PHP thuần túy, có. Có một ví dụ trong the comments for the file_exists
function.
Tùy chọn khác sẽ là chạy tập lệnh của bạn trên hệ thống tệp phân biệt chữ hoa chữ thường.
Cảm ơn! Kết thúc bằng cách sử dụng điều này trong câu trả lời của tôi. –
Cách tiếp cận của bạn hoạt động.
Hoặc bạn có thể sử dụng glob
để lấy danh sách tất cả các tệp và thư mục trong thư mục làm việc hiện tại trong một mảng, sử dụngđể áp dụng strtolower
cho từng phần tử và sau đó sử dụng in_array
để kiểm tra xem tệp của bạn (sau khi áp dụng strtolower
) tồn tại trong mảng .
Tôi gặp sự cố tương tự khi chúng tôi di chuyển từ IIS sang apache. Dưới đây là phần tôi đánh lên. Nó trả về một trong hai đường dẫn đúng như một chuỗi hoặc sai.
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();
}
tôi đã được cải thiện chức năng John Himmelman
's và đưa ra với điều này:
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;
}
tôi điều chỉnh chức năng hơn một chút lil. đoán này tốt hơn để sử dụng
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;
}
Sau khi tìm thấy trang này từ một google nhanh chóng tôi đã sử dụng giải pháp Kirk
's, tuy nhiên nó là chậm nếu bạn gọi nó nhiều lần trên cùng một thư mục, hoặc trên một thư mục có nhiều file trong . Điều này là do nó Looping trên tất cả các tập tin mỗi lần, vì vậy tôi tối ưu hóa nó một chút:
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)]);
}
anh đã đánh rơi lá cờ để kiểm tra các trường hợp vô hồn như tôi giả sử bạn muốn chỉ cần sử dụng file_exists
nếu bạn trai tôi' t cần hành vi này, vì vậy lá cờ dường như dư thừa. Tôi cũng hy vọng rằng nếu bạn đang làm bất cứ điều gì ngoài một kịch bản tầm thường, bạn muốn biến điều này thành một lớp để kiểm soát nhiều hơn bộ đệm ẩn danh sách thư mục, ví dụ: đặt lại nó, nhưng đó là vượt ra ngoài phạm vi của những gì tôi cần và nó sẽ là tầm thường để làm gì nếu bạn cần nó.
Câu hỏi này là một vài năm tuổi nhưng nó được liên kết với các bản sao nên đây là một phương pháp đơn giản.
Returns false
nếu $filename
trong mọi trường hợp không tìm thấy trong các $path
hoặc tên tập tin thực tế của các tập tin đầu tiên được trả về bởi glob()
nếu nó đã được tìm thấy trong mọi trường hợp:
$result = current(preg_grep("/$filename$/i", glob("$path/*")));
Tháo current()
trả lại tất cả các tệp phù hợp. Điều này rất quan trọng đối với các hệ thống tệp phân biệt chữ hoa chữ thường là IMAGE.jpg
và image.JPG
đều có thể tồn tại.
My giải pháp điều chỉnh, hệ điều hành độc lập, case-insensitive realpath()
thay thế, bao gồm cả con đường, mang tên 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));
}
tìm kiếm tên tập tin với glob [nN][aA][mM][eE]
mẫu dường như là giải pháp nhanh hơn
Những câu trả lời khác có thể được rất nhiều nguồn lực trên hệ thống tập tin lớn (số lượng lớn các tập tin để tìm kiếm thông qua). Nó có thể hữu ích để tạo ra một bảng tạm thời của tất cả các tên tập tin (đường dẫn đầy đủ nếu cần thiết). Sau đó thực hiện tìm kiếm điều kiện giống như bảng đó để nhận được bất kỳ trường hợp thực tế nào.
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);
}
Chỉ cần chạy ngang qua ngày hôm nay, nhưng không giống như bất kỳ các câu trả lời ở đây, vì vậy tôi nghĩ tôi sẽ thêm giải pháp của tôi (sử dụng SPL và iterator regex)
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;
}
Cách tôi đang sử dụng nó giống như vậy:
$filepath = 'path/to/file.php';
if(false !== ($filepath = _file_exists($filepath))){
//do something with $filepath
}
Bằng cách này, nó sẽ sử dụng được xây dựng trước, nếu không sử dụng được một cách chính xác, và gán cho vỏ thích hợp với biến số $filepath
.
- 1. URL không phân biệt chữ hoa chữ thường với mod_rewrite
- 2. Không phân biệt chữ hoa chữ thường không hoạt động
- 3. Trường hợp Rspec không phân biệt chữ hoa chữ thường
- 4. Biến Bash: phân biệt chữ hoa chữ thường hay không?
- 5. Tìm kiếm không phân biệt chữ hoa chữ thường SOLR
- 6. Hàm in_array không phân biệt chữ hoa chữ thường
- 7. không phân biệt chữ hoa chữ thường trong NSArray chứaObject:
- 8. Tên tệp không phân biệt chữ hoa chữ thường?
- 9. Tên bảng có phân biệt chữ hoa chữ thường không?
- 10. Không phân biệt chữ hoa chữ thường với Dynamic Linq
- 11. XML có phân biệt chữ hoa chữ thường không?
- 12. Java có phân biệt chữ hoa chữ thường không?
- 13. GetElementsByTagName không phân biệt chữ hoa chữ thường?
- 14. GetMethod không phân biệt chữ hoa chữ thường?
- 15. Đường dẫn XML - không phân biệt chữ hoa chữ thường
- 16. không phân biệt chữ hoa chữ thường số
- 17. Thay thế không phân biệt chữ hoa chữ thường
- 18. khớp với phân biệt chữ hoa chữ thường trong xpath?
- 19. AngularJs, bộ lọc phân biệt chữ hoa chữ thường
- 20. Danh sách phân biệt chữ hoa chữ thường
- 21. DISTINCT MySQL phân biệt chữ hoa chữ thường
- 22. GSON deserialize theo cách phân biệt chữ hoa chữ thường
- 23. Đối sánh phân biệt chữ hoa chữ thường trong Marpa
- 24. Mảng phân biệt chữ hoa chữ thường trong Lua
- 25. Kết hợp mẫu Lua phân biệt chữ hoa chữ thường
- 26. Tìm kiếm danh sách phân biệt chữ hoa chữ thường
- 27. Loại.Không phân biệt chữ hoa chữ thường - WinRT
- 28. Chạy truy vấn cypher phân biệt chữ hoa chữ thường
- 29. JavaScript: tìm kiếm phân biệt chữ hoa chữ thường
- 30. OData và phân biệt chữ hoa chữ thường
vấn đề là, file_exists IS phân biệt chữ hoa chữ thường – Dwza
-1 - điều này cần làm rõ. Đây có phải là hệ thống tệp phân biệt chữ hoa chữ thường hay không. Nếu không, câu hỏi là vô nghĩa, vì 'file_exists()' của PHP không phân biệt dạng chữ cho các tệp trên các hệ thống tệp phân biệt chữ hoa chữ thường. – danorton