php如何实现文件上传啊

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php如何实现文件上传啊相关的知识,希望对你有一定的参考价值。

php如何实现文件上传啊,我原来用jsp做的时候是用数据流,php怎么上传啊,望高手指点

PHP 一般使用 POST 方法上传文件,下面是一个简单的文件上传示例,里面有相关的注释:

up.htm 文件:

----------

<html>

 <head>

  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

  <title>Up Sample</title>

 </head>

 <body>

  <form action="up.php" method="post" enctype="multipart/form-data">

   <!--备注:表单中 enctype="multipart/form-data " 的意思,是设置表单的 MIME 编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了 multipart/form-data ,才能完整的传递文件数据,进行下面的操作,并且 method 要设置为 "post"-->

   File:<br />

   <input type="file" name="upfile" size="30"><br />

   

   <!--上传框要设置 type="file"-->

   

   <br />

   <input type="submit" value="Upload">

  </form>

 </body>

</html>

----------

up.php 文件

----------

<?php

if (is_uploaded_file($_FILES["upfile"]["tmp_name"]))

 

 //如果有文件上传

 //is_uploaded_file -- 判断文件是否是通过 HTTP POST 上传的,返回布尔值

 //$_FILES[\'upfilename\'][\'...\'],其中的 \'upfilename\' 即为上传框的 name 属性

 //$_FILES[\'upfile\'][\'tmp_name\'] -- 文件被上传后在服务端储存的临时文件名,一般是系统默认

 if(!eregi(\'pdf\', $_FILES[\'upfile\'][\'type\']))

  

  //我们这里假设你要上传一个 pdf 文件

  //if(!eregi(\'pdf\', $_FILES[\'upfile\'][\'type\'])) 这个是判断上传文件类型的,是不是 pdf 文件,当然,若是想判断是否是 jpg 文件的话,将 pdf 改成 jpg 就可以了,即 if(!eregi(\'jpg\', $_FILES[\'upfile\'][\'type\']))

  //$_FILES[\'upfile\'][\'type\'] 是文件的 MIME 类型,如果浏览器提供此信息的话。例如“image/gif”

  echo \'The uploaded file is not an pdf File! Please upload a right file!\';

 else

  $filename = $_FILES[\'upfile\'][\'name\'];

  //$filename = $_FILES[\'upfile\'][\'name\'],这里是指定上传后的文件名,这里使用的仍是原来的文件名字,($_FILES[\'upfile\'][\'name\'] 是原始文件的名字)

  if(move_uploaded_file($_FILES["upfile"]["tmp_name"], dirname(__FILE__)."/upload_file/".$filename))

   

   //这里就是上传文件

   //dirname(__FILE__)."/upload_file/".$file_name -- 指定上传的目标文件,假设你要上传的目标文件夹upload_file 是和当前文件(upload.php)在同一文件夹下

   //chmod(dirname(__FILE__)."/upload_file/". $file_name, 0444);

   //上面注释掉的是用来改变上传后文件的属性,444 即只有执行和读的权限(看情况加上)

   echo $_FILES["upfile"]["name"] . " uploaded succeed!!!";

  

  else

   echo "Can\'t upload!!!";

  

 

else

 echo "File is not selected";

//需要注意的:

/*

在你的 up.php 同级目录下建立 upload_file 文件夹,来存放上传的文件

在上传之前要看一下 php 的配置文件:php.ini 中的三处设置

1.是否允许文件上传:( file_uploads = On )

2.文件上传的最大 size:( upload_max_filesize )

3.post 的最大 size ( post_max_size ) 这个大小设置成和 uplod_max_filesize 一样大或比 uplod_max_filesize 大

*/

/*

这只是很简单的一个文件上传的例子,为了帮助理解,只是判断了一下上传文件的类型,还可以使用 if 语句来判断上传文件的大小($_FILES[\'upfile\'][\'type\'])),并进行提示控制等,相关可以查阅 $_FILE[\'upfile\'] 数组的各个值分别代表什么

*/

?>

----------

可以看看 php100 里面的视频,其中一节就是介绍文件上传的.  :)

参考技术A 提交之后,上传文件的信息已经到了$_files数组里面,文件保存在临时文件,只要循环$_files数组就可以看到所有上传的文件信息了,确定之后,copy到目标文件夹就好 参考技术B 文件上传的例子很多,自己百度或谷歌一下。
看这个例子,希望对你有帮助。

参考资料:http://www.llh4.com/post/81.html

php如何实现大文件断点续传-php文件

总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块),但这不是我们现在说的重点,我们要做的事是保证在网络中断后1G的文件已上传的那部分在下次网络连接时不必再重传。所以我们本地在上传的时候,要将大文件进行分片,比如分成1024*1024B,即将大文件分成1M的片进行上传,服务器在接收后,再将这些片合并成原始文件,这就是分片的基本原理。断点续传要求本地要记录每一片的上传的状态,我通过三个状态进行了标记(wait  loading  finish),当网络中断,再次连接后,从断点处进行上传。服务器通过文件名、总片数判断该文件是否已全部上传完成。

        下面来说细节:

  1、首先获取文件(音视频、图片)

分两种情况,一种是在相册库里直接获取,一种是调用相机。如果是通过UIImagePickerView来获取(细节不详述,网上一大堆),我们会发现当你选定一个视频的时候,会出现图1的压缩页面,最后我们的app获取的视频就是这个经过压缩后的视频(不是视频库里的原始视频,这里有个注意点,操作完该压缩视频后记得释放,系统不会帮你释放的,需要你手动来操作,下面会说到),然后通过UIImagePickerView的协议方法中的- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info获取视频的Info

fileInfo = {

    UIImagePickerControllerMediaType = "public.movie";

    UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/2AAE9E44-0E6D-4499-9AC3-93D44D8342EA/tmp/trim.F36EC46C-4219-43C8-96A7-FA7141AB64D2.MOV";

    UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=DEDA9406-3223-4F87-ABB2-98FB5F5EB9C4&ext=MOV";

}

UIImagePickerControllerMediaType是选取文件的类型,如KUTTypeImage,KUTTypeMovie。这里注意一下movie和video的区别,一个是有声音的视频文件,一个是没有声音的视频文件,当然还有Audio是只有声音没有视频。UIImagePickerControllerMediaURL是视频的URL(如果是相机拍摄的,那么这个就是原始拍摄得到的视频;如果是在相册库里选择的,那就是压缩之后生成的视频),注意这个URL不指向相册库,通过这个URL你可以操作这个视频如删除,拷贝等,可以获取压缩后的视频的大小。UIImagePickerControllerReferenceURL是一个指向相册的URL,官方的解释是an NSURL that references an asset in the AssetsLibrary framework,通过这个URL,你可以获取视频的所有信息,包括文件名,缩略图,时长等(通过ALAssetsLibrary里的assetsLibraryassetForURL:referenceURLresultBlock:)。

如果是相机拍摄的,注意两个保存方法:图片保存到相册assetsLibrarywriteImageDataToSavedPhotosAlbum:UIImageJPEGRepresentation([infovalueForKey:UIImagePickerControllerOriginalImage],(CGFloat)1.0)metadata:nilcompletionBlock: failureBlock:

高保真压缩图片的方法NSData * UIImageJPEGRepresentation ( UIImage *image, CGFloat compressionQuality)

视频保存到相册:assetsLibrary writeVideoAtPathToSavedPhotosAlbum:MediaURL completionBlock:failureBlock:


到这里,我们就获取了所有需要的文件以及文件信息。下面要做的就是将文件分片。


2、将获取到的文件分片

首先,我将获取到的文件保存在这这样一个类中

@interface CNFile : NSObject

@property (nonatomic,copy)NSString* fileType;//image  or  movie

@property (nonatomic,copy)NSString* filePath;//文件在app中路径

@property (nonatomic,copy)NSString* fileName;//文件名

@property (nonatomic,assign)NSInteger fileSize;//文件大小

@property (nonatomic,assign) NSInteger trunks;//总片数

@property (nonatomic,copy)NSString* fileInfo;

@property (nonatomic,strong)UIImage* fileImage;//文件缩略图

@property (nonatomic,strong) NSMutableArray* fileArr;//标记每片的上传状态

@end

这样我们就可以对每一个CNFile对象进行操作了。


-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{

  总片数的获取方法:

    int offset =1024*1024;(每一片的大小是1M)

    NSInteger chunks = (file.fileSize%1024==0)?((int)(file.fileSize/1024*1024)):((int)(file.fileSize/(1024*1024) + 1));

    NSLog(@"chunks = %ld",(long)chunks);

    将文件分片,读取每一片的数据:

    NSData* data;

    NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:file.filePath];

    [readHandle seekToFileOffset:offset * chunk];

    data = [readHandle readDataOfLength:offset];

}


