5.6.1, 5.5.17로 업데이트 후 cURL을 사용하시는 분들은 cURL 모듈이 작동을 멈춘다는 사실에 직면했습니다. 그 이후로 문제는 사라지지 않았습니다. 최신 버전의 PHP 5.6.4에서도 이 문제가 지속되었습니다.

cURL이 작동하는지 어떻게 알 수 있습니까?

만들다 PHP 파일거기에 복사하십시오 :

서버에서 엽니다. 출력이 다음과 같은 경우:

배열( => 468736 => 3 => 3997 => 0 => 7.39.0 => x86_64-pc-win32 => OpenSSL/1.0.1j => 1.2.7.3 => 배열( => dict => 파일 => ftp => ftps => gopher => http => https => imap => imaps => ldap => pop3 => pop3s => rtsp => scp => sftp => smtp => smtps => telnet => tftp) )

따라서 cURL은 괜찮습니다. 대신 PHP 오류라면 문제가 있는 것입니다.

먼저, 물론 php.ini 파일을 확인하고 거기에 있는 줄을 찾으십시오.

확장자=php_curl.dll

그리고 세미콜론이 앞에 오지 않았는지 확인하십시오.

이 경우 cURL이 작동하지 않으면 비정상적인 상황을 확인하기 위해 다른 테스트를 수행할 수 있습니다. 내용이 포함된 다른 PHP 파일을 만듭니다.

브라우저에서 cURL을 검색합니다. 일치하는 항목이 하나만 있으면 cURL 모듈이 로드되지 않습니다.

동시에 Apache와 PHP는 모두 평소와 같이 작동합니다.

세 가지 솔루션:

  1. 방법 1(정결하지 않음). PHP 5.6.*이 있는 경우 PHP 5.6.0 버전을 사용합니다. 거기에서 이전 파일 php_curl.dll을 가져와서 버전의 새 파일(예: PHP 5.6.4)로 바꿉니다. PHP 5.5.17 이상을 사용하는 경우 PHP 5.5.16에서 동일한 파일을 가져와서 교체해야 합니다. 여기서 유일한 문제는 이러한 이전 버전을 찾는 것입니다. 물론 http://windows.php.net/downloads/snaps/php-5.6 을 둘러볼 수 있지만 개인적으로 필요한 것을 찾지 못했습니다. 그리고 결정 자체는 어떻게 든 아주 정결하지 않습니다.
  2. 두 번째 방법(매우 빠르지만 정결하지 않음). PHP 디렉토리에서 Apache24bin 디렉토리로 libssh2.dll 파일을 복사하고 Apache를 다시 시작하십시오.
  3. 방법 3(정결한 - 정결한 사람들이 서서 박수를 친다). PHP 디렉토리를 PATH에 추가해야 합니다. 이 작업을 수행하는 방법은 공식 문서에 잘 설명되어 있습니다.

우리는 다음을 확인합니다:

짜잔, cURL 섹션이 있습니다.

왜 그런 겁니까? 이 문제는 어디에서 왔습니까? 발생 메커니즘이 이미 설명되었지만 이 질문에 대한 답은 없습니다.

문제는 5.6.1이 업데이트된 libcurl 7.38.0과 함께 출시되어야 한다는 사실과 관련이 있는 것 같습니다. 그러나 이것은 확실하지 않다고 PHP 작성자는 Apache에 몇 가지 버그가 있다고 고개를 끄덕입니다.

문제의 메커니즘: 시스템 PATH가 포함되지 않은 경우 PHP 디렉토리, Apache 서비스가 시작될 때 php_curl에 대한 종속성인 새 dll(libssh2.dll)을 찾을 수 없습니다.

관련 버그 보고서:

치명적인 오류: 정의되지 않은 함수 curl_multi_init() 호출 ...

일반적으로 PHP의 cURL에 문제가 있었습니다. 항상 그런 것은 아니지만 매우 자주 발생하는 것 같습니다. 내 문제를 인터넷 검색하는 과정에서 스레드를 발견했는데 그 중 일부는 12년이 넘었습니다.

또한 인터넷 검색을 통해 다음과 같은 몇 가지 결론을 얻었습니다.

php.ini 파일에서 extension=php_curl.dll 행의 주석을 제거하는 방법을 사진과 함께 자세히 설명하는 "바보를 위한 지침"이 인터넷에 충분합니다.

공식 PHP 사이트의 cURL 설치 섹션에는 Windows 시스템에 대한 두 가지 제안만 있습니다.

이 모듈을 사용하려면 Windows 파일 libeay32.dll 및 ssleay32.dll이 시스템에 있어야 합니다. 환경 변수길. cURL 사이트의 libcurl.dll 파일은 필요하지 않습니다.

