요청 받기 컬 PHP의 예. CURL PHP: 무엇이고 어떻게 사용하나요? POST 요청 사용 예

이 게시물에서는 cURL을 사용하는 방법, 사용 위치, 아직 이해하지 못한 경우 cURL을 이해해야 하는 이유를 예제와 함께 보여 드리겠습니다.

그것이 무엇인지, 무엇과 함께 먹는지 간략하게 설명하겠습니다.

Guzzle은 HTTP 요청 전송 프로세스를 단순화하기 위해 만들어졌습니다. 요청을 보내는 데 자주 사용됩니다. API그리고 일반적으로 무엇이든.

실제 예:

최근에 개발한 API가 있고 이제 작업을 시작할 시간입니다. 자신만의 라이브러리를 작성하거나 이를 사용하는 미니 클래스를 작성할 수도 있지만 (1) 시간이 많이 걸리고 그렇지 않더라도 솔루션이 최선이 아닐 가능성이 높습니다. ( 2) 지속적인 지원과 개선이 필요합니다. 이 경우에는 대규모 커뮤니티에서 지원하고 Guzzle 저장소에 이미 12,000개의 별이 있는 기성 솔루션을 사용하는 것이 좋습니다. 이는 매우 칭찬할만한 일입니다.

당신은 질문할 수 있습니다: 이미 많은 라이브러리가 있는데 이것이 왜 필요한가요?

Guzzle은 그 자체로 최고의 모든 것을 모아 더욱 향상시켰으며 이제 HTTP 요청 작업을 위한 가장 인기 있는 PHP 라이브러리입니다. 정말 멋지네요. 요청의 단순성을 살펴보세요.

// 기본 URI를 사용하여 클라이언트를 생성합니다. $client = new GuzzleHttp\Client(["base_uri" => "http://site/"]); // 이제 http://bologe로 요청을 보낼 수 있습니다. Guzzle은 기본 링크를 기억하므로 이제 편의를 위해 후속 페이지만 지정할 수 있습니다. $response = $client->request("GET", "about");

시원한? 좋아요.

Guzzle의 문서는 매우 광범위하여 모든 옵션을 설명하는 것은 불가능하며 전체 게시물이 필요하므로 곧 작성하겠습니다 :)

후문

궁금한 사항이 있는 경우 이 게시물에 아래 내용을 적어 주시면 기꺼이 도와드리겠습니다. 또한, 기사에 수정사항이 있거나 어딘가에 오류가 있거나 추가하고 싶은 내용이 있으면 언제든지 알려주시면 감사하겠습니다.

지난 기사에서 우리는 당신과 논의했습니다. 그러나 때로는 스크립트가 허용하는 경우도 있습니다. GET 요청(보통 검색 스크립트입니다). 그리고 그러한 스크립트로부터 데이터를 처리하고 수신하려면 다음을 수행할 수 있어야 합니다. cURL에서 GET 요청 보내기이 글을 읽으면 당신도 그 점을 배우게 될 것입니다.

원칙 cURL에서 GET 요청 보내기와 완전 똑같아 POST 방식으로 보내기: 있다 소스 파일그리고 거기에 대상 파일. 모듈을 사용하는 소스 파일 곱슬 곱슬하다, GET 요청을 보낸다대상 파일에. 대상 파일은 이 요청을 처리하고 다시 기능을 사용하여 소스 파일에서 허용되는 결과를 반환합니다. 곱슬 곱슬하다.

모든 것을 명확하게 하기 위해 우리가 본 간단한 예를 살펴보겠습니다. POST 요청 보내기. 즉, 소스 파일은 두 개의 숫자를 보내고, 대상 파일은 이 숫자의 합을 반환하며, 소스 파일은 이를 받아 변수에 쓴 다음 브라우저에 출력합니다.

우선 대상 파일(" 수신기.php"):

$a = $_GET["a"];
$b = $_GET["b"];
에코 $a + $b;
?>

