목차
PHP模拟发送POST请求之五curl基本使用和多线程优化,之五curl
백엔드 개발 PHP 튜토리얼 PHP模拟发送POST请求之五curl基本使用和多线程优化,之五curl_PHP教程

PHP模拟发送POST请求之五curl基本使用和多线程优化,之五curl_PHP教程

Jul 12, 2016 am 09:05 AM
curl

PHP模拟发送POST请求之五curl基本使用和多线程优化,之五curl

今天来介绍PHP模拟发送POST请求的重型武器——cURL函数库的使用和其多线程的优化方法。

说起cURL函数,可谓是老生常谈,但网上许多资料都在关键部分语焉不详,列出一大堆手册上的东西,搞得我入门时也万分痛苦,我翻了些资料,结合自己的笔记,总结了这篇博文,希望能给初次接触cURL的开发者提供一些帮助。


 

cURL的基本使用步骤

首先来介绍cURL:

cURL按照HTTP头信息来模拟浏览器传输数据,它支持FTP, FTPS, HTTP, HTTPS, DICT, FILE等协议,拥有HTTPS认证,HTTP POST方法,HTTP PUT方法,FTP上传,HTTP上传,代理服务器,cookies,用户名/密码认证等功能。cURL可谓是实现爬站抓取网页、POST数据等功能的利器。

使用cURL函数主要分为四部分:

1.初始化cURL。

2.设置cURL变量,这是cRUL的核心,扩展功能全靠这一步骤。

3.执行cURL,获取结果。

4.关闭连接,回收资源。

<span>$ch</span> = curl_init();<span>//</span><span>1</span>
<span>
curl_setopt(</span><span>$ch</span>, CURLOPT_URL, "http://localhost");<span>//</span><span>2</span>

<span>$output</span> = curl_exec(<span>$ch</span>);<span>//</span><span>3</span>
<span>
curl_close(</span><span>$ch</span>);<span>//</span><span>4</span>
로그인 후 복사

另外,我们还可以使用curl_getinfo($ch)函数获取curl执行的信息,其结果为一个数组

$info数组的内容包括如下等内容:

  • “url” //资源网络地址
  • “content_type” //内容编码
  • “http_code” //HTTP状态码
  • “filetime” //文件创建时间
  • “total_time” //总耗时
  • “size_upload” //上传数据的大小
  • “size_download” //下载数据的大小
  • “speed_download” //下载速度
  • “speed_upload” //上传速度
  • “download_content_length”//下载内容的长度
  • “upload_content_length” //上传内容的长度

cURL的常用设置

下面详细介绍curl使用第二步时常用的变量设置,在使用curl函数时,可以按各种需求来设置。

设置基本信息:

curl_setopt($ch, CURLOPT_URL, $string);//设置curl的目录地址

curl_setopt($ch, CURLOPT_PORT, $port);//设置连接端口,一般不设置默认80

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//返回结果流,并不是输出它留待后续处理,一般会设置这一项,稍后处理抓取到的信息,而不是直接输出出来。

设置POST数据信息:

curl_setopt($ch, CURLOPT_POST, 1);//设置传送数据方式为POST

curl_setopt($ch, CURLOPT_POSTFIELDS, $string);//设置要传输的数据

设置验证信息:

curl_setopt($ch, CURLOPT_COOKIE, $string);//设置curl执行时所携带的Cookie信息

curl_setopt($ch, CURLOPT_USERAGENT, $string);//设置curl模拟的浏览器信息

curl_setopt($ch, CURLOPT_REFERER, $string);//设置header中的referer,有利于破解防盗链

curl_setopt($ch, CURLOPT_USERPWD, $string);//传递一个连接中需要的用户名和密码,格式为:"[username]:[password]"

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);//设置允许服务器重定向

设置强化信息:

curl_setopt($ch, CURLOPT_NOBODY, 1);//设置不允许输出HTML body体,如果在抓取页面标题等信息时设置此选项会大大加快速度

