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

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

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

مفهوم شی گرایی

در برنامه نویسی غیر شی گرا که معمولا به آن procedural گفته می شود ما کارها را با توابع انجام می دهیم.

مثلا می خواهیم فرمی داشته باشیم و کاربر اطلاعاتش را وارد کند و در سایت ما ثبت نام کند. ساده ترین راه این است یک فرم با html بسازیم با متد POST اطلاعاتی که کاربر وارد می کند را به فایل دیگر ارسال کنیم و آنجا این اطلاعات را در دیتابیس ثبت کنیم.

یا اصلا یک سایت فروشگاهی داریم می خواهیم کدی بنویسیم که در یک صفحه یک محصول به سایت اضافه شود. محصول هم در صفحه محصولات نمایش داده شود.

در حالت procedural ما برای هر کاری که بخواهیم بکنیم می آییم تابع می نویسیم.

برنامه ما تقسیم می شود به چندین تابع هر تابع یک وظیفه ای را برعهده می گیرد.

مثلا یک تابع برای دریافت محصولات مینویسیم (()get_products) یک تابع محصولات را نمایش می دهد  یک تابع هزینه پرداختی را محاسبه می کند یک تابع کد تخفیف می سازد یک تابع تخفیف ر اعمال می کند و …

درست است که با این روش  هم می شود کار کرد اما به همان دلیلی که قبل تر گفته شد، در ادامه و توسعه برنامه کارمان بسیار سخت تر می شود.

در بزرگتر شدن برنامه با حجم عظیمی از توابع روبرو هستیم که تغییر هر کدام ممکن است نیاز به تغییر ده تای دیگر هم داشته باشد و هر تابع دیگری هم که عوض شود یک جایی از برنامه را با مشکل مواجه می کند. حالا باید آن قسمت را هم درست کنیم.

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

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

یک سری عملکرد و رفتار هم برای هر شی می شود تعریف کرد. اگر در حالت procedural می خواستیم قیمت یک محصول را دریافت کنیم و نمایش دهیم یک تابعی تعریف میکریدم مثلا به نام get_product_price. حالا در حالت شی گرا درون خود شی می شود همچین تابعی تعریف کرد. اینجا دیگر اسم تابع روی آن نمی گذاریم اینجا به این متد(method) گفته می شود.

 

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

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

در مبحث شی گرایی همیشه یک واژه در کنار شی به کار برده می شود

کلاس (Class)

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

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

تمام محصولاتی که در این فروشگاه وجود دارند همه یک شی از کلاس محصول هستند.

ایجاد شی در php

برای ساخت شی در php اول باید کلاس را ایجاد کرد.

یک کلاس می خواهم برای ایجاد محصولات. اسم کلاس را می گذارم Product:

 

<?php
Class Product{
}

اول باید کلاس را ایجاد کرد بعد به این شکل یک شی ساخت

$product1= new Product();

حالا شی که ساخته ام درون یک متغیر به نام product1 ذخیره شده است من اینجا درون این کلاس هیچ چیزی نداده ام  طبیعی است درون شی ساخته شده ام هیچ ویژگی و متدی نباشد.

تعریف property در کلاس

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

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

<?php

Class Product{

Public $product_name = "car";
Public $product_price = "2000 tomans";
Public $product_description = "best car";
{

واژه public اینجا نشان می دهد که property که ساخته ایم در تمام برنامه در دسترس خواهد بود. سطح دسترسی به پراپرتی ها با سه واژه public، private و protected مشخص می شود. به private و protected بعدا می پردازیم.

تا اینجا کلاس را ساخته ایم درون کلاس پراپرتی تعریف کردیم. حالا من می خواهم که مقدار این پرارپ ها را نمایش دهم.

اولین کار این است که یک شی از این کلاس بسازم.

$product1= new Product;

این شکلی یک آبجکت(شی) از کلاس Product ایجاد شد. همیشه وقتی شی را می سازیم آن را داخل یک متغیر ذخیره می کنیم تا هر جه درون شی هست با این متغیر قابل دسترسی باشد.

الان شی ایجاد شده من داخل متغیر product$1 ذخیره شده است. اگر بخواهم مقدار پراپرتی های ساخته شده درون شی را ببینم باید این شکلی کد بنویسم:

echo $product1 -> product_name;

دستور echo کار چاپ را انجام می دهد.

اول اسم متغیری که شی درون آن است را می نویسیم به دنبال آن <- و بعد هم پرارپرتی مورد نظر را بدون علامت $ می نویسیم.

تعریف متد برای کلاس

همانطور که پرارپرتی ها متغیرهای معمولی درون کلاس بودند، متدها هم همان توابع معمولی درون کلاس هستند.

باز هم برای تعریف متدها باید دامنه دسترسی را با واژه های public private ،protected مشخص کنیم.

فعلا با همین public تابع را تعریف می کنیم.

من یک متد تعریف می کنم به نام setPrice که به پرارپتی product_price مقدار می دهد.

<?php
Class Product{

Public $product_name = "car";
Public $product_price = "2000 tomans";
Public $product_description = "best car";

public function Public function setPrice($price){
    $this->product_price = $price;


}
}

برای استفاده هم بازهم یک شی میسازیم و بعد متد را صدا می زنیم همان طور که در مثال قبلی متغیر را نمایش دادیم:

$product1= new Product;
$product1->setPrice("1000 tomans");

الان اگر پراپرتی product_price را چاپ کنیم می بینیم که مقدار تغییر کرده است.

 

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

$this->product_price

هر جا داخل خود کلاس بخواهیم به پراپرتی های شی دسترسی پیدا کنیم باید از <-this$ و به دنبال آن نام پراپرتی بدون علامت $ استفاده کنیم. این نشان می دهد که منظورمان متغیر product_price در همین آبجکتی است که ایجاد شده.

در این چند مثال دیدیم که هر بار یک آبجکت ساخته می شد. در یک متغیر ذخیره و سپس اگر میخواستیم می توانستیم متدی را از شی صدا بزنیم.

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

برای این کار از متد جادویی construct__ استفاده می کنیم. به این  تابع سازنده یا constructor هم گفته می شود.

(به متدهای پیش فرض موجود در php که با دوتا آندرلاین __ شروع می شوند magic method گفته می شود.)

من اینجا میخواهم هر بار که شی ساخته شد اسم محصول(product_name)بدون اینکه از متدی استفاده کنم چاپ شود.

<?php
Class Product{

Public $product_name = "car";
Public $product_price = "2000 tomans";
Public $product_description = "best car";

public function __construct()
{
    echo $this ->product_name;
}

Public function setPrice($price){
    $this->product_price = $price;

}
}
$product1= new Product;

حالا اکر برنامه را اجرا کنیم می بینیم اسم محصول(product_name) نمایش داده می شود بدون اینکه متغیری را بعد از ساختن شی صدا زده باشیم چون این در تابع constructor شی انجام شده است.

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