여기서는 모든 것이 매우 간단합니다. 변수를 작성합니다. $a그리고 $b데이터 GET 요청, 그런 다음 소스 파일에서 허용되는 합계를 표시합니다.

이제 파일 자체를 만들어 보겠습니다.

CURL(클라이언트 URL) 라이브러리를 사용하면 다양한 인터넷 프로토콜을 사용하여 파일을 원격 컴퓨터로 전송할 수 있습니다. 구성이 매우 유연하며 거의 모든 원격 요청을 이행할 수 있습니다.

CURL은 HTTP, HTTPS, FTP, FTPS, DICT, TELNET, LDAP, FILE 및 GOPHER 프로토콜은 물론 HTTP-post, HTTP-put, 쿠키, FTP 업로드, 중단된 파일 전송 재개, 비밀번호, 포트 번호, 인증서 SSL을 지원합니다. , Kerberos 및 프록시.

CURL을 사용하면 웹 서버는 XML-RPC, SOAP 또는 WebDAV와 같은 HTTP 프로토콜 기반 서비스의 완전한 클라이언트 역할을 할 수 있습니다.

일반적으로 라이브러리 사용은 다음 네 단계로 이루어집니다.

  1. cur_init 함수를 사용하여 CURL 리소스를 생성합니다.
  2. 컬_setopt 함수를 사용하여 매개변수를 설정합니다.
  3. cur_exec 함수를 사용하여 요청을 실행합니다.
  4. cur_close 함수를 사용하여 CURL 리소스를 해제합니다.

CURL을 사용하는 간단한 예

// 컬 라이브러리 초기화
if ($ch = @curl_init())
{
// 요청 URL 설정
@curl_setopt($ch, CURLOPT_URL, "http://server.com/");
// true인 경우 CURL은 출력에 헤더를 포함합니다.
@
// 요청 결과를 저장할 위치:
// false - 표준 출력 스트림으로,
// true - 컬_exec 함수의 반환 값입니다.
@
// 최대 대기 시간(초)
@
// User-agent 필드의 값을 설정합니다.
@curl_setopt($ch, CURLOPT_USERAGENT, "PHP 봇(http://blog.yousoft.ru)");
// 요청을 실행합니다.
$data = @curl_exec($ch);
//받은 데이터를 출력한다
에코 $데이터 ;
// 리소스를 해제합니다.
@curl_close($ch);
}
?>

GET 요청 사용 예

$ch = 컬_초기화();
// GET 요청은 URL 라인에 지정됩니다.
cur_setopt($ch, CURLOPT_URL, "http://server.com/?s=CURL");
컬_setopt($ch, CURLOPT_HEADER, false);
컬_setopt($ch, CURLOPT_RETURNTRANSFER, true);
컬_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);

$data = 컬_exec($ch);
컬_닫기($ch);
?>

GET 요청을 보내는 것은 페이지를 받는 것과 다르지 않습니다. 쿼리 문자열은 다음과 같이 구성된다는 점에 유의하는 것이 중요합니다.

http://server.com/index.php?name1=value1&name2=value2&name3=value3

여기서 http://server.com/index.php는 페이지 주소, nameX는 변수 이름, valueX는 변수 값입니다.

POST 요청 사용 예

$ch = 컬_초기화();
cur_setopt($ch, CURLOPT_URL, "http://server.com/index.php");
컬_setopt($ch, CURLOPT_HEADER, false);
컬_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// POST 요청이 있을 것임을 명시적으로 나타내야 합니다.
컬_setopt($ch, CURLOPT_POST, true);
// 여기에 변수 값이 전달됩니다.
cur_setopt($ch, CURLOPT_POSTFIELDS, "s=CURL");
컬_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
cur_setopt($ch, CURLOPT_USERAGENT, "PHP 봇(http://mysite.ru)");
$data = 컬_exec($ch);
컬_닫기($ch);
?>

POST 요청을 보내는 것은 GET 요청을 보내는 것과 크게 다르지 않습니다. 모든 기본 단계는 동일하게 유지됩니다. 변수는 쌍으로 지정됩니다: name1=value1&name2=value2 .

