آموزش کار با کتابخانه cURL در زبان PHP

cURL library in PHP

0
42
آشنایی با کتابخانه cURL در زبان PHP

اکثر توسعه دهندگان تصور می کنند که توسعه backend به معنی این است که داده های ما فقط از سمت پایگاه داده می آیند اما اصلا اینطور نیست. در واقع هر چه دنیای وب به جلوتر حرکت می کند ما متوجه می شویم که قسمت بزرگی از داده های یک توسعه دهنده backend از منابع خارجی می آیند. به طور مثال در برنامه های مدرن جاوا اسکریپتی از API های مختلفی استفاده شده و داده های مورد نظر به توسعه دهنده پاس داده می شود. در بین تمام این ارتباطات حتما نام cURL را شنیده اید. cURL یک extension برای زبان PHP است که به ما اجازه می دهد داده های خود را با URL Syntax (نحو و قاعده ای که هنگام نوشتن URL ها رعایت می کنیم) ارسال کرده و یا دریافت کنیم. در واقع cURL کار برقراری ارتباط بین دو یا چند سرور را بسیار ساده تر می کند. ما می خواهیم در این مقاله، آموزش کار با cURL در PHP را شرح دهیم و استفاده های مهم و شایع از cURL را یاد بگیریم. اگر بخواهیم کمی به عقب تر برگردیم، آقای Daniel Stenberg کتابخانه ای به نام libcurl می نویسد که به ما اجازه می داد با پروتکل های مختلف و انواع روش ها با سرورهای دیگر ارتباط برقرار کنیم. این کتابخانه در حال حاضر پروتکل های http و https و ftp و gopher و telnet و dict و file و ldap را پشتیبانی می کند.

نحوه کار cURL

برای شروع آموزش کار با cURL در PHP ابتدا باید نحوه کار cURL را درک کنیم. cURL برای ارسال درخواست به یک وب سایت از چهار مرحله اصلی پیروی می کند. در مرحله اول که initialization یا آماده سازی اولیه نام دارد. در این مرحله باید یک handle را برای خودمان تعریف کنیم تا cURL شروع شود:

handle در انگلیسی به معنی دستگیره است که تا حدی درک ما را ساده تر می کند. ما از طریق این handle با کتابخانه cURL ارتباط خواهیم داشت. مرحله دوم تنظیم option ها یا همان تنظیمات مختلف است. این گزینه ها بسیار زیاد هستند و تک تک شان نیز روی handle ما تنظیم خواهند شد. مثلا ما می توانیم URL یا آدرس اینترنتی مقصد را به شکل زیر تعریف کنیم:

در بسیاری از اوقات به جای handle$ نام متغیر را ch$ می گذارند که مخفف cURL handle است. این نام ها سلیقه ای بوده و اهمیتی ندارند. مرحله سوم اجرای درخواست است که با کمک دستور curl_exec انجام می شود:

متغیر Data$ در کد بالا قرار است نتیجه curl_exec یا همان درخواست ما را در خود داشته باشد. پس از آنکه درخواست ما تمام شد می توانیم handle را به شکل زیر رها کنیم که همان مرحله چهارم است:

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

مثال اول: دانلود محتوای یک صفحه اینترنتی

همانطور که در ابتدای مقاله گفتم من می خواهم چند مورد استفاده جالب از cURL را برایتان مثال بزنم تا با قدرت cURL آشنا شوید.

مثال اول ما برای زمانی است که می خواهید محتوای یک آدرس اینترنتی را دانلود کنید. option ای که در این قسمت به کمک ما می آید CURLOPT_URL است که آدرس اینترنتی هدف/مقصد را مشخص می کند. همچنین از CURLOPT_RETURNTRANSFER استفاده خواهیم کرد که به ما اجازه می دهد داده های دانلود شده را به یک متغیر پاس بدهیم. در واقع اگر CURLOPT_RETURNTRANSFER را نداشته باشیم، نتیجه مستقیما نمایش داده می شود اما با پاس دادن این option مطمئن می شویم که نتیجه به صورت یک رشته (String) در آمده و سپس return می شود، حالا ما می توانیم آن را در یک متغیر ذخیره کرده یا هر کار دیگری با آن انجام بدهیم.

