
দুর্দান্ত curl_multi_exec
cURL সম্পর্কে পিএইচপি প্রোগ্রামাররা কমবেশি জানেন। কমপক্ষে এইটা সবাই জানি যে, এই জিনিস কোড থেকে HTTP রিকোয়েস্টগুলো করার জন্য ব্যবহৃত হয় এবং রিকোয়েস্টেড URL থেকে রেসপন্সটা নিয়ে আসে। খুব সাম্প্রতিক ফুরফুরে এক হেমন্তের সন্ধ্যায় একটা কাজে বসে দেখলাম আমার একবারে একাধিক cURL রিকোয়েস্ট করতে হবে। স্বাভাবিক ভাবে যেটা মাথায় এলো সেটা হচ্ছে, একটা লুপের মধ্যে একটা একটা করে cURL রিকোয়েস্টকে execute করার কথা! চলুন তো দেখি সেই ‘উর্বর’ কোডটা কেমন হতোঃ
$result=array();
foreach ($students as $i => $student) {
$data = array(
'username'=>"username",
'password'=>"**********",
'number'=> $student->number,
'message'=>$student->message
);
$url= 'http://myapiurl.com/api';
$ch = curl_init(); // Initialize cURL
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result[] = curl_exec($ch);
curl_close($ch);
}
এখানে দেখা যাচ্ছে আমি কিছু শিক্ষার্থীর অভিভাবকের মোবাইলে SMS পাঠাতে চাচ্ছি। এখন যদি আমার এই লুপে শিক্ষার্থী সংখ্যা 50 জন হয় তাহলে একবার রিকোয়েস্টে প্রাপ্ত গড় Response Time 50X গুণ হবে! অর্থাৎ সবগুলো রিকোয়েস্টের সমষ্টিগত সময় হবে পুরো রিকোয়েস্টটির রেসপন্স টাইম! এবং ভয়াবহভাবে এটি HTTP এর যেকোন Timeout Error (408, 504 ইত্যাদি)-এর স্বীকার হতে পারে! ফলশ্রুতিতে উপর্যুক্ত কোডটি একটি ‘নিম্নমানের’ কোড হিসেবে বিবেচিত হবে।
কিন্তু আমার তো এক রিকোয়েস্টেই সব SMS গুলো পাঠাতে হবে। একটু ঘাটাঘাটি করে দেখলাম, cURL এর মাল্টিপল রিকোয়েস্ট হ্যান্ডেল করার মতো একটি মেথড আছেঃ curl_multi_exec
এই অসাধারণ ফাংশন curl_multi_exec দিয়ে পুরো কোডটাকে চলুন রিফ্যাক্টর করে দেখি-
$url = "http://myapiurl.com/api";
// array of curl handles
$multiCurl = array();
// data to be returned
$result = array();
// multi handle, a parameter of curl_multi_exec
$mh = curl_multi_init();
// sms data
$smsdata = [];
foreach ($students as $i => $student) {
$smsdata[$i] = array(
'username'=>"username",
'password'=>"**********",
'number'=> $student->number,
'message'=>$student->message
);
$multiCurl[$i] = curl_init(); // Initialize cURL
curl_setopt($multiCurl[$i], CURLOPT_URL, $url);
curl_setopt($multiCurl[$i], CURLOPT_HEADER, 0);
curl_setopt($multiCurl[$i], CURLOPT_POSTFIELDS, http_build_query($smsdata[$i]));
curl_setopt($multiCurl[$i], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $multiCurl[$i]);
}
$index=null;
do {
curl_multi_exec($mh, $index);
} while($index > 0);
// get content and remove handles
foreach($multiCurl as $k => $ch) {
$result[$k] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
এই অংশটি ব্যবহার করে আমি সত্যিকারের কিছু মোবাইল নম্বর দিয়ে টেস্ট করে দেখলাম রেসপন্স টাইম উল্লেখযোগ্যভাবে হ্রাস পেয়েছে। এবং কোন সিঙ্গেল cURL রিকোয়েস্ট-এর জন্য Timeout Error হবার কারণও নেই!