Advertisement
  1. Code
  2. PHP

تعلم OOP في PHP في اسرع وقت ممكن!

Scroll to top
Read Time: 10 min

Arabic (العربية/عربي) translation by Maryam Abbas (you can also view the original English article)

PHP هي أكثر بكثيرمن لغة البرمجة النصية. إنها لغة كاملة قادرة على بناء تطبيقات معقدة للغاية. من خلال الاستفادة من القوة الكاملة للبرمجة الموجهة بالكائن، يمكنك تقليل الوقت الذي تقضيه في الترميز واستخدامه لإنشاء مواقع ويب أفضل. هذا البرنامج التعليمي سوف يظهر لك كيفية القيام بذلك.




ما هو OOP؟

OOP ترمزللبرمجة الموجهة بالكائن. OOP هو نموذج برمجي حيث تقوم بإنشاء "كائنات" للعمل معها. يمكن بعد ذلك تخصيص هذه الكائنات وفقًا لاحتياجاتك الخاصة، لتخدم أنواع مختلفة من التطبيقات مع الحفاظ على نفس قاعدة الكود. مفيدة للغاية حقا.

ما هو الكائن؟

الكائن هو مجرد نسخة أو نموذج من "الفئة". يمكن تعريف الفئة بأنها "الصندوق الأسود" والذي منه نقوم بإنشاء كائناتنا والوصول إلى سماتها (المتغيرات) والأساليب (الوظائف). التشابه الأكثر شيوعًا عند شرح الفئات و OOP هو كيفية قيادة السيارة: بشكل أساسي، لديك 2 من الدواسات أو 3 دواسات، عصا تروس وعجلة قيادة. لا تحتاج (وأغلب الظن لا تريد) أن تعرف كيف تعمل السيارة عندما تضغط على الدواسات. أنت فقط تريد لسيارتك أن تسير ذهابا وإيابا، إلى اليسار واليمين. و OOP هو بالضبط كذلك. لست بحاجة إلى معرفة كيفية عمل أساليب الفئات (إذا لم تقم بتطبيقه بنفسك)، فقط ما تفعله. يعد OOP مفيدًا أيضًا إذا كان لديك عدد كبير من الكائنات من نفس النوع في النظام: كل ما عليك فعله هو إنشاء الكائنات ثم التعامل معها جميعًا بالطريقة نفسها، بدون إعادة كتابة أي شفرة. وعلاوة على ذلك، فإن الكائن قادر على الحفاظ على حالته (قيم متغيرة ومثل هذه) طوال فترة تنفيذ البرنامج.

إن آلية تشغيل "السيارة" مخفية عنا، ومع ذلك يمكننا استخدام قدراتها الكاملة.

OOP في PHP

PHP 5 (على الرغم من أن معظم الأفكار الواردة في هذه المقالة تنطبق أيضًا على PHP 4)  يقدم دعمًا كبيرًا للبرامج الموجهة للكائنات من خلال توفير سهولة إنشاء الفئة. يوفر PHP كل نموذج آخر بلغات "OOP " الحقيقية الأخرى (Python و JAVA، على سبيل المثال)، مثل الوراثة وتعدد الأشكال والتغليف.

الوراثة

الفكرة الأساسية وراء الوراثة هي أن الكائنات المتشابهة تتشارك في الخصائص المشتركة. لذلك من خلال إنشاء فئة "عامة"، يمكن أن يكون لدينا مخطط لإنشاء فئاتنا اللاحقة. تخيل، إذا شئت ، خصائص السيارة: اللون، عدد العجلات، القوة بالحصان ، عدد المقاعد، إلخ. بوجود هذا القالب يمكننا أن نزيد تخصص سياراتنا من خلال توسيع هذه الفئة: إنشاء سيارة سباق تحتوي على خاصية "نيترو"، أو شاحنة لها خاصية "مقطورة". خلاصة القول هي: إنشاء فئة أكثر عمومية تحتوي على معظم السمات المشتركة وسيكون لديك عمل أقل بكثير من تحديد كائنات أخرى مختلفة قليلاً. بدلاً من إعادة كتابة الشيفرة بأكملها، عليك فقط توسيع خصائصها، مما يوفر الكثير من الوقت في العملية.

مخطط الوراثة لفئات السيارات لدينا.

التغليف

كما أوضحنا سابقاً، فإن إحدى المزايا الرئيسية لاستخدام الكائنات هي أننا لا نحتاج إلى الكشف عن جميع أعضائها (سمات أو وظائف)؛ فقط الواجهات اللازمة للعمل بها. يجب إخفاء التفاصيل غير المفيدة لاستخدام هذه الكائنات من بقية الكائنات. هذا هو ما يشار إليه على أنه تغليف.