HTTP 인증 예

// HTTP 인증
$url = "http://server.com/protected/";
$ch = 컬_초기화();


컬_setopt($ch, CURLOPT_USERPWD, "내 사용자 이름:내 비밀번호");
$결과 = 컬_exec($ch);
컬_닫기($ch);
에코 $결과 ;
?>

예제 FTP 세션

$fp = fopen(__FILE__, "r");
$url = "ftp://사용자 이름: [이메일 보호됨]:21/경로/to/newfile.php";
$ch = 컬_초기화();
컬_setopt($ch, CURLOPT_URL, $url);
컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
컬_setopt($ch, CURLOPT_UPLOAD, 1);
컬_setopt($ch, CURLOPT_INFILE, $fp);
컬_setopt($ch, CURLOPT_FTPASCII, 1);
컬_setopt($ch, CURLOPT_INFILESIZE, 파일 크기(__FILE__));
$결과 = 컬_exec($ch);
컬_닫기($ch);
?>

cURL을 사용하는 데 문제가 있는 경우, 마지막 요청에 대한 보고서를 얻으려면 컬_close를 호출하기 전에 다음 줄을 추가해야 합니다.

print_r(curl_getinfo($ch));
echo "cURL 오류 번호:" . 컬_errno($ch). "
" ;
echo "cURL 오류:" . 컬_오류($ch). "
" ;
컬_닫기($ch);
?>

cURL은 URL 구문을 사용하여 파일과 데이터를 전송하도록 설계된 특수 도구입니다. 이 기술은 HTTP, FTP, TELNET 등 다양한 프로토콜을 지원합니다. cURL은 원래 명령줄 도구로 설계되었습니다. 다행스럽게도 cURL 라이브러리는 PHP 프로그래밍 언어에서 지원됩니다. 이 기사에서는 cURL의 고급 기능 중 일부를 살펴보고, 습득한 지식을 PHP를 사용하여 실제로 적용하는 방법도 다룰 것입니다.

왜 cURL을 사용하나요?

실제로 웹페이지 콘텐츠를 샘플링하는 데는 몇 가지 대체 방법이 있습니다. 많은 경우 주로 게으름 때문에 cURL 대신 간단한 PHP 함수를 사용했습니다.

$content = file_get_contents("http://www.nettuts.com"); // 또는 $lines = file("http://www.nettuts.com"); // 또는 readfile("http://www.nettuts.com");

그러나 이러한 기능은 사실상 유연성이 없으며 오류 처리 등의 측면에서 엄청난 단점을 포함하고 있습니다. 또한 쿠키 상호 작용, 인증, 양식 제출, 파일 업로드 등 이러한 표준 기능으로는 수행할 수 없는 특정 작업이 있습니다.

cURL은 다양한 프로토콜과 옵션을 지원하고 URL 요청에 대한 자세한 정보를 제공하는 강력한 라이브러리입니다.

기본 구조

  • 초기화
  • 매개변수 할당
  • 실행 및 결과 가져오기
  • 메모리 확보

// 1. 초기화 $ch = cur_init(); // 2. URL을 포함한 매개변수를 지정합니다.curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 컬_setopt($ch, CURLOPT_HEADER, 0); // 3. 결과로 HTML을 얻습니다. $output = cur_exec($ch); // 4. 연결을 닫습니다. 컬_close($ch);

2단계(즉,curl_setopt() 호출)는 다른 모든 단계보다 이 문서에서 훨씬 더 많이 논의될 것입니다. 이 단계에서는 알아야 할 가장 흥미롭고 유용한 모든 일이 발생합니다. cURL에는 가장 신중한 방법으로 URL 요청을 구성하기 위해 지정해야 하는 다양한 옵션이 있습니다. 우리는 전체 목록을 고려하지 않고 이 수업에 필요하고 유용하다고 생각하는 것에만 초점을 맞출 것입니다. 이 주제에 관심이 있다면 다른 모든 것을 직접 공부할 수 있습니다.

