实现文件下载功能 PHP 代码片断

 更新时间:2016年11月25日 15:36  点击:1498
网站有从远程服务器通过http下载文件的需求,于是写了个提供文件下载的脚本,下面我们来看看用PHP如何实现文件下载功能的。

偶尔用用PHP写点这种很小很小的Web程序,还是蛮简单方便的。

PHP实现文件下载功能的代码如下

<?php
$base_dir = "/usr/share/nginx/html/";
$myfile = $base_dir . $_GET["file"];
//echo $myfile;
 
if( ! file_exists($myfile) ) {
echo "file: " . $myfile . " doesn't exist.";
} elseif ( is_dir($myfile) ) {
echo "file: " . $myfile . " is a directory.";
} else {
    header("Content-type: application/octet-stream");
    header('Content-Disposition: attachment; filename="' . basename($myfile) . '"');
    header("Content-Length: ". filesize($myfile));
    readfile($myfile);
}
?>

github: https://github.com/smilejay/other-code/blob/master/php/download.php

另外,一个牛人分析一下使用apache/nginx的一些模块让php实现问下下载更加的高效:

http://www.laruence.com/2012/05/02/2613.html

301跳转必须由程序或服务器来实现,如果是页面跳转可以使用js或页面html来实现,下面我们先来介绍页面跳转,然后再介绍301跳转了.


一般情况下,此类跳转是302跳转,只是暂时性跳转,如果需要进行永久重写向(SEO上比较有用),可如下实现:

header("HTTP/1.1 301 Moved Permanently");
header("Location: redirect.php");


平时我们使用html做页面的时候,都会碰到定时刷新,可以看到如下标签:

<meta http-equiv="Refresh" content="2;url='refresh.php'">

表示每隔两秒刷新一次页面,实际上是重定向到页面。

由此,PHP根据HTTP协议,可以如下实现:

header( "refresh:2;url=refresh.php" );

1.window.location.href方式
    <script language="javascript" type="text/javascript">
           window.location.href="target.aspx";
    </script>

2.window.navigate方式跳转
   <script language="javascript">
    window.navigate("target.aspx");
</script>

 

3.window.loction.replace方式实现页面跳转,注意跟第一种方式的区别
<script language="javascript">
    window.location.replace("target.aspx");
</script>
有3个jsp页面(1.aspx, 2.aspx, 3.aspx),进系统默认的是1.aspx,当我进入2.aspx的时候, 2.aspx里面用window.location.replace("3.aspx");

与用window.location.href ("3.aspx");

从用户界面来看是没有什么区别的,但是当3.aspx页面有一个"返回"按钮,调用window.history.go(-1); wondow.history.back();方法的时候,一点这个返回按钮就要返回2.aspx页面的话,区别就出来了,当用 window.location.replace("3.aspx");连到3.aspx页面的话,3.aspx页面中的调用 window.history.go(-1);wondow.history.back();方法是不好用的,会返回到1.aspx。

4.self.location方式实现页面跳转,和下面的top.location有小小区别
   <script language="JavaScript">
          self.location='target.aspx';
   </script>

5.top.location
   <script language="javascript">
          top.location='target.aspx';
   </script>

说到缓存估计大家会想到ob_start函数吧,但如果要做到嵌套输出缓存的话我们是需要使用另一个函数了,下面一起来看看吧。

PHP的输出缓存是可以嵌套的。用ob_get_level()就可以输出嵌套级别。

测试发现在cli和浏览器下输出结果不一样(PHP5.4)。

ob_level1.png手册说明如下:

ob_get_level() will always return 0 inside a destructor.
This happens because the garbage collection for output buffers has already done before the destructor is called

想要正确输出也很简单:

ob_end_clean();
echo ob_get_level(); //0

回到正题:

ob_end_clean();
 
ob_start();
echo 'php1';//此处并不会在页面中输出
$a = ob_get_level();
$b = ob_get_contents();//获得缓存结果,赋予变量
ob_clean();
 
ob_start();
echo 'php2';//此处并不会在页面中输出
$c = ob_get_level();
$d = ob_get_contents();//获得缓存结果,赋予变量
ob_clean();
 
ob_start();
echo 'php3';//此处并不会在页面中输出
$e = ob_get_level();
$f = ob_get_contents();//获得缓存结果,赋予变量
ob_clean();
 
echo 'level:'.$a.',ouput:'.$b.'<br>';
echo 'level:'.$c.',ouput:'.$d.'<br>';
echo 'level:'.$e.',ouput:'.$f.'<br>';

结果如下:

level:1,ouput:php1
level:2,ouput:php2
level:3,ouput:php3