나는 그것들을 열 번 읽었다. 로 전환됨 영어그리고 영어로 몇 번 더 읽어보세요. 매번, 이 두 문장이 동물에 의해 쓰여졌거나 누군가가 방금 키보드를 뛰어 넘었다는 것을 점점 더 확신하게 되었습니다. 나는 그 의미를 이해하지 못합니다.

미친 팁과 지침도 있습니다.

PHP 버그 보고서 사이트에서 나는 이미 PATH 시스템 변수에 PHP가 있는 디렉토리를 포함해야 할 필요성을 풀기 직전에 이르렀습니다.

일반적으로 cURL에 문제가 있고 "PATH 시스템 변수에 PHP가 있는 디렉토리를 포함"해야 하는 사용자의 경우 http://php.net/manual/ru/faq.installation에서 이미 언급한 지침으로 이동하십시오. .php#faq .installation.addtopath . 모든 것이 간단하고 가장 중요한 것은 수행해야 할 작업이 인간의 언어로 쓰여 있다는 것입니다.

PHP 5.2.3, Windows XP, Apache 1.3.33이 있습니다.
문제 - PHP가 Apache에서 실행되는 경우 cURL 모듈이 감지되지 않습니다.
php.ini extension=php_curl.dll에서 주석 처리가 제거되고 extension_dir이 올바르게 설정됩니다.
libeay32.dll 및 ssleay32.dll이 c:\windows\system32에 복사됩니다.
그러나 phpinfo() 함수는 설치된 모듈 중 cURL 모듈을 표시하지 않으며, Apache가 시작되면 다음과 같이 로그에 기록됩니다.

PHP 시작: 동적 라이브러리 "c:/php/ext/php_curl.dll"을 로드할 수 없습니다. - 지정된 모듈을 찾을 수 없습니다.

에서 PHP를 실행하면 명령줄, cURL의 명령을 포함하는 스크립트는 제대로 작동하고 Apache에서 실행하면 다음을 제공합니다.
치명적인 오류: 정의되지 않은 함수 호출: curl_init() - PHP 설치 방법에 관계없이 - CGI 또는 모듈로.

인터넷에서 특히 cURL 모듈에 대한 이 문제에 대한 설명을 반복적으로 접했지만 거기에서 제안된 솔루션은 도움이 되지 않습니다. 그리고 이미 PHP 5.2를 PHP 5.2.3으로 변경했지만 여전히 도움이 되지 않았습니다.

데이비드 므자울리안 [서류]
php.ini가 하나 있습니다. 디스크를 검색하여 확인했습니다. 동일한 php.ini가 사용된다는 사실은 변경 사항이 Apache 및 명령줄에서 스크립트 실행에 모두 영향을 미친다는 사실로도 쉽게 확인할 수 있습니다.

다닐 이바노프 [서류] 전화로 파일을 만드는 것이 좋습니다.

그리고 브라우저로 엽니다.
그런 다음 명령에서 실행하십시오. PHP 라인-나 | grep ini를 실행하고 디스크에 파일이 있는지 여부가 아니라 php가 볼 때 php.ini에 대한 경로를 확인합니다.

다닐 이바노프 [서류] php -i는 무엇을 출력합니까? 기본 바이너리는 컴파일 옵션에 따라 다른 곳에서 구성을 찾을 수 있습니다. mod_php.dll과 php.exe가 서로 다른 ini 파일을 보고 하나에서 작동하는 파일이 다른 파일에서 작동하지 않는다는 사실을 알게 된 것은 이번이 처음이 아닙니다.

바실리 스비리도프 [서류]
php -i는 다음을 생성합니다.

구성 파일(php.ini) 경로 => C:\WINDOWS
로드된 구성 파일 => C:\PHP\php.ini

php.ini 파일을 디렉토리로 이동 Windows 상황변하지 않는다.

다닐 이바노프 [서류]
나머지 모듈은 어떻습니까? 예를 들어 php_mysql??? 연결 중? 아니면 너무 불쾌한 cURL입니까?

흠, 저에게도 로드되지 않습니다... 매우 다른 구성에서(Zend Studio에서 Apache 2.2와 PHP 5.1.6). 하지만 그게 핵심이 아닙니다. 명령줄(더 정확하게는 FAR에서)에서 Apache를 실행하는 실험은 흥미로운 것을 보여주었습니다. Kurl 연결을 시도하지 않고 모든 것이 번들로 시작됩니다. Kurl을 연결하려고 하면 ... php5ts.dll에서 오류가 발생합니다.

안녕하세요!
나는 비슷한 문제가 있었고 오랫동안 해결책을 찾고 있었는데 더 넣어 새로운 버전 PHP는 결국 이 포럼을 찾았습니다. 여기에는 해결책이 없었기 때문에 스스로 더 노력했습니다.

