2013-02-24 9 views
7

Se $filename contiene dieresi (ä, ö, ü) file_get_contents($filename) non funziona sul mio sistema operativo Windows. Per tentativi ed errori ho scoperto che devo fare file_get_contents(utf8_decode($filename)) per farlo funzionare.Perché Windows ha bisogno di nomi di file `utf8_decode` per` file_get_contents` per funzionare?

Tuttavia, quando ho trasmesso questo live al mio server (suppongo che sia una specie di Linux) ha restituito un errore di nuovo, così ho rimosso il utf8_decode e improvvisamente ha funzionato perfettamente.

Come una soluzione (quindi non c'è bisogno di cambiare questo pezzo di codice manualmente ogni volta che apportare modifiche al codice) già provato

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

poiché già lavorato per lo stesso problema all'altro way round (aveva lo stesso problema con utf8_encode), ma $filename si è rivelato codificato in UTF8 in ogni ambiente (server), quindi questo non funziona, come è sempre vero.

Qualche idea su come farlo funzionare su entrambi i sistemi? (Si prega di non "solo la migrazione a Linux per lo sviluppo di PHP" -Ho ottenuto Linux, ma bancomat sto usando Windows per una serie di motivi)


Edit: il problema appare anche con fopen e accettato anche la soluzione funziona.

+1

le tue ultime righe sono molto accattivanti :) – swapnesh

+0

Non usare caratteri non ASCII nei nomi di file .... causa sempre problemi –

+0

Temo che, come un essere di lingua tedesca, io abbia l'abitudine di usare dieresi in titoli (che a loro volta fungono da nomi di file). No sul serio, non c'è una soluzione per questo? Questo "progetto" sarebbe così complicato in altro modo (ed è solo un blog super semplice su cui sto lavorando) – Peter

risposta

3

Il modo migliore sarebbe quello di rilevare se si utilizza il server Windows o meno. Da che è possibile applicare il comando giusto

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

che ha fatto il trucco, grazie mille! – Peter

2

il problema è per il file system finestra che non supporta UTF-8 per il nome del file o il nome dir ma il supporto Linux UTF-8 in php 6 questo problema risolto, per risolvere questo problema nella versione attuale di PHP che possiamo fare un certo lavoro, come:

1) supporto finestra UTF-16 e Linux non ha alcun problema con questo tipo di Unicode siamo in grado di salvare tutti il ​​nome del file e il nome della directory in questo Unicode

2) urlencode che codifica UTF-8, questo è un altro modo per risolvere questo problema ho raccomandato di usarlo.

ho scritto questo script per risolvere questo problema testarlo.

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); 
} 

campione:

file aperto per scrittura e lettura se directory o file non esiste crearla. 1)

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

ritorno alcune informazioni come la maniglia di fopen

uscita

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) file aperto per leggere se non esiste return false

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

e un po ' un'altra modalità uguale a fopen

+0

grazie mille per questa risposta esauriente, ma immagino che sarebbe una sorta di esagerazione per il mio piccolo blog. – Peter

+0

Inoltre, non sono sicuro di quale sia il punto di 'LocatePath()'. Ti restituisce un sacco di informazioni, certo, ma non è in un formato che puoi trasmettere a qualcosa di cui sono a conoscenza. – duskwuff

Problemi correlati