PDA

View Full Version : سوال: CLI & CGI



masoud_tamizy
جمعه 05 اسفند 1390, 20:42 عصر
نسخه CGI و CLI پی اچ پی چه تفاوتی با هم دارند ؟ لطفا توضیح دهید

eshpilen
جمعه 05 اسفند 1390, 21:40 عصر
CGI یک استاندارد برای اجرای برنامه های خارجی روی وب سرور است به شکلی که بتونن مثل صفحات وب مورد دسترسی و استفاده قرار بگیرن.
این برنامه ها توسط وب سرور (مثلا آپاچی) در پاسخ درخواستهای وب اجرا شده و خروجی اونها بعنوان پاسخ توسط وب سرور به کلاینت ارسال میشه.
هر برنامه ای رو اعم از اسکریپتی و اجرایی استاندارد (باینری) میشه به این شکل اجرا کرد و بعنوان پردازندهء درخواستهای وب مورد استفاده قرار داد. البته مسلما برنامه باید برای این کار نوشته شده باشه و استانداردهای خاصی رو رعایت کرده باشه.
در قدیم که زبانهای اختصاصی برنامه نویسی وب وجود نداشتن و این امکانات در نرم افزار سرویس دهندهء وب وجود نداشت، از CGI استفاده میشد تا امکانات فراتر از صفحات استاتیک رو بوسیلهء برنامه های اجرایی روی سیستم فراهم کنن. مثلا یک فایل اجرایی که حاصل از کامپایل برنامه ای به زبان سی++ بود و میتونست با دیتابیس و سیستم فایل کار کنه به این شکل برای پردازش درخواستها استفاده میشد. این وسط نرم افزار وب سرور بیشتر نقش واسطه رو داره که درخواستهای HTTP رو از کلاینت دریافت کرده و بر اساس آدرس درخواست شده برنامهء CGI مورد نظر رو اجرا کرده و اطلاعات درخواست رو به شکل متغییرهای محیطی در اختیار اون برنامه میذاره، برنامه پردازشهایی رو که میخواد انجام میده، سپس پاسخ رو با همون توابع و روشهای عادی مثل printf یا cout که در برنامه های خط فرمان مورد استفاده قرار میگیرن خروجی میده، این خروجی توسط نرم افزار سرویس دهدهء وب گرفته شده و به کلاینت ارسال میشه. البته فرمت این خروجی باید از قوانین پروتکل HTTP تبعیت بکنه (مثلا برنامه هدرهای لازم رو با فرمت صحیح پرینت کنه) و خروجی هم طبیعتا اگر میخواد در مرورگر بصورت صفحهء وب نمایش داده بشه باید به زبان HTML باشه.

البته PHP هم امروزه داره به همین روش CGI یا نسخهء بهینه تر اون FastCGI اجرا میشه. یعنی درواقع اون برنامهء خارجی مفسر PHP هست که سورس صفحات PHP ما رو بعنوان دستورات و عملیات لازم میخونه و اجرا میکنه و هرچیزی رو که بهش با echo گفتیم خروجی بده خروجی میده و الی آخر. ولی طبیعتا یکسری کارها رو خود مفسر PHP انجام میده و کلا خیلی سطح بالاتر و راحتتره نسبت به زبانهای برنامه نویسی عمومی ای مثل سی و سی++. مثلا شما نیازی نیست فرمت درونی هدرها و امکانات دیگر HTTP رو بدونید و دقیقا اونا رو رعایت کنید، و مثلا میتونید به سادگی از توابعی مثل header یا cookie استفاده کنید و مفسر PHP خودش بقیهء کارها و ایجاد فرمت خروجی مورد نیاز رو انجام میده.

یک حالت دیگه که PHP در بعضی سرورها اجرا میشه با استفاده از یک ماجول آپاچی بنام mod_php است که در این حالت مفسر PHP در درون خود آپاچی در پاسخ به درخواستها اجرا میشه و یک برنامهء خارجی نیست و بنابراین این روش CGI نیست.

masoud_tamizy
جمعه 05 اسفند 1390, 22:53 عصر
خیلی مطلب خوبیه ممنون ولی کم سنگینه ! لطفا اگه دوستان مطالب دیگه ای دارن بذارن :لبخندساده:

