为什么Windows需要为`file_get_contents`命名`utf8_decode`文件名?

如果$filename包含元音变音(ä,ö,ü), file_get_contents($filename)在我的Windows操作系统上不起作用。 通过试验和错误,我发现我需要做file_get_contents(utf8_decode($filename))才能正常工作。

但是,当我把这个活到我的服务器(猜测它是某种Linux)时,它又一次返回了一个错误,所以我删除了utf8_decode并突然发现它工作正常。

作为一个解决方法(所以我不需要手动改变这段代码每次我改变代码)我已经尝试

 (mb_detect_encoding($filename, 'UTF-8', true)) ? utf8_decode$filename) : $filename; 

因为这已经为相同的问题(相同的问题与utf8_encode )相同的问题,但$filename竟然是在每个(服务器)环境UTF8编码,所以这是行不通的,因为它总是如此。

任何想法如何得到这个在两个系统上工作? (请不要“只是迁移到Linux的PHP开发” – 我有Linux,但ATM我使用Windows的原因有很多)


编辑:问题也出现在fopen和接受的解决scheme也是如此。

Solutions Collecting From Web of "为什么Windows需要为`file_get_contents`命名`utf8_decode`文件名?"

最好的方法是检测是否使用Windows服务器。 从那里你可以应用正确的命令

 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { echo 'This is a server using Windows!'; } else { echo 'This is a server not using Windows!'; } 

问题是不支持UTF-8的文件名或目录名称,但Linux支持UTF-8在PHP 6这个问题解决了,为解决这个问题在当前版本的PHP我们可以做一些工作,如:

1)窗口支持UTF-16和linux这种Unicode没有任何问题我们可以保存所有的文件名和目录名在这个Unicode

2)编码UTF-8的urlencode ,这是解决这个问题的另一种方式,我推荐使用这个。

