2010-09-08 77 views
9

我在我的開發機器上遇到了一個問題,它似乎與本機隔離,我無法弄清楚。 我有一個jQuery文件上傳器,它將用戶選擇的文件發佈到PHP腳本以使用XmlHttpRequest進行處理。這個腳本在運行帶有MAMP 1.9的OSX10.6.3的MacBook Pro上工作的很好,但是在我的iMac上使用完全相同的操作系統和版本的MAMP,並且具有相同的服務器映像時,它會失敗。

我已經追溯到屬性$_SERVER["CONTENT_LENGTH"]返回 0的錯誤原因,即使我可以得到文件名就好了,其他所有內容似乎都成功了請求。由於某種原因,它似乎不會給我實際的內容長度。這裏是導致問題的代碼 - 有問題的函數是getSize()

class qqUploadedFileXhr { 
    /** 
    * Save the file to the specified path 
    * @return boolean TRUE on success 
    */ 
    function save($path) {  
     $input = fopen("php://input", "r"); 
     $temp = tmpfile(); 
     $realSize = stream_copy_to_stream($input, $temp); 
     fclose($input); 

     if ($realSize != $this->getSize()){    
      return false; 
     } 

     $target = fopen($path, "w");   
     fseek($temp, 0, SEEK_SET); 
     stream_copy_to_stream($temp, $target); 
     fclose($target); 

     return true; 
    } 
    function getName() { 
     return $_GET['qqfile']; 
    } 
    function getSize() { 
     if (isset($_SERVER["CONTENT_LENGTH"])){ 
      return (int)$_SERVER["CONTENT_LENGTH"]; //*THIS* is returning 0    
     } else { 
      throw new Exception('Getting content length is not supported.'); 
     }  
    } 
} 
+0

是否還有其他遺漏?您是否嘗試過print_r($ _ SERVER)和print_r($ _ POST)以查看腳本正在接收的所有字段? – Jhong 2010-09-08 03:58:49

+0

print_r'ing這給了我大量的字段,包括正確的查詢字符串,腳本標題和位置等。有什麼特別的我應該找?由於字符太多,我無法將整個響應粘貼到此處。 – Sam 2010-09-08 04:53:15

回答

3

您是否將您的編碼類型設置爲multipart/form-data

<form action="upload.php" method="post" enctype="multipart/form-data"> 
    ... 
    <input type="file" ... /> 
    ... 
</form> 
+0

是的,這是由jQuery插件處理,並且編碼是正確的。 – Sam 2010-09-08 04:20:47

6

解決了!似乎我使用的jQuery腳本在firefox 3.5.x下失敗,我更新到3.6.9並且工作正常。

現在我必須找到一些方法來使其與舊版本的Firefox的向後兼容。

0

我使用相同的插件,即使使用舊版本的瀏覽器,最新版本似乎也能正常工作。我仍然對IE6和IE7有一些顯示/渲染問題,但我通過使按鈕不透明並添加圖像來解決這些問題。我也將接收的PHP腳本修改爲一個函數而不是多個函數。並不適合所有的場合,但它工作正常,我對所有的瀏覽器:

public function web_upload_file_ajax(){ 
    $return    = array(); 
    $uploaded_file  = array('name'=>'', 'size'=>0); 
    // list of valid extensions, ex. array("jpeg", "xml", "bmp") 
    $allowedExtensions = array('jpg', 'jpeg', 'png', 'gif', 'bmp','txt','csv'); 
    // max file size in bytes 
    $sizeLimit   = 3 * 1024 * 1024; 
    //folder to upload the file to - add slash at end 
    $uploadDirectory = TMPPATH.'tmp_upload'.DIRECTORY_SEPARATOR; 
    if(!is_dir($uploadDirectory)){ 
     @mkdir($uploadDirectory, 0766, true); 
    } 
    if(!is_dir($uploadDirectory)){ 
     $return   = array('error' => 'Server error. Impossible to create the cache folder:'.$uploadDirectory); 
    }elseif(!is_writable($uploadDirectory)){ 
     $return   = array('error' => 'Server error. Upload directory is not writable.'); 
    } else { 
     $postSize   = $this->bytes_to_num(ini_get('post_max_size')); 
     $uploadSize   = $this->bytes_to_num(ini_get('upload_max_filesize')); 

     if ($postSize < $sizeLimit || $uploadSize < $sizeLimit){ 
      $size = max(1, $sizeLimit/1024/1024) . 'M'; 
      $return = array('error' => 'increase post_max_size and upload_max_filesize to '.$size); 
     }elseif (isset($_GET['qqfile'])) { 
      $uploaded_file['name'] = $_GET['qqfile']; 
      if (isset($_SERVER['CONTENT_LENGTH'])){ 
       $uploaded_file['size'] = (int)$_SERVER['CONTENT_LENGTH']; 
      } else { 
       $return = array('error'=>'Getting content length is not supported.'); 
      } 
     } elseif (isset($_FILES['qqfile'])) { 
      $uploaded_file['name'] = $_FILES['qqfile']['name']; 
      $uploaded_file['size'] = $_FILES['qqfile']['size']; 
     } else { 
      $return = array('error' => 'No files were uploaded.'); 
     } 
     if(count($return)==0){ 
      if($uploaded_file['size'] == 0)       $return = array('error' => 'File is empty'); 
      elseif($uploaded_file['size'] > $sizeLimit)    $return = array('error' => 'File is too large'); 
      elseif($uploaded_file['name']!=''){ 
       $pathinfo = pathinfo($uploaded_file['name']); 
       $filename = $pathinfo['filename']; 
       $ext  = $pathinfo['extension']; 
       if($allowedExtensions && !in_array(strtolower($ext), $allowedExtensions)){ 
        $return = array('error' => 'File has an invalid extension, it should be one of '.implode(', ', $allowedExtensions).'.'); 
       } 
      } 
     } 
     if(count($return)==0){ 
      // overwrite previous files that were uploaded 
      $filename = ll('sessions')->get_id(); 

      // don't overwrite previous files that were uploaded 
      while (file_exists($uploadDirectory.$filename.'.'.$ext)) { 
       $filename .= rand(10, 99); 
      } 

      $saved = false; 
      $path = $uploadDirectory.$filename.'.'.$ext; 
      if (isset($_GET['qqfile'])) { 
       $input  = fopen('php://input', 'r'); 
       $temp  = tmpfile(); 
       $realSize = stream_copy_to_stream($input, $temp); 
       fclose($input); 

       if ($realSize != $uploaded_file['size']){ 
        $saved = false; 
       } else { 
        $target = fopen($path, 'w'); 
        fseek($temp, 0, SEEK_SET); 
        stream_copy_to_stream($temp, $target); 
        fclose($target); 
        $saved = true; 
       } 
      } else { 
       if(!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)){ 
        $saved = false; 
       } 
       $saved = true; 
      } 
      if ($saved){ 
       $return = array('success'=>true, 'file'=>$filename.'.'.$ext); 
      } else { 
       $return = array('error'=> 'Could not save uploaded file. The upload was cancelled, or server error encountered'); 
      } 
     } 
    } 
    // to pass data through iframe you will need to encode all html tags 
    echo htmlspecialchars(json_encode($return), ENT_NOQUOTES); 
} 

,這裏是我作爲一個輔助函數使用bytes_to_num,但你可以包括在同一個函數這個問題,以及如果你想:

/** 
* This function transforms bytes (like in the the php.ini notation) for numbers (like '2M') to an integer (2*1024*1024 in this case) 
*/ 
public function bytes_to_num($bytes){ 
    $bytes = trim($bytes); 
    $ret = $bytes+0; 
    if($ret==0 || strlen($ret)>=strlen($bytes)){ 
     return $ret; 
    } 
    $type = substr($bytes, strlen($ret)); 
    switch(strtoupper($type)){ 
     case 'P': 
     case 'Pb': 
      $ret *= 1024; 
     case 'T': 
     case 'Tb': 
      $ret *= 1024; 
     case 'G': 
     case 'Gb': 
      $ret *= 1024; 
     case 'M': 
     case 'Mb': 
      $ret *= 1024; 
     case 'K': 
     case 'Kb': 
      $ret *= 1024; 
      break; 
    } 
    return $ret; 
} 
0
$headers = apache_request_headers(); 
echo $headers['Content-Length']; 

我會認爲這其中也返回0?

3

可能正在使用分塊編碼,它不會發送內容長度。

相關問題