eshpilen
جمعه 05 اسفند 1390, 23:24 عصر
CLI هم مخفف Command-Line Interface است و به حالت اجرا و استفاده از مفسر PHP مستقیما در خط فرمان گفته میشه.
توجه کنید که این حالت به وب و درخواست و پاسخ HTTP ارتباطی نداره (البته به روش اجرای CGI شباهت زیادی داره). یک اجرای مستقیم مثل برنامه های معمولی هست.
یعنی شما مثلا در خط فرمان مفسر PHP رو فراخوانی میکنید و نام یک فایل PHP رو بهش میدید و مفسر PHP هم دستورات اون فایل رو اجرا میکنه؛ خروجیها هم در خط فرمان پرینت میشن.
مثلا من در خط فرمان این رو تست کردم:

C:\Program Files\EasyPHP-5.3.2\php>php.exe cli.php
که نتیجه چاپ عدد 12 در خط فرمان بود، چون محتویات فایل cli.php که برای تست درست کردم این بود:

<?php

echo 3*4;

?>

ضمنا چند روش دیگر هم برای استفادهء مستقیم از مفسر PHP وجود داره.

مثلا مطابق این مثال میشه فرمان یا فرمانهایی رو مستقیما در یک خط فرمان به مفسر PHP داد تا اجرا کنه:

C:\Program Files\EasyPHP-5.3.2\php>php -r "echo 3*4; file_put_contents('out.txt', '1234');"

همینطور با آپشن a میشه مفسر PHP رو مثل بعضی زبانهای اسکریپتی دیگر (مثلا پایتون) درحالت Interactive استفاده کرد.
در این حالت مفسر اجرا شده و در خط فرمان خودش منتظر تایپ فرمانهای کاربر میمونه و هر فرمان تایپ شده توسط کاربر رو بعد از زدن Enter فورا اجرا میکنه (البته اجرای این حالت روی ویندوز مقداری مشکل داره).

eshpilen
جمعه 05 اسفند 1390, 23:43 عصر
خیلی مطلب خوبیه ممنون ولی کم سنگینه ! لطفا اگه دوستان مطالب دیگه ای دارن بذارن :لبخندساده:
CGI چیز پیچیده ای نیست. فقط باید از فرمت پروتکل HTTP و ساختار HTML پیروی کنید (البته این مورد اخیر درصورتیکه خروجی مورد نظر یک صفحهء HTML باشه - چون میتونه چیزهای دیگری مثل دیتای باینری مربوط به یک تصویر هم باشه).
مثلا این یک برنامهء CGI خیلی ساده به زبان C هست:


#include <stdio.h>

int main(void)
{
printf("Content-type: text/html\n\n");
printf("<html><title>Hello</title><body>\n");
printf("Goodbye Cruel World\n");
printf("</body></html>");
return 1;
}

منبع: http://www.purplepixie.org/cgi/howto.php

درواقع این برنامه رو مثل برنامه های عادی کامپایل میکنیم و میتونیم مثل برنامه های عادی در خط فرمان اجرا کنیم. ولی طبیعتا خروجی ای که میده غیر از وب کاربردی نداره، چون یک هدر HTTP و مقداری کد HTML پرینت میکنه.
وب سرور میاد و وقتی درخواستی از کلاینت دریافت میشه که آدرسش به این برنامه نگاشت میشه، این برنامه رو اجرا میکنه، و البته پارامترهای مختلف و دیتای درخواست کلاینت (درصورتیکه درخواست POST باشه در قسمت بدنه دیتا هم داره) رو هم بوسیلهء متغییرهای محیطی و ورودی استاندارد خط فرمان در اختیار برنامه میذاره (که البته ما در این برنامهء ساده از هیچکدام از این موارد استفاده نکردیم)، بعد هرچی که برنامه پرینت میکنه توسط وب سرور گرفته و به کلاینت ارسال میشه.

درمورد PHP برنامه ای که برای پردازش تمام درخواستها اجرا میشه مفسر PHP هست (البته طبیعتا مفسر نسخهء CGI و نه نسخهء CLI). فایل PHP مورد نظر هم طبیعتا باید بعنوان پارامتر بهش پاس بشه که شما این فایل رو با آدرسی که در مرورگر وارد کردید مشخص کردید.

eshpilen
شنبه 06 اسفند 1390, 00:06 صبح
راستی شباهت و تفاوت CGI و CLI رو میشه در این مثال مشاهده کرد:

C:\Program Files\EasyPHP-5.3.2\php>php-cgi.exe cli.php
X-Powered-By: PHP/5.3.2
Content-type: text/html