오류 검사

또한 조건문을 사용하여 작업이 성공적으로 완료되었는지 테스트할 수도 있습니다.

// ... $output = 컬_exec($ch); if ($output === FALSE) ( echo "cURL 오류: " .curl_error($ch); ) // ...

여기서는 매우 중요한 점을 지적해 주시기 바랍니다. 비교를 위해 "== false" 대신 "=== false"를 사용해야 합니다. 잘 모르는 사람들을 위해 이는 빈 결과와 오류를 나타내는 부울 값 false를 구별하는 데 도움이 됩니다.

정보 수신

또 다른 추가 단계는 cURL 요청이 실행된 후 해당 요청에 대한 데이터를 얻는 것입니다.

// ... 컬_exec($ch); $info = 컬_getinfo($ch); echo "찍었어요" . $info["total_time"] . "URL의 초". $info["url"]; //…

반환된 배열에는 다음 정보가 포함됩니다.

  • "URL"
  • "컨텐츠 타입"
  • "http_코드"
  • "헤더_크기"
  • "요청_크기"
  • "파일 시간"
  • "ssl_verify_result"
  • "리디렉션_카운트"
  • "총 시간"
  • "이름 조회_시간"
  • “연결_시간”
  • “사전 환승_시간”
  • “크기_업로드”
  • “크기_다운로드”
  • "속도_다운로드"
  • "속도_업로드"
  • “다운로드 콘텐츠_길이”
  • “업로드_콘텐츠_길이”
  • “starttransfer_time”
  • "리디렉션_시간"

브라우저에 따른 리디렉션 감지

첫 번째 예에서는 다양한 브라우저 설정을 기반으로 URL 리디렉션을 감지할 수 있는 코드를 작성하겠습니다. 예를 들어, 일부 웹사이트는 휴대폰이나 기타 장치의 브라우저를 리디렉션합니다.

CURLOPT_HTTPHEADER 옵션을 사용하여 사용자의 브라우저 이름 및 사용 가능한 언어를 포함하여 나가는 HTTP 헤더를 정의하겠습니다. 결국 우리는 어떤 사이트가 우리를 다른 URL로 리디렉션하는지 확인할 수 있게 될 것입니다.

// URL 테스트 $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // 브라우저 테스트 $browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5 .6 (.NET CLR 3.5.30729)", "언어" => "en-us,en;q=0.5"), "iphone" => 배열 ("user_agent" => "Mozilla/5.0 (iPhone; U ; Mac OS X와 ​​같은 CPU; en) AppleWebKit/420+(KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3", "언어" => "en"), "프랑스어" => 배열("user_agent" => "Mozilla/4.0(호환; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "언어" => "fr,fr-FR;q=0.5")); foreach ($urls as $url) ( echo "URL: $url\n"; foreach ($browsers as $test_name => $browser) ( $ch = cur_init(); // URL 지정 cur_setopt($ch, CURLOPT_URL , $url); // 브라우저에 대한 헤더 지정curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["언어"] )" )); // 페이지의 내용은 필요하지 않습니다. cur_setopt($ch, CURLOPT_NOBODY, 1); // HTTP 헤더를 가져와야 합니다. cur_setopt($ch, CURLOPT_HEADER, 1); // 대신 결과를 반환합니다. 출력의 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = 컬_exec($ch); 컬_close($ch); // HTTP 리디렉션이 있었습니까? if (preg_match("!Location: (.*)!", $output, $matches)) ( echo " $test_name: $matches\n"로 리디렉션됩니다; ) else ( echo "$test_name: 리디렉션 없음\n"; ) ) echo "\n\n"; )

먼저 확인할 사이트의 URL 목록을 지정합니다. 보다 정확하게는 이러한 사이트의 주소가 필요합니다. 다음으로 이러한 각 URL을 테스트하기 위해 브라우저 설정을 정의해야 합니다. 그런 다음 얻은 모든 결과를 살펴보는 루프를 사용합니다.