curl_setopt($ch, CURLOPT_TIMEOUT, $int);//设置允许执行的最长秒数(超时时间),设置数值小的时候,CURL会放弃执行时间长的页面

curl_setopt($ch, CURLOPT_HEADER, 1);//设置允许将读取目标时产生的header头文件包含在输出流中


cURL批处理功能的基本使用

当然cURL的功能并不止于此,在手册上你可以找到它更多的变量设置。而且cURL最强大的地方在其批处理功能。

cURL的批处理似乎也很好理解,以下是一般步骤:

1.$mh = curl_multi_init();//初始化一个批处理句柄。

2.curl_multi_add_handle($mh,$ch); //往批处理句柄中添加设置好的$ch句柄。

3.curl_multi_exec($mh,$running);//执行$mh句柄,并将$mh句柄的运行状态写入$running变量中

4.当$running为true时循环执行curl_multi_close()函数

5.循环结束后遍历$mh句柄,用curl_multi_getcontent()获取第一个句柄的返回值

6.用curl_multi_remove_handle()将$mh中的句柄移除

7.用curl_multi_close()关闭$mh批处理句柄。

代码如下:

 <?<span>php 

        </span><span>$chArr</span>=<span>[];

        </span><span>for</span>(<span>$i</span>=0;<span>$i</span><50;<span>$i</span>++<span>){

              </span><span>$chArr</span>[<span>$i</span>]=curl_init("http://www.baidu.com"<span>);

              curl_setopt(</span><span>$chArr</span>[<span>$i</span>],CURLOPT_RETURNTRANSFER,1<span>);

        }

       </span><span>$mh</span> = curl_multi_init(); <span>//</span><span>1</span>

       <span>foreach</span>(<span>$chArr</span> <span>as</span> <span>$k</span> => <span>$ch</span><span>){      

         curl_multi_add_handle(</span><span>$mh</span>,<span>$ch</span>); <span>//</span><span>2</span>
<span>    
    }

       </span><span>$running</span> = <span>null</span><span>; 

       </span><span>do</span><span>{ 

           curl_multi_exec(</span><span>$mh</span>,<span>$running</span>); <span>//</span><span>3</span>
<span>
        }</span><span>while</span>(<span>$running</span> > 0); <span>//</span><span>4</span>

        <span>foreach</span>(<span>$chArr</span> <span>as</span> <span>$k</span> => <span>$ch</span><span>){ 

              </span><span>$result</span>[<span>$k</span>]= curl_multi_getcontent(<span>$ch</span>); <span>//</span><span>5</span>
<span>
              curl_multi_remove_handle(</span><span>$mh</span>,<span>$ch</span>);<span>//</span><span>6</span>
<span>
        }

        curl_multi_close(</span><span>$mh</span>); <span>//</span><span>7</span>

      ?>    
로그인 후 복사


cURL批处理时内存占用过多的问题

但是,执行大批量的句柄时我们会发现一个很严重的问题,那就是执行时系统CPU占用率几乎100%,几乎是死机状态了。纠其原因,那是因为在$running>0,执行 curl_multi_exec($mh,$running)而整个批处理句柄没有全部执行完毕时,系统会不停地执行curl_multi_exec()函数。我们用实验来证明:

我们在循环中curl_multi_exec($mh,$running)句前加入一个echo "a";的语句。我们的目的是执行50次对百度的访问,然后来看一下结果。

从图中滚动条的大小(滚动条已经最小状态了)可以大概看出输出a的个数,500个也不止,所以我们便可以找到占用CPU的罪魁祸首了。


cURL批处理时的内存优化方案

进行改动的方式是应用curl函数库中的curl_multi_select()函数,其函数原型如下:

<p>int curl_multi_select ( resource $mh [, float $timeout = 1.0 ] )</p>
<p>阻塞直到cURL批处理连接中有活动连接。成功时返回描述符集合中描述符的数量。失败时,select失败时返回-1,否则返回超时(从底层的select系统调用)。</p>
로그인 후 복사