这样我们就获取了每一片要上传的数据,然后询问服务器,该片是否已经存在

(方法-(void)ifHaveData:(NSData*)data WithChunk:(NSInteger)chunk file:(CNFile*)file)

,如果存在,令chunk+1,重复上面的方法读取下一片,直到服务器不存在该片,那么上传该片数据。在这个方法中注意设置该chunk的上传状态(wait  loading finish),这将关系到本地判断该文件是否已全部上传完成。


下一步就是上传的过程:

-(void)uploadData:(NSData*) data WithChunk:(NSInteger) chunk file:(CNFile*)file;

在服务器返回该片上传成功后,我们要做的事有很多:

1)先将已经成功上传的本片的flagfinish

[file.fileArr replaceObjectAtIndex:chunk withObject:@“finish"];


2)查看是否所有片的flag都已经置finish,如果都已经finishi,说明该文件上传完成,那么删除该文件,上传下一个文件或者结束。

for (NSInteger j =0; j<chunks; j++){

if (j == chunks || ((j == chunks -1)&&([file.fileArr[j]isEqualToString:@"finish"])))

     [me deleteFile:file.filePath];

     [me readNextFile];

}

3)如果没有都finish,那么看本地下一chunk对用的flag是否是wait

 NSLog(@"查看第%ld片的状态",chunk+1);

 for(NSInteger i = chunk+1;i < chunks;i++)

  {

     NSString* flag = [file.fileArrobjectAtIndex:i];

      if ([flagisEqualToString:@"wait"]) {

             [me readDataWithChunk:ifileName:fileNamefile:file];

               break;

          }

   }

