현재 위치: > 최신 기사 목록> curl_multi_add_handle 함수가 청크 업로드 및 다운로드 작업에 어떻게 적용되는지에 대한 처리 방법은 무엇입니까?

curl_multi_add_handle 함수가 청크 업로드 및 다운로드 작업에 어떻게 적용되는지에 대한 처리 방법은 무엇입니까?

M66 2025-06-22

curl_multi_add_handle 함수가 청크 업로드 및 다운로드 작업에 어떻게 적용되는지에 대한 처리 방법은 무엇입니까?

Curl_multi_add_handle은 PHP에서 여러 동시 HTTP 요청을 처리 할 때 CURL 멀티 인터페이스의 주요 기능 중 하나입니다. 이를 통해 단일 핸들을 멀티 핸들 세션에 결합하여 비 블로킹 동시 처리를 가능하게합니다. 이 메커니즘은 대형 파일을 처리 해야하는 청크 업로드 및 다운로드 시나리오에 매우 유용합니다.

1. 청크에서 작업을 업로드하는 처리 방법

블록 업로드의 기본 아이디어는 큰 파일을 여러 개의 작은 조각으로 분할 한 다음이 작은 조각을 동시에 업로드하는 것입니다. curl_multi_add_handle을 사용하면 업로드 효율을 크게 향상시킬 수 있습니다.

샘플 흐름 :

  1. 대형 파일을 여러 개의 작은 파일 청크로 분할합니다 ( fread () 로 수동으로 청크 할 수 있음).

  2. 각 블록에 대한 독립적 인 요청을 만듭니다 (PUT 또는 POST 메소드 사용).

  3. 이 요청 핸들을 curl_multi_init () 에서 만든 다중 핸들 관리자에 추가하십시오.

  4. curl_multi_exec ()를 사용하여 모든 업로드 요청을 동시에 실행하도록 유도하십시오.

간단한 샘플 코드 :

 <span><span><span class="hljs-variable">$multiHandle</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_init</span></span><span>();
</span><span><span class="hljs-variable">$chunkFiles</span></span><span> = [</span><span><span class="hljs-string">'chunk1.bin'</span></span><span>, </span><span><span class="hljs-string">'chunk2.bin'</span></span><span>, </span><span><span class="hljs-string">'chunk3.bin'</span></span><span>]; </span><span><span class="hljs-comment">// 샘플 블록 파일</span></span><span>
</span><span><span class="hljs-variable">$curlHandles</span></span><span> = [];

</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$chunkFiles</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$index</span></span><span> =&gt; </span><span><span class="hljs-variable">$file</span></span><span>) {
    </span><span><span class="hljs-variable">$ch</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_init</span></span><span>(</span><span><span class="hljs-string">'https://example.com/upload_chunk'</span></span><span>);
    </span><span><span class="hljs-variable">$fileData</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>);

    </span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>, CURLOPT_RETURNTRANSFER, </span><span><span class="hljs-literal">true</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>, CURLOPT_POSTFIELDS, </span><span><span class="hljs-variable">$fileData</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>, CURLOPT_HTTPHEADER, [
        </span><span><span class="hljs-string">'Content-Type: application/octet-stream'</span></span><span>,
        </span><span><span class="hljs-string">'Content-Length: '</span></span><span> . </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$fileData</span></span><span>),
        </span><span><span class="hljs-string">'X-Chunk-Index: '</span></span><span> . </span><span><span class="hljs-variable">$index</span></span><span>
    ]);

    </span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-variable">$curlHandles</span></span><span>[] = </span><span><span class="hljs-variable">$ch</span></span><span>;
}

</span><span><span class="hljs-comment">// 모든 업로드 작업을 수행하십시오</span></span><span>
</span><span><span class="hljs-variable">$running</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-keyword">do</span></span><span> {
    </span><span><span class="hljs-title function_ invoke__">curl_multi_exec</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$running</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_multi_select</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>);
} </span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$running</span></span><span> &gt; </span><span><span class="hljs-number">0</span></span><span>);

</span><span><span class="hljs-comment">// 리소스 정리</span></span><span>
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$curlHandles</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$ch</span></span><span>) {
    </span><span><span class="hljs-title function_ invoke__">curl_multi_remove_handle</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_close</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>);
}
</span><span><span class="hljs-title function_ invoke__">curl_multi_close</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>);
</span></span>

2. 블록 다운로드 작업을 처리하는 방법

블록 다운로드의 경우 동일한 메커니즘이 적용됩니다. 범위 헤더를 설정하면 파일의 특정 바이트 간격을 요청하여 전체 파일의 다른 부분을 동시에 다운로드 한 다음 해당 부분을 병합 할 수 있습니다.

