2014-04-28 79 views
1

我想要一個HTML表單來向用戶發送文件到我的服務器。我需要知道他開始發送這個文件的確切時間 - 而不是文件被接收的時間(我可以通過檢查服務器上的文件修改時間來檢查接收到的時間)。這段代碼應該這樣做 - 當點擊「提交」時,當前服務器時間應該寫入logsForSendingForm.txt,並且文件接收時間應該寫入logsForReceivedForm.txt。 不幸的是,發送文件時,只有接收到文件的時間被寫入到logsForReceivedForm.txt中 - 沒有任何內容寫入到logsForReceivedForm.txt中。 有趣的是,如果我不選擇任何文件並單擊提交,當前時間將寫入這兩個文件。檢查表單中提交文件的時間

如果你不知道如何調試這個,但你可以建議任何其他的解決方案(也許沒有AJAX),這也是可以的,我不需要像在這段代碼中那樣做。

<?php 

if (isset($_POST['tickStart'])) 
{ 
    file_put_contents('logsForSendingForm.txt', time() . "\n", FILE_APPEND); 
} 
elseif (!empty($_FILES)) 
{ 
    file_put_contents('logsForReceivedForm.txt', time() . "\n", FILE_APPEND); 
    $f = $_FILES['file']; 
    $patch = str_replace('index.php', '', $_SERVER['SCRIPT_FILENAME']); 
    copy($f['tmp_name'], $patch.$f['name']); 
} 

?><!DOCTYPE html> 
<html> 
    <head> 
     <script src='http://code.jquery.com/jquery-2.1.0.min.js'></script> 
     <script type='text/javascript'> 
       function sending() 
       { 
        $.ajax({ 
         url: 'index.php', 
         type: 'POST', 
         data: { tickStart: true } 
        }); 

        return true; 
       } 
     </script> 
    </head> 
    <body> 
     <form action='index.php' method='post' enctype='multipart/form-data'> 
      <input type='file' name='file'><br> 
      <input type='submit' name='submit' value='Submit' onsubmit="return sending()"> 
     </form> 
    </body> 
</html> 
+1

你就不能滑動VAR STARTIME =新的日期() ;在Ajax調用之前的某個地方,並將其傳遞給服務器? – TimSPQR

+0

@TimSPQR,這會從用戶的計算機傳遞時間,而不是服務器的時間,對嗎?我需要這是服務器時間,所以沒有人可以「欺騙」。 – user1809811

+0

因爲多個「同時」調用file_put_contents到同一個文件可能會破壞它,所以你將會遇到一個併發問題。 – denjello

回答

1

你需要對你的部分做更多的檢查,但這裏有一些簡單測試的代碼。我使用microtime()而不是時間,因爲對於小文件,我的localhost在秒數上沒有差別。例如,我還從here中投擲了一些東西來幫助告知用戶他們的文件太大了。你可能想要按照MIME類型捕捉,並通知他們...

我拋出了Jquery,因爲它看起來多餘。

如果(以及當)多個客戶端嘗試寫入日誌時,您仍然可能會收到損壞的文件。 (這就是爲什麼我添加| LOCK_EX標誌到你的追加。我沒有做任何負載測試,所以沒有保證。)數據庫???

否則,你可能還想做一些文件名規範化來擺脫非法/非ascii字符。但這是另一個在別處處理過的問題。

乾杯。

編輯: 時間:0.084668874740601(用於在本地主機上一個23MB文件) 時間:0.0021710395812988(對於74K文件在本地主機上)

<?php 
    if (isset($_POST['tickStart'])) 
    { 
     // this is the moment the script began 
     $mtime1=$_SERVER['REQUEST_TIME_FLOAT']; 
     $log = 'sent: ' . $mtime1; 
    } 
    if(isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) == 'post' && $_FILES['file']['size'] == 0){ 
     $postMax = ini_get('post_max_size'); 
     $fileMax = ini_get('upload_max_filesize'); 
     $message = "Max filesize: $fileMax<br>Max postsize: $postMax"; 
     $log = 'file too large'; 
    } 
     elseif (!empty($_FILES) && !empty($_POST) && $_FILES['file']['size'] > 0) 
    { 
     $f = $_FILES['file']; 
     $patch = str_replace('index.php', '', $_SERVER['SCRIPT_FILENAME']); 
     copy($f['tmp_name'], $patch.$f['name']); 
     // this is the time NOW 
     $mtime2=microtime(true); 
     file_put_contents('logsForSendingForm.txt', $mtime1 . "\n", FILE_APPEND | LOCK_EX); 
     file_put_contents('logsForReceivedForm.txt', $mtime2 . "\n", FILE_APPEND | LOCK_EX); 
     $duration = $mtime2 - $mtime1; 
     $log = $log . '\nduration: '.$duration; 
     $message = $f['name'].' uploaded.'; 
    } 
     else 
    { 
     $log = 'no file selected'; 
     $message = 'Please choose a file.'; 
    } 

?> 
<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
     <script type='text/javascript'> 
      console.log('<?php print $log ?>'); 
     </script> 
    </head> 
    <body> 
     <form action='index.php' enctype='multipart/form-data' method='POST'> 
      <input type='file' name='file'><br> 
      <input type='hidden' value='true' name='tickStart'> 
      <input type='submit' name='submit' value='Submit'> 
     </form> 
     <h2> 
     <?php print $message; ?> 

     </h2> 
    </body> 
</html> 
+0

不起作用...該文件上傳了大約30秒,但發送時間和rcvd時間之間的差異爲0.001,它在上傳此文件後只檢查了兩次。我認爲它不起作用,因爲這個隱藏的輸入是在文件發送完成的同時發送的。 – user1809811

+0

順便說一句,你真的應該使用你的上傳系統的東西,就像這裏的答案:http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously-with-jquery?rq= 1 – denjello

+0

如果更改適用於您,則應將此問題標記爲已回答。 – denjello