我用们curl_multi_select()函数来达到没有需要读取的程序就阻塞住的目的。

我们对批处理的第3、4步进行优化,利用其多线程,模拟并发程序。

很多朋友会对手册中提供的代码心存疑惑(我一开始也是),下面的代码及解释。

<span>$running</span> = <span>null</span><span>;

</span><span>do</span><span> {

    </span><span>$mrc</span> = curl_multi_exec(<span>$mh</span>, <span>$running</span><span>);

} </span><span>while</span> (<span>$mrc</span> ==<span> CURLM_CALL_MULTI_PERFORM);

</span><span>//</span><span>本次循环第一次处理$mh批处理中的$ch句柄,并将$mh批处理的执行状态写入$running,当状态值等于CURLM_CALL_MULTI_PERFORM时,表明数据还在写入或读取中,执行循环,当第一次$ch句柄的数据写入或读取成功后,状态值变为CURLM_OK,跳出本次循环,进入下面的大循环之中。

//$running为true,即$mh批处理之中还有$ch句柄正待处理,$mrc==CURLM_OK,即上一次$ch句柄的读取或写入已经执行完毕。</span>

<span>while</span> (<span>$running</span> && <span>$mrc</span> ==<span> CURLM_OK) { 

    </span><span>if</span> (curl_multi_select(<span>$mh</span>) != -1) {<span>//</span><span>$mh批处理中还有可执行的$ch句柄,curl_multi_select($mh) != -1程序退出阻塞状态。</span>

        <span>do</span> {                            <span>//</span><span>继续执行需要处理的$ch句柄。</span>

             <span>$mrc</span> = curl_multi_exec(<span>$mh</span>, <span>$running</span><span>);

        } </span><span>while</span> (<span>$mrc</span> ==<span> CURLM_CALL_MULTI_PERFORM);

    }

}</span>
로그인 후 복사

这样执行的好处是$mh批处理中的$ch句柄会在读取或写入数据结束后($mrc==CURLM_OK),进入curl_multi_select($mh)的阻塞阶段,而不会在整个$mh批处理执行时不停地执行curl_multi_exec,白白浪费CPU资源。


cURL批处理的内存优化结果

完整代码如下:

<?<span>php 

        </span><span>$chArr</span>=<span>[];

        </span><span>for</span>(<span>$i</span>=0;<span>$i</span><50;<span>$i</span>++<span>){

        </span><span>$chArr</span>[<span>$i</span>]=curl_init("http://www.baidu.com"<span>);

        curl_setopt(</span><span>$chArr</span>[<span>$i</span>],CURLOPT_RETURNTRANSFER,1<span>);

        }

       </span><span>$mh</span> =<span> curl_multi_init(); 

        </span><span>foreach</span>(<span>$chArr</span> <span>as</span> <span>$k</span> => <span>$ch</span><span>)      

        curl_multi_add_handle(</span><span>$mh</span>,<span>$ch</span><span>); <br />
        </span><span>$running</span> = <span>null</span><span>; 

        </span><span>do</span><span> {
<br /></span><span>        $mrc</span> = curl_multi_exec(<span>$mh</span>, <span>$running</span><span>);

     } </span><span>while</span> (<span>$mrc</span> ==<span> CURLM_CALL_MULTI_PERFORM);


    </span><span>while</span> (<span>$running</span> && <span>$mrc</span> ==<span> CURLM_OK) {

         </span><span>if</span> (curl_multi_select(<span>$mh</span>) != -1<span>) {

             </span><span>do</span><span> {

                  </span><span>$mrc</span> = curl_multi_exec(<span>$mh</span>, <span>$running</span><span>);

             } </span><span>while</span> (<span>$mrc</span> ==<span> CURLM_CALL_MULTI_PERFORM);

         }

    }

       </span><span>foreach</span>(<span>$chArr</span> <span>as</span> <span>$k</span> => <span>$ch</span><span>){ 

               </span><span>$result</span>[<span>$k</span>]= curl_multi_getcontent(<span>$ch</span><span>); 

               curl_multi_remove_handle(</span><span>$mh</span>,<span>$ch</span><span>);

       }

        curl_multi_close(</span><span>$mh</span><span>); 

      </span>?>
