💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت در ۵ آذر ماه (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۲ محسن موحد
مسائل مقدماتی از سایت‌های داینامیک و مسائل پشت پرده ی سمت سرور و مرورگر
جامعه پی اچ پی ایجاد شده در ۲۵ آذر ۱۳۹۸

مقالاتی که درج میشه با اینکه مباحث مقدماتی هستند ولی داخلشون جزئیاتی اورده شده که میتونه دیدتون رو نسبت به اون قضایا عوض کنه و همچنین نگاه بهتری به مسائل و حتی گرامر‌های پشت پرده ی PHP داشته باشید.بنابراین حتی اگر اون مسئله از نگاهتون ساده بود، مقالشو کامل بخونید احتمالاً جزئیات بیشتری نسبت به اون موضوع یاد خواهید گرفت.

سال 1989، Tim Berners-Lee (یکی از کارمندان پروژه CERN) پیشنهاد اولیه وب(World Wide Web) رو مطرح کرد. در ابتدا برای حل یک مشکل قرار بر این بود بعنوان یک سیستم ارتباطی برای CERN باشد، تا از این داده‌ها به شکل مشترک استفاده شود ولی Tim متوجه شد که میتوان این پروژه رو در سطح جهانی اجرا کرد.
در نتیجه برای اینکه کاربران اینترنتی بتوانند صفحات وب را پیمایش کنند، او چارچوبی(پروتوکلی) رو ابداع کرد که توسط آن بتوانند، بین صفحات وب، بوسیله ی Hyperlink ها(لینکهای داخل صفحه) جابجا شوند. این چارچوب بعنوان Hypertext Transfer Protocol یا HTTP شناخته شد.

همچنین او یک زبان نشانه گذاری بنام Hypertext Markup Language یا همان HTML را ابداع کرد و با امدن HTTP و HTML، اولین مرورگر بنام NEXTcube و یک وب سرور ساده بنام CERN httpd را طراحی کرد. در نهایت CERN آنها را در سال  1991 منتشر کند.

با آمدن HTTP و Web Server، بستر وب جهانی محیا شد.
شما میتوانید HTTP را سیمی تصور کنید، که مرورگر کاربر را به سرور، وصل کرده است و تمام داده‌ها بین مرورگر و سرور، روی این سیم، جابجا میشوند.(این جابجایی طبق قوانین تعریف شده در HTTP انجام میشود.)
Web Server هم یک هندلر و گرداننده، روی سرور میباشد. پس سیم اتصال، بین مرورگر و Web Server جریان دارد. در ادامه بیشتر توضیح داده ایم.

با انقلابی که در حوزه ی وب اتفاق افتاد، خیلی زود بسیاری از مردم، بوسیله ی مودم‌های خانگی و بصورت Dial Up به یک صفحه ی متنی ساده، که این صفحه روی کامپیوتری بنام NeXT قرار گرفته بود متصل شدند. در ادامه این تحولات، سه مروگر گرافیکال هم عرضه شد که توجه خیلی از کاربران رو به خودش جلب کرده بود اما با وجود لینک‌های متنوع و حتی تصاویر انیمیشن(GIF)، این صفحات Static، پویایی لازم رو نداشت و جوابگوی نیازهای کاربران نبود در نتیجه نیاز به محتوای Dynamic احساس میشد.

با امدن مرورگرهایی چون NetScape و بعد از اون IE، بستر استفاده و اجرای جاوا(Web Start Application ، Applet) و جاوااسکریپت(JavaScript) و جی اسکریپت(JScript) و Activex روی مروگر ایجاد شد.

ازآنجایی که، زبان های Javascript ، Jscript ، HTML ، CSS روی مرورگر کاربر اجرا میشوند، به این زبان ها، Client Side یا سمت کاربر میگویند.

در آن زمان که زبان مخصوص وب وجود نداشت و نیاز به تولید محتوای داینامیک احساس میشد، رابطی بنام CGI معرفی شد که توسط آن میشد با زبانی مثل C یا PERL و ... روی بستر وب، محتوای داینامیک تولید کرد. اما در ادامه ی پیشرفت حوزه ی وب، با امدن زبان PHP و همچنین با محبوبیتی که این زبان بدست اورد، PHP جایگزینی برای PERL و دیگر زبان هایی که استفاده میشد، بود.

زبان PHP و همچنین زبان هایی مثل PERL و Python و C++ و Java و ... (با استفاده از CGI) که برای تولید محتوای داینامیک در برنامه هایمان استفاده میکنیم روی کامپیوتر سرور اجرا میشوند، ازینرو به آنها Server Side یا سمت سرور گفته میشود.

 

بد نیست بدانید، Java ربطی به JavaScript نداره و صرفا فقط همنامند. JavaScript توسط شرکت NetScape ساخته شد و ابتدا تحت نام Mocha توسعه داده شد. این نام در انتشار نسخه ی Beta مرورگر NetScape Navigator 2.0 به LiveScript تغییر نام داد و در آخر در انتشار Netscape Navigator 2.0 beta 3 به JavaScript تغییر نام داد.

 

حالا با این توضیحاتی که تا اینجا داده شد، ببنیم زمانی که کاربر، آدرس سایتی رو وارد مرورگرش میکنه، بین مرورگر و سرور اون سایت چه اتفاقی میفته، Request‌ها و Response‌ها چطور جابجا میشن:

 

 

این تصویر1 رو ببینید...

 

قسمت 1. در مرحله ی اول فرض میکنیم، میخواهیم سایت http://example.com رو در مرورگر باز کنیم. پس آدرس سایت بیت هاب را در مرورگر وارد میکنیم.

قسمت 2. مرورگر کاربر برای باز کردن سایت، به آیپی سایت(در اینجا یعنی آیپی example.com) احتیاج داره و باید بدونه آیپی نام سایتی که وارد کردیم، چیه!؟ یعنی از طریق آیپی، اون سایت رو پیدا میکنه. پس اگر آیپی سایت را در مرورگر وارد کنیم، قاعدتا سایت روی مرورگر باز میشود.
تبدیل آدرس سایت به آیپی، وظیفه ی DNS است. DNS Server‌ها کامپیوترهایی در مسیر اینترنت هستن که آیپی سایت‌ها را در پایگاه داده ی خود نگه میدارند. بنابراین برای یافتن آیپی یک سایت از این پایگاه داده‌ها پرس و جو میشود.
مرورگر عمل DNS Lookup رو انجام میده و ابتدا میگرده ببینه قبلا این سایت داخل مرورگر Cache شده یا نه(ممکنه این سایت قبلا در مرورگر باز شده باشه)، اگر آیپی وجود نداشت، Cache سیستم عامل کاربر چک میشه(و اگر نبود)، جستجوی آیپی در Cache روتر کاربر انجام میشه (و بازهم اگر نبود)، درخواست جستجوی آیپی به DNS Server درون ISP ارسال میشه (کش ISP هم بررسی میشه) و اگر آیپی یافت نشد، به DNS Server یک سطح بالاتر از ISP درخواست ارسال میشه و اگر باز هم پیدا نشد، بصورت بازگشتی این عمل به DNS Server‌های سطوح بالاتر ادامه پیدا خواهد کرد تا آیپی(آدرس تایپ شده) پیدا بشه و آیپی مد نظرو به مرورگر برگردونه. اگر هم پیدا نشد، خطایی به مرورگر ارسال خواهد شد.

آیپی سایت ما 185.94.96.154 است ولی اگر این آدرس را در مرورگرتان وارد کنید، سایت را باز نمیکند. چون هاست اشتراکی است و روی این آیپی چندین سایت دیگر هم وجود دارد. پس چطور سایت پیدا میشود؟ مرورگر، داخل درخواستی که به آیپی 185.94.96.154 ارسال میکند، به این آیپی می‌گوید که دنبال چه سایتی میگردد.

 

اما برای مثال میتوانید از سایت google.com پینگ بگیرید: ping google.com و با وارد کردن آیپی آن یعنی 216.58.214.238 در مرورگر، ببینید که سایت گوگل باز میشود.

قسمت 3. در مرحله ی سوم، آیپی پیدا شده بنابراین مرورگر کاربر، درخواستی(HTTP Request) رو به آیپی مورد نظر، ارسال میکنه.

کار HTTP از این مرحله شروع میشود. ارتباط HTTP از سمت مرورگر به سمت سایت مورد نظر، صورت میگیرد.

قسمت 4. در مرحله چهارم، همونطور که در تصویر میبینید، سرور سایت ما، درخواستی رو از مروگر کاربر دریافت کرده.

نکته: زمانی که درخواستی به سرور میرسد، این درخواست باید بدرستی پردازش شود و درنهایت، پاسخ مناسبی برای مرورگر ارسال گردد. مدیریت روی این درخواست‌ها و درنهایت بازگرداندن پاسخ مناسب به مرورگر، وظیفه ی وب سرور است. بنابراین، وقتی مرورگر، درخواستی را برای لود سایت به سوی سرور میفرستد، این درخواست به وب سرور میرسد و وب سرور پس از گذراندن یک سری مراحل(در ادامه توضیح میدهیم)، محتوای سایت را بعنوان پاسخ، به مرورگر کاربر، ارسال میکند.

 

پاسخ وب سرور، به همان مرورگری که درخواست لود سایت را داده است، برمیگردد. یعنی وب سرور میداند که چه کسی، چه درخواستی فرستاده است و درخواست‌ها را بدرستی مدیریت میکند.

خب، اینجا کاربر در مروگر، آدرس http://example.com رو وارد کرده و در تصویر دیدیم که درخواست به وب سرور رسیده است. اما در انتهای آدرس کاربر چیزی ذکر نشده که کدوم صفحه از سایت مد نظرشه!(index.php یا default.html یا ...)

نکته: وقتی آدرسی مثل http://example.com یا ... را در مرورگر وارد میکنید، انگار نام فولدری را صدا میزنید. تصور کنید در کامپیوترتان فولدری را با نام example.com دارید. داخل این فولدر، فایلی به نام index.html وجود دارد. حالا اگر بخواهیم مسیر این فایل را بگوییم، به این شکل میشود: example.com/index.html
بنابراین، اسم یک سایت، مانند نام یک پوشه است و برای باز کردن صفحه ای از این سایت، باید نام آن صفحه را در آخر ذکر کنیم.

 

سؤال: ما در مرورگر example.com را وارد کردیم و هیچ فایلی را به آخر آدرس سایت، اضافه نکردیم. چرا سایت باز میشود؟
پاسخ: اینجاست که وب سرور براساس مقدار پیش فرضی که در کانفیگش آمده(فرض میکنیم در کانفیگ index.html آمده) دنبال صفحه ی index.html میگردد. یعنی وب سرور این آدرس را در نظر میگیرد: http://example.com/index.html

وب سرور آپاچی برای یافتن صفحه ی پیش فرض، به مقدار DirectoryIndex در داخل فایل تنظیماتش نگاه میکنه. ممکنه مدیر سرور در کنار index.html صفحه ی  index.php هم گذاشته باشه. بنابراین وب سرور، بترتیب ابتدا دنبال صفحه ی index.html میگرده و اگر این صفحه وجود نداشت بعد بدنبال index.php میگرده و ...

بطور مثال، این یک نمونه از تنظیمات DirectoryIndex وب سرور هست:

 DirectoryIndex index.html index.php

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

 

قسمت 5. وب سرور، صفحه ی index.html رو روی هارد سرور، پیدا کرده و فراخوانی میکنه.(بر اساس DirectoryIndex)

اگر صفحه ی index.html پیدا نمیشد، صفحه ی index.php جستجو میشد، و اگر آن صفحه هم نبود، خطای Not Found به مرورگر کاربر، ارسال میشد.

 

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

قسمت 7. و در مرحله ی آخر، مروگر پاسخ رو دریافت کرده، و صفحه ی وب رو Render کرده و نمایش میدهد.

مرورگر درخواست را در قالب HTTP Request ارسال میکند و در آن سو Web Server سایت، بسته ی پاسخ را در قالب HTTP Response تحویل مرورگر کلاینت میدهد. بنابراین شروع کار این پروتوکل از سمت مرورگر کاربر هست و به سمت وب سرور سایت ارسال میشه و این ارتباط تا دریافت پاسخ باز میمونه.

 

بین کلاینت و سرور ممکنه چندین دستگاه دیگه مثل Router‌ها و Proxy‌ها و Gateway‌ها و ... وجود داشته باشد. بنابراین روی ارسال درست درخواست‌ها و پاسخ‌ها تأثیر میگذارن.

 

حالا بررسی کنیم، اگر صفحه ی درخواستی کاربر، یک فایل داینامیک بود، چه اتفاقی میفته

 

این تصویر2 رو ببینید...

 

قسمت 1 و 2 و 3 و 4: همون مراحل قبلی طی میشه.

قسمت 5. وب سرور با توجه به توضیحات قبلی، ابتدا دنبال صفحه ی index.html میگرده و درصورت پیدا شدن، صفحه فراخوانی میشه ولی برفرض ما، این صفحه، وجود ندارد، پس صفحه ی index.php فراخوانی میشود.

قسمت 6. با توجه به تنظیمات وب سرور، بخاطر اینکه فایل درخواستی دارای پسوند .php هست، بنابراین وب سرور صفحه ی index.php رو (برای تفسیر کدهای PHP) ارجاع میده به مفسر PHP.

فرض میکنیم صفحه ی index.php حاوی کدهای زیر است:

 آموزش برنامه نویسی
 BiDak
 <div>
 <?php $format = 'Y/m/d - H:i:s'; ?>
 <?php $date = date($format); ?>
 <span>تاریخ امروز: <?php echo $date; ?></span>
 </div>
<p>برنامه نویسی توسط <strong>محسن موحد</strong></p>

قسمت 7. حالا مفسر در فایل index.php اگر بلاک <?php ?> پیدا کرد، کدهای داخل این بلاک رو خط به خط اجرا میکنه و گرنه هر چیزی خارج از این بلاک را بعنوان خروجی در نظر میگیرد.

صفحات درخواستی روی RAM سرور لود میشوند، بنابراین تمام این پردازش‌ها روی RAM صورت میگیره.

 

با توجه به مثالی که از صفحه ی index.php داریم(کد بالا)، حالا ببینیم مفسر چگونه عمل میکنه:
خط 1: 
بلاک PHP وجود ندارد. پس بعنوان خروجی در نظر گرفته میشه و این خط تفسیر نمیشود.

در این مثال فرض میگیریم بافر در تنظیمات پیش فرض PHP با مقدار 4 کیلوبایت فعال است بنابراین خروجی تولید شده در یک متغیر، روی RAM ذخیره میشود و تا زمانیکه تفسیر فایل index.php به پایان نرسیده، چیزی بعنوان پاسخ، برگردانده نمیشود.

خط 2: هیچ چیزی وجود ندارد و چون این خط، بنابراین یک خط خالی بعنوان خروجی در نظر گرفته میشود و به مقدار خروجی قبلی اضافه میشود.

در سورس HTML هر تعداد فاصله یا Enter وجود داشته باشد، در مرورگر بعنوان یک فاصله نمایش داده میشود. فرضا اگر 10، Enter بین دو خط بزنید، در سورس مرورگر 10 تا Enter خواهید دید ولی در صفحه ی نمایشی مرورگر فقط یک WhiteSpace یا فاصله در نظر گرفته میشود.

خط 3: بلاک PHP وجود ندارد بنابراین هر جه که هست بعنوان خروجی در نظر گرفته میشود و به داده‌های خروجی قبل اضافه میشود.(اینجا 4 فاصله و کلمه ی BiDak)
خط 4: بلاک PHP وجود ندارد بنابراین هر جه که هست بعنوان خروجی در نظر گرفته میشود و به خروجی قبلی اضاقه میشود.(اینجا 4 فاصله و تگ div)

تا اینجای کار، خروجی به شکل زیر است:

 آموزش برنامه نویسی
 BiDak
 <div>

اما همانطور که در بالا گفتیم، هنوز پردازش فایل تمام نشده است و تاپایان پردازش ممکن است به این خروجی چیزی اضافه شود، بنابراین تا پایان پردازش فایل درخواستی یعنی فایل index.php، چیزی بعنوان پاسخ به مرورگر برگردانده نمیشود.

بررسی فایل را ادامه میدیم:
خط 5: ابتدا 8 تا فاصله بعنوان خروجی در نظر گرفته میشود و در ادامه ی خط 5، بلاک PHP وجود دارد بنابراین این قسمت توسط PHP تفسیر میشود و بعد از اجرای این خط، مقدار متغیر format در داخل RAM ذخیره میشود. بنابراین در این فایل، اگر متغیر format را صدا بزنیم، به مقدارش یعنی Y/m/d - H:i:s دسترسی خواهیم داشت.

خط 6: مثل خط قبلی ابتدا 8 تا فاصله در خروجی و در ادامه بلاک PHP تفسیر میشود. ایندفعه بعد از اجرای دستور، متغیری با نام date و مقداری بعنوان مثال: 2017/03/18 - 16:17:54 خواهیم داشت.

خط 7: ابتدا 8 تا فاصله در خروجی و بعد تگ span در خروجی و بعد بلاک PHP قرار دارد که با تفسیر این خط، و با توجه به دستور echo مقدار متغیر date یعنی 2017/03/18 - 16:17:54 بعد از تگ span به داده‌های خروجی اضافه میشود و در نهایت بعد از تگ بسته ?>، تگ بسته ی span به خروجی اضافه میشود.

دستور echo، یک خروجی تولید میکند.

خط 8: 4 تا فاصله و تگ بسته ی div در خروجی قرار میگیرد.
خط 9: تگ p و محتویات داخل آن در خروجی قرار یگیرد.

زمانیکه پردازش صفحه ی index.php یا هر صفحه ی دیگر، به اتمام می‌رسد، تمام متغیرهای روی حافظه ی رم سرور، از بین می‌روند.

بعد از پردازش کامل صفحه ی index.php، خروجی به شکل زیر است:

 آموزش برنامه نویسی
 BiDak
 <div>
 <span>تاریخ امروز: 2017/03/18 - 16:17:54</span>
 </div>
<p>برنامه نویسی توسط <strong>محسن موحد</strong></p>

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

اگر میخواهید سورس صفحه را ببینید، میتوانید روی صفحه راست کلیک کنید و View Page Surce را بزنید یا از کلید‌های Ctrl + U استفاده کنید.

 

اگر دقت کرده باشین، تگ span قبلش 24 تا فاصله(6 تب) خورده، علت خط‌های 5 و 6 هستند. هر کدومشون 2 تا تب فاصله دارن و خود تگ span هم 2 تب، بنابراین 6 تب فاصله گرفته.
این فاصله‌ها بعنوان مثال و برای تفهیم مطلب آمده است.

 

مرورگر پاسخ رو دریافت میکنه و به شکل زیر نمایش میده:

 آموزش برنامه نویسی BiDak
تاریخ امروز: 2017/03/18 - 16:17:54
برنامه نویسی توسط محسن موحد

البته این نکته را باید بدانیم که بطور پیش فرض، مفسر PHP در حین پردازش یک فایل، خروجی را بصورت چندین تکه ی مجزا به وب سرور میدهد(با توجه به تنظیم پیشفرض بافر، تکه‌های 4 کیلو بایتی)، و وب سرور هم این تکه از خروجی را به مروگر برمیگرداند و مرورگر هر تکه از خروجی را که دریافت کرد به کاربر نشان میدهد ولی ارتباط بین مروگر و وب سرور، تا پایان پردازش فایل، باز میماند(مدام بین مرورگر کاربر و وب سرور مکالمه انجام میشود) و کاربر علامت لودینگ را همچنان روی مرورگر میبیند و متوجه میشود که سایت هنوز بطور کامل لود نشده است.

 

بنابراین نتیجه میگیریم، در حین تفسیر یک فایل توسط مفسر PHP و همچنین تا قبل از اتمام تفسیر این فایل، ممکن است چندین بار تکه‌های خروجی را به مرورگر ارسال شود.(هر تکه از خروجی یکبار فرستاده میشود.)
پس در مثال فایل index.php، چرا گفتیم هیچ خروجی تا اتمام تفسیر فایل، برای مرورگر ارسال نمیشود؟ در نکته ی قبلی گفتیم PHP داده هارو بصورت تکه تکه برمیگرداند، و از آنجایی که فرض گرفتیم بافر، فعال است و مقدارش 4KB است، بنابراین در مثال ما، تا پایان تفسیر کامل فایل index.php، حتی یک تکه ی 4 کیلوبایتی هم پر نمیشود. پس یا باید این تکه ی 4 کیلوبایتی پر شود یا باید تفسیر فایل به اتمام برسد تا خروجی برگردانده شود.

 

برای پیچیده نشدن ماجرا، فعلا همین سازو کارهایی که در مثال index.php گفتیم را در ذهن داشته باشید تا در جلسات جلوتر و در جلسه ی Output Buffering بصورت کامل و با چندین مثال به جزئیاتی که پیش خواهد آمد، بپردازیم.

قسمت 8. اما ممکنه لابلای کدهای PHP از دستورات کار با بانک اطلاعاتی استفاده شده باشه، بنابراین مفسر دستورات Sql رو ارجاع میده به بانک و در نتیجه بانک خروجی مناسب رو برمیگردونه به مفسر PHP و ... (البته در کدهای بالا از بانک اطلاعاتی استفاده نشده است و مورد 8، توضیحی برای تصویر بالا بود.)

قسمت 9 و 10 و 11 هم باقی ماجرا (قبل از مورد 8 توضیح دادم که چه زمان و چطور خروجی تولید شده توسط مفسر، بعنوان پاسخ به مرورگر ارسال میشود.)

اسلاید مقاله: لینک اسلاید
نویسنده:
 محسن موحد

ممنون جناب موحد بابت محتوا و وقتی که برای نوشتن و انتشارش گذاشتید 

لقمان آوند ۲۶ آذر ۱۳۹۸، ۱۱:۴۷

ممنون از شما دوست عزیز بابت مقاله خوبتون ..

 

زری فاتح ۰۵ اسفند ۱۳۹۸، ۱۷:۴۵