PHP之文件的锁定、上传与下载的方法
1.文件锁定
现在都在讲究什么分布式、并发等,实际上文件的操作也是并发的,在网络环境下,多个用户在同一时刻访问页面,对同一服务器上的同一文件进行着读取,如果,这个用户刚好读到一半,另一个用户就写入了消息,那么前一个用户读到的就是错误数据,在数据库里面好像是称为脏数据,而如果某用户写到一半时,另一用户也对该文件进行写操作,那么就造成了写入数据的混乱和错误,因此�php有一个锁机制,类似于数据库的锁,当某用户在对文件操作时就加上某种锁,使得在同一时间其他用户不能对该文件进行操作或只能进行有限的操作,来保证在这些情况下的文件数据的正确性。
主要使用flock函数,原型:bool flock(resource $handle , int $operation [, int &$wouldblock ]),第一个参数是指向文件的句柄变量,第二个是加锁的方式,分别为
LOCK_SH:共享锁(share),在读取文件时加的锁,加锁后就其他用户不能再对该文件进行写,但可以读取该文件内容;
LOCK_EX:排他锁(exclude),或者叫独占锁,在写文件时使用,加了该锁后,只能是当前用户进行写操作,其他的用户不能读取和写入;
LOCK_NB:附加锁,在文件锁定短时间大量用户的访问操作可能会造成flock在锁定时堵塞,如果再加上该锁后可避免该情况(是不是这么一弄就能解决大量读写操作的问题,怕不行...);
LOCK_UN:释放锁,对前面的各种锁进行一次性释放,解锁。
如果容易堵塞,还可使用第三个参数wouldblock,如果把它设置为1,在锁定后就会阻挡其他进程来进行一些操作,但是windows上不支持,另外附加锁LOCK_NB,windows也是不支持的。
另外,关闭句柄变量的fclose操作也可以释放这些锁。
废话少说,看代码
复制代码
<?php
function readFileData($filename){
if(true == ($handle = fopen($filename, 'r'))){
if(flock($handle, LOCK_SH+LOCK_NB)){ // 加共享锁和附加锁,附加锁防止阻塞
$str = '';
while(!feof($handle)){
$str .= fread($handle, 128);
}
flock($handle, LOCK_UN); // 释放该锁
fclose($handle);
return $str;
}
else{
echo 'add a share lock failed';
return '';
}
}
else{
return '';
}
}
复制代码
注意使用多重锁的方式,是LOCK_SH+LOCK_NB,,在排他锁时也可这么用,它们都是枚举变量。对于写操作类似
复制代码
<?php
function writeInFile($filename, $data){
if(true == ($handle = fopen($filename, 'a'))){
if(flock($handle, LOCK_EX)){ //加上排他锁
fwrite($handle, $data);
flock($handle, LOCK_UN); //释放锁
fclose($handle);
}
else{
echo 'add exclusive lock failed';
return;
}
}
}
复制代码
实际上这也是解决php来实现多进程/线程读取文件的方式,php没有多线程这么一说,但加锁机制可以来模拟这种方式,实现对文件某些操作的队列处理,面试时别说你不知道-_-
2.文件上传
文件上传就是将本地的文件上传到服务器上,我们在用度场的云、鹅场的云上传文件时均是如此,当然实际情况肯定比这简单程序复杂。HTTP协议实现了文件的上传机制,首先要在本地选择上传的文件,上传到服务器后,服务端又要做一些处理,为此客户端和服务端均要做一些设置。
1、客户端
文件上传最基本的方法是通过form表单进行POST传递文件,实际上通过PUT方法也可以上传文件,只不过这种方法不安全,需要配置一些安全验证机制,这里只写最常用的方式。form表单的input标签可以设置成文件上传按钮type="file",直接解决了如何选择文件的问题,接下来需要设置form的两个属性:enctype和method
enctype:设置成multipart/form-data
method:设置成post
关于enctype属性设置可参考W3School的解释
第一条是默认的值,在我们使用HTTP协议传递一般的表单数据时,实际上默认对数据进行了分块编码,比如默认的urlencode方式(空格转为+,其他非字母字符转为%加两个十六进制大写数);当enctype设置为第二个时,不会进行字符编码,使用上传控件(input标签type设为file时即是)上传文件,必须设定为这个值;第三个则是值对空格编码为+,但不对非字母字符进行编码。
我们知道GET方法一般用于获取数据,且传递数据大小有限,而且POST方法可以传递比GET大得多的数据。
form的属性设置完成后,还要传递一个值过去,使用隐藏域(<input
type="hidden">),它的name属性设为MAX_FILE_SIZE,之所以要设定这个值,是先大概定一个文件尺寸值,避免在用户传一个大文件传了半天再告诉他:sorry,你的文件太大了-_-它的value属性值就是文件的size,以字节为单位。当然某些书上说,这个值只是作为参考,可轻易进行欺骗,这里只是象征性的表示,很可惜我这只菜鸟对安全了解甚少,只知道普通注入、XSS等,暂且用着吧。
那么就可以写一个简单得不能再简单的页面了,作为客户端用:
<form method="post" action="upload.php" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
选择文件: <input type="file" name="uploadFile" value="upload"/><br/>
<input type="submit" name="submit" value="上传" />
</form>
PHP之文件的锁定、上传与下载的方法的更多相关文章
- Java实现FTP文件与文件夹的上传和下载
Java实现FTP文件与文件夹的上传和下载 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制 ...
- 与众不同 windows phone (13) - Background Task(后台任务)之后台文件传输(上传和下载)
原文:与众不同 windows phone (13) - Background Task(后台任务)之后台文件传输(上传和下载) [索引页][源码下载] 与众不同 windows phone (13) ...
- Asp.Net MVC 文件管理Demo(文件展示,上传,下载,压缩,文件重命名等)
之前 ,有想做一个文件管理页面. 参考了 许多资料,终于完成了一个基于Asp.net MVC 的文件管理Demo.界面如下. 一,实现功能及相关技术 文件管理Demo基于Asp.NET MVC , ...
- 利用putty实现文件在linux上传和下载
利用putty实现文件上传和下载:1.打开windows命令提示符窗口d:(putty在d盘下)cd putty(pscp.exe所在目录)2:上传(主要利用pscp程序)pscp d:/jdk-8u ...
- pikachu 文件包含,上传,下载
一.文件包含 1.File Inclusion(local) 我们先测试一下,选择kobe然后提交 发现url出现变化 可以猜测此功能为文件包含,包含的文件为 file1.php,所以我在此盘符的根目 ...
- JavaScript开发——文件夹的上传和下载
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 首先我们需要了解的是上传文件三要素: 1.表单提交方式:post (get方式提交有大小 ...
- JS开发——文件夹的上传和下载
文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹. ...
- B/S开发——文件夹的上传和下载
本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...
- Java web开发——文件夹的上传和下载
我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,i ...
随机推荐
- 第四周课堂笔记3th
1.函数的嵌套 作用域,说的是变量 全局作用域:内置命名空间,全局命名空间 全局空间不可以引用局部空间 局部作用域: 局部命名空间 开辟的临时空间前提是调用了函数 全局作用域在整个文件中被使用 L ...
- webpack用了manifest为何还是每次都生成新的vendor?
原来的代码 //用于提取公共代码 new webpack.optimize.CommonsChunkPlugin({ //记得要在开头引入webpack names: ['vendor','manif ...
- java_网络编程之上传文件案例
初期成果: 客户端: package FileUpload; import java.io.*; import java.net.Socket; import java.util.Scanner; p ...
- curl http_code 状态码
1.只得到一个url的http_code的状态码 curl -I -m 10 -o /dev/null -s -w %{http_code} http://127.0.0.1/a.html 查询hea ...
- Linux-c对一个十六进制数的某一位取反
enum SWITCH_FLAG { SWITCH_ALL_FLAG = , SWITCH_WEB_FLAG = , …… } unsigned int switch_by_bit_value = 0 ...
- Luogu P2079 烛光晚餐(背包)
P2079 烛光晚餐 题意 题目背景 小明准备请小红去一家咖啡厅,共进烛光晚餐.小红高兴地和他一起去了咖啡厅. 题目描述 小红说:"小明,你点菜吧."小明看到菜单上有\(N\)道菜 ...
- JavaWeb中请求转发和请求重定向的区别
针对于JavaWeb中请求与重定向的一个cheatsheep: 1.转发 1)完成一次转发,用户浏览器发送一次请求 2)转发之后,浏览器URL地址栏不改变(服务器帮忙完成) 3)请求域中数据不丢失 4 ...
- myeclipse 无法部署项目到jboss服务器 部署不上去
关于myeclipse部署项目到jboss点击add deployments没有反应的问题,如图 此处点击右键,选择add deployments没有反应,原因是默认的web-root folder为 ...
- ymfx
一.APIView 入口 在路由层执行as_view()方法 rest-framework/views.py/class APIView/def as_view() 可以看到,APIView继承了Dj ...
- [Bzoj3743][Coci2015] Kamp【换根Dp】
Online Judge:Bzoj3743 Label:换根Dp,维护最长/次长链 题目描述 一颗树n个点,n-1条边,经过每条边都要花费一定的时间,任意两个点都是联通的. 有K个人(分布在K个不同的 ...