マルチスレッドの cURL

WBOY
WBOYオリジナル
2016-07-25 08:49:341008ブラウズ
これは、cURL への柔軟なマルチスレッド呼び出しです。
これは、PHP マニュアル http://us2.php.net/manual/zh/function.curl-multi-select.php で提供されているサンプルとは異なり、コードの実行効率がはるかに高くなります。ここには 2 つのファイルがあります。 one は 2 つのクラスを含む muti_curl のファイルです
1 つは利用可能な方法で、ここでは大量検査エージェント IP が利用可能かどうかを確認します。
  1. class request_setting {
  2. public $url = false;
  3. public $method = 'GET';
  4. public $post_data = null;
  5. public $headers = null;
  6. public $options = null;
  7. function __construct($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
  8. $this->url = $url;
  9. $this->method = $メソッド;
  10. $this->post_data = $post_data;
  11. $this->headers = $headers;
  12. $this->gt;options = $options;
  13. }
  14. public function __destruct() {
  15. unset($this- >url, $this->メソッド, $this->post_data, $this->headers, $this->options);
  16. }
  17. }
  18. /*************************************************** * *******************************************
  19. バッチ操作用のクラス
  20. * ************************************************ ** ***************************************/
  21. class muti_curl {
  22. protected $thread_size = 100;
  23. protected $timeout = 30;
  24. private $callback;
  25. protected $options = array(
  26. CURLOPT_SSL_VERIFYPEER => false,// 使用を禁止した後、cURL はサービス端末からのテストを終了します。CURLOPT_CAINFO を使用します置CURLOPT_CAPATH 設定を使用してください。 CURLOPT_SSL_VERIFYPEER (承認値は 2) が使用されている場合、CURLOPT_SSL_VERIFYHOST は FALSE に設定されている必要があります。 TRUE。cURL 7.10 から承認済みのインストールが開始されます。
  27. CURLOPT_RETURINTRANSFER => ; true, //curl_exec() で取得した情報を直接送信するのではなく、ファイル ストリームの形式で返します
  28. CURLOPT_CONNECTTIMEOUT => 15、
  29. CURLOPT_TIMEOUT => 30,
  30. // CURLOPT_HTTP_VERSION=>CURL_HTTP_VERSION_1_0, // 代理店を使用するときにデータを参照し、更
  31. // CURLOPT_AUTOREFERER=>false,// 現在Location: 重定方向、自動設置ヘッダー中のReferer: 情報。
  32. // CURLOPT_BINARYTRANSFER=>false, // CURLOPT_RETURNTRANSFER を使用する場合、この不使用の設定が返されます。
  33. // CURLOPT_COOKIESESSION=>true,// timecurl セッションのみを使用します仅传递一个セッション cookie、他の cookie、承認状態の下の cURL はすべての cookie を返します
  34. // CURLOPT_CRLF=>false,// 一時的に Unix の交換行番号を交換行程に変換します。
  35. // CURLOPT_DNS_USE_GLOBAL_CACHE=> false, // 時間会議は完全なローカルの DNS を使用して保存され、これはインターネット上で安全であり、アプリケーションを承認します。 HTTP 情報。
  36. // CURLOPT_FILETIME=>true, // 使用時に変更されたプログラム内の情報が返されます。結果の情報は、curl_getinfo() 関数の CURLINFO_FILETIME オプションによって返されます。
  37. // CURLOPT_FOLLOWLOCATION=>false, // 一時的にサーバーが返す「Location:」の戻りサーバーは、CURLOPT_MAXREDIRS を使用して戻りの数を制限できます。本当の, // 通信が完了した後に接続を強制的に切断するため、再利用できません。
  38. // CURLOPT_FRESH_CONNECT=>true,// 新しい接続の取得を制限し、既存の接続を置き換えます。
  39. // CURLOPT_FTP_USE_EPRT=>false,// FALSE に設定すると、FTP のダウンロード時に EPRT (または LPRT) コマンドが使用され、PORT コマンドのみが使用されます。
  40. // CURLOPT_FTP_USE_EPSV=>false,// 使用時、FTP 転送中に PASV モードに戻る前に最初に EPSV コマンドが実行されます。FALSE に設定されている場合は EPSV コマンドを無効にします。
  41. // CURLOPT_FTPAPPEND=>false,// 使用時
  42. // CURLOPT_FTPASCII=>false,// CURLOPT_TRANSFERTEXT の名前。
  43. // CURLOPT_FTPLISTONLY=>false,// 一時的に FTP 項目の名前のみを出力します。
  44. // CURLOPT_HEADER= >true,// 使用時間は、ファイルの情報をデータ ストリームとして出力します。
  45. // CURLINFO_HEADER_OUT=>false, // 使用時間を追跡する句柄の要求文字列。
  46. // CURLOPT_HTTPGET=>true,//
  47. // CURLOPT_HTTPPROXYTUNNEL =>true,// アプリタイム ミーティングは HTTP のメソッドを GET に設定します。GET は承認されているため、変更された場合にのみ使用されます。 =>true,// 使用中に、cURL 関数内の変更されたすべてのパラメータが値に置き換えられます。
  48. // CURLOPT_NETRC=>false, // 接続の確立後、~/.netrc ファイルがユーザー名と暗号情報を取得します。 Curlopt_nobody => true、gt、启用启用时不不对对对中中部分// curlopt_noprogress => false、//
  49. // CURLOPT_NOSIGNAL=>false,// 一時的に、php を介して転送されるすべてのカールのシグナルを使用します。この項目は、SAPI マルチスレッド送信中にデフォルトで有効になります。 cURL 7.10 で追加されました。
  50. // CURLOPT_POST=>false,// 有効にすると、フォーム送信と同様に、application/x-www-form-urlencoded と入力して、通常の POST リクエストが送信されます。
  51. // CURLOPT_PUT=>false,// 有効にすると HTTP によるファイルの送信を許可します。CURLOPT_INFILE と CURLOPT_INFILESIZE を同時に設定する必要があります。
  52. // CURLOPT_TRANSFERTEXT=>false,// 有効にすると、FTP 送信に ASCII モードを使用します。 LDAP の場合、HTML ではなくプレーン テキスト情報を取得します。 Windows システムでは、システムは STDOUT をバイナリ モードに設定しません。
  53. // CURLOPT_UNRESTRICTED_AUTH=>true,// ドメイン名が変更された場合でも、CURLOPT_FOLLOWLOCATION を使用して生成されたヘッダー内の複数の場所にユーザー名とパスワードの情報を継続的に追加します。
  54. // CURLOPT_UPLOAD=>false,// 有効な場合、ファイルのアップロードを許可します。
  55. // CURLOPT_VERBOSE =>true,// 有効にすると、すべての情報が報告され、STDERR または指定された CURLOPT_STDERR に保存されます。
  56. );
  57. private $headers = array();
  58. private $requests = array();
  59. private $requestMap = array();
  60. /*********************
  61. コールバック関数を構築します
  62. ********************/
  63. function __construct($callback = null) {
  64. $this->callback = $callback;
  65. }
  66. /*************************************************** * ******************
  67. __get メソッドのオーバーロード
  68. ************************* *******************************************/
  69. public function __get($name) {
  70. return (isset($this->gt;{$name})) ? $this->{$name} : null;
  71. }
  72. /*************************************************** * *******************
  73. __set メソッドのオーバーロード
  74. ************************ * *******************************/
  75. public function __set($name, $value) {
  76. // ヘッダーに增加一设設置
  77. if ($name = = "オプション" || $name == "ヘッダー") {
  78. $this->{$name} = $value + $this->{$name};
  79. } else {
  80. $this->{ $name} = $value;
  81. }
  82. return true;
  83. }
  84. //增加一请求
  85. public function add($request) {
  86. $this->requests[] = $request;
  87. return true;
  88. }
  89. public function request($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
  90. $this->requests[] = new request_setting($url, $method , $post_data, $headers, $options);
  91. return true;
  92. }
  93. public function get($url, $headers = null, $options = null) {
  94. return $this->request($url, " GET", null, $headers, $options);
  95. }
  96. public function post($url, $post_data = null, $headers = null, $options = null) {
  97. return $this->request($url , "POST", $post_data, $headers, $options);
  98. }
  99. プライベート関数 single_curl() {
  100. $ch =curl_init(); //初期化
  101. $request = array_shift($this->requests);//結果として最初の单元を移動します
  102. $options = $this->get_options($request);//この单元の配置を取得します
  103. curl_setopt_array($ch, $options);//批设置
  104. $output =curl_exec($ch);
  105. $curl_info =curl_getinfo($ch);
  106. if ($this->callback) {
  107. $callback = $this->callback;
  108. if (is_callable($this->callback)) {
  109. call_user_func($callback, $output, $curl_info, $request);
  110. }
  111. }
  112. else
  113. return $output;
  114. return true;
  115. }
  116. プライベート関数rolling_curl($thread_size = null) {
  117. if ($thread_size){
  118. $this->thread_size = $thread_size;
  119. }
  120. if (count($this->requests) < $this->thread_size){
  121. $this->thread_size = count($this->requests);
  122. }
  123. if ($this->thread_size < 2) {
  124. $errorinfo = '線程大小必ず 1 より大きい!!!!';
  125. throw new Exception($errorinfo);
  126. }
  127. $queue =curl_multi_init();
  128. //在線程里开始增加任务队列
  129. for ($i = 0; $i <; $this->スレッドサイズ; $i++) {
  130. $ch =curl_init();
  131. $options = $this->get_options($this->requests[$i]);
  132. curl_setopt_array($ch, $options);//获得设置
  133. curl_multi_add_handle($queue, $ch);// 追加去
  134. $key = (string) $ch;
  135. $this->requestMap[$key] = $i;
  136. }
  137. do {
  138. while (($statu_run_muti_exec = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) ;
  139. if ($statu_run_muti_exec != CURLM_OK){ Break; }
  140. // 完了したリクエストを発行し、処理を実行します
  141. while ($done =curl_multi_info_read($queue)) {
  142. $curl_info =curl_getinfo($done['handle']);
  143. $output =curl_multi_getcontent($done[' handle']);
  144. $callback = $this->callback;
  145. if (is_callable($callback)){
  146. $key = (string) $done['handle'];
  147. $request = $this-> request[$this->requestMap[$key]];
  148. unset($this->requestMap[$key]);//これは销毁变量用得很帅
  149. call_user_func($callback, $output, $curl_info, $request);
  150. }
  151. //完了済みのリクエストに未処理のリクエストを追加
  152. if ($i < count($this->requests) && isset($this->requests[$ i]) && $i < count($this->requests)) {
  153. $ch =curl_init();
  154. $options = $this->get_options($this->requests[$i]);
  155. curl_setopt_array($ch, $options);
  156. curl_multi_add_handle($queue, $ch);
  157. $key = (string) $ch;
  158. $this->requestMap[$key] = $i;
  159. $i++;
  160. }
  161. curl_multi_remove_handle($queue, $done['handle']);
  162. echo "done ";
  163. print_r($queue);
  164. print_r ($done);
  165. }
  166. // このステップは非常に重要です。 a completed 、タイムアウト設定をリセットします
  167. //ここで重要な点は、すべてのスレッドの少なくとも 1 つのリクエストが初めて有効であることを確認することです。そうでない場合、初めてのすべてのリクエストは効果がなく、結果的に $ active になります。 =0 なので、以下は実行されません
  168. if ($active >0){
  169. curl_multi_select($queue, $this->timeout);
  170. }
  171. } while ($active);
  172. curl_multi_close($queue ) ;
  173. return true;
  174. }
  175. public functionexecute($thread_size = null) {
  176. //thread_sizeのサイズを判断する。リクエストが1つしかない場合は、シングルスレッドモードを使用する
  177. if (count($this->requests) ) == 1) {
  178. return $this->single_curl();
  179. } else {
  180. return $this->rolling_curl($thread_size);
  181. }
  182. }
  183. private function get_options($request) {
  184. $options = $this ->__get('options');
  185. if (ini_get('safe_mode') == 'オフ' || !ini_get('safe_mode')) {
  186. // $options[CURLOPT_FOLLOWLOCATION] = 1;
  187. // $ options[CURLOPT_MAXREDIRS] = 5;
  188. }
  189. $headers = $this->__get('headers');
  190. if ($request->options) {
  191. $options = $request->options + $options ;
  192. }
  193. $options[CURLOPT_URL] = $request->url;
  194. //以下に投稿オプションとヘッダー オプションをそれぞれ設定します
  195. if ($request->post_data){
  196. $options[CURLOPT_POST] = 1;
  197. $options[CURLOPT_POSTFIELDS] = $request->post_data;
  198. }
  199. if ($headers) {
  200. $options[CURLOPT_HEADER] = 0;
  201. $options[CURLOPT_HTTPHEADER] = $headers;
  202. }
  203. return $options ;
  204. }
  205. public function __destruct() {
  206. unset($this->thread_size, $this->callback, $this->options, $this->headers, $this->requests);
  207. }
  208. }
  209. ?>
