php代码不执行不产生任何异常
微wx笑
2019-09-04【帝国CMS】
253
21
0关键字:
帝国cms php
最近遇到一个比较奇怪的问题,下面这段拉取远程图片的代码,readfile部分不执行,也不抛出任何异常。php.ini中display_errors=On,error_reporting=
E_ALL也配置了,甚至代码中使用
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'on');
都没有用,这到底是什么原因呢?
php代码不执行不产生任何异常
最近遇到一个比较奇怪的问题,下面这段拉取远程图片的代码,readfile部分不执行,也不抛出任何异常。php.ini中display_errors=On,error_reporting= E_ALL也配置了,甚至代码中使用
ini_set('error_reporting', E_ALL);
ini_set('display_errors', 'on');
都没有用,这到底是什么原因呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /** * 拉取远程图片 * @return mixed */ private function saveRemote() { $imgUrl = htmlspecialchars( $this ->fileField); $imgUrl = str_replace ( "&" , "&" , $imgUrl ); //http开头验证 if ( strpos ( $imgUrl , "http" ) !== 0) { $this ->stateInfo = $this ->getStateInfo( "ERROR_HTTP_LINK" ); return ; } preg_match( '/(^https*:\/\/[^:\/]+)/' , $imgUrl , $matches ); $host_with_protocol = count ( $matches ) > 1 ? $matches [1] : '' ; // 判断是否是合法 url if (!filter_var( $host_with_protocol , FILTER_VALIDATE_URL)) { $this ->stateInfo = $this ->getStateInfo( "INVALID_URL" ); return ; } preg_match( '/^https*:\/\/(.+)/' , $host_with_protocol , $matches ); $host_without_protocol = count ( $matches ) > 1 ? $matches [1] : '' ; // 此时提取出来的可能是 ip 也有可能是域名,先获取 ip $ip = gethostbyname ( $host_without_protocol ); // 判断是否是私有 ip if (!filter_var( $ip , FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) { $this ->stateInfo = $this ->getStateInfo( "INVALID_IP" ); return ; } //获取请求头并检测死链 $heads = get_headers( $imgUrl , 1); if (!( stristr ( $heads [0], "200" ) && stristr ( $heads [0], "OK" ))) { $this ->stateInfo = $this ->getStateInfo( "ERROR_DEAD_LINK" ); return ; } //格式验证(扩展名验证和Content-Type验证) $fileType = strtolower ( strrchr ( $imgUrl , '.' )); if ( strpos ( $fileType , "?" )){ $fileType = strstr ( $fileType , "?" , true); } if (!isset( $heads [ 'Content-Type' ]) || ! stristr ( $heads [ 'Content-Type' ], "image" )) { $this ->stateInfo = $this ->getStateInfo( "ERROR_HTTP_CONTENTTYPE" ); return ; } else { if ( count ( $this ->config[ 'allowFiles' ]) > 0){ if (!in_array( $fileType , $this ->config[ 'allowFiles' ])){ //$this->stateInfo = $this->getStateInfo("ERROR_HTTP_ALLOWFILES").$heads['Content-Type']; //image/webp return ; } } } //打开输出缓冲区并获取远程图片 ob_start(); $context = stream_context_create( array ( 'http' => array ( 'follow_location' => false // don't follow redirects )) ); readfile( $imgUrl , false, $context ); $img = ob_get_contents(); ob_end_clean(); $imgUrl2 = $imgUrl ; if ( strpos ( $imgUrl , "?" )){ $imgUrl2 = substr ( $imgUrl , 0, strripos ( $imgUrl , "?" )); } preg_match( "/[\/]([^\/]*)[\.]?[^\.\/]*$/" , $imgUrl2 , $m ); $this ->oriName = $m ? $m [1]: "" ; $this -> fileSize = strlen ( $img ); $this -> fileType = $this ->getFileExt(); $this ->fullName = $this ->getFullName(); $this ->filePath = $this ->getFilePath(); $this ->fileName = $this ->getFileName(); $dirname = dirname( $this ->filePath); //检查文件大小是否超出限制 if (! $this ->checkSize()) { $this ->stateInfo = $this ->getStateInfo( "ERROR_SIZE_EXCEED" ); return ; } //创建目录失败 if (! file_exists ( $dirname ) && ! mkdir ( $dirname , 0777, true)) { $this ->stateInfo = $this ->getStateInfo( "ERROR_CREATE_DIR" ); return ; } else if (! is_writeable ( $dirname )) { $this ->stateInfo = $this ->getStateInfo( "ERROR_DIR_NOT_WRITEABLE" ); return ; } //移动文件 if (!( file_put_contents ( $this ->filePath, $img ) && file_exists ( $this ->filePath))) { //移动失败 $this ->stateInfo = $this ->getStateInfo( "ERROR_WRITE_CONTENT" ); } else { //移动成功 $this ->stateInfo = $this ->stateMap[0]; } } |
没有执行的代码段:
1 2 3 4 5 6 7 8 9 10 | //打开输出缓冲区并获取远程图片 ob_start(); $context = stream_context_create( array ( 'http' => array ( 'follow_location' => false // don't follow redirects )) ); readfile( $imgUrl , false, $context ); $img = ob_get_contents(); ob_end_clean(); |
关键并不是所有情况都不执行,而是拉取微信公众号的图片时存在这一问题。
而改用以下代码是可以拉取成功的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | function mkdirs( $dir , $mode = 0777) { if ( is_dir ( $dir ) || @ mkdir ( $dir , $mode )) return TRUE; if (!mkdirs(dirname( $dir ), $mode )) return FALSE; return @ mkdir ( $dir , $mode ); } function download123( $url , $path = 'images/' ) { $ch = curl_init(); curl_setopt( $ch , CURLOPT_URL, $url ); curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT, 30); $file = curl_exec( $ch ); curl_close( $ch ); $filename = pathinfo ( $url , PATHINFO_BASENAME); if ( stripos ( $filename , "?" )){ $filename = strstr ( $filename , "?" , true); } if (! stripos ( $filename , "." )){ $filename = $filename . ".jpeg" ; } mkdirs( $filename ); $resource = fopen ( $path . $filename , 'a' ); echo "<br>4" ; fwrite( $resource , $file ); fclose( $resource ); echo "<br>5<br>" ; } |
注:mkdirs 函数有问题,没有对传入路径的文件名进行处理。
本文由 微wx笑 创作,采用 署名-非商业性使用-相同方式共享 4.0 许可协议,转载请附上原文出处链接及本声明。
原文链接:https://www.ivu4e.cn/blog/EmpireCMS/2019-09-04/176.html