단계 설명 :

  1. 대상 파일의 총 크기를 가져옵니다.

  2. 예를 들어 세그먼트 1MB 자당 여러 세그먼트로 나눕니다.

  3. 각 세그먼트에 대한 범위 헤더로 요청을 작성하십시오.

  4. curl_multi_add_handle을 사용하여 동시 다운로드를 위해 멀티 핸들 세션을 추가하십시오.

  5. 다운로드 결과를 순서대로 병합하십시오.

간단한 코드 예 :

 <span><span><span class="hljs-variable">$url</span></span><span> = </span><span><span class="hljs-string">'https://example.com/largefile.zip'</span></span><span>;
</span><span><span class="hljs-variable">$fileSize</span></span><span> = </span><span><span class="hljs-number">10000000</span></span><span>; </span><span><span class="hljs-comment">// 파일 크기가 있다고 가정합니다10MB</span></span><span>
</span><span><span class="hljs-variable">$chunkSize</span></span><span> = </span><span><span class="hljs-number">1000000</span></span><span>;  </span><span><span class="hljs-comment">// 각 조각1MB</span></span><span>
</span><span><span class="hljs-variable">$multiHandle</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_init</span></span><span>();
</span><span><span class="hljs-variable">$curlHandles</span></span><span> = [];
</span><span><span class="hljs-variable">$results</span></span><span> = [];

</span><span><span class="hljs-keyword">for</span></span><span> (</span><span><span class="hljs-variable">$start</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>; </span><span><span class="hljs-variable">$start</span></span><span> &lt; </span><span><span class="hljs-variable">$fileSize</span></span><span>; </span><span><span class="hljs-variable">$start</span></span><span> += </span><span><span class="hljs-variable">$chunkSize</span></span><span>) {
    </span><span><span class="hljs-variable">$end</span></span><span> = </span><span><span class="hljs-title function_ invoke__">min</span></span><span>(</span><span><span class="hljs-variable">$start</span></span><span> + </span><span><span class="hljs-variable">$chunkSize</span></span><span> - </span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-variable">$fileSize</span></span><span> - </span><span><span class="hljs-number">1</span></span><span>);
    </span><span><span class="hljs-variable">$ch</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_init</span></span><span>(</span><span><span class="hljs-variable">$url</span></span><span>);

    </span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>, CURLOPT_RETURNTRANSFER, </span><span><span class="hljs-literal">true</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>, CURLOPT_RANGE, </span><span><span class="hljs-string">"<span class="hljs-subst">$start</span></span></span><span>-</span><span><span class="hljs-subst">$end</span></span><span>");

    </span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-variable">$curlHandles</span></span><span>[] = </span><span><span class="hljs-variable">$ch</span></span><span>;
}

</span><span><span class="hljs-comment">// 모든 다운로드 작업을 수행하십시오</span></span><span>
</span><span><span class="hljs-variable">$running</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-keyword">do</span></span><span> {
    </span><span><span class="hljs-title function_ invoke__">curl_multi_exec</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$running</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_multi_select</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>);
} </span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$running</span></span><span> &gt; </span><span><span class="hljs-number">0</span></span><span>);

</span><span><span class="hljs-comment">// 결과를 수집하고 병합하십시오</span></span><span>
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$curlHandles</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$ch</span></span><span>) {
    </span><span><span class="hljs-variable">$results</span></span><span>[] = </span><span><span class="hljs-title function_ invoke__">curl_multi_getcontent</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_multi_remove_handle</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_close</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>);
}
</span><span><span class="hljs-title function_ invoke__">curl_multi_close</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>);

</span><span><span class="hljs-comment">// 전체 파일에 씁니다</span></span><span>
</span><span><span class="hljs-title function_ invoke__">file_put_contents</span></span><span>(</span><span><span class="hljs-string">'merged_file.zip'</span></span><span>, </span><span><span class="hljs-title function_ invoke__">implode</span></span><span>(</span><span><span class="hljs-string">''</span></span><span>, </span><span><span class="hljs-variable">$results</span></span><span>));
</span></span>

3. 주목할만한 것들

  1. 연결 제한 : 동시성이 너무 많으면 서버가 연결을 거부 할 수 있습니다. 동시성 수를 제어하는 ​​것이 좋습니다 (예 : 매번 5 개의 처리).

  2. 오류 처리 : curl_error ()curl_multi_info_read ()를 사용하여 각 요청의 상태를 확인하십시오.

  3. 시간 초과 설정 : 전체 프로세스에서 개별 요청이 갇히지 않도록 Curlopt_Timeout을 설정하는 것이 좋습니다.

요약

curl_multi_add_handle은 동시 HTTP 요청을 구축하기위한 핵심 도구 중 하나입니다. 청킹 전략을 결합하면 대형 파일의 업로드 및 다운로드를 효율적으로 처리 할 수 ​​있습니다. 합리적인 요청 구성, 동시 제어 및 오류 처리는 실제 응용 프로그램에서 고려해야 할 중요한 요소입니다. PHP 네트워크 통신의 성능과 신뢰성을 크게 향상시킬 수 있습니다.