コードをコピー
  1. header("content-type:text/html; charset=utf-8");
  2. require("muti_curl_class.php");
  3. set_time_limit(0);
  4. $sucesesnum=0;
  5. $good_proxy=array();
  6. function request_callback($response, $info, $request) {
  7. global $sucesesnum,$g​​ood_proxy;
  8. // 次の正規表現は、返された結果を選択的に表示できます
  9. /* if ( preg_match( "~(.*?)~i", $response, $out)) {
  10. $title = $out[1];
  11. }*/
  12. // echo '< ;br> ;'.$response .'
    ';
  13. echo '
    ';
  14. //応答 ($response) をチェックして、設定された文字が含まれているかどうかを確認し、含まれている場合は、エージェント成功
  15. if( $response !== false && substr_count($response, 'ユーザーエージェント: Baiduspider') >=1 ) {
  16. // $result = true;
  17. echo "true
    ";
  18. / / echo $request[options][10004];
  19. // print_r ($request->options);
  20. echo $request->options[CURLOPT_PROXY];
  21. $good_proxy[]=$request->options[CURLOPT_PROXY] ] ;
  22. }
  23. echo '
    the-->'. $sucesesnum.'<---use:'
  24. // print_r ($request);
  25. / / echo $request->url;
  26. $sucesesnum++;
  27. echo "
    ";
  28. }
  29. $params = array_merge($_GET, $_POST) // ここで渡されたプロキシ IP のアドレスを取得します
  30. $ result = $proxy_ip = トリム($params['ip']);
  31. $timeout=intval(trim($params['timeout']));
  32. if($timeout<3 ){$timeout=3;}
  33. if($timeout>300){$timeout=300;}
  34. $thread_size=intval(trim($params['thread_size']));
  35. if($thread_size<5){$thread_size =5;}
  36. if( $thread_size>300){$thread_size =300;}
  37. if($proxy_ip == '') {
  38. echo 'IP を入力してください!!';
  39. return;
  40. }
  41. $replace_arr1 = array(' ', 'qq プロキシ:'、'dn28.com'、'qqip'、'qq プロキシ'、'qq プロキシ ip'、'エージェント ip:'、'ip:'、'エージェント ip'、'"'、"'" ,'\','/',' ');
  42. $result = str_replace($replace_arr1, array(''), $result);
  43. $result = str_replace(",", "n", $result);
  44. $resArr =explode("n", $result);
  45. foreach($resArr as $k => $v) {
  46. $posProxy = getPos($v, '@');
  47. if($posProxy== =false){
  48. if (!empty($v)){$proxyip_and_port = $v; }
  49. }else{
  50. $proxyip_and_port = substr($v, 0, $posProxy);
  51. }
  52. $newRes[] =trim ($proxyip_and_port);
  53. }
  54. print_r($newRes);
  55. //die();
  56. $option_setting = array(
  57. CURLOPT_SSL_VERIFYPEER => 0,
  58. CURLOPT_RETURNTRANSFER => true,
  59. CURLOPT_CONNECTTIMEOUT => 5,
  60. CURLOPT_TIMEOUT => 30,
  61. CURLOPT_HEADER=>false,
  62. CURLOPT_PROXY=>'',//ここにプロキシが設定されます
  63. );
  64. $url= 'http://www.baidu.com/robots.txt ' ;
  65. $btime=time();
  66. $rc = new muti_curl("request_callback");
  67. $rc->timeout = $timeout;
  68. $rc->thread_size = $thread_size;
  69. foreach ($newRes as $ v) {
  70. $option_setting[CURLOPT_PROXY]=$v;
  71. $request = new request_setting($url, $method = "GET", $post_data = null,$header= null, $option_setting);
  72. $rc-> ; add($request);
  73. }
  74. $rc->execute();
  75. $etime=time();
  76. $usedtime=$etime-$btime;
  77. 「すべて」をエコーし​​ます。 $ usedtime;
  78. echo '
    ';
  79. $good_proxy= array_unique($good_proxy);
  80. $str='';
  81. foreach ($good_proxy as $v){
  82. $str.="'".trim( $ v)."',";
  83. }
  84. $str= str_replace (' ' , '' ,$str );
  85. $str = preg_replace('/s+/', ' ', $str);
  86. echo $str '
    ';
  87. var_export ($good_proxy);
  88. //var_dump ($good_proxy);
  89. //********* *********************************************** **** *************************************
  90. //****** **** *********************使用する関数は 1 つだけです
  91. function parseProxyInfo ( $proxyStr ) {
  92. //$proxyStr = '202.115.207.25: 80@HTTP; 四川省成都の四川師範大学';
  93. $posIp = getPos($proxyStr, ':');
  94. $ip = substr($proxyStr, 0, $posIp);
  95. $posPort = getPos($ proxyStr, '@' );
  96. $port = substr($proxyStr, $posIp+1, $posPort-$posIp-1);
  97. $posType = getPos($proxyStr, ';');
  98. $type = substr( $proxyStr, $posPort +1, $posType-$posPort-1);
  99. $location = substr(strstr($proxyStr, ';'), 1);
  100. return array(
  101. 'ip' => $ip,
  102. 'port' = > $port,
  103. 'type' => $type,
  104. 'location' => $location
  105. );
  106. }
  107. function getPos($haystack, $needle){
  108. return strpos( $干し草の山、$針 );
  109. }
  110. function check_proxy_is_useful($model, $proxy_info_arr = array()) {
  111. global $params, $config;
  112. if($model == 'single') {
  113. $proxy_port = intval(trim($params['port' ]));
  114. $check_proxy_url = $config['verify_url'];
  115. $proxy_time_out = intval(trim($params['timeout']));
  116. $retry = intval(trim($params['retry']) );
  117. $proxy_ip = trim($params['ip']);
  118. $proxy = new proxy( $proxy_ip, $proxy_port, $check_proxy_url, $proxy_time_out, $retry );
  119. //成功した文字列の戻り成功、失敗した戻り値ブール値 false
  120. $result = $proxy -> check_proxy();
  121. //var_dump($result);
  122. $proxy_str_success = ''.$proxy_ip.':'.$proxy_port.'@'.'HTTP プロキシ验证成功! ';
  123. $proxy_str_failed = ''.$proxy_ip.':'.$proxy_port.'@'.'HTTP プロキシ验证失败!' ;
  124. $result を返す !== false ? $proxy_str_success : $proxy_str_failed;
  125. } elseif ($model == 'collect') {
  126. $proxy_port = intval(trim($proxy_info_arr['port']));
  127. $check_proxy_url = $config['verify_url'];
  128. $proxy_time_out = intval(trim ($params['timeout']));
  129. $retry = intval(trim($params['retry']));
  130. $proxy_ip = トリム($proxy_info_arr['ip']);
  131. /*echo $proxy_ip .'
    ';
  132. echo $proxy_port.'
    ';
  133. echo $check_proxy_url.'
    ';
  134. echo $proxy_time_out.'
    ';
  135. echo $retry.'
    ';*/
  136. if(!isset($proxy)) {
  137. $proxy = 新しいプロキシ( $proxy_ip, $proxy_port, $check_proxy_url, $proxy_time_out, $retry );
  138. }
  139. //成功はstring成功を返し、失敗はboolean falseを返します
  140. $result = $proxy -> check_proxy();
  141. return $result;
  142. }
  143. }
  144. function get_single(){
  145. global $params, $config;
  146. $proxy_ip = トリム($params['ip']);
  147. if($proxy_ip == '') {
  148. echo '请输入IP!!';
  149. return;
  150. }
  151. echo check_proxy_is_useful('single');
  152. }
  153. function get_proxy_by_collect(){
  154. global $params, $config;
  155. $params[' url'] = トリム($params['url']);
  156. if($params['url'] == '') {
  157. echo '请输入url!';
  158. return;
  159. }
  160. //$url = 'http://www.dn28.com/html/75/n-5175.html';
  161. $con = iconv('GBK', 'UTF-8', file_get_contents($params['url'])) ;
  162. preg_match ('/
(.*)
/s', $con, $arr);
  • $result =trip_tags ($arr[1], '
    ');
  • $replace_arr1 = array(' ', 'qq代理:', 'dn28.com', 'qqip', 'qq代理', 'qq代理ip', '代理ip:', 'ip:', '代理ip');
  • $result = str_replace($replace_arr1, array(''), $result);
  • //print_r($arr);
  • $ resArr =explode('
    ', $result);
  • //print_r($resArr);
  • echo '

    代理人開始批准中、全体の手続きは会花の承認を数分間行います。

    ';
  • unset($_SESSION['success_arr']);
  • foreach($resArr as $k => $v) {
  • $newRes[$k] = parseProxyInfo($v);
  • / /print_r($newRes[$k]);
  • /*return;*/
  • $result = check_proxy_is_useful('collect', $newRes[$k]);
  • $proxy_str_success = '';
  • $proxy_str_failed = ' '.$newRes[$k]['ip'].':'.$newRes[$k]['port'].'@'.$newRes[$k]['type'].'    IP アドレス:'.$newRes[$k]['location'].'';
  • if($result !== false ){
  • echo $proxy_str_success ;
  • $_SESSION['success_arr'][] = $success_arr[] = $newRes[$k];
  • } else {
  • echo $proxy_str_failed;
  • }
  • echo '
    ';
  • }
  • if(isset($success_arr) && count($success_arr) > 0 ) {
  • save_success_proxy($success_arr);
  • echo '

    [保存验证成功代理人宛本地電脑]   [我要看历史数据]

    ';
  • } else {
  • echo '

    [我要看看历史データベース]

    ';
  • }
  • //print_r($success_arr);
  • }
  • function get_proxy_by_rule(){
  • global $params, $config;
  • $result = $proxy_ip =トリム($params['ip']);
  • if($proxy_ip == '') {
  • echo '请输入IP!!';
  • return;
  • }
  • $replace_arr1 = array(' ', 'qq代理人:', 'dn28.com', 'qqip', 'qq代理', 'qq代理ip', '代理ip:', 'ip:', '代理ip');
  • $result = str_replace($replace_arr1 , array(''), $result);
  • $resArr =explode("n", $result);
  • //print_r($resArr);
  • echo '

    代理开始量批验证中,整过程将

    ';
  • unset($_SESSION['success_arr']);
  • foreach($resArr as $k => $v) {
  • $newRes[$k] = parseProxyInfo($v);
  • //print_r($newRes[$k]);
  • /*return;*/
  • $result = check_proxy_is_useful('collect', $newRes [$k]);
  • //var_dump($result);
  • $proxy_str_success = ''.$newRes[$k]['ip'].':'.$newRes [$k]['ポート'].'@'.$newRes[$k]['タイプ'].'    IP アドレス:'.$newRes[$k]['location'].'';
  • $proxy_str_failed = ' '.$newRes[$k]['ip'].':'.$newRes[$k]['port'].'@'.$newRes[$k]['type'].'    IP アドレス:'.$newRes[$k]['location'].'';
  • if($result !== false ){
  • echo $proxy_str_success ;
  • $_SESSION['success_arr'][] = $success_arr[] = $newRes[$k];
  • } else {
  • echo $proxy_str_failed;
  • }
  • echo '
    ';
  • }
  • if(isset($success_arr) && count($success_arr) > 0 ) {
  • save_success_proxy($success_arr);
  • echo '

    [php格式ファイルの保存] ;  [保存成功した代理店を本地電器に保存]   [我要看看历史数据]

    ';
  • } else {
  • echo '

    [我要看看历史数据]

    ';
  • }
  • }
  • function save_success_proxy($success_arr){
  • global $config;
  • date_default_timezone_set('PRC');
  • $str = '';
  • foreach($success_arr as $k => $v) {
  • $ str .= $v['ip'].':'.$v['port'].'@'.$v['type'].';'.$v['location']."n" ;
  • }
  • $fp = fopen($config['root_path'].'/success_proxy/'.date('YmdHi').'.log', 'a+');
  • fwrite($fp, $str);
  • fclose($fp);
  • unset($str);
  • }
  • ?>
  • 复制代


    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    前の記事:自動ファイルバックアップソフト次の記事:自動ファイルバックアップソフト

    関連記事

    続きを見る