برنامه نویسی شیء گرا در PHP قسمت دوم

فروردین ۲۸, ۱۳۹۱ توسط : سعید

در آموزش قبل با مقدمات شیء گرایی در PHP آشنا شدید.در این قسمت به نحوه دسترسی به متدها و متغیرها در کلاس میپردازیم.هم چنین مقدماتی از ارث بری رو هم برای درک بیشتر موضوع گفتم که امید وارم مفید باشه.

فرض کنید در یک پروژه شما قراره یک کلاس برای دسترسی به دیتابیس بنویسید تا بقیه اعضای تیم بتونن با استفاده ازکلاس شما به دیتابیس دسترسی داشته باشن.توی این کلاس یه سری توابع و متغیرها هستند که نباید توسط بقیه اعضای تیم دستکاری بشن.مثلا یک تابع برای SELECT مثل زیر مینویسید :

class Database
{
	….
	public function select($query)
	{
		// کدهای مربوط به تابع
	}
}

مقادیر از دیتابیس مینویسید.خب همینطور که میدونید بقیه اعضای تیم باید از این متد استفاده کنن.اما یک تابع مینویسید تا قبل از اجرای دستور select چک کنه که آیا جدول مورد نظر در دیتابیس وجود داره یا خیر؟

function table_exists($table)
{
	///
}

تابع table_exists تابعی هست که نباید توسط بقیه استفاده بشه و فقط باید توسط متدهای اصلی کلاس استفاده بشن.یعنی در متد select قبل از اجرای کوئری مورد نظر چک کنه که آیا جدول مورد نظردر دیتابیس وجود داره یا خیر اگر نبود پیغام خطا بده :

function select()
{
	if($this->table_exists($table))
	{

	}else
	{
		return false;
	}
}

منظور من از مثال بالا این بود که در برنامه نویسی شیء گرا باید بعضی از متدها و متغیرهای کلاس رو از دید بقیه کسانی که از کلاس ما(که شامل بقیه کلاسها هم میشه) استفاده میکنن مخفی نگه داریم تا نتونن توی مقادیر و نحوه کار کرد کلاس خواسته یا ناخواسته خلل ایجاد کنن.

برای همین در شیء گرایی مفهومی ارایه شد به نام encapsulation که جدا از معنی لغوی این کلمه به نحوه دسترسی اعضای کلاس شامل متد ها و متغیر ها ، در خارج کلاس رو تعریف میکنه.

در برنامه نویسی شیء گرا سه نوع نحوه دسترسی داریم :

Public

Private

Protected

در ادامه به توضیح هر کدوم از اینها میپردازیم.

Public

کلاسهایی که ما مینویسیم در اکثر موارد باید شامل متدها و متغیرهایی باشن تا در خارج از کلاس بتونیم بهشون دسترسی داشته باشیم.بهتره با یک مثال بریم جلو .

کلاس دیتابیس رو در نظر بگیرید.متد select متدی هست که باید در خارج از کلاس بهش دسترسی داشته باشیم. منظور از خارج از کلاس بقیه کاربران یا کلاسهایی هستند که میخوان از کلاس ما استفاده کنن. برای دسترسی به یک متغیر یا تابع درخارج از کلاس باید از کلمه کلیدی public استفاده کنیم :

class Database
{
	public function select()
	{
		///codes
	}
}

هنگامی که از کلمه کلیدی public قبل از function استفاده میکنیم به محیط خارج از کلاس اجازه میدیم که به متد ما دسترسی داشته باشن.

include 'database.php';
$db = new Database();
$db->select();

با اجرای کد بالا میبینید که کلاس Database اجازه دسترسی به متد select رو به شما میده.

چون متد select به صورت public یا عمومی تعریف شده.

Private

در مثال اول دیدیم که کاربران یا کلاسهای دیگه نباید به بعضی از متدها و متغیرهای کلاس ما دسترسی داشته باشن.به همین منظور باید توابع و متغیرهامون رو به صورت private یا خصوصی تعریف کنیم تا فقط در داخل کلاس بشه ازشون استفاده کرد.

class Database
{
	public function select()
	{
		///codes
	}
private function table_exists($table)
{
		///
}

}

در کد بالا تابع table_exists در خارج از کلاس در دسترس نیست و با اجرای کد زیر پیغام خطا دریافت خواهید کرد:

include 'database.php';
$db = new Database();
$db->table_exists('users');

Protected

در مبحث ارث بری از این نوع نحوه دستری زیاد استفاده میشه.پس بیاید ابتدا مروری بر ارث بری داشته باشیم تا کاربرد protected رو بیشتر متوجه بشیم.

ارث بری

در یک پروژه تیمی قسمتی از پروژه که باید توسط شما آماده بشه گاهی اوقات ممکنه فقط شامل سک کلاس باشه یا میتونه از چندین کلاس مختلف تشکیل بشه. در یک سیستم پیشرفته (وحتی متوسط) به شما میگن باید بخش دیتابیس رو بنویسید.(هی نگین گیر داده به دیتابیس به خاطر این میگم دیتابیس که میدونم همه باهاش کار کردین و تصورش براتون راحت تره و کاربردی هم هست 😉 ).ممکنه بخش دیتابیس یک سایت از چند کلاس مختلف تشکیل شده باشه.یک کلاس برای ساخت خودکار کوئری ها ، یکی برای اجرای کوئری ها ، یکی برای مدیریت خطاها و …

در این سیستم یک کلاس برای اجرای کوئری ها مثلا با نام Database مینویسیم.برای استفاده از این کلاس دو راه داریم:

۱- در هر جای پروژه که بخوایم یک کوئری خاص رو اجرا کنیم باید یک شیء از این کلاس بسازیم بعد کوئری مورد نظر رو بهش پاس بدیم تا اجرا بشه.

۲- یک کلاس بنویسیم با نام Users که از کلاس Database ارث بری کنه.سپس به واسطه کلاس Users به متدهای کلاس Database دسترسی پیدا کنیم.

شاید بپرسید که چه فرقی داره؟ در روش دوم هم ما باید هر جا تو پروژه نیاز داشتیم از کلاس Users یک شیء بسازیم. اما نکته ای که هست اینه که ما میتونیم به واسطه کلاس Users یه سری تنظیمات رو فقط یکبار تعریف کنیم. با مثال بیشتر متجه میشید.

روش اول :

کلاس Database

class Database
{
	private  $table;
	private $primary_key;
	public function __construct($table , $pk)
	{
		$this->table   = $table;
		$this->primary_key = $pk;
	}
	…
	public function exec($query)
	{
		…
		// کدهای مربوط
	}
}

در روش اول برای هر بار اجرای یک کوئری باید ابتدا نام جدول سپس کلید اصلی جدول رو تنظیم کنیم :

