کسانی که پس از به روز رسانی به 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. روش اول (نه کوشر). اگر 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. روش دوم (بسیار سریع، اما نه کوشر). فایل libssh2.dll را از دایرکتوری PHP در پوشه Apache24bin کپی کنید و آپاچی را مجددا راه اندازی کنید.
  3. روش سوم (کوشر - مردم کوشر ایستاده کف می زنند). شما باید دایرکتوری PHP خود را به PATH اضافه کنید. نحوه انجام این کار به خوبی در اسناد رسمی توضیح داده شده است.

بررسی می کنیم:

Voila، بخش cURL در جای خود قرار دارد.

چرا اینطور است؟ این مشکل از کجا آمده است؟ هیچ پاسخی برای این سوال وجود ندارد، اگرچه مکانیسم وقوع آن قبلاً توضیح داده شده است.

به نظر می رسد مشکل به این واقعیت مربوط می شود که 5.6.1 قرار بود با libcurl 7.38.0 به روز شده منتشر شود. اما این به طور قطع مشخص نیست، نویسندگان PHP به Apache اشاره می کنند و می گویند که برخی از اشکالات در آنجا وجود دارد.

مکانیسم مشکل: اگر PATH سیستم گنجانده نشده باشد دایرکتوری PHP، سپس هنگامی که سرویس آپاچی شروع می شود، نمی تواند dll جدید (libssh2.dll) را که یک وابستگی برای php_curl است پیدا کند.

گزارش اشکال مربوطه:

خطای مرگبار: فراخوانی تابع تعریف نشده curl_multi_init () در ...

به طور کلی، مشکلاتی با cURL در PHP وجود داشت، به نظر می رسد، اگر نه همیشه، پس اغلب اوقات. در روند جستجوی مشکلم، به موضوعاتی برخوردم که برخی از آنها بیش از ده سال قدمت داشتند.

علاوه بر این، گوگل چند نتیجه گیری دیگر نیز ارائه کرد:

به اندازه کافی "دستورالعمل هایی برای احمق ها" در اینترنت وجود دارد که در آنها به تفصیل، همراه با تصاویر، نحوه لغو نظر از خط extension=php_curl.dll در فایل php.ini را می گویند.

در سایت رسمی PHP، در قسمت نصب cURL، تنها دو پیشنهاد در مورد سیستم ویندوز وجود دارد:

برای کار با این ماژول در فایل های ویندوز libeay32.dll و ssleay32.dll باید در سیستم وجود داشته باشد متغیر محیطیمسیر. شما به فایل libcurl.dll از سایت cURL نیاز ندارید.

ده بار آنها را خوانده ام. تغییر به زبان انگلیسیو چند بار دیگر به زبان انگلیسی بخوانید. هر بار، بیشتر و بیشتر متقاعد شدم که این دو جمله توسط حیوانات نوشته شده است، یا کسی فقط روی صفحه کلید پریده است - معنی آنها را نمی فهمم.

همچنین نکات و دستورالعمل های دیوانه کننده ای وجود دارد (حتی موفق شدم برخی از آنها را امتحان کنم).

در سایت گزارش اشکال PHP، من قبلاً به کشف نیاز به گنجاندن دایرکتوری با PHP در متغیر سیستم PATH نزدیک شده ام.

به طور کلی، برای کسانی که با cURL مشکل دارند و باید یک دایرکتوری با PHP را در متغیر سیستم PATH وارد کنند، به دستورالعمل ذکر شده در بالا بروید http://php.net/manual/en/faq.installation .php#faq .installation.addtopath . همه چیز در آنجا ساده است و مهمتر از همه، آنچه باید انجام شود به زبان انسان نوشته شده است.

ما داریم: php 5.2.3، Windows XP، Apache 1.3.33
مشکل - اگر PHP از زیر آپاچی اجرا شود، ماژول cURL شناسایی نمی شود
در php.ini extension=php_curl.dll بدون نظر است، extension_dir به درستی تنظیم شده است،
libeay32.dll و ssleay32.dll در c:\windows\system32 کپی می شوند.
با این حال، تابع phpinfo() ماژول cURL را در بین موارد نصب شده نشان نمی دهد و زمانی که آپاچی راه اندازی می شود، موارد زیر در گزارش نوشته می شود:

راه اندازی PHP: بارگیری کتابخانه پویا "c:/php/ext/php_curl.dll" ممکن نیست - ماژول مشخص شده یافت نشد.

اگر php را از خط فرمان، سپس اسکریپت های حاوی دستورات از cURL به خوبی کار می کنند، و اگر از زیر آپاچی اجرا شوند، موارد زیر را ارائه می دهند:
خطای مرگبار: فراخوانی تابع تعریف نشده: curl_init () - و صرف نظر از نحوه نصب PHP - به عنوان CGI یا به عنوان یک ماژول.

در اینترنت، من بارها و بارها با توضیحاتی در مورد این مشکل مواجه شدم - مخصوصاً برای ماژول cURL، اما راه حل هایی که در آنجا پیشنهاد شده بود کمکی نمی کند. و من قبلاً PHP 5.2 را به PHP 5.2.3 تغییر دادم - هنوز کمکی نکرد.

دیوید مزارولیان [پرونده]
من یک php.ini دارم - با جستجو در دیسک آن را بررسی کردم. این واقعیت که از همان php.ini استفاده می شود نیز به راحتی توسط این واقعیت تأیید می شود که تغییرات ایجاد شده در آن بر روی راه اندازی اسکریپت ها از زیر Apache و از خط فرمان تأثیر می گذارد.

دانیل ایوانف [پرونده] بهتر است با یک تماس یک فایل بسازید

و با مرورگر بازش کنید
و سپس در فرمان اجرا کنید خط php-i | grep ini و مسیرهای php.ini را همانطور که php می بیند بررسی کنید، نه با وجود فایل روی دیسک.

دانیل ایوانف [پرونده] خروجی php -i چیست؟ بسته به گزینه های کامپایل، باینری پیش فرض ممکن است پیکربندی را در جای دیگری جستجو کند. این اولین بار نیست که با این واقعیت مواجه می شوم که mod_php.dll و php.exe به فایل های ini مختلف نگاه می کنند و آنچه در یکی کار می کند در دیگری کار نمی کند.

واسیلی سویریدوف [پرونده]
php -i موارد زیر را تولید می کند:

فایل پیکربندی (php.ini) مسیر => C:\WINDOWS
فایل پیکربندی بارگذاری شده => C:\PHP\php.ini

انتقال فایل php.ini به دایرکتوری موقعیت های ویندوزتغییر نمی کند.

دانیل ایوانف [پرونده]
بقیه ماژول ها چطور؟ مثلا php_mysql؟؟؟ برقراری ارتباط؟ یا فقط cURL خیلی بد است؟

هوم، برای من هم لود نمی شود... روی یک پیکربندی بسیار متفاوت (Apache 2.2 به همراه PHP 5.1.6 تحت Zend Studio). اما موضوع این نیست. آزمایشی با اجرای آپاچی از خط فرمان (به طور دقیق تر از FAR) چیز جالبی را نشان داد. بدون تلاش برای اتصال کورل - همه چیز در یک دسته شروع می شود. هنگام تلاش برای اتصال Kurl یک خطا در ... php5ts.dll می دهد.

سلام!
من مشکل مشابهی داشتم، خیلی وقت بود دنبال راه حل میگشتم، بیشتر بزارم نسخه جدید PHP، در نهایت این انجمن را پیدا کرد. هیچ راه حلی در اینجا وجود نداشت، بنابراین خودم بیشتر تلاش کردم.

من یک استودیوی zend برای خودم راه اندازی کردم و قبل از آن نسخه قبلی PHP وجود داشت. شاید یکی از آنها کتابخانه های خود را نصب کرده باشد و در آنجا باقی بمانند - قدیمی.

با تشکر از راهنمایی ها، به خصوص آخرین مورد از "نهکسبی". من وارد C:\windows\system32 شدم و متوجه شدم که کتابخانه های libeay32.dll و ssleay32.dll به اندازه کتابخانه های اصلی نیستند. من memcached رو نصب کردم شاید بعدش. بنابراین، اگر chot را اضافه کردید، در system32 بروید :)