در مثال زیر که برایتان آماده کرده ام، تمام داده های دانلود شده را در متغیر output$ قرار می دهیم:

همانطور که می بینید کد بالا از همان 4 مرحله اصلی پیروی می کند. ابتدا یک handle می سازیم تا بتوانیم از طریق آن به کتابخانه cURL دستور بدهیم. من در اینجا url$ را برابر یک سایت فرضی گذاشته ام اما شما می توانید از هر سایتی که خواستید استفاده کنید. در مرحله دوم باید option ها را تنظیم کنیم اما نکته جالبی در کد بالا وجود دارد. ما در cURL تمام گزینه ها را یکجا پاس نمی دهیم بلکه برای هر کدام از آن ها باید curl_setopt را جداگانه صدا بزنیم. در ضمن setopt مخفف set options است (با دانستن این موارد، مطالب بهتر در ذهنتان باقی می ماند). ما دو option را پاس داده ای که اولی آدرس URL مقصد را مشخص کرده و دومی، نتیجه درخواست را به صورت یک رشته در آورده و برمی گرداند. در مرحله سوم handle خود را با curl_exec (مخفف curl execute) اجرا می کنیم و نتیجه اش را در output$ می گذاریم. در نهایت باید handle را ببندیم چرا که دیگر با آن کاری نداریم. فرض کنید وب سایت هدف ما یک وب سایت واقعی بود. با این حساب اگر output$ را echo کنیم، در مرورگر یک کپی از همان صفحه اینترنتی را خواهید دید! دقیقا به همان شکل و بدون هیچ تغییری!

احتمالا با خودتان می گویید که شاید تعداد option های ما بسیار زیاد باشد. آیا باید برای هر کدام باید یک curl_setopt جداگانه را صدا بزنیم؟ پاسخ قطعا خیر است. توسعه دهندگان PHP و این کتابخانه به فکر این موضوع بوده اند. برای حل این مشکل تابعی به نام curl_setopt_array را داریم که تمام این گزینه ها را به صورت یک آرایه دریافت می کند:

با انجام این کار دیگر نیازی به صدا زدن جداگانه curl_setopt نخواهیم داشت.

مثال دوم: دانلود یک فایل از یک سایت

تا به اینجا با extension ای به نام cURL آشنا شدیم و چهار مرحله اصلی کار با آن را نیز توضیح دادیم. همانطور که در آن مثال مشاهده کردید، cURL قدرت زیادی به ما می دهد و قبلا هم گفته بودم که از انواع و اقسام پروتکل های ارتباطی مانند پروتکل های http و https و ftp و gopher و telnet و dict و file و ldap را پشتیبانی می کند. مثالی که در قسمت قبل داشتیم، دانلود یک صفحه اینترنتی بود اما در این جلسه می خواهیم یک فایل مشخص را از یک سایت دیگر دانلود کنیم.

ابتدا باید با کلمه remote resources آشنا شوید. واژه remote به معنی «دور» یا «از راه دور» (بسته به متن) می باشد بنابراین remote resources به معنی منابع از راه دور می باشد. حالا این یعنی چه؟ زمانی که شما یک سرور دارید، فایل های درون سرور شما یا به طور کل منابع درون سرور شما، محلی یا local هستند بنابراین هر چیزی که خارج از سرور شما است remote محسوب می شود. با این حساب remote file یعنی فایلی که روی سرور دیگری میزبانی می شود.

