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

به عنوان توسعه دهنده ی وب، شاید بد نباشه مسیر توسعه و پیشرفت زبان PHP رو بدونیم.
در ادامه نقات قوت و خصیصه‌های ذاتی و تفاوت نسخه‌های PHP رو شرح میدیم.
ریشه ی PHP برمیگرده به سال 1995، زمانیکه توسعه دهنده ی نرم افزار به نام Rasmus Lerdorf با توسعه دادن یک اسکریپت PERL/CGI متوجه شد که چه تعداد بیننده، رزومه ی آنلاین او را خوانده اند.

اسکریپت او دو وظیفه را انجام میداد:
1. ورود به سیستم
2. نمایش تعداد بازدیدکنندگان صفحه ی وب

از آنجایی که وب در آن زمان هنوز تکنولوژی نوپایی بود، ابزاری مثل اسکریپت Lerdorf وجود نداشت. بنابراین اسکریپت لردورف، علاقه مندان زیادی را به خود جلب کرد.
نسخه ی اول این اسکریپت Pesonal Home Page Tools یا PHP Tools نامیده شد. تقاضای بالا باعث شد، لردورف توسعه ی این زبان را ادامه دهد.
شاید قابل توجه‌ترین ویژگی در اوایل کار، تبدیل داده‌های (وارد شده توسط کاربر) داخل یک فرم HTML به متغیر‌های مشخص بود. برای انجام این کار، او تصمیم گرفت برای ادامه ی کار از زبان C استفاده کند.(بجای استفاده از PERL)