이 예에서 cURL 설정을 지정하는 데 사용하는 트릭을 사용하면 페이지의 콘텐츠가 아니라 HTTP 헤더($output에 저장됨)만 가져올 수 있습니다. 다음으로, 간단한 정규식을 사용하여 "Location:" 문자열이 수신된 헤더에 존재하는지 여부를 확인할 수 있습니다.

이 코드를 실행하면 다음과 같은 결과가 나타납니다.

특정 URL에 대한 POST 요청 생성

GET 요청을 구성할 때 전송된 데이터는 "쿼리 문자열"을 통해 URL로 전달될 수 있습니다. 예를 들어, Google 검색을 수행하면 검색어가 새 URL의 주소 표시줄에 배치됩니다.

http://www.google.com/search?q=ruseller

이 요청을 시뮬레이션하기 위해 cURL을 사용할 필요는 없습니다. 게으름이 너무 심하다면 "file_get_contents()" 함수를 사용하여 결과를 얻으세요.

그러나 문제는 일부 HTML 양식이 POST 요청을 보낸다는 것입니다. 이러한 양식의 데이터는 이전 사례와 달리 HTTP 요청 본문을 통해 전송됩니다. 예를 들어, 포럼에서 양식을 작성하고 검색 버튼을 클릭하면 POST 요청이 이루어질 가능성이 높습니다.

http://codeigniter.com/forums/do_search/

이러한 종류의 URL 요청을 시뮬레이션할 수 있는 PHP 스크립트를 작성할 수 있습니다. 먼저 POST 데이터를 받아들이고 표시하는 간단한 파일을 만들어 보겠습니다. post_output.php라고 부르자:

Print_r($_POST);

그런 다음 cURL 요청을 수행하는 PHP 스크립트를 만듭니다.

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "Nettuts", "action" => "제출"); $ch = 컬_초기화(); 컬_setopt($ch, CURLOPT_URL, $url); 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // POST 요청이 있음을 나타냅니다. cur_setopt($ch, CURLOPT_POST, 1); // 변수 추가curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = 컬_exec($ch); 컬_닫기($ch); 에코 $ 출력;

이 스크립트를 실행하면 다음과 같은 결과가 나타나야 합니다.

따라서 POST 요청은 post_output.php 스크립트로 전송되었으며, 이는 다시 cURL을 사용하여 얻은 내용인 슈퍼전역 $_POST 배열을 출력합니다.

파일 업로드

먼저 파일을 생성하여 upload_output.php 파일로 보내겠습니다.

Print_r($_FILES);

위의 기능을 수행하는 스크립트 코드는 다음과 같습니다.

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // 업로드할 파일 "upload" => "@C:/wamp/www/test.zip"); $ch = 컬_초기화(); 컬_setopt($ch, CURLOPT_URL, $url); 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 컬_setopt($ch, CURLOPT_POST, 1); 컬_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = 컬_exec($ch); 컬_닫기($ch); 에코 $ 출력;

파일을 업로드하고 싶을 때 해야 할 일은 @ 기호 앞에 일반 게시물 변수로 파일을 전달하는 것뿐입니다. 작성된 스크립트를 실행하면 다음과 같은 결과를 얻게 됩니다.

다중 cURL

cURL의 가장 큰 장점 중 하나는 "다중" cURL 핸들러를 생성할 수 있다는 것입니다. 이를 통해 여러 URL에 대한 연결을 동시에 비동기적으로 열 수 있습니다.

cURL 요청의 클래식 버전에서는 스크립트 실행이 일시 중지되고 요청 URL 작업이 완료될 때까지 기다린 후 스크립트가 계속될 수 있습니다. 여러 URL과 상호 작용하려는 경우 클래식 버전에서는 한 번에 하나의 URL만 사용할 수 있으므로 상당한 시간 투자가 필요합니다. 그러나 특수 핸들러를 사용하면 이 상황을 해결할 수 있습니다.

