有几种方法可以实现您的既定目标,我使用不同的方法创建了两个工作版本。以下使用AJAX 每隔几秒查询一次服务器,这可能是最简单的方法。任何长轮询 ajax 的问题在于它产生的流量,但在某些情况下,这不是问题。
在问题中,您展示了如何尝试将 PHP 脚本作为外部文件包含在 Javascript 标记中。这是可能的,但您需要在 php 文件中指定 Content-Type 标头(如 text/javascript 或类似名称)。也就是说,PHP 运行一次,然后在调用任何客户端代码之前终止,因此所述 javascript(PHP) 文件的内容将是静态的 - 你将如何获取新文件信息??
如果您使用 Ajax,则无需重新加载页面即可获取新文件信息 - 您可以安排 ajax 函数每 X 秒运行一次,并使用回调函数来操作 DOM 并显示图像。
<?php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
ob_clean();
$path=explode( '/', $_SERVER['SCRIPT_NAME'] );
array_pop( $path );
$dir=__DIR__ . '/images/tmp'; # sub-directory of current working directory
$path=implode( '/', $path ); # suitable path for use in displaying images - root relative
/* scan the directory for jpg, jpeg and png images */
$col=preg_grep( '@(\.jpg|\.jpeg|\.png)@i', glob( $dir . '/*.*' ) );
/* Most recent file - sort array by comparing file modification timestamps */
usort( $col, function( $a, $b ){
return filemtime( $a ) < filemtime( $b ) ? 1 : 0;
});
/* tweak the sorted array to create suitable image paths */
array_walk( $col, function( &$item, $key ) use ( $path ){
$item=str_replace( __DIR__, $path, $item );
});
$payload=array(
'latest' => array_shift( $col ),
'oldest' => array_pop( $col )
);
exit( json_encode( $payload, JSON_UNESCAPED_SLASHES ) );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Directory monitor using ajax</title>
<script>
document.addEventListener('DOMContentLoaded',()=>{
const output=document.querySelector('output');
const image=document.querySelector('img');
const span=document.querySelector('span');
const loadimage=function( url ){
return new Promise( ( resolve, reject )=>{
let img=new Image();
img.onload=resolve( img );
img.onerror=reject( new Error( `Bogus!\n\nUnable to load ${url}` ) );
img.src=url;
});
};
const ajax=function(url,callback){
let xhr=new XMLHttpRequest();
xhr.onload=function(){
if( this.status==200 && this.readyState==4 )callback( this.response )
};
xhr.onerror=function(e){
alert(e)
};
xhr.open( 'POST', url, true );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
xhr.send();
};
const ajaxcallback=function(r){
let json=JSON.parse( r );
if( json.latest!=null ){
loadimage( json.latest ).then( img=>{ image.src=img.src } ).catch( err=>{ alert(err) } );
}
};
/* anonymous, self-executing function to re-query every X seconds or whatever... */
(function(){
ajax( location.href, ajaxcallback )
setTimeout( arguments.callee, 1000 * 5 );
})();
});
</script>
<style></style>
</head>
<body>
<div>
<h1>Directory Monitor using ajax</h1>
<output></output>
<span><img /></span>
</div>
</body>
</html>
上面查看了名为 images 的 current working directory 的子目录,并通过定期将新文件复制到所述目录中进行了测试,只要新复制的文件设置了 Last Modified 时间,这种方法就可以正常工作到复制操作的时间 - filemtime 毕竟获取文件修改时间。
/ monitor.php
└─
images/
└─
pic1.jpg
pic2.jpg
我尝试(并且更喜欢)的另一种方法是使用EventSource 连接,该连接在无限循环中使用 PHP 来查询您的目录并发回消息。这使用从 Javascript 到 PHP 脚本的单个连接,只要页面打开(或直到显式终止),该脚本就会保持打开状态