12
C:\Program Files\EasyPHP-5.3.2\php>
همونطور که میبینید بنده همون فایل cli.php رو در خط فرمان اجرا کردم، منتها این بار با استفاده از نسخهء CGI مفسر PHP.
تنها تفاوتی که دیده میشه اینه که دو هدر قبل از عدد 12 بوسیلهء مفسر PHP پرینت شدن. البته بعد از هدرها یک خط خالی هم داریم که این در پروتکل HTTP برای مشخص کردن پایان بخش هدرها و شروع بخش بدنه استفاده میشه.
طبیعتا این تنها یک مثال خیلی ساده و محدود بود و ممکنه تفاوتها و مسائل دیگری هم در موارد پیچیده تر وجود داشته باشن. بهرحال میخواستم نشون بدم که از نظر روش اجرا CGI و CLI مشابه هم هستن. در هر دو روش مفسر PHP بصورت یک برنامهء خارجی اجرا میشه و مفسر PHP فایل PHP مورد نظر را خوانده و دستورات آن را اجرا کرده و خروجی را با مکانیزم عادی خروجی استاندارد برنامه های خط فرمان پرینت میکنه.
درمورد CGI این نرم افزار وب سرور هست که مفسر رو اجرا میکنه و ورودی ها رو به برنامه میده و خروجیها رو میگیره (و به کلاینت ارسال میکنه) و پنجرهء خط فرمانی هم باز نمیشه (تمام این کارها پشت پرده انجام میشن)، اما در مورد CLI مفسر مستقیما و مثل برنامه های خط فرمان معمولی اجرا شده و ورودیهاش از خط فرمان گرفته شده و خروجیها هم مطابق حالت عادی در پنجرهء خط فرمان چاپ میشن.

masoud_tamizy
شنبه 06 اسفند 1390, 07:28 صبح
فوق العاده متشکرم :لبخندساده:

MMSHFE
شنبه 06 اسفند 1390, 08:28 صبح
ضمن تشکر از دوستمون جناب eshpilen، فقط یک نکته که فکر میکنم فراموش کردن بگن اینه که CGI مخفف Common Gateway Interface هست و لازم نیست برنامه ای که با هر زبانی نوشته شده رو حتماً با نوع EXE یا COM کامپایل کنید بلکه همینکه به زبان ماشین (Native Code) تبدیل شده باشه (مثلاً در زبان C فایل obj. تولید شده بعد از کامپایل) کافیه و اون فایل رو مستقیماً میشه توسط CGI مورد دسترسی قرار داد. بنابراین، باید دقت کنید که برنامه های کامپایل شده روی لینوکس (فرضاً) روی ویندوز قابل اجرا نیستن و بالعکس. حتی اگه از زبانهای Multi-Platform مثل ++C یا Java استفاده کرده باشیم. حداقل کاری که برای انتقال برنامه ها به سیستمهای عامل دیگه باید انجام بشه، کامپایل مجدد در اون سیستم عامل هست. موفق باشید.

eshpilen
شنبه 06 اسفند 1390, 09:26 صبح
لازم نیست برنامه ای که با هر زبانی نوشته شده رو حتماً با نوع EXE یا COM کامپایل کنید بلکه همینکه به زبان ماشین (Native Code) تبدیل شده باشه (مثلاً در زبان C فایل obj. تولید شده بعد از کامپایل) کافیه و اون فایل رو مستقیماً میشه توسط CGI مورد دسترسی قرار داد

نه بابا :متعجب:
من نمیدونستم.
جدا فایل obj کار میکنه؟
اونوقت میشه یک فایل obj یکسان رو در هردوی لینوکس و ویندوز اجرا کرد؟
منبعی داری براش بده بخونم.


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

MMSHFE
شنبه 06 اسفند 1390, 10:08 صبح
بله کار میکنه. البته اگه فایلهای دیگه هم ضمیمه شده باشه، باید با linker اونها رو ادغام کنید. البته همونطور که گفتم فایلهای یک سیستم عامل روی سیستم عامل دیگه اجرا نمیشه چون Native Code اونها متفاوته.

eshpilen
شنبه 06 اسفند 1390, 10:18 صبح
بله کار میکنه. البته اگه فایلهای دیگه هم ضمیمه شده باشه، باید با linker اونها رو ادغام کنید. البته همونطور که گفتم فایلهای یک سیستم عامل روی سیستم عامل دیگه اجرا نمیشه چون Native Code اونها متفاوته.
بازم منظورت برام مبهمه.
فکر کنم میگی با هر کامپایلری روی هر سیستم عاملی میتونیم obj کد رو بدست بیاریم و این obj کد مستقل از پلتفرم هست. و بعدش اگر خواستیم روی هر سیستمی بصورت CGI استفاده کنیم باید این obj ها رو link کنیم.