로그인 후 복사

我们再次在 $mrc = curl_multi_exec($mh, $running)句子前加入echo "a";结果如下图:

虽然也不止50次,但是比之未优化前,CPU使用率已经大为改观。

虽然curl函数非常强大,但是我们还是有使用其他函数来发送POST请求的机会,另外也能从更底层了解curl函数,所以本辑也用大很大篇幅在其他函数上。

OK,本辑结束,写这辑博文的同时,我也学习到了很多。如果您觉得本博文对您有帮助,请您点推荐或关注我,我们继续分享我的笔记总结。如果有什么问题,您可以在下方留言讨论,谢谢阅读。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1067637.htmlTechArticlePHP模拟发送POST请求之五curl基本使用和多线程优化,之五curl 今天来介绍PHP模拟发送POST请求的重型武器cURL函数库的使用和其多线程的优化方...
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Python에서 CURL과 Python 요청 간의 상호 변환을 실현하는 방법 Python에서 CURL과 Python 요청 간의 상호 변환을 실현하는 방법 May 03, 2023 pm 12:49 PM

컬과 Pythonrequests는 모두 HTTP 요청을 보내는 강력한 도구입니다. 컬은 터미널에서 직접 요청을 보낼 수 있는 명령줄 도구인 반면, Python의 요청 라이브러리는 Python 코드에서 요청을 보내는 보다 프로그래밍적인 방법을 제공합니다. 컬을 Pythonrequestscurl 명령으로 변환하는 기본 구문은 다음과 같습니다. 컬[OPTIONS]URL 컬 명령을 Python 요청으로 변환할 때 옵션과 URL을 Python 코드로 변환해야 합니다. 다음은 컬POST 명령의 예입니다: 컬-XPOST https://example.com/api

Linux에서 컬 버전을 업데이트하는 방법에 대한 튜토리얼입니다! Linux에서 컬 버전을 업데이트하는 방법에 대한 튜토리얼입니다! Mar 07, 2024 am 08:30 AM

Linux에서 컬 버전을 업데이트하려면 다음 단계를 따르세요. 현재 컬 버전을 확인하세요. 먼저 현재 시스템에 설치된 컬 버전을 확인해야 합니다. 터미널을 열고 다음 명령을 실행합니다. 컬 --version 이 명령은 현재 컬 버전 정보를 표시합니다. 사용 가능한 컬 버전 확인: 컬을 업데이트하기 전에 사용 가능한 최신 버전을 확인해야 합니다. 최신 버전의 컬을 찾으려면 컬의 공식 웹사이트(curl.haxx.se)나 관련 소프트웨어 소스를 방문하세요. 컬 소스 코드 다운로드: 컬 또는 브라우저를 사용하여 선택한 컬 버전의 소스 코드 파일(일반적으로 .tar.gz 또는 .tar.bz2)을 다운로드합니다.

처음부터 끝까지: PHP 확장 cURL을 사용하여 HTTP 요청을 만드는 방법 처음부터 끝까지: PHP 확장 cURL을 사용하여 HTTP 요청을 만드는 방법 Jul 29, 2023 pm 05:07 PM

처음부터 끝까지: HTTP 요청에 PHP 확장 cURL을 사용하는 방법 소개: 웹 개발에서는 종종 타사 API 또는 기타 원격 서버와 통신해야 합니다. cURL을 사용하여 HTTP 요청을 하는 것은 일반적이고 강력한 방법입니다. 이 기사에서는 PHP를 사용하여 cURL을 확장하여 HTTP 요청을 수행하는 방법을 소개하고 몇 가지 실용적인 코드 예제를 제공합니다. 1. 준비 먼저 php에 cURL 확장이 설치되어 있는지 확인하세요. 명령줄에서 php-m|grepcurl을 실행하여 확인할 수 있습니다.

