我知道这个标题有点奇怪,但我会到达那里。在使用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