php.net에서 가져온 예제 코드를 살펴보겠습니다.

// 여러 cURL 리소스 생성 $ch1 = cur_init(); $ch2 = 컬_init(); // URL 및 기타 매개변수를 지정합니다. curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); 컬_setopt($ch1, CURLOPT_HEADER, 0); 컬_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); 컬_setopt($ch2, CURLOPT_HEADER, 0); //다중 cURL 핸들러 생성 $mh = cur_multi_init(); //여러 핸들러 추가 컬_multi_add_handle($mh,$ch1); 컬_멀티_추가_핸들($mh,$ch2); $ 활성 = null; //실행 do ( $mrc ​​​​= cur_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc ​​​​== CURLM_OK) ( if (curl_multi_select($mh) != -1) ( do ( $mrc ​​​​= 컬_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) //curl_multi_remove_handle($mh, $ch1) 닫기; curl_multi_remove_handle($mh, $ch2); 컬_다중_닫기($mh);

아이디어는 여러 cURL 처리기를 사용할 수 있다는 것입니다. 간단한 루프를 사용하면 아직 완료되지 않은 요청을 추적할 수 있습니다.

이 예에는 두 개의 주요 루프가 있습니다. 첫 번째 do-while 루프는curl_multi_exec()를 호출합니다. 이 기능은 차단할 수 없습니다. 가능한 한 빨리 실행되고 요청 상태를 반환합니다. 반환된 값이 'CURLM_CALL_MULTI_PERFORM' 상수인 한 이는 작업이 아직 완료되지 않았음을 의미합니다(예: http 헤더가 현재 URL로 전송되고 있음). 이것이 바로 우리가 다른 결과를 얻을 때까지 이 반환 값을 계속 확인하는 이유입니다.

다음 루프에서는 변수 $active = "true"인 동안 조건을 확인합니다. curl_multi_exec() 함수의 두 번째 매개변수입니다. 기존 변경 사항이 활성화되어 있는 한 이 변수의 값은 "true"입니다. 다음으로 우리는 cur_multi_select() 함수를 호출합니다. 응답이 수신될 때까지 하나 이상의 활성 연결이 있는 동안 실행이 "차단"됩니다. 이런 일이 발생하면 메인 루프로 돌아가 쿼리 실행을 계속합니다.

이제 이 지식을 많은 사람들에게 정말 유용할 예시에 적용해 보겠습니다.

WordPress에서 링크 확인하기

엄청난 수의 게시물과 메시지가 있고 각 게시물과 메시지에는 외부 인터넷 리소스에 대한 링크가 포함되어 있는 블로그를 상상해 보십시오. 이러한 링크 중 일부는 여러 가지 이유로 이미 작동하지 않을 수 있습니다. 페이지가 삭제되었거나 사이트가 전혀 작동하지 않을 수 있습니다.

우리는 모든 링크를 분석하고 로딩되지 않는 웹사이트와 404페이지를 찾아 상세한 보고서를 제공하는 스크립트를 생성할 예정입니다.

이것은 WordPress용 플러그인을 만드는 예가 아니라는 점을 바로 말씀드리겠습니다. 이것은 우리 테스트를 위한 절대적으로 좋은 테스트 장소입니다.

드디어 시작해 보겠습니다. 먼저 데이터베이스에서 모든 링크를 가져와야 합니다.

// 구성 $db_host = "localhost"; $db_user = "루트"; $db_pass = ""; $db_name = "워드프레스"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // 변수 초기화 $url_list = array(); $working_urls = 배열(); $dead_urls = 배열(); $not_found_urls = 배열(); $ 활성 = null; // MySQL에 연결 if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("연결할 수 없습니다: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("연결할 수 없습니다. not select db: " . mysql_error()); ) // 링크가 있는 모든 게시된 게시물을 선택합니다. $q = "SELECT post_content FROM wp_posts WHERE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post " "; $r = mysql_query($q) 또는 die(mysql_error()); while ($d = mysql_fetch_assoc($r)) ( // 정규식을 사용하여 링크를 가져옵니다. if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $ match) ) ( foreach ($matches as $url) ( $tmp = parse_url($url); if (in_array($tmp["host"], $excluded_domains)) ( continue; ) $url_list = $url; ) ) ) / / 중복 제거 $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("확인할 URL이 없습니다."); )

