我知道這個標題有點奇怪,但我會到達那裏。在使用ajax和PHP獲取最新文件時避免部分上傳文件(通過FTP)
我有一臺相機連接到筆記本電腦。使用遙控拍攝,當攝影師拍攝照片時,將其保存到筆記本電腦硬盤上的文件夾中。在文件夾上設置了一個Automator(Mac OS X)操作,無論何時出現新文件,它都會調整其大小並使用傳輸將其上傳到FTP。
這裏就是代碼進來。
我有顯示拍攝的最新照片的網頁。它使用ajax重複檢查是否上傳了新文件,如果有,請加載新照片並用舊照片交叉淡入淡出。這是在頁面上運行的Javascript。
(function() {
var delay, refreshLoop;
// Alias to setTimeout that reverses the parameters, making it much cleaner in code (for CoffeeScript)
delay = function(time, callback) {
return setTimeout(callback, time);
};
// Function that drives the loop of refreshing photos
refreshLoop = function(currentFolderState, refreshRate) {
// Get the new folder state
$.get("ajax/getFolderState.php", function(newFolderState) {
// If the new folder state is different
if (newFolderState !== currentFolderState) {
// Get the newest photo
$.get("ajax/getNewestPhoto.php", function(photoFilename) {
var img;
// Create the new image element
img = $('<img class="new-photo"/>')
// Append the src attribute to it after so it can BG load
.attr('src', "/events/mindsmack/booth/cinco-de-mindsmack-2012/" + photoFilename)
// When the image is loaded
.load(function() {
// Append the image to the photos container
$('#photos').append(img);
// Crossfade it with the old photo
$('#photos .current-photo').fadeOut();
$('#photos .new-photo').fadeIn().removeClass("new-photo").addClass("current-photo");
});
});
}
// Wait for the refresh rate and then repeat
delay(refreshRate, function() {
refreshLoop(newFolderState, refreshRate);
});
});
};
// Document Ready
$(function() {
var refreshRate;
// Load the first photo
$.get("ajax/getNewestPhoto.php", function(photoFilename) {
$('#photos').append("<img src='/events/mindsmack/booth/cinco-de-mindsmack-2012/" + photoFilename + "' class='current-photo' />");
});
refreshRate = 2000;
// After the timeout
delay(refreshRate, function() {
// Get the initial folder state and kick off the loop
$.get("ajax/getFolderState.php", function(initialFolderState) {
refreshLoop(initialFolderState, refreshRate);
});
});
});
}).call(this);
這裏是兩個PHP文件被稱爲在使用Javascript
getFolderState.php
<?php
$path = $_SERVER['DOCUMENT_ROOT'] . "/events/mindsmack/booth/cinco-de-mindsmack-2012/";
// Get a directory listing of the path where the photos are stored
$dirListing = scandir($path);
// Echo an md5 hash of the directory listing
echo md5(serialize($dirListing));
getNewestPhoto.php
<?php
$path = $_SERVER['DOCUMENT_ROOT'] . "/events/mindsmack/booth/cinco-de-mindsmack-2012/";
// Get a directory listing of the path where the photos are stored
$listing = scandir($path);
$modTime = 0;
$mostRecent = "";
// Find the most recent file
foreach ($listing as $file) {
if (is_file($path.$file) && $file !== ".DS_Store" && filectime($path.$file) > $modTime) {
$modTime = filectime($path.$file);
$mostRecent = $file;
}
}
// Echo the most recent filename
echo $mostRecent;
所有這些作品大多完美。我相信問題是當文件處於上傳過程中時,循環被觸發。偶爾會拍攝一張照片,它只會在頁面中間顯示。一個錯誤不會被拋出,腳本繼續運行得很好,並且圖像文件實際上被緩存在該狀態中,這導致我相信我的代碼正在捕獲正在進行的文件上載,並且只顯示文件的一部分那個時候已經上傳了。
我不介意改變我的解決方案,如果我需要爲了克服這個問題,我只是不知道該怎麼做。
編輯
一種按照下面的建議之一,我再次添加代碼,以我的getNewestPhoto.php,檢查照片的文件大小,等待了一下,並檢查它。如果它們不同,則返回並再次檢查,直到文件大小相同。我希望這可以捕獲上傳的文件,因爲文件大小會在循環之間變化,但即使照片部分渲染,文件大小檢查也無法捕捉到。
這是我加入
$currFilesize = filesize($path . $mostRecent);
$newFilesize;
while (true) {
sleep(.5);
$newFilesize = filesize($path . $mostRecent);
if ($newFilesize == $currFilesize) {
break;
}
else {
$currFilesize = $newFilesize;
}
}
我想(通過另一個建議),我需要添加某種對上傳鎖定的文件,它從清涼的照片停止碼,並且當移除代碼上傳完成,但看到我沒有在連接到相機的計算機上運行任何類型的Web服務器,我不知道如何實現這一點。我很樂意提出建議。
除非您可以在上傳時存儲「鎖定」文件或其他東西,否則PHP將如何知道您正處於傳輸過程中?可能是最簡單的解決方案。上傳一個'filename.lck'並在包含它之前檢查它。然後在完成傳輸後刪除鎖。 – MetalFrog 2012-04-26 19:16:19
這聽起來像是一個非常棒的解決方案,但我不確定如何去做,因爲在文件上傳中沒有涉及到實際的代碼。 – 2012-04-26 19:19:55
是的,我對Automator一無所知,只是想把想法拋出去。希望我能有更多的幫助。 – MetalFrog 2012-04-26 19:21:46