我写这个脚本来解决这个问题测试一下。

  function GetExt($sFileName)//ffilter { $sExt=""; $sTmp=$sFileName; while($sTmp!="") { $sTmp=strstr($sTmp,"."); if($sTmp!="") { $sTmp=substr($sTmp,1); $sExt=$sTmp; } } return ($sExt); } function LocatePath($Path='/',$Mode="rb",$Root="",$Open=true,$IsFile=false){//make real Path and create new Directory switch(strtolower($Mode)){ case 'r': $Read=true; $Write=false; $Create=false; break; case 'rb'://Open for reading only; place the file pointer at the beginning of the file. $Read=true; $Write=false; $Create=false; break; case 'r+'://Open for reading and writing; place the file pointer at the beginning of the file. $Read=true; $Write=true; $Create=false; break; case 'x'://Create and open for writing only; place the file pointer at the beginning of the file. If the file already exists, the open() call will fail by returning FALSE $Read=false; $Write=true; $Create=false; break; case 'wb': $Read=false; $Write=true; $Create=true; break; case 'ab': $Read=false; $Write=true; $Create=true; break; case 'w'://Open for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it. $Read=false; $Write=true; $Create=true; break; case 'w+'://Open for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it. $Read=true; $Write=true; $Create=true; break; case 'a'://Open for writing only; place the file pointer at the end of the file. If the file does not exist, attempt to create it. $Read=false; $Write=true; $Create=true; break; case 'a+'://Open for reading and writing; place the file pointer at the end of the file. If the file does not exist, attempt to create it. $Read=true; $Write=true; $Create=true; break; case 'x+'://Create and open for reading and writing; otherwise it has the same behavior as 'x'. $Read=true; $Write=true; $Create=true; break; case 'c'://Open the file for writing only. If the file does not exist, it is created. If it exists, it is neither truncated (as opposed to 'w'), nor the call to this function fails (as is the case with 'x'). The file pointer is positioned on the beginning of the file. $Read=false; $Write=true; $Create=true; break; case 'c+'://Open the file for reading and writing; otherwise it has the same behavior as 'c'. $Read=true; $Write=true; $Create=true; } $Path=str_replace("./",'/',trim($Path)); $Path=str_replace("../",'/',$Path); $Path=str_replace(".../",'/',$Path); $Path=ltrim($Path,'/'); if($Path==NULL or $Path=="")$Path="/"; $DOCUMENT_ROOT=$_SERVER['DOCUMENT_ROOT']; $FileRoot=$DOCUMENT_ROOT."/".$Root; $FileRoot=str_replace("\\",'/',$FileRoot); $FileRoot=rtrim(str_replace('//','/',$FileRoot),'/'); $TMkDir=0; $ISDir=true; $RelativePath=$Path; $Type=GetExt($FileRoot."/".$Path); if($Type!=""){ $FileName=basename($FileRoot."/".$Path); } $ParentDir=dirname($Path); $T=urlencode($FileRoot."/".$Path); $T=str_replace("%3A",':',$T); $T=str_replace("%2F",'/',$T); if(is_file($T)){ if($IsFile){ return array("ISDir"=>false,"Handle"=>false,"Path"=>$T,'FileName'=>$FileName,"Type"=>$Type,"RelativePath"=>$RelativePath,'ParentDir'=>$ParentDir,'Read'=>$Read,'Write'=>$Write); } $Handle=fopen($T,$Mode); return array("ISDir"=>false,"Handle"=>$Handle,"Path"=>$T,'FileName'=>$FileName,"Type"=>$Type,"RelativePath"=>$RelativePath,'ParentDir'=>$ParentDir,'Read'=>$Read,'Write'=>$Write); } if(is_dir($T)){ return array("ISDir"=>true,"Handle"=>NULL,"Path"=>$T,"RelativePath"=>$RelativePath,'ParentDir'=>$ParentDir,'Read'=>$Read,'Write'=>$Write); } $PathSplit=explode("/",$Path); if($Create==true){ try{ foreach($PathSplit as $PartDir){ $TPartDir=$PartDir; $PartDir=urlencode($PartDir); $Temp=$FileRoot."/".$PartDir; if(!is_file($Temp) and $TPartDir!=$FileName){ if(!is_dir($Temp)){ mkdir($Temp); } }else{ $ISDir=false; $Temp=$FileRoot."/".$FileName; $Handle=fopen($Temp,$Mode); $FileRoot=$FileRoot."/".$PartDir; break; } $FileRoot=$FileRoot."/".$PartDir; } }catch(Extension $e){ echo ($e); return false; } }else{ try{ foreach($PathSplit as $PartDir){ $TPartDir=$PartDir; $PartDir=urlencode($PartDir); $Temp=$FileRoot."/".$PartDir; if(!is_file($Temp) and $TPartDir!=$FileName){ if(!is_dir($Temp)){ return false; } }else{ $ISDir=false; $Handle=fopen($Temp,$Mode); $FileRoot=$FileRoot."/".$PartDir; break; } $FileRoot=$FileRoot."/".$PartDir; } }catch(Extension $e){ echo ($e); return false; } } if($Open!=true){//keep open Handle for User fclose($Handle); } return array("ISDir"=>$ISDir,"Handle"=>$Handle,"Path"=>$FileRoot,'FileName'=>$FileName,"Type"=>$Type,"Create"=>(!$ISDir)?true:false,"RelativePath"=>$RelativePath,'ParentDir'=>$ParentDir,'Read'=>$Read,'Write'=>$Write); } 

样品:

打开文件进行写入和读取,如果目录或文件不存在创建它。 1)

  print_r(LocatePath('/er/ert/aیgfسبd/ی.af',"w+")); 

返回一些像fopen句柄的信息

产量

 Array ( [ISDir] => [Handle] => Resource id #3 [Path] => F:/xampp/htdocs/er/ert/a%DB%8Cgf%D8%B3%D8%A8d/%DB%8C.af [FileName] => ی.af [Type] => af [Create] => 1 [RelativePath] => er/ert/aیgfسبd/ی.af [ParentDir] => er/ert/aیgfسبd [Read] => 1 [Write] => 1 ) 

2)打开文件如果不存在则返回false

  print_r(LocatePath('/er/ert/aیgfسبd/ی.af',"rb")); 

还有一些与FOPN相同的模式