먼저 데이터베이스와의 상호 작용을 위한 구성 데이터를 생성한 다음 검사에 참여하지 않을 도메인 목록($excluded_domains)을 작성합니다. 또한 스크립트에서 사용할 최대 동시 연결 수를 나타내는 숫자($max_connections)를 정의합니다. 그런 다음 데이터베이스에 가입하고 링크가 포함된 게시물을 선택하여 배열($url_list)에 누적합니다.

다음 코드는 약간 복잡하므로 처음부터 끝까지 살펴보세요.

// 1. 다중 핸들러 $mh = cur_multi_init(); // 2. ($i = 0; $i에 대한 URL 세트를 추가합니다.< $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. инициализация выполнения do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 4. основной цикл while ($active && $mrc == CURLM_OK) { // 5. если всё прошло успешно if (curl_multi_select($mh) != -1) { // 6. делаем дело do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 7. если есть инфа? if ($mhinfo = curl_multi_info_read($mh)) { // это значит, что запрос завершился // 8. извлекаем инфу $chinfo = curl_getinfo($mhinfo["handle"]); // 9. мёртвая ссылка? if (!$chinfo["http_code"]) { $dead_urls = $chinfo["url"]; // 10. 404? } else if ($chinfo["http_code"] == 404) { $not_found_urls = $chinfo["url"]; // 11. рабочая } else { $working_urls = $chinfo["url"]; } // 12. чистим за собой curl_multi_remove_handle($mh, $mhinfo["handle"]); // в случае зацикливания, закомментируйте данный вызов curl_close($mhinfo["handle"]); // 13. добавляем новый url и продолжаем работу if (add_url_to_multi_handle($mh, $url_list)) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } } } // 14. завершение curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n",$dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если у нас есть ещё url, которые нужно достать if ($url_list[$index]) { // новый curl обработчик $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_multi_add_handle($mh, $ch); // переходим на следующий url $index++; return true; } else { // добавление новых URL завершено return false; } }

여기서는 모든 것을 자세히 설명하려고 노력할 것입니다. 목록의 숫자는 주석의 숫자와 일치합니다.

  1. 1. 다중 핸들러를 생성하십시오.
  2. 2. add_url_to_multi_handle() 함수는 잠시 후에 작성하겠습니다. 호출될 때마다 새 URL 처리가 시작됩니다. 처음에는 10개($max_connections)개의 URL을 추가합니다.
  3. 3. 시작하려면, cur_multi_exec() 함수를 실행해야 합니다. CURLM_CALL_MULTI_PERFORM을 반환하는 한 아직 해야 할 일이 있습니다. 이는 주로 연결을 생성하는 데 필요합니다.
  4. 4. 다음은 적어도 하나의 활성 연결이 있는 한 실행되는 메인 루프입니다.
  5. 5. URL 검색이 완료될 때까지 컬_멀티_선택()이 정지됩니다.
  6. 6. 다시 한번, 일부 작업, 즉 반환 응답 데이터를 가져오기 위해 cURL을 가져와야 합니다.
  7. 7. 여기에서 정보를 확인합니다. 요청을 실행한 결과 배열이 반환됩니다.
  8. 8. 반환된 배열에는 cURL 처리기가 포함되어 있습니다. 이를 사용하여 별도의 cURL 요청에 대한 정보를 선택합니다.
  9. 9. 링크가 끊어졌거나 스크립트 시간이 초과된 경우 http 코드를 검색해서는 안 됩니다.
  10. 10. 링크가 404 페이지를 반환한 경우 http 코드에는 값 404가 포함됩니다.
  11. 11. 그렇지 않으면 우리 앞에 작동 링크가 있습니다. (오류 코드 500 등에 대한 추가 검사를 추가할 수 있습니다...)
  12. 12. 다음으로 cURL 핸들러는 더 이상 필요하지 않으므로 제거합니다.
  13. 13. 이제 다른 URL을 추가하고 이전에 이야기한 모든 내용을 실행할 수 있습니다.
  14. 14. 이 단계에서 스크립트는 작업을 완료합니다. 필요하지 않은 모든 것을 제거하고 보고서를 생성할 수 있습니다.
  15. 15. 마지막으로 핸들러에 URL을 추가하는 함수를 작성하겠습니다. 이 함수가 호출될 때마다 정적 변수 $index가 증가합니다.