پیشرفت مجموعه ابزار‌های PHP در نوامبر سال 1997 با انتشار PHP 2.0 یا (Personal Home Page/Form Interpreter (PHP/FI به اوج خود رسید.
نسخه ی 2، با پیشرفت و بهبود زیادی توسط برنامه نویسان در سراسر جهان همراه بود.
انتشار نسخه ی جدید PHP، دارای محبوبیت زیادی شد و یک تیم هسته ی مرکزی از توسعه دهندگان خیلی زود به لردورف پیوستند.

آنها ذات اولیه یعنی ترکیب PHP با HTML (استفاده ی این دو در کنار هم) را نگه داشتند و فقط هسته ی PHP را بازنویسی کردند، که منجر به روی کار آمدن PHP 3.0شد. از این نسخه، PHP به PHP: Hypertext Preprocessor تغییر نام داد.
با انتشار PHP 3.0 در سال 1998، کاربران این حوزه به بیش از 50 هزار نفر رسیدند. توسعه با سرعت بیشتری بیش از دو سال ادامه پیدا کرد.(با صدها تابع جدید در حال اضافه شدن و کاربران در حال رشد.)

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

دو تیم توسعه دهنده Zeev Suraski و Andi Gutmans (بنیان گذاران Zend) ابتکار عمل را بدست گرفتند و بفکر تجدید نظر در عملکرد PHP افتادند که در نهایت، منجر به بازنویسی Parser شد و به نام Zend Script لقب گرفت. نتیجه ی آن PHP 4 بود.

Zend Engine با زبان C نوشته شده و وظیفه ی آن، تفسیر کدهای PHP بوده و Open Source می باشد. اولین نسخه ی این موتور در سال 1999 در نسخه ی چهارم PHP رونمایی شد.
نسخه ی دوم آن یعنی Zend Engine II در PHP 5 به کار برده شده و نسخه ی سوم(Zend Engine III موسوم به PHP Next Generation یا به اختصار PHPNG) در هسته ی PHP 7 به کار رفته است.

PHP 4:
در ماه May سال 2000، حدود 18 ماه پس از تلاش‌های تیم توسعه، PHP 4.0 منتشر شد. خیلی‌ها اعتقاد داشتند، انتشار نسخه 4 اولین حضور رسمی این زبان در صحنه ی توسعه است.
تنها چند ماه پس از این انتشار، NetCraft تخمین زده است که PHP در بیش از 3.6 میلیون دامنه نصب شده است.

PHP 4 بهبودهایی را اضافه کرده بود، از جمله ی این موارد، در زیر شرح داده شده:
1. بهبود بخشیدن به کنترل منابع:
یکی از مشکلات اولیه نسخه‌های 3.x مقیاس پذیری بود، چرا که پروژه‌ها در مقیاس بزرگ با مشکل مواجه میشدند. بهمین منظور توسعه دهندگان تجدید نظر بیشتری روی مکانیسم زبان در این زمینه داشتن.
2. پشتیبانی Object Oriented:
در نسخه 4 این قابلیت اضافه شد، اگر چه عمدتا اعتقاد داشتند ضعیفتر از آنچه تصور میشد، پیاده سازی شده. با این حال، ویژگی‌های جدید نقش مهمی را در جذب کاربران برای استفاده از برنامه نویسی شی گرا ایفا کرد.

البته Object Oriented Programming یا به اختصار OOP در نسخه ی 5 بصورت جامعتر در دسترس قرار گرفت.

3. مدیریت کنترل Session:
در PHP 3.x کاربران تنها از طریق برنامه های Third Party (مانند PHPLib) میتوانستند کنترلی بر سشن‌ها داشته باشند، اما در نسخه ی 4 بصورت توکار در داخل هسته ی PHP گنجانده شد. ارائه ی این ویژگی توسط توسعه دهندگان، وسیله ای برای ردیابی فعالیت کاربران بهمراه تنظیمات آسان آن بود.

4. Encryption: کتابخانه Mcrypt بطور پیش فرض گنجانده شد.
5. پشتیبانی از ISAPI: برای کاربران این امکان را فراهم میکرد تا از PHP در وب سرور IIS هم بهره ببرند. بعدها یک همکاری مشترک بین Zend و Microsoft شکل گرفت که IIS با استفاده از FastCGi از PHP پشتیبانی کند.

6. پشتیبانی از COM/DCOM: یکی دیگر از ویژگی‌های فوق العاده برای کاربران ویندوز که می‌توانستند دسترسی و نمونه سازی از اشیاء COM داشته باشند. این یکی از  قابلیتهای همکاری با برنامه‌های ویندوز بود.

7. پشتیبانی از Java: یکی دیگر از قابلیت‌های نسخه ی 4 PHP، پشتیبانی از اتصال اشیاء جاوا به یک برنامه ی PHP فراهم شد.

8. کتابخانه ی PCRE: زبان PERL مدت زمان زیادیست که حاکمیت تجزیه ی رشته‌ها را دارد. توسعه دهندگان میدانستند که قابلیت قدرتمند REGEX نقش مهمی در PHP میتواند ایفا کند و بهمین منظور تصمیم گرفتند، بسادگی قابلیت PERL را با PHP تلفیق کنند.(بجای اینکه دوباره از نو ایجاد کنند)
کتابخانه PCRE بطور پیش فرض در PHP 4.2.0 آمده است.

علاوه بر این ویژگی‌ها صدها تابع به نسخه ی 4 اضافه شد که تا حد زیادی موجب افزایش قابلیت‌های این زبان بود.
PHP 4 یک جهش عظیم و رو به جلو بهمراه ارائه ی ویژگیهای جدید، قدرت و Scalability همراه بود. با این حال تیم توسعه بازهم به کار توسعه ادامه داد که در نهایت ثمره ی این تلاش، انتشار PHP 5 بعنوان یکی از محبوبترین ها در جهان بود.

PHP 5:
نسخه ی 5، نقطه ی عطفی برای تکامل بود. اگرچه نسخه ی قبلی دارای تعداد زیادی کتابخانه و قابلیت جدید بود، اما نسخه ی پنجم این زبان اسکریپتی، شامل پیشرفتی بیش از قابلیت‌های موجود بود.
در این نسخه، ویژگیهای جدیدی افزوده شد که در زیر، به این قابلیت ها، نگاهی اجمالی خواهیم داشت:

1. بهبود قابلیت‌های شیء گرایی(بطور وسیع):
OO در این نسخه با اضافات متعددی همراه بود، مانند: Constructor، Destructor، Object Cloning، Class Abstraction، Interface و ...

2. کنترل خطاهای برنامه Try/Catch:
این ویژگی در نسخه ی 5 اضافه شده و برای جلوگیری از خطاهای احتمالی در بلاک کد، استفاده میشود.

3. بهبود Xml و پشتیبانی از وب سرویس ها:
در نسخه ی 5، پشتیبانی از Xml بر پایه ی کتابخانه ی LibXml2 صورت میگیرد و برای تجزیه و دستکاری Xml، افزونه ی SimpleXml معرفی شده است.

4. پشتیبانی از Sqlite:
راه حل مناسبی است برای توسعه دهندگانی که دنبال بسیاری از ویژگیهای برخی از پایگاه داده‌های سنگین وزن، بدون سربار اضافی هستند.

با انتشار نسخه ی 5، این زبان محبوبیت بیشتری پیدا کرد که در آن زمان، رکوردی تاریخی بود. 
براساس تخمین NetCraft، تقریبا 19 میلیون دامنه از PHP استفاده میکرد. PHP تا حد زیادی در کنار وب سرور آپاچی(Apache) می‌آمد.(تقریبا 54 درصد)

 

 

PHP 6:
در سال 2005، پروژه ای برای ایجاد پشتیبانی کامل از Unicode در هسته ی PHP، به رهبری Andrei Zmievski آغاز شد اما بدلیل سنگینی عملیات و پیچیدگی در پیاده سازی آن، میلی به توسعه ی این پروژه نشان داده نشد و پروژه بصورت معلق و در شاخه ی در حال توسعه (Trunk) قرار گرفت. کمبود توسعه دهنده، پروژه را با تأخیر مواجه کرده بود.
در سال 2009، نسخه ی PHP 5.3 بهمراه یک سری قابلیت هایی که قرار بود در PHP 6 افزوده شود، منتشر شد.
در سال 2010، رسماً PHP 6 رها شد و در عوض مابقی قابلیت‌های PHP 6 که هنوز به هسته ی رسمی PHP افزوده نشده بود، سال 2012 در PHP 5.4 منتشر شد.

PHP در خروجی گرفتن از Unicode مشکلی ندارد و مشکل زمانی ایجاد میشود که شما بخواهید از توابع کار با رشته مانند: substr یا strlen و ... استفاده کنید. بخاطر اینکه این توابع برای کار با کاراکتر های یک بایتی در نظر گرفته شده، در حالیکه یک کاراکتر Unicode ممکن است بیشتر از یک بایت باشد. پروژه ی PHP 6 برای رفع این مشکل کلید خورد که به سرانجام نرسید.

 

البته برای کار با رشته های Multi-Byte میتوانید از افزونه ی MbString و توابعش، mb_ ها استفاده کنید.
افزونه ی MbString بصورت پیش فرض، فعال نمی‌باشد.

PHP 5.3:
در واقع زبان PHP در این نسخه رشد چشمگیری داشت. ویژگی هایی چون:
1. namespace ها
2. Late Static Binding
3. توابع Lambda 
4. Closure ها 
5. پشتیبانی از SQLite نسخه ی 3
6. استفاده از کتابخانه ی Mysqlnd بجای LibMysql برای برقراری ارتباط با Mysql
7. افزونه ی Fileinfo جایگزین Mime_Magic شد.(کارایی بهتری نسبت به MIME‌ها دارد)

همونطور که در صحبت‌های قبل هم گفته شد، 3 سال پس از PHP 5.3، نوبت به انتشار PHP 5.4 رسید و یک سال بعد، یعنی در سال 2013، نسخه ی PHP 5.5 و در سال 2014 نسخه ی PHP 5.6 منتشر شد.
انتشار این نسخه‌ها با حذف برخی امکانات ناکارامد و افزوده شدن قابلیت هایی چون Trait، OpCache، Generators و ... همراه بود. همچنین قابلیت‌های نسخه‌های پیشین هم، بروزرسانی شدند.

 

 

 

معرفی PHP 7 و کامپایلر Just-In-Time

شاید برای شما هم سؤال پیش بیاید چرا بجای نسخه ی 6، نسخه ی 7 منتشر شد!؟
پس از یک رأی گیری در سال 2014، رسما تصمیم گرفته شد، نام نسخه ی بعدی را PHP 7 بگذارند.
یکی از دلایلی که مطرح است، تلاش ناموفق در انتشار نسخه ی PHP 6 و وجود کتاب‌ها و منابع مختلفی که حتی قبل از انتشار PHP 6 نوشته شده بود که باعث رجوع و سردرگمی برنامه نویسان این حوزه میشد.

PHP 7 با هدف، بهبود بخشیدن به Performance برنامه‌ها (حداقل مشابه چیزی که فیسبوک در HHVM فراهم کرده) به توسعه ی خود ادامه پیدا کرد تا بالاخره در سال 2015، این انتشار صورت گرفت.
PHP 7 با بهبود بخشیدن به کارایی برنامه‌ها و مصرف بهینه از منابع سرور، میتوان گفت به اهداف خودش رسیده. میتوانید گوشه ای از مقایسه هارو اینجا ببینید.

PHP 7، میتواند سریعتر هم باشد:
Dmitry Stogov گفته بود، توسعه ی PHPNG با انگیزه ی تحقیق در پیاده سازی موتور کامپایل Just In Time به اختصار JIT آغاز شد. اما با انتشار PHP 7 این موتور هنوز به نسخه ی رسمی PHP اضافه نشده و هنوز مراحل تست رو طی میکنه. البته در این شاخه، قابل دسترس هست که میتونید ببینید.

اینجا در مورد JIT صحبت کردیم که شاید واستون سؤال پیش بیاد که چی هست یا مگه PHP تفسیری نیست، پس کامپایل چیه و ...
برای شفاف شدن موضوع شاید بد نباشه در مورد نوع اجرا و تفسیر شدن کد‌های PHP صحبت کنیم.

تفسیر کدهای PHP از 3 فاز + فاز اجرای دستورات تشکیل شده:
مرحله اول Lexical Analyze: تمام نوشته های داخل سورس فایل، با توجه به فاصله هایی(WhiteSpace) که بینشان هست، شکسته میشن و این تکه‌ها در دسته بندی خاصی قرار میگیرند.

هر کدام از این تکه‌ها را یک Token میگوییم. مثلا <?php echo 123 ?> توکن‌های این دستور: <?php و echo و 123 و ?> و البته بهمراه 3 تا WhiteSpace.

حالا کد زیرو در نظر بگیرید:

<?php
$a = 5;
$b = 3;
echo $a + ($b * 2);

نتیجه ی آنالیز کد بالا به شکل زیر است:

Array
[
 [0] => Array
 [
 [0] => 379 /**T_OPEN_TAG**/
 [1] => <?php
 [2] => 1 /**Line Number**/
 ]
 [1] => Array
 [
 [0] => 320 /**T_VARIABLE**/
 [1] => $a
 [2] => 2
 ]
 [2] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 2
 ]
 [3] => =
 [4] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 2
 ]
 [5] => Array
 [
 [0] => 317 /**T_LNUMBER**/
 [1] => 5
 [2] => 2
 ]
 [6] => ;
 [7] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 2
 ]
 [8] => Array
 [
 [0] => 320 /**T_VARIABLE**/
 [1] => $b
 [2] => 3
 ]
 [9] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 3
 ]
 [10] => =
 [11] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 3
 ]
 [12] => Array
 [
 [0] => 317 /**T_LNUMBER**/
 [1] => 3
 [2] => 3
 ]
 [13] => ;
 [14] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 3
 ]
 [15] => Array
 [
 [0] => 328 /**T_ECHO**/
 [1] => echo
 [2] => 4
 ]
 [16] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 4
 ]
 [17] => Array
 [
 [0] => 320 /**T_VARIABLE**/
 [1] => $a
 [2] => 4
 ]
 [18] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 4
 ]
 [19] => +
 [20] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 4
 ]
 [21] => (
 [22] => Array
 [
 [0] => 320 /**T_VARIABLE**/
 [1] => $b
 [2] => 4
 ]
 [23] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 4
 ]
 [24] => *
 [25] => Array
 [
 [0] => 382 /**T_WHITESPACE**/
 [1] => 
 [2] => 4
 ]
 [26] => Array
 [
 [0] => 317 /**T_LNUMBER**/
 [1] => 2
 [2] => 4
 ]
 [27] => )
 [28] => ;
]

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