当然,当你关闭某个级别的缓冲,如下测试:
ob_end_clean();
 
ob_start();
echo 'php1';
$a = ob_get_level();
$b = ob_get_contents();
ob_clean();
 
ob_start();
echo 'php2';
$c = ob_get_level();
$d = ob_get_contents();
ob_end_clean();  //清空缓存并关闭缓存
 
ob_start();
echo 'php3';
$e = ob_get_level();
$f = ob_get_contents();
ob_clean();
 
echo 'level:'.$a.',ouput:'.$b.'<br>';
echo 'level:'.$c.',ouput:'.$d.'<br>';
echo 'level:'.$e.',ouput:'.$f.'<br>';

结果如下:

level:1,ouput:php1
level:2,ouput:php2
level:2,ouput:php3

php读取文件有很多的方法了,我们下文来为各位介绍一些常用的文件读取与输入读取文件内容的例子。

一,读取文件

先解释一下,什么是读取文件本身,什么叫读取文件输入内容。举个例子test.php里面的内容<?php  echo "test"; ?>

1,读取文件本身就是读取文件内所有内容,读取后就能得到<?php  echo "test"; ?>
2,读取文件输出内容是读取文件所表现出来的东西,读取后得到test

二,fopen方法

1,读取文件本身
 
<?php 
$filename = "test.php"; 
$handle = fopen($filename, "r"); 
$contents = fread($handle, filesize ($filename)); 
fclose($handle); 
echo strlen($contents); 
?> 

2,读取文件输出内容
 