include 'database.php';
$db = new Database('users' , 'user_id);

روش دوم :

کلاس Database رو مثل قبل مینویسیم با این تفاوت که نوع متغیرهای $table , $primary_key رو از نوع protected میزاریم که بتونیم در کلاس فرزند بهشون مقدار بدیم  :

class Database
{
	protected  $table;
	protected $primary_key;
	public function __construct($table , $pk)
	{
		$this->table   = $table;
		$this->primary_key = $pk;
	}
	…
	public function exec($query)
	{
		…
		// کدهای مربوط
	}
}

در روش دوم باید یک مرحله بیشتر انجام بدیم. در این روش باید برای هر جدول در دیتابیس یک کلاس جدا بسازیم مثلا کلاس Users که باید از کلاس Database ارث بری کنه (با استفاده از کلمه کلیدی extends ):


class Users extends Database{
<pre>	protected  $table = &#039;users&#039;;
	protected $primary_key = &#039;user_id&#039;;</pre>
}

بیاید مزایای روش دوم رو بررسی کنیم.

فرض کنید شما در پروژه ۱۰۰ بار به دیتابیس متصل میشید و جدول users رو دستکاری میکنید. ممکنه در آینده نام جدول یا نام کلید اصلی جدول رو بخواید تغییر بدید. اگر از روش اول استفاده کنید :

include 'database.php';

$db = new Database

('users' , 'user_id);

باید همه جاهایی که کد بالا رو نوشتید پیدا کنید و تغییرش بدید.اما در روش دوم در صورتی هر تغییری در دیتابیس اجام بشه و نام فیلد اصلی و جدول تغییر کنه فقط با یکبار تغییر در کلاس Users میتونید توی کل پروژه این تغییر رو اعمال کنید.میبینیم روش دوم یکی از مزایای شیء گرایی که ” نگهداری و توسعه آسان ” هست رو در اختیار ما میذاره.

بحث ارث بری یکی از شیرین ترین بحثهای برنامه نویسی شیء گراست.تا اینجا رو گفتم که با مفهومش آشنا بشید و کاربردش رو ببینید به امید خدا حتما در یک پست جدا در موردش صحبت میکنیم.

حالا ببینیم کاربرد Protected در برنامه نویسی شیء گرا کجاست.

Protected به کلاسهای فرزند اجازه استفاده از توابع و متغیرها رو میده اما در خارج از کلاس این اجازه داده نمیشه.

یک مثال از دنیای واقعی : توی یک خانواده پدر ، مادر ، پسر ، دختر هستند.ممکنه در این خانواده دختر و پسر از پدرشون به خاطر بعضی مسایل انتقاد کنن.اما همین پسر و دختر به کسی که خارج از اعضای خانواده است اجازه انتقاد از پدرشون رو نمیدن.یعنی فقط پسرو دختر و مادر حق انتقاد از پدر رو دارن.پس توی یک خانواده ” انتقاد از پدر” به صورت protected تعریف شده و اگر کسی خارج از خانواده از پدر انتقاد کنه با کتک (پیغام خطا) مواجه میشه.

این بحث هم به پایان رسید.امید وارم خوب توضیح داده باشم و مفهوم رو رسونده باشم.به هر حال چیزی که توی آموزش PHP مد نظرم هست اینه که مفهوم رو بفهمید و سعی کنید خودتون رو درگیر اصطلاحات مختلف نکنید.برنامه نویسی شیء گرا واقعا لذت بخشه.

موفق باشید

سعید مقدم زاده

بازدید : ۷۱۱۰

فروردین ۲۸, ۱۳۹۱ @ ۸:۳۳ ق.ظ

خیلی عالی نوشتی! اصلاً همین که از کلاس نمونه database استفاده کردی خودش خیلی مفهومیبل (قابل فهم) بود! 😉
خیلی بهتر می شه مفاهیم دیگه هم به مرور و به همین شکل توضیح بدید! چیزی مثل «چند ریختی» یا …

ممنونم ازت

پاسخ دادن
    سعید
    فروردین ۲۸, ۱۳۹۱ @ ۶:۱۹ ب.ظ

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

    پاسخ دادن
wandad
اردیبهشت ۱۵, ۱۳۹۱ @ ۵:۰۴ ب.ظ

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

پاسخ دادن
Hosein
فروردین ۲۵, ۱۳۹۲ @ ۱۰:۲۶ ب.ظ

سلام ببخشید توی روش اول و دوم تقاوت کد ها چیه ؟
قسمتی که دارید شی ایجاد میکنید و ازش استفاده می کنید:
روش اول :
$db = new Database(‘users’ , ‘user_id);
روش دوم :
$db = new Database
(‘users’ , ‘user_id);

پاسخ دادن
Hosein
فروردین ۳۰, ۱۳۹۲ @ ۲:۱۴ ب.ظ

حس میکنم یه جایی از کد جا افتاده !!!!
در روش دوم باید یک مرحله بیشتر انجام بدیم. در این روش باید برای هر جدول در دیتابیس یک کلاس جدا بسازیم مثلا کلاس Users که باید از کلاس Database ارث بری کنه (با استفاده از کلمه کلیدی extends ):
؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟

پاسخ دادن
    سعید
    فروردین ۳۰, ۱۳۹۲ @ ۲:۵۹ ب.ظ

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

    پاسخ دادن
اردیبهشت ۷, ۱۳۹۲ @ ۹:۲۰ ب.ظ

اساتید سایتتون خیلی خوبه میشه یه آموزش کامل در مورد mvc بزارید
مرسی

پاسخ دادن
آذر ۱۶, ۱۳۹۲ @ ۹:۲۱ ق.ظ

سلام
ای کاش فایل پی دی اف آموزشت رو هم در انتها برای دانلود میزاشتی!
ممنون

پاسخ دادن
محمدرضا
اردیبهشت ۱۶, ۱۳۹۴ @ ۱۱:۴۱ ق.ظ

آقا دمت گرم.واقعا آموزش خوبی بود.خیلی مردی

پاسخ دادن

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *


*