我试图用PHP创建一个下载计数器。我创建的脚本是有效的,但当我单击下载链接时,脚本会将我发送到一个空白页面。在下载和计数时是否可以停留在页面上?
这是我下载的php文件的代码:
<?php
$Down=$_GET['Down'];
?>
<html>
<head>
<meta http-equiv="refresh" content="0;url=<?php echo $Down; ?>">
</head>
<body>
<?php
$fp = fopen("counter.txt", "r");
$count = fread($fp, 1024);
fclose($fp);
$count = $count + 1;
$fp = fopen("counter.txt", "w");
fwrite($fp, $count);
fclose($fp);
?>
</body>
</html>
这就是我的index.php中的链接的样子:
<a href="download.php?Down=download.zip">download</a>
非常感谢!
好吧,因为这里缺少大部分代码,这是一个例子,基本上你需要调用download.php
文件中的计数器代码,并在完成计数器代码和设置下载头之后传递文件内容。还要小心,或者只需将文件名传递给下载功能,就可以允许恶意人员从您的服务器下载任何文件。download.php?file=index.php
等
<?php
function get_download_count($file=null){
$counters = './counters/';
if($file == null) return 0;
$count = 0;
if(file_exists($counters.md5($file).'_counter.txt')){
$fp = fopen($counters.md5($file).'_counter.txt', "r");
$count = fread($fp, 1024);
fclose($fp);
}else{
$fp = fopen($counters.md5($file).'_counter.txt', "w+");
fwrite($fp, $count);
fclose($fp);
}
return $count;
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
</head>
<body>
<a href="./download.php?file=exampleA.zip">exampleA.zip</a> (Downloaded <?php echo get_download_count('exampleA.zip');?> times)<br>
<a href="./download.php?file=exampleB.zip">exampleB.zip</a> (Downloaded <?php echo get_download_count('exampleB.zip');?> times)<br>
</body>
</html>
download.php正如您所看到的,它不会输出HTML,因为这会损坏文件。
<?php
//where the files are
$downloads_folder = './files/';
$counters_folder = './counters/';
//has a file name been passed?
if(!empty($_GET['file'])){
//protect from people getting other files
$file = basename($_GET['file']);
//does the file exist?
if(file_exists($downloads_folder.$file)){
//update counter - add if dont exist
if(file_exists($counters_folder.md5($file).'_counter.txt')){
$fp = fopen($counters_folder.md5($file).'_counter.txt', "r");
$count = fread($fp, 1024);
fclose($fp);
$fp = fopen($counters_folder.md5($file).'_counter.txt', "w");
fwrite($fp, $count + 1);
fclose($fp);
}else{
$fp = fopen($counters_folder.md5($file).'_counter.txt', "w+");
fwrite($fp, 1);
fclose($fp);
}
//set force download headers
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . sprintf("%u", filesize($downloads_folder.$file)));
//open and output file contents
$fh = fopen($downloads_folder.$file, "rb");
while (!feof($fh)) {
echo fgets($fh);
flush();
}
fclose($fh);
exit;
}else{
header("HTTP/1.0 404 Not Found");
exit('File not found!');
}
}else{
exit(header("Location: ./index.php"));
}
?>
请确保检查$downloads_folder
变量是否正确。希望能有所帮助。
下载完整的示例代码
尝试使用php头重定向而不是JS或元标记重定向:
<?php
//counter code
$fp = fopen("counter.txt", "r");
$count = fread($fp, 1024);
fclose($fp);
$count = $count + 1;
$fp = fopen("counter.txt", "w");
fwrite($fp, $count);
fclose($fp);
// redirect
header("location: ".$_GET["Down"]);
exit;
还要确保在标头之前没有任何输出。
http://www.php.net/manual/en/function.header.php
同样对于链接,如果它仍然不起作用,请尝试添加目标属性:
<a href="download.php?Down=download.zip" target="_new">download</a>
我想改进Lawrence Cherone的答案。下载计数器imho应该是透明的,所以它更安全,没有人可以直接访问php脚本。最后,我集成了jquery,以便通过ajax实时更新计数器。。。所以不需要重新加载页面来查看结果。。。
.htaccess(位于root/files/中)
RewriteEngine on
RewriteRule ^(.*).(rar|zip)$ /php/doing_download.php?file=$1.$2 [R,L]
doing_download.php(位于root.php中)
<?php
$downloads_folder = $_SERVER['DOCUMENT_ROOT'] . '/files/';
$counters_folder = $_SERVER['DOCUMENT_ROOT'] . '/files/counter/';
if (!empty($_GET['file'])) {
$file = basename($_GET['file']);
$type = array("zip", "rar");
$exts = strtolower(substr(strrchr($file, "."), 1));
if (!in_array($exts, $type)) {
header("HTTP/1.0 403 Forbidden");
exit('File not allowed!');
} else {
if (file_exists($downloads_folder . $file)) {
if (file_exists($counters_folder . md5($file) . '_counter.txt')) {
$fp = fopen($counters_folder . md5($file) . '_counter.txt', "r");
$count = fread($fp, 1024);
fclose($fp);
$fp = fopen($counters_folder . md5($file) . '_counter.txt', "w");
fwrite($fp, $count + 1);
fclose($fp);
} else {
$fp = fopen($counters_folder . md5($file) . '_counter.txt', "w+");
fwrite($fp, 1);
fclose($fp);
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . sprintf("%u", filesize($downloads_folder . $file)));
$fh = fopen($downloads_folder . $file, "rb");
while (!feof($fh)) {
echo fgets($fh);
flush();
}
fclose($fh);
exit;
} else {
header("HTTP/1.0 404 Not Found");
exit('File not found!');
}
}
}
?>
count_download.php(位于root/php/)
<?php
function get_download_count($file = null) {
$counters = $_SERVER['DOCUMENT_ROOT'] . '/files/counter/';
if ($file == null) return 0;
$count = 0;
if (file_exists($counters . md5($file) . '_counter.txt')) {
$fp = fopen($counters . md5($file) . '_counter.txt', "r");
$count = fread($fp, 1024);
fclose($fp);
} else {
$fp = fopen($counters . md5($file) . '_counter.txt', "w+");
fwrite($fp, $count);
fclose($fp);
}
return $count;
}
?>
call_download.php(位于root.php中)
<?php
include($_SERVER["DOCUMENT_ROOT"] . "/php/count_download.php");
$item['item1'] = get_download_count('exampleA.zip');
$item['item2'] = get_download_count('exampleB.zip');
echo json_encode($item);
?>
static_download.php(位于root.php中)
<?php
include($_SERVER["DOCUMENT_ROOT"] . "/php/count_download.php");
$item['item1'] = get_download_count('exampleA.zip');
$item['item2'] = get_download_count('exampleB.zip');
?>
download.js(位于root/jsc/)
$(document).ready(function() {
$.ajaxSetup({cache: false});
getStatus();
});
function getStatus() {
$.getJSON('php/call_download.php', function(data) {
$('#item1').html(data.item1);
$('#item2').html(data.item2);
});
setTimeout("getStatus()",1000);
}
index.php(位于root/)
<?php include($_SERVER["DOCUMENT_ROOT"] . "/php/static_download.php"); ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Download Page</title>
<script type="text/javascript" src="jsc/jquery.min.js"></script>
<script type="text/javascript" src="jsc/download.js"></script>
</head>
<body>
File: <a href="files/exampleA.zip">exampleA.zip</a> - Downloaded <span id="item1"><?php echo $item['item1']; ?></span> Times<br />
File: <a href="files/exampleB.zip">exampleB.zip</a> - Downloaded <span id="item2"><?php echo $item['item2']; ?></span> Times<br />
File: <a href="test/test.zip">test.zip</a><!-- this file never will be counted since is located in other folder --><br />
</body>
</html>
在这里,您可以下载所有文件并进行测试
我希望我基于劳伦斯·切隆的回答能解决任何问题:)@Lawrence Cherone:干得好!!!
<?php
function downloadCount(){
$counter = file_get_contents('counter.txt','r');
$counter = $counter+ 1;
$myfile = fopen("counter.txt", "w");
fwrite($myfile, $counter);
fclose($myfile);
return $counter;
}
?>
</header>
<body>
HTML...
<a href="download.php?Down=True">
DOWNLOAD </a> <br> DOWNLOADED
<?php
if ($_GET['Down'])
{
$counter = downloadCount();
header("location: YourDownloadLink.fileExtension ");
}
$counter = file_get_contents('counter.txt','r');
echo $counter
?>
TIMES</h2>