البته وقتی لینک بکنی میشه همون فایل اجرایی استاندارد دیگه. من فکر کردم شما میگی میتونیم همون کدهای obj رو مستقیما با CGI اجرا کنیم.

MMSHFE
شنبه 06 اسفند 1390, 14:38 عصر
نه عزیز میشه بگیم کاملاً منظورم رو برعکس برداشت کردین. دقت کنید که کامپایلرها سه بخش دارن:
1- مفسر (Interpreter) که سورس کد هر فایل از پروژه رو میگیره و فایل Native سیستم عاملی که مترجم روش نصب شده رو تحویل میده
2- متصل کننده (Linker) که وظیفه برقراری ارتباط بین فایلهای ترجمه شده متعددی که در پروژه موجود هست رو برعهده داره و با ترکیب همه اونها، یک فایل نهایی تولید میکنه
3- ایجاد کننده (Maker) که فایل نهایی خروجی متصل کننده رو میگیره و فایل اجرایی با پسوند scr. و cmd. و com. و exe. و... (بسته به نوع سیستم عامل مربوطه و نوع خروجی مورد درخواست) رو ایجاد میکنه
اگه دقت کنید، میبینید که از همون مرحله اول، نوع خروجی بستگی به سیستم عامل مربوطه داره و مثلاً اگه یک برنامه ++C رو توی لینوکس کامپایل کنیم، نمیتونیم از این Native Code توی ویندوز استفاده کنیم.
لینک کردن هم یعنی اینکه اگه فرضاً توی یک فایل C فایل هدری مثل stdio.h رو ضمیمه کردیم، اون فایل هم بعد از ترجمه به زبان ماشین، با فایل برنامه ما ادغام بشه و یک فایل واحد تولید بشه که دیگه برای اجرای اون نیاز نباشه هدر فایل رو هم همراهش ذخیره کنیم. خروجی لینک کردن هم فایل اجرایی استاندارد نیست.
باز هم تأکید میکنم کدهای obj. رو مستقیماً میشه با CGI اجرا کرد به شرط اینکه سیستم عاملی که قراره روش کدها رو اجرا کنیم، همون سیستم عاملی باشه که کد باهاش کامپایل شده. فایلهای obj. فایلهای باینری صرف هستن که با یک تبدیل ساده میشه خروجی اجرایی com. یا exe. و... رو از اونها بدست آورد (درواقع Maker با اضافه کردن هدرهای مربوط به هر فرمت اجرایی، فایل باینری ما رو به اون قالب در میاره). البته باید دقت کنیم فایلهای بالای 64 کیلوبایت رو نمیشه بصورت com. درآورد.
موفق باشید.