همین مشکل را داشت، از دستور php -i | استفاده کرد grep ini
نشان داد که کتابخانه zlib1.dll وجود ندارد
در پوشه با آپاچی بود، من یک کپی در پوشه با PHP نوشتم
دستور رو تکرار کردم، نشون داد که کتابخانه zlib.dll کافی نیست، توی پوشه آپاچی نوشتم و همه چی کار کرد.
و تمام کتابخانه ها نیز php5ts.dll بودند، بنابراین وجود تمام کتابخانه های لازم را در نظر بگیرید.

تصمیم گرفت اضافه کند. چون من هم با این مشکل مواجه شدم. من از طریق لینکی در سایت دیگری با این انجمن آشنا شدم. به طور کلی، همه گزینه های پیشنهادی چیزی جز عصا نیستند. اصل راه حل در ویندوز شما باید متغیر 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()) در این مقاله بسیار بیشتر از تمام مراحل دیگر مورد بحث قرار خواهد گرفت، زیرا. در این مرحله همه جالب ترین و مفیدترین چیزهایی که باید بدانید اتفاق می افتد. تعداد زیادی گزینه مختلف در cURL وجود دارد که باید مشخص شوند تا بتوانید درخواست URL را به بهترین شکل پیکربندی کنید. ما کل لیست را به عنوان یک کل در نظر نخواهیم گرفت، بلکه فقط بر آنچه که برای این درس ضروری و مفید می دانم تمرکز خواهیم کرد. اگر این موضوع به شما علاقه مند است، هر چیز دیگری را که می توانید خودتان کشف کنید.

بررسی خطا

علاوه بر این، شما همچنین می توانید استفاده کنید عبارات مشروطبرای بررسی موفقیت آمیز بودن عملیات:

// ... $output = curl_exec($ch); if ($output === FALSE) ( echo "cURL Error: " . curl_error($ch); ) // ...

در اینجا از شما می خواهم که بسیار توجه داشته باشید نکته مهم: برای مقایسه باید از "=== false" به جای "== false" استفاده کنیم. برای کسانی که نمی دانند، این به ما کمک می کند بین یک نتیجه خالی و یک مقدار بولی نادرست که نشان دهنده یک خطا است تشخیص دهیم.

دریافت اطلاعات

یکی دیگر از گام های اضافی دریافت اطلاعات در مورد درخواست cURL پس از اجرای آن است.

// ... curl_exec($ch); $info = curl_getinfo ($ch); پژواک "گرفت". $info["total_time"] . " ثانیه برای آدرس اینترنتی " . $info["url"]; //...

آرایه برگشتی حاوی اطلاعات زیر است:

  • "url"
  • "نوع محتوا"
  • http_code
  • "هدر_اندازه"
  • "درخواست_اندازه"
  • "زمان فایل"
  • "ssl_verify_result"
  • "redirect_count"
  • "Total_time"
  • “namelookup_time”
  • "connect_time"
  • "پیش انتقال_زمان"
  • "size_upload"
  • اندازه_دانلود
  • “speed_download”
  • "speed_upload"
  • "دانلود_محتوای_طول"
  • "upload_content_length"
  • "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)"، "language" => "en-us,en;q=0.5")، "iphone" => آرایه ("user_agent" => "Mozilla/5.0 (iPhone; U ؛ CPU مانند Mac OS X؛ en) AppleWebKit/420+ (KHTML، مانند Gecko) نسخه/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)"، "language" => "fr,fr-FR;q=0.5")); foreach ($urls به عنوان $url) ( echo "URL: $url\n"؛ foreach ($browers به ​​عنوان $test_name => $browser) ($ch = curl_init(); // url را مشخص کنید curl_setopt($ch، CURLOPT_URL، $url)؛ // تنظیم سرصفحه های مرورگر curl_setopt($ch، CURLOPT_HTTPHEADER، آرایه("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 ها تعریف کنیم. پس از آن، از یک حلقه استفاده می کنیم که در آن تمام نتایج به دست آمده را بررسی می کنیم.

ترفندی که در این مثال برای تنظیم استفاده می کنیم تنظیمات cURL، به ما این امکان را می دهد که نه محتوای صفحه، بلکه فقط هدرهای HTTP (ذخیره شده در $output) را دریافت کنیم. در مرحله بعد، با استفاده از یک regex ساده، می توانیم تعیین کنیم که آیا رشته "Location:" در سرصفحه های دریافتی وجود دارد یا خیر.

وقتی این کد را اجرا می کنید، باید چیزی شبیه به این دریافت کنید:

ایجاد یک درخواست POST به یک URL خاص

هنگام تشکیل یک درخواست GET، داده های ارسال شده را می توان از طریق "رشته پرس و جو" به 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);

سپس یک اسکریپت PHP برای اجرای درخواست cURL ایجاد می کنیم:

$url = "http://localhost/post_output.php"; $post_data = array("foo" => "bar"، "query" => "Nettuts"، "action" => "Submit"); $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); $output = curl_exec($ch); curl_close ($ch); echo $output;