مستويات الرؤية

  • عام: يعني أن أحد أعضاء الفئة مرئي ويمكن استخدامه / قابل للتعديل من قبل الجميع
  • خاص: يعني أن عضو الفئة قابل للاستخدام / التعديل فقط من قِبل الفئة نفسها.
  • محمية: تعني أن العضو في الفئة يمكن استخدامه / تعديله فقط بواسطة الفئة نفسه وفئات فرعية في نهاية المطاف

ملاحظة: افتراضيًا، في PHP، يكون عضو الفئة عامًا ما لم يتم الإعلان عن أنه خاص أو محمي. تحقق من مثال هنا.

تعدد الأشكال

تعدد الأشكال هو خاصية OOP التي تسمح للمبرمج بتخصيص معنى أو استخدام مختلف لشيء ما في سياقات مختلفة - على وجه التحديد، للسماح لأحد أعضاء الفئة  بأداء مهام مختلفة حسب السياق الذي تم استخدامه فيه. تخيل أن لديك فئة شخص وفئتين فرعيتين للشخص: يابانية وأمريكية. يقوم كلاهما بتنفيذ وظيفة تسمى تحدث ()، ولكن بلغات وسياقات اجتماعية مختلفة. وعلى الرغم من أن كلاهما أساسًا من الأشخاص (حيث أنهما مشتقين من فئة الشخص  ذات مستوى عالي )، إلا أن تطبيقهما للوظيفة () مختلف تمامًا. إذاً فأنت في الأساس لديك كائنان من الفئة شخص التي تعمل فيه وظيفة تحدث () بشكل مختلف.

لنعمل بأيدينا

حسنا، الآن للعمل الحقيقي. سنقوم بإنشاء فئة بسيطة للتعامل مع معالجة الصور واستخراج المعلومات. طوال مدة هذا البرنامج التعليمي سوف أفترض أن لديك فهم أساسي لـ PHP (المتغيرات، إنشاء الوظائف، العمل مع بيانات تدفق التحكم والحلقات). قراءة دليل GD PHP سيزيل أي شكوك قد تكون لديك حول وظائف معالجة الصور.

الخطوة 1: إنشاء فئتنا

نبدأ بتحديد فئتنا:

1
<?php
2
class Image {
3
}
4
?>

هذا يخبر PHP فقط أننا سنبدأ في تحديد فئة جديدة ، تسمى "صورة". الآن سوف نحدد منشئ الفئة. المنشئ هو ببساطة الدالة التي تستدعى عند إنشاء كائن جديد. في PHP 5 يمكن تحقيق ذلك من خلال طريقتين مختلفتين: إنشاء وظيفة عامة بنفس اسم الفئة (PHP 4 وهكذا) أو عن طريق إنشاء دالة تسمى "__construct ()" (PHP 5 فقط):

الخطوة 2: إنشاء مُنشئ الفئة

القطعتين التاليتين من التعليمات البرمجية تفعل تماماً نفس الشيء:

1
<?php
2
class Image {
3
  public function Image() {
4
		echo "We just created and object!";
5
	}
6
}
7
$image = new Image(); // prints "We just created and object!"

8
?>
1
<?php
2
class Image {
3
	function __construct() {
4
		echo "We just created and object!";
5
	}
6
}
7
$image = new Image(); // prints "We just created and object!"

8
?>

ملاحظة: يكون مُنشئ الفئة دائمًا عامًا.

يجب استخدام منشئات الفئة للتأكد من أن الكائن الذي تم إنشاؤه يحتوي على الحد الأدنى من البيانات للعمل بها؛ في حالتنا، الصورة المطلوبة.

على هذا النحو، فإن أول شيء يتعين علينا القيام به هو قراءة الصورة، مهما كان نوعها. تدعم مكتبة GD حاليًا عددًا من أنواع الصور، مثل jpg، و png، و gif، و bmp، وغيرها؛ علينا فقط قراءة الصورة وتحديد نوعها.

1
<?php
2
class Image {
3
	function __construct($filename) {
4
		
5
		// read the image file to a binary buffer

6
		$fp = fopen($filename, 'rb') or die("Image '$filename' not found!");
7
		$buf = '';
8
		while(!feof($fp))
9
			$buf .= fgets($fp, 4096);
10
		
11
		// create image

12
		imagecreatefromstring($buf);
13
	}
14
}
15
$image = new Image("image.png"); // If everything went well we have now read the image

16
?>