<?php 
$filename = "http://localhost/test/test.php"; 
$handle = fopen($filename, "r"); 
$contents = ""; 
while (!feof($handle)) { 
 $contents .= fread($handle, 8192); 

fclose($handle); 
echo strlen($contents); 
?> 

上面二个读取的文件是同一个,但是为什么会不一样呢,http://localhost/test/test.php,在这里test.php文件被解释了,fopen只是得到这个脚本所输入的内容,看看php官方网站的解释吧
fopen() 将 filename 指定的名字资源绑定到一个流上。如果 filename 是 "scheme://..." 的格式,则被当成一个 URL,PHP 将搜索协议处理器(也被称为封装协议)来处理此模式。如果该协议尚未注册封装协议,PHP 将发出一条消息来帮助检查脚本中潜在的问题并将 filename 当成一个普通的文件名继续执行下去。

三,file方法

1,读取文件本身
 
<?php 
$filename = "test.php"; 
$content = file($filename);                 //得到数组 
print_r($content); 
?> 
2,读取文件显示输出内容
<?php
$filename = "http://localhost/test/test.php";
$content = file($filename);
print_r($content);
?>

四,file_get_contents方法

1,读取文件本身
 
<?php 
$filename = "test.php"; 
$content = file_get_contents($filename);     //得到字符串 
echo strlen($content); 
?> 
2,读取文件显示输出内容
<?php
$filename = "http://localhost/test/test.php";
$content = file_get_contents($filename);
echo strlen($content);
?>

五,readfile方法

1,读取文件本身
 
<?php 
$filename = "test.php"; 
$num = readfile($filename);     //返回字节数 
echo $num; 
?> 
2,读取文件显示输出内容
 
<?php 
$filename = "http://localhost/test/test.php"; 
$num = readfile($filename);     //返回字节数 
echo $num; 
?> 

六,ob_get_contents方法

1,读取文件显示输出内容
 
<?php 
ob_start(); 
require_once('bbb.php'); 
$content = ob_get_contents(); 
ob_end_clean(); 
echo strlen($content); 
?> 

总结

php,读取文件的方法很多,读取url的方法也很多,个人总结了一下,如有不对请大家指正,如果有不足请大家补充。

去年年底小编做了一个调用淘宝api返回用户ip所在城市并给出相对应的域名了,今天我整理了一篇常用的IP地址查询接口及调用方法,里面集成了几乎所有的ip地址接口了,具体如下.

腾讯IP地址查询接口:http://fw.qq.com/ipaddress
新浪IP地址查询接口:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js
搜狐IP地址查询接口:http://pv.sohu.com/cityjson
谷歌IP地址查询接口:http://j.maxmind.com/app/geoip.js
有道IP地址查询接口:http://www.youdao.com/smartresult-xml/search.s
1616 IP地址查询接口:http://w.1616.net/chaxun/iptolocal.php
126 http://ip.ws.126.net/ipquery
hao123 http://app.hao123.com/ipquery/getcity.php?rtype=2
淘宝 http://ip.taobao.com/service/getIpInfo.php?ip=117.89.35.58
太平洋电脑网 http://whois.pconline.com.cn/
设计蜂巢接口调用方法

API请求地址 : http://www.hujuntao.com/api/ip/ip.php?参数

参数说明:

IP : IP地址 可选
format : 输出格式 json 可选 默认为JS
JSON调用示例:
请求地址:http://www.hujuntao.com/api/ip/ip.php?callback=jQuery17107324279078748077_1327024991339&format=json&_=1327024991363

{
“ip”: “117.89.35.58″,
“province”: “u6c5fu82cf”,
“city”: “u5357u4eac”
}
腾讯接口调用方法

<script type="text/javascript" src="http://fw.qq.com/ipaddress"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

//反回格式如下: //var IPData = new Array("117.89.35.98","","江苏省","南京市"); console.log(IPData[0]+','+IPData[2]+','+IPData[3]) //117.89.35.98,江苏省,南京市

// ]]></script>


该方法已经不可用,访问http://fw.qq.com/ipaddre显示“The page you are looking for is temporarily unavailable.
Please try again later.”。腾讯对Referer做了判断,虽然可以通过PHP伪造Referer,但是实际测试中获得的是服务器的IP地址而不是客户端的IP地址。我们一起鄙视一下腾讯。?∩?(︶︿︶)?∩?

新浪接口调用方法

<script type="text/javascript" src="http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

//format参数设置返回格式 js/json //ip 要查询IP 可选 //反回格式如下: //var remote_ip_info = {"ret":1,"start":"117.89.35.0","end":"117.89.35.255","country":"u4e2du56fd","province":"u6c5fu82cf","city":"u5357u4eac","district":"u767du4e0b","isp":"u7535u4fe1","type":"","desc":""}; console.log(remote_ip_info["country"]+','+remote_ip_info["province"]+"省"+','+remote_ip_info["city"]+"市")//中国,江苏省,南京市

// ]]></script>


搜狐接口调用方法

<script type="text/javascript" src="http://pv.sohu.com/cityjson?ie=utf-8"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

//默认为GBK可通过ie参数设置编码 console.log(returnCitySN["cip"]+','+returnCitySN["cname"])//117.89.35.98,江苏省南京市

// ]]></script>


谷歌接口调用方法

据说是谷歌的,不知道是不是真的。

<script type="text/javascript" src="http://j.maxmind.com/app/geoip.js"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

console.log(geoip_country_name()+','+geoip_region_name()+','+geoip_city())//China,Jiangsu,Nanjing

// ]]></script>


有道接口调用方法

调用接口示例:http://www.youdao.com/smartresult-xml/search.s?type=ip&q=123.233.157.9

返回XML数据

<?xml version=”1.0″ encoding=”gbk”?>
<smartresult>
<product type=”ip”>
<ip>123.233.157.9</ip>
<location>山东省济南市 网通</location>
</product>
</smartresult>
或者

http://www.youdao.com/smartresult-xml/search.s?jsFlag=true&keyfrom=163.com&event=fYodaoCallBack&type=ip&q=192.168.1.1

返回JSON数据

fYodaoCallBack(1, {‘product’:'ip’,'ip’:’192.168.1.1′,’location’:'局域网 对方和您在同一内部网’} , ”);
IP地址查询接口及调用方法设计蜂巢 | 2011-12-29 | javascript
设计蜂巢IP地址查询接口:http://www.hujuntao.com/api/ip/ip.php
腾讯IP地址查询接口:http://fw.qq.com/ipaddress
新浪IP地址查询接口:http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js
搜狐IP地址查询接口:http://pv.sohu.com/cityjson
谷歌IP地址查询接口:http://j.maxmind.com/app/geoip.js
有道IP地址查询接口:http://www.youdao.com/smartresult-xml/search.s
1616 IP地址查询接口:http://w.1616.net/chaxun/iptolocal.php
126 http://ip.ws.126.net/ipquery
hao123 http://app.hao123.com/ipquery/getcity.php?rtype=2
淘宝 http://ip.taobao.com/service/getIpInfo.php?ip=117.89.35.58
太平洋电脑网 http://whois.pconline.com.cn/
设计蜂巢接口调用方法

API请求地址 : http://www.hujuntao.com/api/ip/ip.php?参数

参数说明:

IP : IP地址 可选
format : 输出格式 json 可选 默认为JS
JSON调用示例:
请求地址:http://www.hujuntao.com/api/ip/ip.php?callback=jQuery17107324279078748077_1327024991339&format=json&_=1327024991363

{
“ip”: “117.89.35.58″,
“province”: “u6c5fu82cf”,
“city”: “u5357u4eac”
}
腾讯接口调用方法

<script type="text/javascript" src="http://fw.qq.com/ipaddress"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

//反回格式如下: //var IPData = new Array("117.89.35.98","","江苏省","南京市"); console.log(IPData[0]+','+IPData[2]+','+IPData[3]) //117.89.35.98,江苏省,南京市

// ]]></script>


该方法已经不可用,访问http://fw.qq.com/ipaddre显示“The page you are looking for is temporarily unavailable.
Please try again later.”。腾讯对Referer做了判断,虽然可以通过PHP伪造Referer,但是实际测试中获得的是服务器的IP地址而不是客户端的IP地址。我们一起鄙视一下腾讯。?∩?(︶︿︶)?∩?

新浪接口调用方法

<script type="text/javascript" src="http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

//format参数设置返回格式 js/json //ip 要查询IP 可选 //反回格式如下: //var remote_ip_info = {"ret":1,"start":"117.89.35.0","end":"117.89.35.255","country":"u4e2du56fd","province":"u6c5fu82cf","city":"u5357u4eac","district":"u767du4e0b","isp":"u7535u4fe1","type":"","desc":""}; console.log(remote_ip_info["country"]+','+remote_ip_info["province"]+"省"+','+remote_ip_info["city"]+"市")//中国,江苏省,南京市

// ]]></script>


搜狐接口调用方法

<script type="text/javascript" src="http://pv.sohu.com/cityjson?ie=utf-8"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

//默认为GBK可通过ie参数设置编码 console.log(returnCitySN["cip"]+','+returnCitySN["cname"])//117.89.35.98,江苏省南京市

// ]]></script>


谷歌接口调用方法

据说是谷歌的,不知道是不是真的。

<script type="text/javascript" src="http://j.maxmind.com/app/geoip.js"></script><script type="text/javascript">// < ![CDATA[

// < ![CDATA[

console.log(geoip_country_name()+','+geoip_region_name()+','+geoip_city())//China,Jiangsu,Nanjing

// ]]></script>


有道接口调用方法

调用接口示例:http://www.youdao.com/smartresult-xml/search.s?type=ip&q=123.233.157.9

返回XML数据

<?xml version=”1.0″ encoding=”gbk”?>
<smartresult>
<product type=”ip”>
<ip>123.233.157.9</ip>
<location>山东省济南市 网通</location>
</product>
</smartresult>
或者

http://www.youdao.com/smartresult-xml/search.s?jsFlag=true&keyfrom=163.com&event=fYodaoCallBack&type=ip&q=192.168.1.1

返回JSON数据

fYodaoCallBack(1, {‘product’:'ip’,'ip’:’192.168.1.1′,’location’:'局域网 对方和您在同一内部网’} , ”);

[!--infotagslink--]

相关文章

  • php读取zip文件(删除文件,提取文件,增加文件)实例

    下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
  • Jupyter Notebook读取csv文件出现的问题及解决

    这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06
  • Photoshop打开PSD文件空白怎么解决

    有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
  • C#操作本地文件及保存文件到数据库的基本方法总结

    C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • C#实现HTTP下载文件的方法

    这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • SpringBoot实现excel文件生成和下载

    这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
  • php无刷新利用iframe实现页面无刷新上传文件(1/2)

    利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25
  • php批量替换内容或指定目录下所有文件内容

    要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
  • PHP文件上传一些小收获

    又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
  • AI源文件转photoshop图像变模糊问题解决教程

    今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • Zend studio文件注释模板设置方法

    步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
  • C#路径,文件,目录及IO常见操作汇总

    这篇文章主要介绍了C#路径,文件,目录及IO常见操作,较为详细的分析并汇总了C#关于路径,文件,目录及IO常见操作,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • php文件上传你必须知道的几点

    本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
  • C#使用StreamWriter写入文件的方法

    这篇文章主要介绍了C#使用StreamWriter写入文件的方法,涉及C#中StreamWriter类操作文件的相关技巧,需要的朋友可以参考下...2020-06-25
  • ant design中upload组件上传大文件,显示进度条进度的实例

    这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29
  • php实现文件下载实例分享

    举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07
  • 查找php配置文件php.ini所在路径的二种方法

    通常php.ini的位置在:复制代码 代码如下:/etc目录下或/usr/local/lib目录下。如果你还是找不到php.ini或者找到了php.ini修改后不生效(其实是没找对),请使用如下办法:1.新建php文件,写入如下代码复制代码 代码如下:<?phpe...2014-05-31
  • C# 向二进制文件进行读写的操作方法

    该例子使用 BinaryStream 和 BinaryWriter 对二进制文件进行读写操作先上代码再根据我理解的所分享给各位朋友...2020-06-25