هنگامی که این اسکریپت را اجرا می کنید، باید نتیجه مشابهی دریافت کنید:

بنابراین، درخواست POST به اسکریپت post_output.php ارسال شد که به نوبه خود آرایه superglobal $_POST را که محتوای آن را با استفاده از cURL به دست آوردیم، خروجی داد.

آپلود فایل

ابتدا بیایید یک فایل برای تشکیل آن ایجاد کنیم و آن را به فایل upload_output.php ارسال کنیم:

Print_r($_FILES);

و در اینجا کد اسکریپت است که عملکرد فوق را انجام می دهد:

$url = "http://localhost/upload_output.php"; $post_data = آرایه ("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); $output = curl_exec($ch); curl_close ($ch); echo $output;

زمانی که می خواهید فایلی را آپلود کنید، تنها کاری که باید انجام دهید این است که آن را طبق معمول آپلود کنید متغیر پست، نماد @ را در جلوی آن قرار دهید. هنگامی که اسکریپت نوشته شده را اجرا می کنید، نتیجه زیر را دریافت خواهید کرد:

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); $active = null; //execution do ($mrc = curl_multi_exec($mh, $active); ) در حالی که ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc‎== CURLM_OK) ( if (curl_multi_select($mh) != -1) ( انجام دهید ($mrc = curl_multi_exec($mh, $active); ) در حالی که ($mrc == CURLM_CALL_MULTI_PERFORM); ) ) //close 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() را فراخوانی می کنیم. تا زمانی که حداقل یک اتصال فعال وجود داشته باشد، تا زمانی که پاسخ دریافت شود، اجرای آن مسدود می شود. وقتی این اتفاق افتاد، برای ادامه اجرای درخواست ها به حلقه اصلی برمی گردیم.

و اکنون بیایید آنچه را که یاد گرفتیم با مثالی که واقعاً برای تعداد زیادی از مردم مفید خواهد بود به کار ببریم.

بررسی لینک ها در وردپرس

وبلاگی را تصور کنید با مقدار زیادیپست ها و پیام هایی که هر کدام حاوی پیوندهایی به منابع اینترنتی خارجی هستند. برخی از این پیوندها ممکن است به دلایل مختلف قبلا "مرده" باشند. شاید صفحه حذف شده یا سایت اصلا کار نمی کند.

ما قصد داریم یک اسکریپت ایجاد کنیم که تمام پیوندها را تجزیه کند و وب سایت هایی را که بارگذاری نمی شوند و صفحات 404 را پیدا کند و سپس یک گزارش بسیار دقیق به ما ارائه دهد.

من بلافاصله می گویم که این نمونه ای از ایجاد یک افزونه برای وردپرس نیست. این تقریباً همه چیز یک زمین آزمایشی خوب برای ما است.

بیایید در نهایت شروع کنیم. ابتدا باید همه پیوندها را از پایگاه داده واکشی کنیم:

// پیکربندی $db_host = "localhost"; $db_user = "ریشه"; $db_pass = ""; $db_name = "وردپرس"; $excluded_domains = آرایه("localhost", "www.mydomain.com"); $max_connections = 10; // مقداردهی اولیه متغیر $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // به MySQL متصل شوید if (!mysql_connect($db_host, $db_user, $db_pass)) (die("نمی توان متصل شد: " . mysql_error()); ) if (!mysql_select_db($db_name)) ( die("Could db را انتخاب نکنید: ". mysql_error()); ) // انتخاب همه پست های منتشر شده با پیوندها $q = "انتخاب post_content از wp_posts جایی که post_content مانند "%href=%" و post_status = "انتشار" و post_type = "پست "" ; $r = mysql_query($q) یا die(mysql_error()); در حالی که ($d = mysql_fetch_assoc($r)) (// واکشی پیوندها با استفاده از عبارات با قاعده if (preg_match_all("!href=\"(.*?)\"!"، $d["post_content"]، $matches)) ( foreach ($ مطابق $url) ($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. تعداد زیادی URL برای ($i = 0؛ $i< $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() را کمی بعد می نویسیم. هر بار که فراخوانی می شود، یک آدرس اینترنتی جدید پردازش می شود. در ابتدا، 10 URL ($max_connections) اضافه می کنیم.
  3. 3. برای شروع باید تابع curl_multi_exec() را اجرا کنیم. تا زمانی که CURLM_CALL_MULTI_PERFORM را برمی گرداند، هنوز کار زیادی برای انجام دادن داریم. ما عمدتاً برای ایجاد ارتباطات به این نیاز داریم.
  4. 4. بعد حلقه اصلی می آید که تا زمانی که حداقل یک اتصال فعال داشته باشیم اجرا می شود.
  5. 5. curl_multi_select() در انتظار تکمیل جستجوی 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. اکنون می‌توانیم یک آدرس اینترنتی دیگر اضافه کنیم و هر چیزی که قبلاً در مورد آن صحبت کردیم را اجرا کنیم.
  14. 14. در این مرحله فیلمنامه به کار خود پایان می دهد. ما می توانیم هر چیزی را که نیاز نداریم حذف کنیم و یک گزارش ایجاد کنیم.
  15. 15. در پایان تابعی می نویسیم که یک url به هندلر اضافه می کند. متغیر استاتیک $index هر بار افزایش می یابد عملکرد داده شدهفراخوانی خواهد شد.

من از این اسکریپت در وبلاگم استفاده کردم (با تعدادی لینک شکسته که عمداً برای آزمایش آن اضافه شده است) و نتیجه زیر را گرفتم:

در مورد من، اسکریپت فقط کمتر از 2 ثانیه طول کشید تا از طریق 40 URL اجرا شود. افزایش عملکرد زمانی که با URL های بیشتری سروکار دارید قابل توجه است. اگر ده کانکشن را همزمان باز کنید، اسکریپت می تواند ده برابر سریعتر اجرا شود.

چند کلمه در مورد دیگر گزینه های مفید 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); $output = curl_exec($ch); curl_close ($ch);

آپلود FTP

PHP همچنین دارای یک کتابخانه برای کار با FTP است، اما هیچ چیز مانع از استفاده از ابزارهای cURL در اینجا نمی شود:

// باز کردن فایل $file = fopen("/path/to/file", "r"); // url باید حاوی محتوای زیر باشد $url = "ftp://username: [ایمیل محافظت شده]:21/path/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، فایل اندازه ("/path/to/file"))؛ // مشخص کردن ASCII mod curl_setopt ($ch، CURLOPT_FTPASCII، 1)؛ خروجی $exe = curl_ ($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"); $output = 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); تابع progress_function($ch,$str) (echo $str؛ return strlen($str)؛ )

چنین تابعی باید طول رشته را برگرداند که یک الزام است.

نتیجه

امروز با نحوه استفاده از کتابخانه cURL برای اهداف خودخواهانه خود آشنا شدیم. امیدوارم از این مقاله لذت برده باشید.

متشکرم! روز خوبی داشته باشید!