나는 내 블로그에서 이 스크립트를 사용했고(테스트를 위해 일부러 깨진 링크를 추가했습니다) 다음과 같은 결과를 얻었습니다.

내 경우에는 스크립트가 40개의 URL을 크롤링하는 데 2초도 채 걸리지 않았습니다. 더 많은 URL로 작업할 때 성능이 크게 향상됩니다. 동시에 10개의 연결을 열면 스크립트가 10배 더 빠르게 실행될 수 있습니다.

다른 유용한 cURL 옵션에 대한 몇 마디

HTTP 인증

URL에 HTTP 인증이 있으면 다음 스크립트를 쉽게 사용할 수 있습니다.

$url = "http://www.somesite.com/members/"; $ch = 컬_초기화(); 컬_setopt($ch, CURLOPT_URL, $url); 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 사용자 이름과 비밀번호를 지정합니다. cur_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // 리디렉션이 허용되는 경우 cur_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 그런 다음 cURL에 데이터를 저장합니다. cur_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = 컬_exec($ch); 컬_닫기($ch);

FTP 업로드

PHP에는 FTP 작업을 위한 라이브러리도 있지만 여기서 cURL 도구를 사용하는 데 방해가 되는 것은 없습니다.

// 파일 열기 $file = fopen("/path/to/file", "r"); // URL에는 다음 내용이 포함되어야 합니다. $url = "ftp://username: [이메일 보호됨]:21/path/to/new/file"; $ch = 컬_init(); 컬_setopt($ch, CURLOPT_URL, $url); 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 컬_setopt($ch, CURLOPT_UPLOAD, 1); curl_setopt($ch, CURLOPT_INFILE, $fp);curl_setopt($ch, CURLOPT_INFILESIZE,filesize("/path/to/file")); //ASCII 모드 지정curl_setopt($ch, CURLOPT_FTPASCII, 1); $output = 컬_exec($ch), 컬_닫기($ch);

프록시 사용

프록시를 통해 URL 요청을 수행할 수 있습니다.

$ch = 컬_초기화(); 컬_setopt($ch, CURLOPT_URL,"http://www.example.com"); 컬_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 주소 지정 cur_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // 사용자 이름과 비밀번호를 제공해야 하는 경우 cur_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = 컬_exec($ch); 컬_닫기($ch);

콜백 함수

cURL 요청이 완료되기 전에도 트리거될 함수를 지정할 수도 있습니다. 예를 들어 응답 콘텐츠가 로드되는 동안 완전히 로드될 때까지 기다리지 않고 데이터 사용을 시작할 수 있습니다.

$ch = 컬_초기화(); cur_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); 컬_setopt($ch, CURLOPT_WRITEFUNCTION,"진행_기능"); 컬_exec($ch); 컬_닫기($ch); 함수 Progress_function($ch,$str) ( echo $str; return strlen($str); )

이와 같은 함수는 요구 사항인 문자열 길이를 반환해야 합니다.

결론

오늘 우리는 cURL 라이브러리를 자신의 이기적인 목적으로 사용하는 방법을 배웠습니다. 이 기사를 즐겼기를 바랍니다.

감사합니다! 좋은 하루 보내세요!



 

다음 내용을 읽어보는 것이 도움이 될 수 있습니다.