在第2、3步之间可以有一个 2.5)判断是否暂停上传

if(me.isPause ==YES)

  {

  //将目前读到了第几个文件的第几片保存到本地

     [self saveProgressWithChunk:chunk file:file];

      return ;

   }

这个操作实际上和上传过程中断网是一样的,为了断点续传,在断网或者暂停的时候,我们要将目前的进度保存起来,以便下次上传时略过前面已置finish的片。

然后还有一个问题,如果我们就这样线性的一片一片上传,实际上失去了分片上传的意义,应该结合多线程,使分片上传过程并发执行,同时上传多片,这样就提高了上传效率,并充分利用了网络带宽。

    dispatch_async(dispatch_queue_t queue, ^{

        [me readDataWithChunk: chunk];

    })

最后注意一下,每上传完一个视频,去设置里看看你的app占用的存储空间有没有增大哦,如果你没有处理那个生成的压缩视频,你会发现你的app的空间占用量是很大的。

详细参考这篇文章:http://blog.ncmem.com/wordpress/2019/08/12/%e5%a4%a7%e6%96%87%e4%bb%b6%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0-2/

以上是关于php如何实现文件上传啊的主要内容,如果未能解决你的问题,请参考以下文章

PHP curl 上传大文件非常大慢,导致超时,小文件(10M以下)的还可以,请问如何解决啊!

如何实现用php上传视频文件?

php如何实现一次性上传多个文件

http中上传文件的原理

php上传文件到linux服务器,可以上传成功,但是图片本身为啥没有可执行权限呢,怎么设置啊

php多文件上传实现代码