PHP8.1 출시: 여러 요청을 동시에 처리하기 위한 컬(curl) 도입 PHP8.1 출시: 여러 요청을 동시에 처리하기 위한 컬(curl) 도입 Jul 08, 2023 pm 09:13 PM

PHP8.1 출시: 여러 요청의 동시 처리를 위한 컬 소개 최근 PHP는 여러 요청의 동시 처리를 위한 컬이라는 중요한 기능을 도입한 최신 버전의 PHP8.1을 공식 출시했습니다. 이 새로운 기능은 개발자에게 여러 HTTP 요청을 처리하는 보다 효율적이고 유연한 방법을 제공하여 성능과 사용자 경험을 크게 향상시킵니다. 이전 버전에서는 여러 요청을 처리하려면 여러 컬 리소스를 만들고 루프를 사용하여 각각 데이터를 보내고 받아야 하는 경우가 많았습니다. 이 방법으로 목적을 달성할 수는 있지만

PHP Curl에서 웹 페이지의 301 리디렉션을 처리하는 방법은 무엇입니까? PHP Curl에서 웹 페이지의 301 리디렉션을 처리하는 방법은 무엇입니까? Mar 08, 2024 am 11:36 AM

PHPCurl에서 웹 페이지의 301 리디렉션을 처리하는 방법은 무엇입니까? PHPCurl을 사용하여 네트워크 요청을 보낼 때 웹 페이지에서 반환된 301 상태 코드를 자주 접하게 되는데, 이는 페이지가 영구적으로 리디렉션되었음을 나타냅니다. 이 상황을 올바르게 처리하려면 Curl 요청에 몇 가지 특정 옵션과 처리 논리를 추가해야 합니다. 다음은 PHPCurl에서 웹페이지의 301 리디렉션을 처리하는 방법을 자세히 소개하고 구체적인 코드 예제를 제공합니다. 301 리디렉션 처리 원칙 301 리디렉션은 서버가 30을 반환한다는 의미입니다.

리눅스 컬이 뭐야? 리눅스 컬이 뭐야? Apr 20, 2023 pm 05:05 PM

Linux에서 컬은 서버와 데이터를 전송하는 매우 실용적인 도구입니다. 이는 명령줄에서 작동하는 URL 규칙을 사용하는 파일 전송 도구이며, 포괄적인 전송 도구입니다. Curl은 프록시 액세스, 사용자 인증, FTP 업로드 및 다운로드, HTTP POST, SSL 연결, 쿠키 지원, 중단점 재개 등 매우 유용한 기능을 많이 제공합니다.

PHP 컬에서 쿠키를 설정하는 방법 PHP 컬에서 쿠키를 설정하는 방법 Sep 26, 2021 am 09:27 AM

PHP 컬에서 쿠키를 설정하는 방법: 1. PHP 샘플 파일을 생성합니다. 2. "curl_setopt" 함수를 통해 cURL 전송 옵션을 설정합니다. 3. CURL에 쿠키를 전달합니다.

PHP 치명적인 오류에 대한 해결 방법: 정의되지 않은 함수 컬_setopt() 호출 PHP 치명적인 오류에 대한 해결 방법: 정의되지 않은 함수 컬_setopt() 호출 Jun 23, 2023 am 08:18 AM

PHP는 많은 웹사이트에서 널리 사용되는 오픈 소스 스크립팅 언어입니다. 그러나 때로는 웹사이트가 제대로 작동하지 못하게 할 수 있는 PHPFatalerror:Calltoundefoundfunctioncurl_setopt() 문제가 발생할 수 있습니다. 그렇다면 이 문제의 원인은 정확히 무엇입니까? PHP에서 컬_setopt()는 매우 중요한 함수로, 컬을 통해 라이브러리를 확장하는 데 사용됩니다.

See all articles