2013-02-24 14 views
7

$filenameにウムラウト(ä、ö、ü)が含まれている場合、file_get_contents($filename)はWindows OSでは動作しません。試行錯誤の結果、私はfile_get_contents(utf8_decode($filename))を動作させる必要があることを知りました。なぜWindowsは `file_get_contents`が機能するためにファイル名を` utf8_decode`する必要がありますか?

しかし、このライブを私のサーバーにプッシュすると(それはLinuxのようなものだと思います)、もう一度エラーを返したので、utf8_decodeを削除して突然完全に機能しました。回避策として

(私は手動で自分でコードを変更するたびにコードのこの部分を変更する必要はありません)これは、すでに同じ問題のために他を働いたとして、私はすでに

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

を試してみました(utf8_encodeと同じ問題があった)が、すべての(サーバー)環境で$filenameがUTF8エンコードされていることが判明したため、これはうまくいかなかった。

これを両方のシステムで動作させる方法はありますか? (「ちょうどPHP開発のためのLinuxへの移行」ノーください-I'veは、Linuxを得たが、ATMは、私はいくつかの理由でWindowsを使用しています)


編集:問題はfopenでも表示され、受け入れソリューションも同様に動作します。

+1

あなたの最後の行は非常に魅力的です:) – swapnesh

+0

ファイル名に非ASCII文字を使用しないでください....いつも問題を引き起こします –

+0

私はドイツ語圏の人として、私はウムラウト(ファイル名としても機能します)。真剣に、これのための解決策はありませんか?この「プロジェクト」はそれほど複雑すぎるだろう。(それは私が取り組んでいる単純な単純なブログだ) – Peter

答えて

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!'; 
} 
+1

そのトリックをしました - ありがとうございます! – Peter

2

問題は、UTF-8は、PHP 6でこの問題が解決し、ファイル名やディレクトリ名が、LinuxのサポートのためにUTF-8をサポート、のためにこれを解決しない、ウィンドウのファイルシステムであります

1)ウィンドウのサポートUTF-16とLinuxは、我々は、このUnicodeで

をすべてのファイル名とディレクトリ名を保存することができたUnicodeのこの種のいずれかの問題がありませんがあります。私たちはのようないくつかの作業を行うことができますPHPの現在のバージョンで問題

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)読み取​​りのための オープンファイルのハンドルのようないくつかの情報が存在しない偽

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

といくつかを返す場合fopenと同じ別のモード

+0

この広範な答えはありがとうございますが、これは私の小さなブログのために過酷なものになると思います。 – Peter

+0

また、私は 'LocatePath()'のポイントがどんなものかも分かりません。それはあなたに情報の束を返します、確かに、私が気づいているものに渡すことができる形式ではありません。 – duskwuff

関連する問題