php程序在做下载时,当读取生成的临时文件过大时,PHP内存无法容纳,就会出现php内存溢出的问题。
采用更改PHP内存限制的方法,只能缓解,不能根除。
本文介绍的这个方法,采取把文件分次读取,并下载,基本实现了超大文件支持断点续传的功能。
完整代码如下:
$sourceFile = "xxx.tmp"; //要下载的临时文件名
$outFile = "用户订单.xls"; //下载保存到客户端的文件名
$file_extension = strtolower()(substr(strrchr($sourceFile, "."), 1)); //获取文件扩展名
//echo $sourceFile;
if (!ereg("[tmp|txt|rar|pdf|doc]", $file_extension))exit ("非法资源下载");
//检测文件是否存在
if (!is_file($sourceFile)) {
die("<b>404 File not found!</b>");
}
$len = filesize($sourceFile); //获取文件大小
$filename = basename($sourceFile); //获取文件名字
$outFile_extension = strtolower(substr(strrchr($outFile, "."), 1)); //获取文件扩展名
//根据扩展名 指出输出浏览器格式
switch ($outFile_extension) {
case "exe" :
$ctype = "application/octet-stream";
break;
case "zip" :
$ctype = "application/zip";
break;
case "mp3" :
$ctype = "audio/mpeg";
break;
case "mpg" :
$ctype = "video/mpeg";
break;
case "avi" :
$ctype = "video/x-msvideo";
break;
default :
$ctype = "application/force-download";
}
//Begin writing headers
header("Cache-Control:");
header("Cache-Control: public");
//设置输出浏览器格式
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=" . $outFile);
header("Accept-Ranges: bytes");
$size = filesize($sourceFile);
//如果有$_SERVER['HTTP_RANGE']参数
if (isset() ($_SERVER['HTTP_RANGE'])) {
/*Range头域 Range头域可以请求实体的一个或者多个子范围。
例如,
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。
*/
// 断点后再次连接 $_SERVER['HTTP_RANGE'] 的值 bytes=4390912-
list ($a, $range) = explode()("=", $_SERVER['HTTP_RANGE']);
//if yes, download missing part
str_replace()($range, "-", $range); //这句干什么的呢。。。。
$size2 = $size -1; //文件总字节数
$new_length = $size2 - $range; //获取下次下载的长度
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length"); //输入总长
header("Content-Range: bytes $range$size2/$size"); //Content-Range: bytes 4908618-4988927/4988928 95%的时候
} else {
//第一次连接
$size2 = $size -1;
header("Content-Range: bytes 0-$size2/$size"); //Content-Range: bytes 0-4988927/4988928
header("Content-Length: " . $size); //输出总长
}
//打开文件
//edit www.
$fp = fopen("$sourceFile", "rb");
//设置指针位置
fseek($fp, $range);
//虚幻输出
while (!feof($fp)) {
//设置文件最长执行时间
set_time_limit(0);
print (fread($fp, 1024 * 8)); //输出文件
flush(); //输出缓冲
ob_flush();
}
fclose($fp);
exit ();
?>
您可能感兴趣的文章:
php下载远程文件(支持断点续传)的实现代码
例1,使用echo命令把内容输出到我们的客户端(浏览器)。
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Getting started with dates in php5</title>
</head>
<body>
<?php
date_default_timezone_set('Asia/Shanghai');
echo "Today is ",date('l');
?>
</body>
</html>
输出:
Today is Friday
这个函数输出星期几的文本格式。
date函数至少需要一个字符参数(这个参数告诉我们怎样格式化当前日期)。
介绍完了一个简单的php日期函数的例子,来开始今天的php教程吧,希望对大家有所帮助。
尝试不同的格式
如果你看了php手册中PHP date function,将发现有很多格式化日期的方式。
将得到:
Today is 2012-08-17
PHP提供了一些常量。举例,可以使用Cookie获取到客户端日期。
输出:
Today is Friday, 17-Aug-12 11:34:38 CST
注意,当使用常量的时候不要使用引号。
如果想要输出当前时间,使用date(不同格式化字符参数)。
输出:
The time is 11:39:59am
本地化时区
如果发现以上的代码没有给出正确的时间,很有可能是因为你的服务器设置了与你本地不同的时区。需要在服务器上指定时区,代码:
这个将设置中国上海时区。这是php5的函数(注意旧版本的php),有很多供你选择时区。如果你想永久生效,你可以修改你的php.ini文件。
获取其他时间
经常需要其他时间,而不是现在的时间。当你用date()函数创建时间的时候,系统会使用Unix系统时间。这个时间表示从1970年1月1日 00:00:00 GMT(Unix 纪元时间),到现在的秒数。
为了详细说明怎样获取指定时间的日期,你可以提供秒数做为date(0函数的第二个参数。
结果是:
Today is 2011-06-27
这个看起来没什么用途,但它意味着你能用date()函数做计算。这之前,你需要简单的创建一个时间戳。
创建时间戳
有很多创建时间戳的方式。我们能够使用mktime()函数得到我们需要的时间戳。
$mytime=mktime(9, 23, 33, 6, 26, 2011);
echo "Today is ",date('Y-m-d g:i:sa', $mytime);
?>
输出:
Today is 2011-06-26 9:23:33am
mktime()函数需要你依次传递小时,分钟,秒,月,日,年。这是获取时间戳的好的方式,但是有更酷的方式。
通过字符获取时间戳
可以使用strtotime()函数获取时间戳,php把可读的字符转换成Unix时间戳。PHP在把字符转换成时间戳方面是相当灵活的,因此你可以插入各种各样的值来获取你想要的时间戳。
一个简单例子:
$mytime=strtotime("7:50pm June 26 2011");
echo "Today is ",date('Y-m-d g:i:sa', $mytime);
?>
输出:
Today is 2011-06-26 7:50:00pm
PHP在解释字符方面是相当灵巧的,但不是完美的,因此,在你插入之前一定要测试你输入的字符。使用"english-like instructions"转化成需要的时间戳,这是一个非常不错的方式。你可以像下面这样做:
$nextmonth=strtotime("+1 Month"); //从今天开始计算一个月以后的时间
$lastchristmas=strtotime("-1 year dec 25"); //去年圣诞节
获取日期范围
strtotime返回的值被转换为数字,我们能够用这些数字做基础运算,我们可以用这些数字做很多非常有意思的事情。比如,你每周二需要教一门功课,为期16周,你想得到你教科时间。你能够做下面的事情。
$startdate = strtotime('next Tuesday');
$enddate = strtotime('+16 weeks', $startdate);
$currentdate = $startdate;
echo '<ol>';//www.
while($currentdate < $enddate):
echo "\t<li>", date('M d', $currentdate);
$currentdate = strtotime('+1 week', $currentdate);
endwhile;
echo '</ol>';
?>
结果:
Aug 28
Sep 04
Sep 11
Sep 18
Sep 25
Oct 02
Oct 09
Oct 16
Oct 23
Oct 30
Nov 06
Nov 13
Nov 20
Nov 27
Dec 04
注意这行:$currentdate = strtotime("+1 week", $currentdate)。
在这行,需要指定一个时间戳做为第二个参数,strtotime将使用这个参数代替默认时间戳(今天),并进行运算。
到某一个日期的天数
使用计算器的时候,会试图去计算到某一天的天数。很容易计算11月份第四个星期四的时间戳。
$daysUtilDate = ceil(($someday - time())/60/60/24);
echo "There are ", $daysUtilDate, " until Thanksgiving";
首先,开始计算感恩节日期(11月1号之后的第一个星期四之后的第3个星期四),然后通过简单的算术,计算出感恩节到当前时间之间的天数。
当进行比较运算的时候,可以使用time(),因为它返回,到当前时间的纪元秒数。
就介绍这些吧,有关php中的日期函数的用法,希望对大家有所帮助。
,祝大家学习进步。
一.HTML页面转UTF-8编码问题
1.在head后,title前加入一行:
顺序不能错,一定要在<head>中,否则显示的标题有可能是乱码!
2.html文件编码问题:
点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,
如果是ANSI,需要将编码改成:UTF-8。
3.HTML文件头BOM问题:
将文件从其他的编码转换成UTF-8编码时,有时候会在文件的最开始加上一个BOM标签,
在个BOM标签可能会导致浏览器在显示中文的时候出现乱码。
删除这个BOM标签的方法:
1.可以用Dreamweaver打开文件,并重新保存,即可以去除BOM标签!
2.可以用EditPlus打开文件,并在菜单“首选项”->“文件”->"UTF-8标识",设置为:“总是删除签名”,
然后保存文件,即可以去除BOM标签!
4.WEB服务器UTF-8编码问题:
如果你按以上所列的步骤做了,还是有中文乱码问题,
请检查你的所使用的WEB服务器的编码问题
如果你使用的是Apache,请将配置文件里的:charset 设成:utf-8(这里仅列出方法,具体格式请参考apache的配置文件)
如果你使用的是Nginx,请将nginx.conf里的:charset 设成 utf-8,
具体找到 "charset gb2312;"或者类似的语句,改成:“charset utf-8;”。
二.PHP页面转UTF-8编码问题
1.在代码开始出加入一行:
2.PHP文件编码问题
点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,
如果是ANSI,需要将编码改成:UTF-8。
3.PHP文件头BOM问题:
PHP文件一定不可以有BOM标签
否则,会出现session不能使用的情况,并有类似的提示:
这是因为,在执行session_start() 的时候,整个页面不能有输出,但是当由于前PHP页面存在BOM标签,
PHP把这个BOM标签当成是输出了,所以就出错了!
所以PHP页面一定要删除BOM标签
删除这个BOM标签的方法:
1.可以用Dreamweaver打开文件,并重新保存,即可以去除BOM标签!
2.可以用EditPlus打开文件,并在菜单“首选项”->“文件”->"UTF-8标识",设置为:“总是删除签名”,
然后保存文件,即可以去除BOM标签!
4.PHP以附件形式保存文件的时候,UTF-8编码问题:
PHP以附件形式保存文件,文件名必须是GB2312编码,
否则,如果文件名中有中文的话,将是显示乱码:
如果你的PHP本身是UTF-8编码格式的文件,
需要将文件名变量由UTF-8转成GB2312:
5.截断显示文章标题时,出现乱码或者“?”问号的问题:
一般文章标题很长的时候,会显示一部分标题,会对文章标题进行截断,由于一个UTF-8编码格式的中文字符会占用3个字符宽度,
截取标题的时候,有时会只截取到一个中文字符的1个字符或2字符宽度, 没截取完整,将出现乱码或“?”问号的情况,
用下面的函数截取标题,就不会有问题:
function get_brief_str($str, $max_length)
{
echo strlen($str) ."<br>";
if(strlen($str) > $max_length)
{
$check_num = 0;
for($i=0; $i < $max_length; $i++)
{
if (ord($str[$i]) > 128)
$check_num++;
}
if($check_num % 3 == 0)
$str = substr($str, 0, $max_length)."...";
else if($check_num % 3 == 1)
$str = substr($str, 0, $max_length + 2)."...";
else if($check_num % 3 == 2)
$str = substr($str, 0, $max_length + 1)."...";
}
return $str;
}
三.MYSQL数据库使用UTF-8编码的问题
1.用phpmyadmin创建数据库和数据表
创建数据库的时候,请将“整理”设置为:“utf8_general_ci”
或执行语句:
创建数据表的时候:如果是该字段是存放中文的话,则需要将“整理”设置为:“utf8_general_ci”,
如果该字段是存放英文或数字的话,默认就可以了。
相应的SQL语句,例如:
`id` INT NOT NULL ,
`name` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM ;
2.用PHP读写数据库
在连接数据库之后:
加入两行:
mysql_query("set names 'utf8'");//写库
就可以正常的读写MYSQL数据库了。
四.JS相关的UTF-8编码问题
1.JS读Cookie的中文乱码问题
PHP写cookie的时候需要将中文字符进行escape编码,
否则JS读到cookie中的中文字符将是乱码。
但php本身没有escape函数,新写一个escape函数:
{
preg_match_all("/[\x80-\xff].|[\x01-\x7f]+/",$str,$r);
$ar = $r[0];
foreach($ar as $k=>$v)
{
if(ord($v[0]) < 128)
$ar[$k] = rawurlencode($v);
else
$ar[$k] = "%u".bin2hex(iconv("UTF-8","UCS-2",$v));
}
return join("",$ar);
}
JS读cookie的时候,用unescape解码,
然后就解决cookie中有中文乱码的问题了。
2.外部JS文件UTF-8编码问题
当一个HTML页面或则PHP页面包含一个外部的JS文件时,
如果HTML页面或则PHP页面是UTF-8编码格式的文件,
外部的JS文件同样要转成UTF-8的文件,
否则将出现,没有包含不成功,调用函数时没有反应的情况。
点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,
如果是ANSI,需要将编码改成:UTF-8。
五.FLASH相关的UTF-8编码问题
FLASH内部对所有字符串,默认都是以UTF-8处理
1.FLASH读文普通本文件(txt,html)
要将文本文件的编码存为UTF-8
点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,
如果是ANSI,需要将编码改成:UTF-8。
2.FLASH读XML文件
要将XML文件的编码存为UTF-8
点击编辑器的菜单:“文件”->“另存为”,可以看到当前文件的编码,确保文件编码为:UTF-8,
如果是ANSI,需要将编码改成:UTF-8。
在XML第1行写:
3.FLASH读PHP返回数据
如果PHP编码本身是UTF-8的,直接echo就可以了
如果PHP编码本身是GB2312的,可以将PHP转存成UTF-8编码格式的文件,直接echo就可以了
如果PHP编码本身是GB2312的,而且不允许改文件的编码格式,
用下面的语句将字符串转换成UTF-8的编码格式
$new_str = iconv("GB2312", "UTF-8", "$str");
再echo就可以了
4.FLASH读数据库(MYSQL)的数据
FLASH要通过PHP读取数据库中的数据
PHP本身的编码不重要,关键是如果数据库的编码是GB2312的话,
需要用下面的语句将字符串转换成UTF-8的编码格式
5.FLASH通过PHP写数据
一句话,FLASH传过来的字符串是UTF-8格式的,
要转换成相应的编码格式,再操作(写文件、写数据库、直接显示等等)
还是用iconv函数转换
6.FLASH使用本地编码(理论上不推荐使用)
如果想让FLASH不使用UTF-8编码,而是使用本地编码
对于中国大陆地区而言,本地编码是GB2312或GBK
AS程序内,可以添加以下代码:
那么FLASH内所有字符都是使用GB2312的编码了
所有导入到FLASH或者从FLASH导出的数据,都应该做相应的编码转换
因为使用本地编码,会造成使用繁体中文地区的用户产生乱码,所以不推荐使用。
您可能感兴趣的文章:
php函数substr截取中文字符出现乱码的解决方法
php substr截断中文半个汉字乱码问题的解决方法
php截取中文字符串乱码如何解决呢
php分割GBK中文乱码的解决方法
解决php截取utf-8中文字符串时乱码的问题
如何解决php中文字符乱码,中文字符入库乱码的问题
php中文字符串截断且无乱码的解决方法
有关php中文乱码的解决方法
php utf8 一半乱码的问题