ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 一、PHP文件 执行超时 (1)初始设置脚本执行时间 打开php.ini文件,找到: ``` max_execution_time=30 ``` 修改为: ``` max_execution_time=600 ``` 如果你没有服务器修改权限,可通过内置PHP脚本的方法设置超时时间,在需要执行长时间操作的PHP文件中添加以下代码: ``` <?php ini_set('max_execution_time', 600);//秒为单位,自己根据需要定义 ``` 还可以通过.htaccess 文件设置超时时间,在文件中添加以下代码: php_value max_execution_time 600 (2)重新设置脚本执行时间,并重置计时器 set_time_limit ( int $seconds ) : bool seconds------最大的执行时间,单位为秒。如果设置为0(零),没有时间方面的限制。 设置允许脚本运行的时间,单位为秒。如果超过了此设置,脚本返回一个致命的错误。默认值为30秒,或者是在php.ini的max_execution_time被定义的值,如果此值存在。 当此函数被调用时,set_time_limit()会从零开始重新启动超时计数器。换句话说,如果超时默认是30秒,在脚本运行了了25秒时调用 set_time_limit(20),那么,脚本在超时之前可运行总时间为45秒。 # 二、PHP Curl 请求超时 Curl 是常用的访问HTTP协议接口的lib库,性能高,还有一些并发支持的功能等。 curl_setopt($ch, opt) 可以设置一些超时的设置,主要包括: a 、CURLOPT_TIMEOUT 设置CURL允许执行的最长秒数。 b、CURLOPT_TIMEOUT_MS 设置CURL允许执行的最长毫秒数。 c、 CURLOPT_CONNECTTIMEOUT 在发起连接前等待的时间,如果设置为0,则无限等待。 d、 CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。 e、 CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,默认为120秒。 **三、PHP Socket 请求超时** ``` <?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,array("sec"=> 1, "usec"=> 0 ) ); // 接收 socket_set_option($socket,SOL_SOCKET,SO_SNDTIMEO,array("sec"=> 3, "usec"=> 0 ) ); // 发送 ``` 虽然PHP中对fsockopen()方法有连接socket的超时参数,但是没有类似C中的连接成功后对数据的读写超时参数设置。没关系,PHP中对stream提供了一系列的方法以防止超时。 ``` stream_set_blocking( $fp , false ) ``` 设置数据流为阻塞模式,以防止数据没读完就退出 如果模式为 false, 给定的 socket 描述符将切换到非块模式, 如果为 true, 则切换到块模式. 这个效果类似于 fgets() 从 socket 读的情况. 在非块模式 fgets() 将会立即返回,而在块模式将等待数据满足要求。 ``` stream_set_timeout( $fp , 10 ) ``` 设置超时,应该在成功建立连接之后立即加上此句,后面的参数单位为秒 从封装协议文件指针中取得报头/元数据,返回的是一个数组,其中格式为: Array ( [stream_type] => tcp_socket [mode] => r+ [unread_bytes] => 0 [seekable] => [timed_out] => [blocked] => 1 [eof] => ) 其中索引timed_out为超时信息,超时则为true,未超时则为false,我们可以籍由此来判断socket是否超时,需要注意的是此句应该加在每次需要等待的语句之后,比如fwrite(),fread(),并且每读一次,都要判断一次是否超时,而对于一个连接只需一次超时设置stream_set_timeout( $fp , 10 )就可以了。 ``` $fp = @fsockopen( $ip , $port, $errNo , $errstr, 30 ); if( !$fp ) { return false; } else { stream_set_timeout( $fp , 3 ) ; //发送数据 fwrite( $fp , $packet ) ; $status = stream_get_meta_data( $fp ) ; //发送数据超时 if( $status['timed_out'] ) { echo "Write time out" ; fclose( $fp ); return false; } //读取数据 $buf = fread( $fp , 16 ) ; $status = stream_get_meta_data( $fp ) ; //读取数据超时 if( $status['timed_out'] ) { echo "Read time out" ; fclose( $fp ); return false; } } ``` 更多关于 PHP Socket 相关内容可参考 https://www.jb51.net/Special/70.htm (PHP Socket 用法总结) # 四、file_get_contents 超时处理(封装socket,file_put_contents类似) 从 PHP5 开始,file_get_content 已经支持 context 了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_contents 其实也可以 POST 数据。类似的还有,fopen(也是从PHP5开始加入context支持),file (PHP5加入支持)。 ``` <?php $get_opts = array( 'http'=>array( 'method' => "GET", 'timeout' => 1,//单位秒, 默认使用php.ini中default_socket_timeout的设置 ) ); $post_opts = array( 'http'=>array( 'method' => "POST", 'timeout' => 60,//单位秒, 可用ini_set('default_socket_timeout', 120);进行默认设置 'content' => http_build_query($param_array, '', '&') ) ); $opts = $get_opts; $res = file_get_contents($url, FALSE, stream_context_create($opts)); //返回string,失败返回FALSE ``` # 五、PHP Soap 请求超时 ``` ini_set('default_socket_timeout', 30); //定义响应超时为30秒 try { $options = array( 'cache_wsdl' => 0, 'connection_timeout' => 5, //定义连接超时为5秒,默认php.ini中default_socket_timeout的值 ); libxml_disable_entity_loader(false); $client = new \SoapClient($url, $options); return $client->__soapCall($function_name, $arguments); } catch (\SoapFault $e) { //超时、连接不上 if($e->faultcode == 'HTTP'){ throw new TimeoutException('连接或请求超时', $e->getCode()); } } ``` soap请求也可以使用资源流context,可以将请求超时写到stream_context_create( )中。 ``` try { $arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT)); //$arrContextOptions=array("http"=>array( "method"=>'GET', 'timeout'=>10)); $options = array( 'soap_version'=>SOAP_1_2, 'exceptions'=>true, 'trace'=>1, 'cache_wsdl'=>WSDL_CACHE_NONE, 'stream_context' => stream_context_create($arrContextOptions) ); $client = new SoapClient('https://url/dir/file.wsdl', $options); } catch (Exception $e) { echo "<h2>Exception Error!</h2>"; echo $e->getMessage(); } ``` # 六、PHP文件 操作超时