7

如果$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,但出于多种原因我使用 Windows 的 ATM)


编辑:问题也出现了,fopen并且接受的解决方案也有效。

4

2 回答 2

3

最好的方法是检测您是否使用 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!';
}
于 2013-02-24T19:14:50.010 回答
3

问题是对于不支持文件名或目录名的 UTF-8 但 Linux 在 php 6 中支持 UTF-8 的窗口文件系统,这个问题解决了,为了在当前版本的 php 中解决这个问题,我们可以做一些工作,例如:

1) window 支持 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")); 

以及与 fopen 相同的另一种模式

于 2013-02-24T19:48:27.650 回答