强大的php检查文件类型
代码如下 | 复制代码 |
** * * * @access public * @param string filename 文件名 * @param string limit_ext_types 允许的文件类型,用|包围的类型如:|gif|txt| * @return string */<span id="more-472"></span> function check_file_type($filename, $limit_ext_types = ''){ $extname = strtolower(substr($filename, strrpos($filename, '.') + 1)); if ($limit_ext_types && stristr($limit_ext_types, '|' . $extname . '|') === false){ return ''; } $str = $format = ''; $file = @fopen($filename, 'rb'); if ($file){ $str = @fread($file, 0x400); // 读取前 1024 个字节 @fclose($file); } else{ $format=$extname; } if ($format == '' && strlen($str) >= 2 ){ if (substr($str, 0, 4) == 'MThd' && $extname != 'txt'){ $format = 'mid'; } elseif (substr($str, 0, 4) == 'RIFF' && $extname == 'wav'){ $format = 'wav'; } elseif (substr($str ,0, 3) == "xFFxD8xFF"){ $format = 'jpg'; } elseif (substr($str ,0, 4) == 'GIF8' && $extname != 'txt'){ $format = 'gif'; } elseif (substr($str ,0, 8) == "x89x50x4Ex47x0Dx0Ax1Ax0A"){ $format = 'png'; } elseif (substr($str ,0, 2) == 'BM' && $extname != 'txt'){ $format = 'bmp'; } elseif ((substr($str ,0, 3) == 'CWS' || substr($str ,0, 3) == 'FWS') && $extname != 'txt'){ $format = 'swf'; } elseif (substr($str ,0, 4) == "xD0xCFx11xE0"){ // D0CF11E == DOCFILE == Microsoft Office Document if (substr($str,0x200,4) == "xECxA5xC1x00" || $extname == 'doc'){ $format = 'doc'; } elseif (substr($str,0x200,2) == "x09x08" || $extname == 'xls'){ $format = 'xls'; } elseif (substr($str,0x200,4) == "xFDxFFxFFxFF" || $extname == 'ppt'){ $format = 'ppt'; } } elseif (substr($str ,0, 4) == "PKx03x04"){ $format = 'zip'; } elseif (substr($str ,0, 4) == 'Rar!' && $extname != 'txt'){ $format = 'rar'; } elseif (substr($str ,0, 4) == "x25PDF"){ $format = 'pdf'; } elseif (substr($str ,0, 3) == "x30x82x0A"){ $format = 'cert'; } elseif (substr($str ,0, 4) == 'ITSF' && $extname != 'txt'){ $format = 'chm'; } elseif (substr($str ,0, 4) == "x2ERMF"){ $format = 'rm'; } elseif ($extname == 'sql'){ $format = 'sql'; } elseif ($extname == 'txt'){ $format = 'txt'; } } if ($limit_ext_types && stristr($limit_ext_types, '|' . $format . '|') === false){ $format = ''; } return $format; } |
代码如下 | 复制代码 |
/** * 循环实现编码互转 * * @param string $param(字符串,对象,或者数组),$currCharset当前编码,$toCharset期望编码 * @return 参数类型 */ function zhandi_iconv($param,$currCharset,$toCharset){ if ($currCharset != $toCharset){ if (is_string($param)){ return iconv($currCharset, $toCharset, $param); } elseif (is_array($param)){ foreach ($param as $key => $value){ $param[$key] = zhandi_iconv($value); } return $param; } elseif (is_object($param)){ foreach ($param as $key => $value){ $param->$key = zhandi_iconv($value); } return $param; } else{ return $param; } } return $param; } |
有一个很久的工程今天要莫名其妙的重新启动了,这个工程是xampp的环境——不知道xampp?你Google一下吧,这个我不多说了。
一开始轻车熟路,apahce配置,php配置……一路下来没有任何问题。开始访问吧,问题就来了,很奇怪预料之中可以运行的页面,却出了个预料之外的乱码问题。
第一个想到的是,apache的缺省字符集,于是在apache的语言扩展配置文件中加入:
AddDefaultCharset UTF-8
我的网站页面是utf-8的哦,重新启动并没有预想之中的起到作用——也就是没有作用啦!多方努力都没有作用,就这样在httpd.conf上浪费了半个小时。开始郁闷……
半个小时过去了,抽了一支烟,想到phpinfo可能能够帮上忙哦,于是打开phpinfo一看,立即惊呆了。在HTTP Response Headers一栏下的 Content-Type 项中赫然出现了:text/html gbk字样,我神呢——,为啥是gbk呢。于是重新查找各项设置,httpd.conf没有,各项扩展里面都没有这个gbk的东东……
郁闷中……
php.ini,这是总算找到了,不知道哪个鸟人狂贱的把这个地方的设置打开了,并且还不是正确的,哪个地方?
default_charset = “gbk”
就这个地方,害死老子哦!于是修改成:
default_charset = “UTF-8″
重启,一切正常了!但是咱们也不能害人不是,想着去掉看看可以不,去掉之后一切还是正常的——页面显示编码控制权重新回到了页面本身。
因为用到一个简单的功能,我们用到了file_get_contents 函数,这样它把CPU 100%经过分析确实了是它景起了,现在我们来看看引起cpu 100%的解决办法吧。
运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器,突然系统负载上升,使用 top 命令查看,很多 php-cgi 进程 CPU 使用率接近100%。后来,我通过跟踪发现,这类情况的出现,跟 PHP 的 file_get_contents() 函数有着密切的关系。
大、中型网站中,基于 HTTP 协议的 API 接口调用,是家常便饭。PHP 程序员们喜欢使用简单便捷的 file_get_contents(“http://example.com/”) 函数,来获取一个 URL 的返回内容,但是,如果 http://example.com/ 这个网站响应缓慢,file_get_contents() 就会一直卡在那儿,不会超时。
我们知道,在 php.ini 中,有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的以下参数:
The timeout (in seconds) for serving a single request after which the worker process will be terminated
Should be used when ‘max_execution_time’ ini option does not stop script execution for some reason
’0s’ means ‘off’
<value name=”request_terminate_timeout”>0s</value>
默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。修改该参数,设置一个 PHP 脚本最大执行时间是必要的,但是,治标不治本。例如改成 30s,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免“502 Bad Gateway”。
要做到彻底解决,只能让 PHP 程序员们改掉直接使用 file_get_contents(“http://example.com/”) 的习惯,而是稍微修改一下,加个超时时间,用以下方式来实现 HTTP GET 请求。要是觉得麻烦,可以自行将以下代码封装成一个函数。
代码如下 | 复制代码 |
<?php
|
当然,导致 php-cgi 进程 CPU 100% 的原因不只有这一种,那么,怎么确定是 file_get_contents() 函数导致的呢?
首先,使用 top 命令查看 CPU 使用率较高的 php-cgi 进程。
top – 10:34:18 up 724 days, 21:01, 3 users, load average: 17.86, 11.16, 7.69
Tasks: 561 total, 15 running, 546 sleeping, 0 stopped, 0 zombie
Cpu(s): 5.9%us, 4.2%sy, 0.0%ni, 89.4%id, 0.2%wa, 0.0%hi, 0.2%si, 0.0%st
Mem: 8100996k total, 4320108k used, 3780888k free, 772572k buffers
Swap: 8193108k total, 50776k used, 8142332k free, 412088k cachedPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10747 www 18 0 360m 22m 12m R 100.6 0.3 0:02.60 php-cgi
10709 www 16 0 359m 28m 17m R 96.8 0.4 0:11.34 php-cgi
10745 www 18 0 360m 24m 14m R 94.8 0.3 0:39.51 php-cgi
10707 www 18 0 360m 25m 14m S 77.4 0.3 0:33.48 php-cgi
10782 www 20 0 360m 26m 15m R 75.5 0.3 0:10.93 php-cgi
10708 www 25 0 360m 22m 12m R 69.7 0.3 0:45.16 php-cgi
10683 www 25 0 362m 28m 15m R 54.2 0.4 0:32.65 php-cgi
10711 www 25 0 360m 25m 15m R 52.2 0.3 0:44.25 php-cgi
10688 www 25 0 359m 25m 15m R 38.7 0.3 0:10.44 php-cgi
10719 www 25 0 360m 26m 16m R 7.7 0.3 0:40.59 php-cgi
找其中一个 CPU 100% 的 php-cgi 进程的 PID,用以下命令跟踪一下:
strace -p 10747
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
select(7, [6], [6], [], {15, 0}) = 1 (out [6], left {15, 0})
poll([{fd=6, events=POLLIN}], 1, 0) = 0 (Timeout)
那么,就可以确定是 file_get_contents() 导致的问题了。
PHP的 strtr 函数, 性能要比 str_replace 函数高, 可以代替 str_replace 来使用. strtr 有两种形式:
string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )
当使用第一种的时候, 参数 $from, $to 的字符串长度一定要相同, 否则多余的(不管是$from多还是$to多) 字符被忽略.
比如 $str = 'a-=b' ;
当$from='-=' ,$to='CD',输出'aCDb', 因为'-='与'CD'的长度相同,没有问题.
当$from='-=' ,$to='CDE',输出'aCDb', $to里的'E'被忽略.
当$from='-=' ,$to='C',输出'aC=b', $from里的'='被忽略.
而使用第二种形式, 则没有这个问题, 多余的字条不会忽略.
所以,如果故意用 strtr 函数代替 str_replace, 并且使用了第一种形式, 则一定要注意这个特征, 这可能是一个陷阱.
相关文章
- 下面小编来给大家演示几个php操作zip文件的实例,我们可以读取zip包中指定文件与删除zip包中指定文件,下面来给大这介绍一下。 从zip压缩文件中提取文件 代...2016-11-25
Jupyter Notebook读取csv文件出现的问题及解决
这篇文章主要介绍了JupyterNotebook读取csv文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2023-01-06php中浮点型(float)和整型(integer)数据类型详解
文章分析了关于php中浮点型(float)和整型(integer)数据类型的用法区别以及在那种情况下会出现数据长度不够。 取值只能为True或者False,当其他类型转化为boolean类...2016-11-25- 有时我们接受或下载到的PSD文件打开是空白的,那么我们要如何来解决这个 问题了,下面一聚教程小伙伴就为各位介绍Photoshop打开PSD文件空白解决办法。 1、如我们打开...2016-09-14
- C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 本篇文章主要是对c#中数据类型占用的字节数进行了详细的介绍。需要的朋友可以过来参考下,希望对大家有所帮助...2020-06-25
- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
- 这篇文章主要介绍了Javascript类型转换的规则实例解析,涉及到javascript类型转换相关知识,对本文感兴趣的朋友一起学习吧...2016-02-27
php无刷新利用iframe实现页面无刷新上传文件(1/2)
利用form表单的target属性和iframe 一、上传文件的一个php教程方法。 该方法接受一个$file参数,该参数为从客户端获取的$_files变量,返回重新命名后的文件名,如果上传失...2016-11-25- 要替换字符串中的内容我们只要利用php相关函数,如strstr,str_replace,正则表达式了,那么我们要替换目录所有文件的内容就需要先遍历目录再打开文件再利用上面讲的函数替...2016-11-25
- 又码了一个周末的代码,这次在做一些关于文件上传的东西。(PHP UPLOAD)小有收获项目是一个BT种子列表,用户有权限上传自己的种子,然后配合BT TRACK服务器把种子的信息写出来...2016-11-25
- 今天小编在这里就来给photoshop的这一款软件的使用者们来说下AI源文件转photoshop图像变模糊问题的解决教程,各位想知道具体解决方法的使用者们,那么下面就快来跟着小编...2016-09-14
- 这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
- 步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
- 本篇文章主要说明的是与php文件上传的相关配置的知识点。PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir、upload_max_filesize、post_max_size等选项,下面一一说明。打开php.ini配置文件找到File Upl...2015-10-21
ant design中upload组件上传大文件,显示进度条进度的实例
这篇文章主要介绍了ant design中upload组件上传大文件,显示进度条进度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-10-29- 这篇文章主要介绍了C#使用StreamWriter写入文件的方法,涉及C#中StreamWriter类操作文件的相关技巧,需要的朋友可以参考下...2020-06-25
- 举一个案例:复制代码 代码如下:<?phpclass Downfile { function downserver($file_name){$file_path = "./img/".$file_name;//转码,文件名转为gb2312解决中文乱码$file_name = iconv("utf-8","gb2312",$file_name...2014-06-07