php文件上传之原理分析与上传类代码
今天研究PHP注册POST/GET大变量的时候,看到了关于这块的一些东西,跟踪了半天,先记录下来,免得以后再如此麻烦的跟踪.
处理器注册:
- [mod_php5.c, mod_php5模块初始化]
- php_init_handler(server_rec *s, pool *p)
- ->[main/SAPI.c]sapi_startup(&apache_sapi_module)
- ->[main/SAPI.c]
- sapi_globals_ctor(&sapi_globals)
- ->[main/php_content_types.c]php_setup_sapi_content_types(TSRMLS_C)
- ->[main/php_content_types.c
- php_post_entries如下]sapi_register_post_entries(php_post_entries
- TSRMLS_CC)
- ->[main/SAPI.c]sapi_register_post_entry(p
- TSRMLS_CC)
如下面的代码,共注册了俩个处理器,分别处理post数据和文件上传.
注1:参看在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究
- [main/rfc1867.h]
- #define
- MULTIPART_CONTENT_TYPE
- "multipart/form-data"
- [main/php_content_types.h]
- #define
- DEFAULT_POST_CONTENT_TYPE
- "application/x-www-form-urlencoded"
- [main/SAPI.c]
- struct
- _sapi_post_entry
- {
- char *content_type;
- uint
- content_type_len;
- void
- (*post_reader)(TSRMLS_D);
- void
- (*post_handler)(char *content_type_dup, void *arg
- TSRMLS_DC);
- };
- [main/php_content_types.c]
- static
- sapi_post_entry
- php_post_entries[] = {
- {
- DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler
- },
- {
- MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, rfc1867_post_handler
- },
- {
- NULL, 0, NULL, NULL
- }
- };
- <?php
- #*********************************************************
- #文件名称: yl_upload.class.php
- #功能描述: 印像上传类
- #程序制作:留印(adleyliu)
- #联系qq :14339095
- #联系邮箱:adleyliu@163.com
- #最后更新: 2007-11-11
- #注:转发时请保留此声明信息,这段声明不并会影响你的速度!
- #如有修改请将修改后的文件以邮件形式发送给作者一份,谢谢!
- #
- #*********************************************************
- /*
- //使用说明:
- //声明一个上传类
- $yl_upload = new yl_upload_class();
- //设置参数
- global $yl_filedata,$yl_directroy,$file_urldirectroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- $yl_filedata = 'filedata';//表单名
- $yl_directroy = '../upload_file';//上传主目录
- $file_urldirectroy = 'upload_file';//文件url(在编辑器KindEditor中用到,请查看upload.php实例)
- $yl_settingsnew = 'month_'.date('Ym');//上传主目录1按版块存入不同目录,2按月份存入不同目录,3按天存入不同目录
- $yl_maxsize = 2097152; //这里以字节为单位(1024*2)*1024=2097152 = 2M
- $yl_sizeformat = 'k'; //显示文件大小单位b,k,m
- $yl_arrext = array('gif','jpg','jpeg','png','bmp');//允许上传文件类型
- $yl_ext = 0; //0原文件类型上传,1统一为存为jpg
- //上传
- $yl_upload -> yl_uploadfile();
- */
- class yl_upload_class
- {
- #*********************************************************
- #创建目录函数
- #*********************************************************
- function createfolder($yl_path)
- {
- if (!file_exists($yl_path))
- {
- $this -> createfolder(dirname($yl_path));
- @mkdir($yl_path, 0777);
- }
- return $this -> createfolder;
- }
- #*********************************************************
- #获取文件名称,大小,类型,临时文件名
- #*********************************************************
- function yl_getfilename($yl_type)
- {
- global $yl_filedata,$yl_directroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- return $_FILES[$yl_filedata][$yl_type];
- }
- #*********************************************************
- #获取文件大小
- #*********************************************************
- function yl_getfilesize()
- {
- global $yl_filedata,$yl_directroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- if($this -> yl_getfilename('size') == 0){
- $this -> alert("请选择上传文件!");
- exit;
- }
- if($this -> yl_getfilename('size') > $yl_maxsize){
- $yl_maxsizek=$yl_maxsize/1024;
- $this -> alert("上传文件超出限制范围$yl_maxsizek.K!");
- exit;
- }
- switch (strtolower($yl_sizeformat)){
- case 'b':
- return $this -> yl_getfilename('size') . ' B';
- break;
- case 'k':
- return ($this -> yl_getfilename('size')/1024) . ' K';
- break;
- case 'm':
- return ($this -> yl_getfilename('size'))/(1024*1024) . ' M';
- }
- }
- #*********************************************************
- #获得文件扩展名
- #*********************************************************
- function yl_getfiletype()
- {
- global $yl_filedata,$yl_directroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- $yl_temp_arr = explode(".", $this -> yl_getfilename('name'));
- $yl_file_ext = array_pop($yl_temp_arr);
- $yl_file_ext = trim($yl_file_ext);
- $yl_file_ext = strtolower($yl_file_ext);
- //检查扩展名
- if (in_array($yl_file_ext, $yl_arrext) === false) {
- $this -> alert("上传文件类型被限制!");
- exit;
- }
- return $yl_file_ext;
- }
- #*********************************************************
- #上传
- #*********************************************************
- function yl_uploadfile()
- {
- global $yl_filedata,$yl_directroy,$file_urldirectroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- $yl_file_nameold = $this -> yl_getfilename('name');//原文件名
- $yl_file_namenews = date('Ymd').'_'.md5(date('YmdHis'));//重命名
- if($yl_ext == 0){
- $yl_file_names = $yl_file_namenews.'.'.$this -> yl_getfiletype();//改名
- }elseif ($yl_ext == 1){
- $yl_file_names = $yl_file_namenews.'.jpg';//统一改名为jpg
- }
- $yl_tmp_name = $this -> yl_getfilename('tmp_name');//服务器上临时文件名
- $yl_file_size = $this -> yl_getfilesize();//获取文件大小
- $yl_file_type = $this -> yl_getfiletype();//获取文件类型
- $yl_file_path = $yl_directroy.'/'.$yl_settingsnew;//建立一个目录
- //检查目录是否存在,不存在则创建
- if(@is_dir($yl_file_path) === false) {
- $this -> createfolder(''.$yl_file_path.'');//创建目录
- }
- //检查是否已上传
- if(@is_uploaded_file($yl_tmp_name) === false) {
- $this -> alert("文件已上传!");
- exit;
- }
- //检查目录写权限
- if (@is_writable($yl_file_path) === false) {
- $this -> alert("上传目录没有写权限!");
- exit;
- }
- $yl_doupload = @copy($yl_tmp_name, ''.$yl_file_path.'/'.$yl_file_names.'');
- if($yl_doUpload === false)
- {
- $this -> alert("上传失败!");
- }else{
- echo '上传成功';
- echo '<br>';
- echo '文件目录:'.$yl_file_path.'';
- echo '<br>';
- echo '原文件名:'.$yl_file_nameold.'';
- echo '<br>';
- echo '新文件名:'.$yl_file_names.'';
- echo '<br>';
- echo '文件大小:'.$yl_file_size.'';
- echo '<br>';
- echo '文件类型:'.$yl_file_type.'';
- }
- return;
- }
- #*********************************************************
- #*删除文件
- #*********************************************************
- function delfile()
- {
- global $yl_filedata,$yl_directroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- $yl__dir = dirname(trim($yl_directroy));
- if( $this->_isDel( $yl__dir ) )
- {
- return @unlink( $yl_directroy ) ? true : false;
- }else{
- return false;
- }
- }
- #*********************************************************
- #删除目录 目录下如果有文件不能删除
- #*********************************************************
- function deldir( )
- {
- global $yl_filedata,$yl_directroy,$yl_settingsnew;
- global $yl_maxsize,$yl_sizeformat,$yl_arrext,$yl_ext;
- if( $this->_isdel($yl_directroy) && is_dir( $yl_directroy ) )
- {
- return @rmdir( $yl_directroy ) ? true : false;
- }else{
- return false;
- }
- }
- #*********************************************************
- #提示
- #*********************************************************
- function alert($yl_msg)
- {
- echo '<html>';
- echo '<head>';
- echo '<title>error</title>';
- echo '<meta http-equiv="content-type" c>';
- echo '</head>';
- echo '<body>';
- echo '<script type="text/网页特效">alert("'.$yl_msg.'");;</script>';
- echo '</body>';
- echo '</html>';
- exit;
- }
- }
- ?>