eshpilen
شنبه 06 اسفند 1390, 20:18 عصر
خروجی لینک کردن هم فایل اجرایی استاندارد نیست.من قبلا روی لینوکس مقداری اسمبلی کار کردم از روی یک کتابی. کل کار دو مرحله بود. یک مرحله فرمان as رو اجرا میکردی، مرحلهء بعد با ld لینک میکردی که با این کار فایل اجرایی تولید میشد.
کلا لینکر در لینوکس اینطور هست. یعنی اون مرحلهء بقول شما Make رو هم انجام میده. حالا در بعضی کامپایلرها ممکنه این مراحل و برنامه هاشون جدا باشن.
مقالهء ویکیپدیا هم درمورد لینکر (http://en.wikipedia.org/wiki/Linker_%28computing%29) میگه:

a linker or link editor is a program (http://en.wikipedia.org/wiki/Computer_program) that takes one or more objects (http://en.wikipedia.org/wiki/Object_file) generated by a compiler (http://en.wikipedia.org/wiki/Compiler) and combines them into a single executable (http://en.wikipedia.org/wiki/Executable) program.

ترجمه: «یک لینکر برنامه ایست که یک یا چند آبجکت تولید شده بوسیلهء یک کامپایلر را گرفته و آنها در قالب یک برنامهء اجرایی واحد ترکیب میکند»
در جاهای دیگرش هم صحبت کرده تقریبا روشنه که میگه فایل اجرایی استاندارد تولید میکنه.

کلا دلیل خاصی هم نمیبینم که بعد از مرحلهء لینک بازهم مرحلهء مجزای دیگری باشه تا به فایل اجرایی برسیم. چون در مرحلهء لینک تقریبا تمام کارهای اساسی و زمانبر انجام شدن، و از طرف دیگه بقول خودتون این مراحل از ابتدا به پلتفرم وابسته هستن و بنابراین بنظر نمیرسه وجود یک فایل که حاوی کد ماشین باشه اما هنوز در فرمت کامل یک فایل اجرایی پلتفرم خاصی درنیامده کاربرد و فایدهء خاصی داشته باشه (چون فقط روی همون سیستم قابل استفاده هست و تا وقتی تبدیل به فایل اجرایی اون سیستم نشده نمیشه ازش استفاده ای کرد). منظورم اینه که مثلا اینطور نیست که بشه اون فایل رو ببریم روی پلتفرم دیگه ای و اونجا Make کنیم و با این کار فایل اجرایی اون پلتفرم تولید بشه.


باز هم تأکید میکنم کدهای obj. رو مستقیماً میشه با CGI اجرا کرد به شرط اینکه سیستم عاملی که قراره روش کدها رو اجرا کنیم، همون سیستم عاملی باشه که کد باهاش کامپایل شده.از کجا اینقدر مطمئن هستید؟
خودتون تست کردید؟ جایی دیدید؟ سند و منبعی دارید براش؟


فایلهای obj. فایلهای باینری صرف هستن که با یک تبدیل ساده میشه خروجی اجرایی com. یا exe. و... رو از اونها بدست آورد (درواقع Maker با اضافه کردن هدرهای مربوط به هر فرمت اجرایی، فایل باینری ما رو به اون قالب در میاره).
بله اگر اول لینک کنیم و بعد بقول شما Make کنیم فایل اجرایی نهایی تولید میشه.
ولی اینکه میگید همون obj رو مستقیما با CGI اجرا کنیم یه حرف دیگس که من تاحالا جایی مشابهش رو ندیدم. واسه همین برام عجیب و جالبه. بهرحال پیگیری میکنیم و تست هم میشه کرد حتما.
بعدم مثلا یک برنامه که متشکل از چند فایل obj هست رو چطور میشه مستقیما اجرا کرد؟ این فایلها اول باید باهم ترکیب بشن و یک برنامهء واحد رو تولید کنن تا قابل اجرا باشن، و چنین کاری هم میشه لینک کردن دیگه!

مقالهء ویکیپدیا درمورد Object file (http://en.wikipedia.org/wiki/Object_file) هم میگه:

An object file is a file containing relocatable format machine code (http://en.wikipedia.org/wiki/Machine_code) that is usually not directly executable.

همونطور که میبینید میگه معمولا این فایلها بصورت مستقیم قابل اجرا نیستن.

eshpilen
یک شنبه 07 اسفند 1390, 21:36 عصر
یه سیستم قدیمی PIII دارم که یه گوشه خوابیده. روش لینوکس نصبه (فدورا 5). گاهی برای تست و اینها ازش استفاده میکنم.
این قضیهء امکان اجرای مستقیم obj کد با CGI رو هم روش تست کردم. با یک برنامهء سی ساده.
با آپشن c میتونید به GCC دستور بدید که بجای فایل اجرایی عادی فایل obj بده.
فایل اجرایی عادیش (a.out) با CGI با موفقیت اجرا شد.
اما فایل obj کار نمیکنه. پرمیشن اجرا بهش دادم، با هردوی پسوند o (که پسوند پیشفرض خودش بود) و out روش تست کردم، ولی کار نمیکنه. پیام خطایی در صفحهء مرورگر نمیاد اما هیچ خروجی ای هم دیده نمیشه.
برای اطمینان بیشتر با یک فایل متنی عادی هم تست کردم که ببینم اگر فایلی که قابل اجرا نباشه از طریق CGI فراخوانی بشه همون حالت بدون پیام خطا و بدون خروجی رو نتیجه میده یا نه، که دقیقا همونطور بود.

خلاصه بنده نفهمیدم این ماجرای عجیب اجرای مستقیم فایل obj با CGI از کجا اومد. بهرحال نه اسناد و نه استنباط عقلانی و نه تست عملی این قضیه رو تایید نکردن.
البته هرچیزی ممکنه و علم رایانه و برنامه نویسی گسترده و پیچیده هست، ولی بهرحال تا اینجا شواهدی پیدا نشد. مقالهء ویکیپدیا میگه این فایلها معمولا بصورت مستقیم قابل اجرا نیستن، از این گفته اینطور بنظر میرسه که در موارد خاصی ممکنه قابل اجرا باشن (هرچند این یک حالت کلی هست و به استثنای خاصی درمورد CGI مربوط نمیشه). بهرحال بنده شخصا تاحالا نشنیدم و برخورد نکردم.