问题出在Windows文件系统不支持UTF-8的文件名或目录名,但Linux在php 6中支持UTF-8,因此这个问题得到了解决。为了解决当前版本的php中的这个问题,我们可以进行一些工作,例如:
1)Windows支持UTF-16,Linux对这种Unicode没有任何问题,我们可以将所有文件名和目录名保存为这种Unicode格式。
2)使用urlencode编码UTF-8,这是另一种解决此问题的方法,我建议使用这种方法。
我编写了这个脚本来解决这个问题,请测试它。
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
[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相同的模式