T_OPEN_TAG و بقیه ی عبارت هایی که در مثال بالا میبینید، ثابت هایی هستند که PHP برای Token ID ها در نظر گرفته است. میتونید این لیست رو ببینید.

PHP این امکان رو برای برنامه نویسان فراهم کرده تا بتوانند در برنامه‌های خودشان(مثل Syntax Highlighter و ...) یک سیستم آنالیزی پیاده کنند. اطلاعات بیشتر در این لینک.

بعد از بررسی و آنالیز، اگر در این مرحله خطایی وجود نداشت وارد فاز دوم میشه. 
مرحله دوم Syntax Analyze یا Parsing: توکن‌ها رو دریافت کرده و تا جای ممکن عملیات ساده سازی(مانند حذف فضاهای خالی و قسمت‌های ناکارامد) انجام میگیره و در نهایت، درخت چکیده(Abstract Syntax Tree به اختصار AST) تولید میشه.

Abstract Syntax Tree در PHP 7 اضافه شده است.

درخت چکیده ی مثال بالا رو در زیر ببینید:

Assign statement
 |-- Variable $a
 `-- Integer, value 5
Assign statement
 |-- Variable $b
 `-- Integer, value 3
Echo statement
 `-- Add operation
 |-- Left
 | `-- Variable $a
 `-- Right
 `-- Multiply operation
 |-- Left
 | `-- Variable $b
 `-- Right
 `-- Integer, value 2

مرحله سوم OpCode: بعد از چک کردن قوانین گرامری و تشخیص مناسب بودن عبارات وارد شده، حالا در این بخش AST تولید شده از مرحله ی قبل، کامپایل(ترجمه) میشه به آرایه ای از Operation Code‌ها یا به اختصار OpCode ها.

OpCode‌ها دستورات سطح پایینی هستن که برای ماشین Zend قابل فهم هستن ازیرو بهشون کد میانی هم گفته میشه.

مرحله چهارم Execute: در نهایت Opcode‌ها توسط مفسر یکی یکی و به ترتیب دریافت شده و برای هر Opcode دستورالعمل آن در کد ماشین بصورت مستقیم توسط موتور Zend صدا زده میشه تا دستورات یکی یکی اجرا شوند.

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

ازونجایی که تمام این مراحل روی رم سرور انجام میشود، در هربار فراخوانی صفحه مورد نظر، تمام این مراحل از سر گرفته میشود بنابرایندر اسکریپت‌های سنگین میتواند بار زیادی روی منابع سرور ایجاد کند.
برای حل این موضوع میتوان Opcode Cache به اختصار OpCache را در تنظیمات PHP فعال کرد. این کار باعث میشه، در مرحله ی اول که کد اجرا میشه، OpCode‌ها در رم سرور Cache بشن و دیگه تا زمانی که کد صفحه تغییری نکرده، در هر بار فراخوانی صفحه دیگه مراحل تولید OpCode یعنی اون 3 مرحله ی اول، تکرار نمیشه و مستقیم از روی رم OpCode‌ها رو خونده و در نهایت Execute میکند.
نتیجه ی این کار، صرفه جوبی در مصرف منابع سرور است.

همچنین میتوانید تصویر زیرو هم نگاهی بندازید:

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

 

اماکامپایلر JIT:
کار کامپایلر JIT تبدیل OpCode‌ها به کدهای ماشین هست. JIT هر موقع که نیاز باشد کامپایل را انجام میدهد و قرار نیست در هر بار اجرا این عمل تکرار شود. این تبدیل ممکنه در اجرای اول برنامه، زمان بیشتری نسبت به مفسر، مصرف کنه اما در فراخوانی‌های بعدی بخاطر کش شدن کدهای ماشین، این کدها با سرعت بیشتری اجرا میشوند.

در این قسمت میخوام مقایسه ای انجام بدم تا مقدار حافظه ی مصرفی رو در اجرای یک اسکریپت ببینیم. این تست روی ویندوز انجام شده است.
فرض کنید این اسکریپت رو میخوایم اجرا بگیریم:

$a = [];
for($i=0; $i < 100000; $i++)
{
 $a[] = ['abc','def','ghi','jkl','mno','pqr'];
}
echo memory_get_usage(true);

تابع memory_get_usage، مقدار مصرف حافظه را برحسب بایت برمیگرداند. برای تبدیل Byte به KB یا MB میتونید از تابع زیر استفاده کنید:

function convert($size)
{
 $unit = array('b','kb','mb','gb','tb','pb');
 return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

نتایج بدست آمده:
نسخه PHP 5.6 و OpCache غیر فعال120 MB
نسخه PHP 7 و OpCache غیر فعال44 MB
نسخه PHP 7 و OpCache فعال8 MB

از نتایج بدست آمده میتوانید تفاوت Performance نسخه‌های PHP 5.6 و PHP 7 را بهمراه OpCache در حالت فعال و غیر فعال، ببینید.

 

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

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