لذلك ماذا فعلنا؟ لفتح الصورة بأكبر قدر ممكن من الجهد، سوف نستخدم دالة إنشاء صورة من السلسلة GD's (التي تأخذ سلسلة ثنائية من البيانات كدخل)، بدلاً من إنشاء صورة من jpeg، أو إنشاء صورة من png أو إنشاء صورة من gif، على سبيل المثال.

لذا نحاول فتح ملف صورة وتعيين مؤشر ملفه إلى $ fp، وفي حالة الفشل، إنهاء تنفيذ البرنامج.

1
$fp = fopen($filename, 'rb') or die("Image '$filename' not found!");

بعد ذلك نقوم بإنشاء سلسلة فارغة للاحتفاظ ببياناتنا ...

1
$buf = '';

... وقراءة الملف بأكمله، وسلسلة البيانات التي تقرأ مع محتويات سلسلة المنشأ التي تم إنشاؤها حديثا.

1
while(!feof($fp))
2
	$buf .= fgets($fp, 4096);

الآن علينا فقط إنشاء صورتنا باستخدام البيانات التي قرأناها للتو ...

1
imagecreatefromstring($buf);

... وإنشاء كائن لاستخدام جميع هذه الوظائف.

1
$image = new Image("image.png");

ملاحظة: يجب قراءة ملفات jpg، و png، و gif ومعظم ملفات الصور في الوضع الثنائي، ومن ثم يتم تمرير "rb" كوسيطة ثانية لوظيفة fopen.. "r" تعني القراءة فقط و "b" تعني ثنائي.

الخطوة 3: تحديد سمات الفئات وطرقها

في شكلها الحالي فئتنا ليس مفيدة جدًا. لذلك سنقوم بإضافة بعض السمات والأساليب لجعلها أكثر فائدة. لذا سنبدأ بـ 1: تحديد بعض المتغيرات الداخلية (لاحظ بيان الرؤية "الخاص" قبل كل متغير)

1
<?php
2
class Image {
3
	
4
	// class atributes (variables)

5
	private $image;
6
	private $width;
7
	private $height;
8
	private $mimetype;
9
	
10
	function __construct($filename) {
11
		
12
		// read the image file to a binary buffer

13
		$fp = fopen($filename, 'rb') or die("Image '$filename' not found!");
14
		$buf = '';
15
		while(!feof($fp))
16
			$buf .= fgets($fp, 4096);
17
		
18
		// create image and assign it to our variable

19
		$this->image = imagecreatefromstring($buf);
20
		
21
		// extract image information

22
		$info = getimagesize($filename);
23
		$this->width = $info[0];
24
		$this->height = $info[1];
25
		$this->mimetype = $info['mime'];
26
	}
27
}
28
$image = new Image("image.png"); // If everything went well we have now read the image

29
?>

و 2: طريقة لعرض الصورة.

1
<?php
2
class Image {
3
4
	.
5
	.
6
	.
7
	
8
	public function display() {
9
		header("Content-type: {$this->mimetype}");
10
		switch($this->mimetype) {
11
			case 'image/jpeg': imagejpeg($this->image); break;
12
			case 'image/png': imagepng($this->image); break;
13
			case 'image/gif': imagegif($this->image); break;
14
		}
15
		//exit;

16
	}
17
}
18
$image = new Image($_GET['image']); // If everything went well we have now read the image

19
?>

في هذه الخطوة قمنا للتو بإنشاء بعض سمات الفئة (الصورة، العرض، الارتفاع و وكتابة الوسائط) للاحتفاظ ببيانات الكائن. بعد ذلك أجرينا بعض التعديلات لتعيين الصورة التي تم إنشاؤها لسمة الفئة الصورة$ الخاصة بنا   ...

1
$this->image = imagecreatefromstring($buf)

... واستخرجت معلومات الصورة إلى متغيرات الفئة  المتبقية (اقرأ الوثائق حول getimagesize لفهم كيفية قراءة معلومات الصورة بشكل كامل):

1
// extract image information

2
$info = getimagesize($filename);
3
$this->width = $info[0];
4
$this->height = $info[1];
5
$this->mimetype = $info['mime'];

بعد ذلك أنشأنا وظيفة تقوم بإخراج الصورة إلى المستعرض من خلال تحديد الرؤوس المناسبة (اقرأ المزيد عن رؤوس http هنا) واستخدام الوظيفة المناسبة (مع عبارة التبديل) لإخراج الصورة بناء على نوع الصورة الأصلي (لهذا البرنامج التعليمي سنقوم فقط بدعم jpg، و png و gif ولكن، وكما قلت من قبل، يدعم GD العديد من التنسيقات الأخرى. اقرأ وثائق php لمزيد من المعلومات).