나는 나 자신을 위해 zend 스튜디오를 설정했고, 그 전에 PHP의 이전 버전이 있었습니다. 아마도 그들 중 하나가 그들의 라이브러리를 설치했고 그것들은 거기에 구식으로 남아 있었습니다.

팁, 특히 "Nehxby"의 마지막 팁에 감사드립니다. 나는 C:\windows\system32에 들어가서 라이브러리 libeay32.dll과 ssleay32.dll이 원본과 같은 크기가 아니라는 것을 발견했습니다. 아마도 그 이후에 memcached를 설치했습니다. 따라서 chot를 추가했다면 system32에서 go :)

같은 문제가 있었고 php -i 명령을 사용했습니다 | 그렙 이니
zlib1.dll 라이브러리가 누락되었음을 보여줍니다.
그것은 Apache가있는 폴더에 있었고 PHP가있는 폴더에 사본을 작성했습니다.
명령을 반복했는데 zlib.dll 라이브러리가 충분하지 않다는 것을 보여주고 Apache 폴더에 작성했는데 모두 작동했습니다.
모든 라이브러리도 php5ts.dll이므로 필요한 모든 라이브러리의 존재를 고려하십시오.

추가하기로 결정했습니다. 나는 또한이 문제에 직면했기 때문에. 다른 사이트의 링크를 통해 이 포럼을 알게 되었습니다. 일반적으로 제안된 모든 옵션은 목발에 불과합니다. Windows 솔루션의 본질. PATH 변수를 설정해야 합니다. PHP가 있는 위치를 지정합니다. 그리고 할렐루야 컬은 오류를 던지지 않습니다. 다른 도서관처럼...

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

왜 cURL인가?

사실, 많은 대체 방법웹 페이지의 콘텐츠를 가져옵니다. 대부분의 경우 게으름으로 인해 간단한 PHP 함수 cURL 대신:

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

그러나 이러한 기능은 사실상 유연성이 없으며 오류 처리 등의 측면에서 많은 단점이 있습니다. 또한 쿠키와의 상호 작용, 인증, 양식 제출, 파일 업로드 등과 같은 표준 기능으로는 해결할 수 없는 특정 작업이 있습니다.

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

기본 구조

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

// 1. 초기화 $ch = curl_init(); // 2. url을 포함한 옵션 지정 curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. 결과로 HTML 가져오기 $output = curl_exec($ch); // 4. 연결을 닫습니다. curl_close($ch);

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

오류 확인

또한 다음을 사용할 수도 있습니다. 조건문작업이 성공했는지 확인하려면:

// ... $출력 = curl_exec($ch); if ($output === FALSE) ( echo "cURL 오류: " . curl_error($ch); ) // ...

여기서 나는 당신이 매우 주목하기를 요청합니다. 중요한 포인트: 비교를 위해 "== false" 대신 "=== false"를 사용해야 합니다. 잘 모르는 사람들을 위해 이것은 빈 결과와 오류를 나타내는 거짓 부울 값을 구별하는 데 도움이 될 것입니다.

정보 수신

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

// ... curl_exec($ch); $info = curl_getinfo($ch); echo "잡았다" . $info["총_시간"] . " url 초 " . $정보["URL"]; // ...

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

  • "URL"
  • "컨텐츠 타입"
  • http_code
  • "header_size"
  • "요청_크기"
  • "파일 시간"
  • "ssl_verify_result"
  • "redirect_count"
  • "총 시간"
  • "이름 조회_시간"
  • "연결_시간"
  • "사전 전송 시간"
  • "크기_업로드"
  • 크기_다운로드
  • "속도_다운로드"
  • "속도 업로드"
  • "다운로드_콘텐츠_길이"
  • "업로드_콘텐츠_길이"
  • "starttransfer_time"
  • "redirect_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+ (Gecko와 같은 KHTML) Version/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "french" => 배열("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 = curl_init(); // URL 지정 curl_setopt($ch, CURLOPT_URL, $url); // 브라우저 헤더 설정 curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: ($browser["user_agent"])", "Accept-Language: ($browser["language"])" ) ); // 페이지 내용이 필요하지 않습니다 curl_setopt($ch, CURLOPT_NOBODY, 1); // HTTP 헤더를 가져와야 합니다 curl_setopt($ch, CURLOPT_HEADER, 1); // 출력 대신 결과를 반환 curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_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/

우리는 쓸 수있다 PHP 스크립트, 이러한 종류의 요청 URL을 모방할 수 있습니다. 먼저 POST 데이터를 수락하고 표시하는 간단한 파일을 만들어 보겠습니다. post_output.php라고 부르겠습니다.