چرا این توضیحات را به شما دادم؟ به دلیل اینکه می خواهیم در این جلسه یک remote resource را از سرور دیگری دانلود کنیم. برای این کار نیاز به option دیگری به نام CURLOPT_ FILE خواهیم داشت. یکی از پروژه های بزرگ در فضای وب Project Gutenberg است که هدف آن جمع آوری و دیجیتال سازی کتب مشهور و مختلف می باشد. مثلا در آدرس https://www.gutenberg.org/files/46852/46852-h/46852-h.htm می توانید متن کامل کتاب The Hills of Desire را ببینید. حالا فرض کنید که ما می خواهیم این متن را درون یک فایل html دریافت کنیم.

اگر در PHP با فایل ها کار نکرده باشید، کد بالا برایتان خیلی عجیب خواهد بود بنابراین بگذارید خط به خط توضیح بدهم. در ابتدا آدرس اینترنتی مقصد را در یک متغیر به نام url$ ذخیره کرده ام. در مرحله بعد آدرس فایلی فرضی به نام the_hill_of_desire.html را روی سرور خودم ذخیره کرده ام. چطور؟ بگذارید توضیح بدهم. دستور __DIR__ مسیر فعلی اسکریپت ما را به ما خواهد داد و DIRECTORY_SEPARATOR نیز بر اساس سیستم عامل سرور (لینوکس یا ویندوز) separator یا جداکننده سازگار را برمی گرداند. جداکننده همان علامت / است که در آدرس فایل ها است. مثلا:

C:\Users\Amir\Downloads\Compressed\platform-tools

آدرس بالا در ویندوز کار می کند اما در لینوکس کار نمی کند چرا که جداکننده ها \ نیستند بلکه باید / باشند. توجه داشته باشید با این کاری که کرده ام هیچ فایلی ساخته نمی شود بلکه فقط یک یک آدرس ساده را به صورت یک رشته ایجاد کرده ایم. کل متغیر file$ همین است! در مرحله بعد تابع fopen را داریم. شاید در نگاه اول عجیب باشد اما باید بدانید که در زبان PHP هم برای ساختن فایل جدید و هم برای خواندن آن از fopen استفاده می کنیم. این تابع دو آرگومان می گیرد:

  • آرگومان اول آدرس فایل مورد نظر است. اگر این آدرس واقعی باشد (فایل وجود داشته باشد) طبیعتا همان فایل باز می شود و در غیر این صورت یک فایل جدید در همان آدرس ساخته خواهد شد.
  • آرگومان دوم هدف ما از باز کردن/ساختن این فایل جدید را مشخص می کند. w یعنی Write یا نوشتن داده های جدید در فایل.

در مرحله بعدی curl_setopt_array را صدا زده ایم تا option ها را به آن پاس بدهیم. توجه داشته باشید که در اینجا متغیر fileHandle را به آپشن CURLOPT_FILE پاس داده ایم تا نتیجه اش در آن ذخیره شود. سپس curl_exec کرده ایم تا عملیات انجام شود. در نهایت handle را می بندیم اما یادتان نرود که باید فایلی را که باز کرده بودید نیز ببندید، در غیر این صورت در پس زمینه باز می ماند و باعث مصرف مموری خواهد شد.

در ضمن اگر بخواهید header درخواست را نیز درون همین فایل ذخیره کنید باید یک option دیگر به نام CURLOPT_HEADER را روی true تنظیم کنید:

با این کار header درخواست که شامل اطلاعات کلی و پارامترها می باشد نیز در فایل نهایی ما حضور خواهد داشت اما اگر اطلاعات جزئی تری می خواهید باید curl_getinfo را نیز اضافه کنید. این متد اطلاعات جزئی تری مانند status code و سایز فایل دانلود شده (یا به قولی ساخته شده) را نیز برمی گرداند. البته نحوه استفاده از آن کمی متفاوت است:

همانطور که می بینید این یک متد است که option های خاصی را می گیرد و آن ها را در نتیجه نهایی قرار می دهد. مثلا CURLINFO_HTTP_CODE همان status code و CURLINFO_CONTENT_LENGTH_DOWNLOAD حجم فایل دانلود شده را به ما خواهد داد. همچنین گزینه های دیگری مانند curl_error و curl_errno نیز وجود دارند که به ترتیب آخرین پیام خطا (رشته) و آخرین کد خطا (عدد) را به ما برمی گردانند. مثلا:

هر خطایی یک کد دارد، بنابراین اگر خطایی داشته باشیم حتما curl_errno نیز یک عدد خواهد داشت. به همین خاطر در کد بالا گفته ایم اگر خطایی داشتیم، متن آن خطا (curl_error) را چاپ کن. با اضافه کردن تمام این مسائل به کد اولیه، می توانیم آن را به شکل زیر در بیاوریم:

به همین راحتی یک کد کامل cURL را نوشته ایم.

مثال سوم: نحوه ثبت فرم

همانطور که قبلا هم توضیح داده ام کتابخانه cURL به صورت پیش فرض در PHP وجود دارد و برای فعال سازی آن نیازی به انجام کار دیگری ندارید. ما در دو قسمت قبل در مورد درخواست های GET صحبت کرده ایم، اگرچه که به صورت صریح این نکته را ذکر نکرده بودم (معمولا برای دانلود اسناد و فایل ها از متد GET استفاده می شود) اما در این جلسه می خواهیم از متد POST استفاده کنیم. برای اینکه نحوه ثبت فرم ها از طریق cURL را به شما آموزش بدهم باید دو فایل زیر را ایجاد کنیم:

  • فایل اول php است که از اسکریپت cURL ما نگهداری می کند.
  • فایل دوم php است که از اسکریپت فرم ما نگهداری می کند.

در دنیای واقعی فایل دوم یا همان فرم ما، روی یک سرور remote قرار خواهد داشت. حتما یادتان می آید که در قسمت قبل توضیح دادم remote به معنی «دور» یا «از راه دور» (بسته به متن) می باشد. با همان منطق جلسه قبل remote server یعنی هر سروری غیر از سرور شما. زمانی که می گویم «سرور شما» منظورم مالکیت قانونی نیست، منظورم هر سروری به غیر از سروری است که در حال حاضر اسکریپت cURL ما را دارد. از آنجایی که ما دو سرور جداگانه نداریم، هر دو فایل را روی یک سرور تعریف خواهیم کرد که مشکلی هم ندارد.

من برای فایل دوم یک فرم بسیار ساده با سه فیلد firstName (نام) و lastName (نام خانوادگی) و submit (ثبت) را در نظر گرفته ام و کدهایش را برایتان قرار می دهم:

همانطور که می بینید این اسکریپت از دو قسمت تشکیل شده است:

  • قسمت HTML: در این قسمت یک فرم ساده را با همان سه فیلدی که گفتم داریم. همانطور که مشاهده می کنید method این فرم روی POST است.
  • قسمت PHP: با استفاده از POST_$ بررسی می کنیم که آیا submit وجود دارد یا خیر؟ به عبارتی فقط درخواست های POST را بررسی می کنیم. اگر این چنین بود فیلدها را در یک جمله نمایش می دهیم.

حالا نوبت به فایل اول یا همان اسکریپت cURL می رسد. در این اسکریپت می خواهیم از دو option به نام های CURLOPT_POST و CURLOPT_POSTFIELDS استفاده کنیم. CURLOPT_POST متد درخواست را روی POST قرار می دهد و CURLOPT_POSTFIELDS یک آرایه متناظر را دریافت می کند که در آن هر عضو، برابر یک فیلد از فرم خواهد بود. توجه داشته باشید که key ها برای اعضای آرایه باید برابر نام فیلدها باشند. اسکریپت زیر را در فایل دوم قرار می دهیم:

مثل همیشه در ابتدا یک handle می سازیم. سپس متغیر url$ را داریم که آدرس فایل هدف (فرم) را مشخص می کند. من داده های فرم را درون postData$ قرار داده ام و همانطور که گفتم key ها باید با نام فیلدهای فرم یکی باشند اما مقادیر کاملا دلخواه هستند و شما می توانید هر چیز دیگری را به این فرم پاس بدهید. در مرحله بعد مثل همیشه curl_setopt_array را داریم تا گزینه های خود را برایش ارسال کنیم؛ CURLOPT_URL آدرس مقصد را مشخص می کند، CURLOPT_POST حالت درخواست را روی POST می گذارد، CURLOPT_POSTFIELDS فیلدهای فرم را به همراه مقادیرشان مشخص می کند و در نهایت CURLOPT_RETURNTRANSFER نیز به جای چاپ بلافاصله نتیجه، آن را در یک رشته قرار داده و به ما برمی گرداند. حالا می توانیم handle خود را اجرا یا execute کنیم و در نهایت data را چاپ می کنیم.

بر همین اساس می توانیم وارد مبحث احراز هویت (authentication) نیز بشویم. چرا؟ به دلیل اینکه وارد حساب کاربری شدن و به طور کل فرآیند authentication نیز یک فرم است. برای انجام عملیات احراز هویت با cURL باید سه option زیر را به handle خود بدهید:

  • CURLOPT_HTTPAUTH: این گزینه مشخص می کند که برای عملیات احراز هویت از چه متد هایی استفاده کنیم؟ متد های موجود عبارت اند از CURLAUTH_BASIC و CURLAUTH_DIGEST و CURLAUTH_GSSNEGOTIATE و CURLAUTH_NTLM و CURLAUTH_ANY و CURLAUTH_ANYSAFE. برای اطلاعات بیشتر به وب سایت رسمی php مراجعه کنید.
  • CURLOPT_USERPWD: این گزینه نام کاربری و رمز عبور را مشخص می کند.
  • CURLOPT_RETURNTRANSFER: این گزینه نیز مثل همیشه نتیجه را در قالب یک رشته به ما برمی گرداند.

CURLAUTH_ANY به معنی این است که از هر متدی استفاده کن. اگر بخواهم به صورت دقیق تر بگویم CURLOPT_HTTPAUTH برابر است با CURLAUTH_BASIC و CURLAUTH_DIGEST و CURLAUTH_GSSNEGOTIATE و CURLAUTH_NTLM. حالا می توانیم به آدرس بالا (در صورتی که این آدرس فرضی مسئول احراز هویت باشد) شده و وارد حساب کاربری خودمان بشویم. حتی اگر بخواهیم در این علمیات احراز هویت، کوکی های خودمان را ذخیره کنیم، مشکلی نخواهیم داشت!

اگر می خواهید کوکی هایتان را ذخیره کنید باید دو option زیر را نیز مشخص کنید:

  • CURLOPT_COOKIEJAR: بعد از بسته شدن handle (دستور curl_close) طبیعتا تمام کدهای درون مموری از بین می روند و نمی توانیم کوکی ها را در آنجا ذخیره کنیم بنابراین باید یک فایل را مشخص کنیم تا کوکی ها درون آن ذخیره شوند. این گزینه نام این فایل را مشخص می کند.
  • CURLOPT_COOKIEFILE: در option قبلی، نام فایلی را می دادیم که کوکی ها درون آن ذخیره می شوند (عملیات write) اما در این گزینه نام فایلی را می دهیم که کوکی ها درون آن قرار دارند تا از آن خوانده بشوند (عملیات read).

با این حساب می توانیم دستور قبلی login را با این دو option ترکیب کرده و به کد زیر برسیم:

به همین راحتی کد ساده ای را داریم که می تواند ما را وارد یک endpoint مشخص کند.

امیدواریم آموزش کار با cURL در PHP برای شما مفید بوده باشد.


منبع: سایت phpenthusiast

ارسال دیدگاه

لطفا دیدگاه خود را وارد کنید!
نام خود را وارد کنید