إذن ما هي هذه "$ this" الموجودة هناك؟ يشير "$ this" هذا، في PHP، إلى الفئة نفسها، ويستخدم للإشارة إلى سمات أو وظائف الفئة. على هذا النحو، تشير $ this-> هذه إلى سمة الفئة المسماة "$ picture" و $ this-> image = ... يغير قيمة سمة الفئة . إذا كنت تكتب صورة $ = ... فستكون مجرد إنشاء متغير محلي جديد يسمى "$ picture"، متاح حصريًا خلال فترة الوظيفة. هذا هو أحد الأشياء الرئيسية التي يجب الانتباه إليها عند إنشاء فئات في PHP.

لدينا طريقة العرض ليست مفيدة جدا (بعد!).

الخطوة 4: تعريف "الصورة المصغرة" للفئة الفرعية

الآن فئتنا ليست مفيدة جدا. بالتأكيد، يمكننا قراءة صورتنا وعرضها ولكن هذا كل شيء. سنقوم الآن بإنشاء فئة فرعية لإنشاء صورنا المصغرة. (نحن حقا لا نحتاج إلى إنشاء فئة فرعية، ولكننا سنقوم بذلك من أجل البرنامج التعليمي، لإظهار الوراثة وتعدد الأشكال). لذا، لكي تعمل الوراثة بشكل صحيح، نحتاج إلى تغيير تعريف الفئة  الفائقة (الصورة) بشكل طفيف. نحتاج فقط إلى تغيير مستوى رؤية متغيرات الفئة لدينا من "خاص" إلى "محمي". والآن سنقوم بإنشاء منشئ فئة فرعية لدينا.

1
<?php
2
class Image {
3
	
4
	// class atributes (variables)

5
	protected $image;
6
	protected $width;
7
	protected $height;
8
	protected $mimetype;
9
	
10
	.
11
	.
12
	.
13
}
14
15
class Thumbnail extends Image {
16
	
17
	function __construct($image, $width, $height) {
18
		
19
		// call the super-class contructor

20
		parent::__construct($image);
21
		
22
		// modify the image to create a thumbnail

23
		$thumb = imagecreatetruecolor($width, $height);
24
		imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
25
		$this->image = $thumb;
26
	}
27
}
28
?>

إذاً ما الذي سنفعله هنا بالضبط؟ لقد أنشأنا فئة جديدة، مستمدة من الأصل، مما يعني أنه يمكننا الوصول إلى جميع سماتها وطرقها العامة والمحمية. نحن نطلق على منشئ الطبقة الفائقة، المسؤول عن قراءة الصورة واستخلاص معلوماتها. لا يقوم مُنشئ الفئة الفرعية باستدعاء مُنشئ الطبقة الفائقة لذلك نحتاج إلى الاتصال به بشكل صريح.

الآن نقوم بإنشاء صورة جديدة للصورة المصغرة لدينا، مع اهمال العرض والطول:

1
$thumb = imagecreatetruecolor($width, $height);

أعد تشكيل (تغيير حجم) الصورة الأصلية في الصورة الجديدة، لإنشاء الصورة المصغرة:

1
imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);

وأخيرًا تعدل الصورة الأصلية بحيث تحتوي على الصورة المصغرة بدلاً من الصورة بالحجم الكامل:

1
$this->image = $thumb;

وتخيل ماذا؟ لا نحتاج حقًا إلى كتابة وظيفة جديدة لعرض الصورة المصغرة لأن المبدأ نفسه ينطبق سواء كنت تعرض صورة بالحجم الكامل أو صورة مصغرة. بعد كل شيء، لا تزال صورة! لذلك نحتاج فقط إلى استدعاء وظيفة العرض ()، المحددة في الفئة الفائقة، وقد انتهينا!

لدينا الفئة المكتملة و الفئة الفرعية المعنية.

ويختتم هذا البرنامج التعليمي لدينا. كتمرين، أقترح عليك تنفيذ وظيفة لحفظ الصور المصغرة التي تم إنشاؤها على القرص بدلاً من إخراجها في الهواء (أين يجب تنفيذ هذه الوظيفة؟ في الفئة الفائقة أو الفرعية؟). نتمنى لك التوفيق والتحقق من الملف المضغوط المقدم للاستخدام على سبيل المثال و الفئات الكاملة التي تم تطويرها هنا (تحتاج إلى وجود خادم يعمل بنظام PHP لاختبارها).

  • اشترك في NETTUTS RSS Feed لمزيد من المقتنيات اليومية لتطوير الويب والمقالات.


Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.