Print_r($_POST);

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

$url = "http://localhost/post_output.php"; $post_data = array("foo" => "bar", "query" => "Nettuts", "action" => "제출"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // POST 요청이 있음을 나타냅니다. curl_setopt($ch, CURLOPT_POST, 1); // 변수 추가 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $출력 = curl_exec($ch); curl_close($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 = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $출력 = curl_exec($ch); curl_close($ch); 에코 $출력;

파일을 업로드하고 싶을 때 평소대로 업로드하기만 하면 됩니다. 포스트 변수, 앞에 @ 기호를 추가합니다. 작성된 스크립트를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

다중 cURL

가장 중 하나 강점 cURL은 "여러" cURL 처리기를 만드는 기능입니다. 이를 통해 동시에 비동기적으로 여러 URL에 대한 연결을 열 수 있습니다.

cURL 요청의 클래식 버전에서는 스크립트 실행이 일시 중단되고 URL 요청 작업이 완료될 것으로 예상되며 그 후에 스크립트를 계속할 수 있습니다. 많은 URL과 상호 작용하려는 경우 고전적인 경우 한 번에 하나의 URL로만 작업할 수 있기 때문에 시간이 많이 소요됩니다. 그러나 특수 처리기를 사용하여 이 상황을 해결할 수 있습니다.

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

// cURL 리소스를 생성합니다. $ch1 = curl_init(); $ch2 = curl_init(); // URL 및 기타 매개변수 지정 curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); curl_setopt($ch2, CURLOPT_HEADER, 0); // 다중 cURL 핸들러 생성 $mh = curl_multi_init(); //여러 핸들러 추가 curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $ 활성 = 널; //실행 do ( $mrc ​​​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc ​​​​== CURLM_OK) ( if (curl_multi_select($mh) != -1) ( do ( $mrc ​​​​= curl_multi_exec($mh, $active); ) while ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) // curl_multi_remove_handle($mh, $ch1) 닫기 curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

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

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

다음 루프에서 $active = "true"인 동안 조건을 확인합니다. curl_multi_exec() 함수의 두 번째 매개변수입니다. 이 변수의 값은 기존 변경 사항이 활성화되어 있는 한 "true"입니다. 다음으로 curl_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 = 배열(); $ 활성 = 널; // MySQL에 연결 if (!mysql_connect($db_host, $db_user, $db_pass)) ( die("연결할 수 없음: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Could 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"], $matches)) ( foreach ($url로 $matches) ( $tmp = parse_url($url) ; if (in_array($tmp["host"], $excluded_domains)) ( 계속; ) $url_list = $url; ) ) ) // 중복 제거 $url_list = array_values(array_unique($url_list)); if (!$url_list) ( die("확인할 URL이 없습니다"); )

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

다음 코드는 약간 복잡하므로 처음부터 끝까지 이해하십시오.

// 1. 다중 핸들러 $mh = curl_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이 처리됩니다. 처음에는 URL 10개($max_connections)를 추가합니다.
  3. 3. 시작하려면 curl_multi_exec() 함수를 실행해야 합니다. CURLM_CALL_MULTI_PERFORM을 반환하는 한 아직 해야 할 일이 있습니다. 우리는 주로 연결을 생성하기 위해 이것이 필요합니다.
  4. 4. 다음은 적어도 하나의 활성 연결이 있는 한 실행될 메인 루프입니다.
  5. 5. URL 조회가 완료될 때까지 curl_multi_select()가 멈춥니다.
  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 = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 사용자 이름과 비밀번호 지정 curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // 리디렉션이 허용되는 경우 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 그런 다음 cURL에 데이터를 저장합니다. curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $출력 = curl_exec($ch); curl_close($ch);

FTP 업로드

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

// 파일 열기 $file = fopen("/path/to/file", "r"); // URL은 다음 내용을 포함해야 합니다. $url = "ftp://username: [이메일 보호됨]:21/경로/to/new/file"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_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 = curl_exec ($ch); curl_close($ch);

프록시 사용

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

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 주소 지정 curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // 사용자 이름과 비밀번호를 제공해야 하는 경우 curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $출력 = curl_exec($ch); curl_close($ch);

콜백

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

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function"); curl_exec($ch); curl_close($ch); function progress_function($ch,$str) ( echo $str; return strlen($str); )

이러한 함수는 요구 사항인 문자열의 길이를 반환해야 합니다(MUST).

결론

오늘 우리는 cURL 라이브러리를 이기적인 목적으로 사용하는 방법에 대해 알게 되었습니다. 이 기사를 즐겼기를 바랍니다.

고맙습니다! 좋은 하루 보내세요!