كما نعلم ان البرمجة الكائنية لها مميزات كثيرة، خصوصا بعد التغيرات التي حصلت مع الاصدار الخامس من PHP.
الدرس سيتكلم عن اساسيات و طرق التطوير. برامج ذات هذه الخصائص.
في البدايه لماذا لا نبدء بكتابه قواعد البيانات. لنسمية tutorial ونضع الجداول التالي فيه
كود:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
`username` varchar(50) NOT NULL,
`password` varchar(50) NOT NULL,
`email` varchar(50) NOT NULL,
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
CREATE TABLE IF NOT EXISTS `articles` (
`id` int( 11 ) NOT NULL AUTO_INCREMENT ,
`name` varchar( 50 ) NOT NULL ,
`user_id` int( 11 ) NOT NULL ,
`body` varchar( 50 ) NOT NULL ,
`created` datetime NOT NULL ,
`updated` datetime NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM;
تصميم الجدو جدا سهل. ولكن الفرق هو انني استخدمت احد المعاير القياسية المتبعه من قبل مبرمجي لغة الRuby وهي الان من احدى المعاير المشهورة التي يتبعها اكثر المبرمجين المحترفين. الشروط هي:
1- ان تسمي الجداول باسماء واضحه والاسم يجب ان يكون جمع، فمثلا لا نسمي الجدول car لانه فردي فنسميه cars لاننا كما نعلم ان الجداول سيحتوى على اكثر من سجل.
2- ان تضع المفتاح باسم id، لا تسميه اسماء اخرى، لا جدوى في ذالك!
3- ان تضع في كل جدول name بدون استسناء، حاول ان تبحث لي جدول فيه سجل بدون اسم؟ حتى المواضيع يمكن ان يكون له name بدلا من title، هذا الشرط يأخذه المبرمجون كالمُسلمه، "اما في جداول التي هي مجموعة مفاتيح، فلا تستخدم name"
4- ان تضع created و updated كاسماء للحقول التي ستتعامل مع الزمن، في بعض الاحيان ستلاحض انك تريد حقول اخرى غير created و updated .. في هذه الحاله اضمن انها اسم ماضي، فلا تكتب publish اكتبها published لان عند زيارتها ستكون دائما في الماضي، اما الحقول التي ستكون في المستقبل، لم يتوافق الجميع على المعاير، ولكن الاكثريه ومازالو يستخدمونها في الصيغه الماضيه.
5- المفاتيح الاجنبيه Forign Keys يستعمل اسم الجدول بالصيغه المفردة وتضاف id_ في المؤخرة، في مثالي ستجد user_id
6- الجداول تي تتكون من مفاتيح فقط "هذه الجداو تستخدم في ربط عدة سجلات من جدول بعدة سجلات من جداول اخرى"، اسم الجدول يكون كالتاي .. اسم الجدول الاول زائد اسم الجدول الثاني مفصول ب "_" ويكون اسم الجدول الاول هو الجدول الاول ابجديا.. مثال "articles_tags" او "apartments_owners"
================
الان بعد وضع الجدول. لماذا لا نفعل ملف كونفج لكي نستخدمه في كل مكان!
كود PHP:
<?php
// config.php
$dbUsername = 'root';
$dbPasswor = '';
$dbHost = 'localhost';
$dbDatabase = 'tutorial';
$db = mysql_connect($dbHost,$dbUsername,$dbPasswor);
mysql_select_db($dbDatabase,$db);
?>
وبعدها نكتب ملف الmysql.php سيحتوي هذا الملف على كلاس الmysql الرئيسي.
كود PHP:
<?php
//mysql.php
class mysql{
var $tableName;
function find($rowId,$type = MYSQL_ASSOC){
$result = mysql_query('select * from '.$this->tableName.' where id = '.$rowId.' LIMIT 1') or die(mysql_error());
$row = mysql_fetch_array($result,$type);
return $row;
}
}
?>
الان لقد وضعت داله اسمها find في الكلاس، وذالك الكلاس يتطلب متغير tableName$ فيه. وهو بسيط. دعونا الان ينستفيد من هذا الكلاس بعمل توسعه له من ملف اخر، لنسمية user .. فالان في ملف الuser.php نضع
كود PHP:
<?php
//user.php
require_once 'mysql.php';
class user extends mysql{
function user(){
$this->tableName = 'users';
}
}
?>
السحر كله في الكلمة extends وهي كلما معناها تقريبا توسعه، ... السحر يكمن في انني كتبت قليل ولكن لانني عملت توسعه للكلاس mysql فجعلت الكلاس user يمتلك خصائص الكلاس الاب mysql
فالان في ملف الtest.php ممكن ان تكتب
كود PHP:
<?php
//test.php
require_once 'config.php';
require_once 'user.php';
$user = new user();
print_r($user->find(1));
?>
الان، ادخلت الملفين config.php و الملف user.php لانني ساستخدم الكلاس user. البرنامج الان يطبع السجل الاول من الجدول user .. لماذا نفعل نفس الشيء للجدول articles فنكتب.
كود PHP:
<?php
//articles.php
require_once 'mysql.php';
class article extends mysql{
function user(){
$this->tableName = 'articles';
}
}
?>
فالان كتبت القليل ولكن لدي نفس الخصائص في الmysql وuser وarticles .. لماذا لا نعطي خاصيه جديده لجميع الكلاسات بدون ان اكتب في كل الملفات ... فالحل هو في وضع الخاصيه الجديده في الكلاس mysql ونسنرى ان جميع الكلاسات لديها تلك الخاصيه.. فمثلا. نريد ان نأخذ جميع المعلومات الاخرى من الحقول الاخرى ولكن نريد ان نبحث عن طريق الاسم وليس الid
الحل.
كود PHP:
<?php
//mysql.php
class mysql{
var $tableName;
function find($rowId,$type = MYSQL_ASSOC){
$result = mysql_query('select * from '.$this->tableName.' where id = '.$rowId.' LIMIT 1') or die(mysql_error());
$row = mysql_fetch_array($result,$type);
return $row;
}
function findByName($name,$type = MYSQL_ASSOC){
$result = mysql_query('select * from '.$this->tableName.' where name = "'.$name.'" LIMIT 1') or die(mysql_error());
$row = mysql_fetch_array($result,$type);
return $row;
}
}
?>
الان يمكننا فعل
كود PHP:
<?php
//test.php
require_once 'config.php';
require_once 'user.php';
$user = new user();
print_r($user->findByName("khalid"));
?>
فالان .. الكلاس mysql و user و article لديهم نفس الخصائص. ولكن .. لماذا لا نطور الكلاس user بنفسه؟ لاننا نريد مثلا ان نسجل دخول ونعلم ان تسجيل الدخول فقط من خصائص الكلاس user .. فنعمل التالي
كود PHP:
<?php
//user.php
require_once 'mysql.php';
class user extends mysql{
function user(){
$this->tableName = 'users';
}
function login($userName,$passWord){
$row = $this->findByName($userName);
if($row['password'] == $passWord){
return true;
}
else{
return false;
}
}
}
?>
فالان لاننا فعلنا ذالك فيمكنني ان اكتب
كود PHP:
<?php
//test.php
require_once 'config.php';
require_once 'user.php';
$user = new user();
if($user->login("khalid","abc123")){
echo 'You are successfully loged in';
}
else{
echo 'Your password was not correct, please try again';
}
?>
الان عرفتم ان البرمجه الكائنيه اصلا سهله. ولا تريد ان تكون عبقرايا لكي تتعلمها، وايضا عرفتم ان البرمجه الكائنية هي برمجة تسهل عمليه التحديث وتصحيح الاخطاء لان الشفره لن تتكر كتابتها في امكان مختلفه، اي اذا كانت هناك عطل فستجد ان العطل موجود في ملف واحد، وتصحيح تلك الاخطاء سيصحح جميع الاخطاء في الاماكن الخرى. فهذه هي ميزه البرمجه الكائنية.
الان اذا سئلت اي مبرمج محترف سيحاول ان يقول لك جملتين الاوله KISS وهي اختصار للجمله Keep It Simple Stupid اي حاول ان تعمل برنامج سهل الفهم والقرائه، فلذالك يستعملوا البرمجه الكائنية لانها سهل الفهم من قبل المبرمجين الاخرون
الثانيه هي الجمله Do Not Repeat Yourself ومعناها ان لا تكرر ملفات الشفرات، اي ضع مكان واحد للخصائص، وجعل جميع الملفات يأخذ خصائصها من ملف واحد، اي اذا وجدت خظا ما. فحل الملف الرئيسي يغنيك عن فتح جميع الملفات الاخرى وتحديثهم
=========
ملاحظه: الدرس لا يتكلم عن الطرق الحقيقه في عمل برنامج محكم من الثغرات ولا يتطرق الى طرق تحيسن اداء البرنامج. الدرس فقط للتوضيح.
الدرس القادم: استخدام الJquery انا اعرف ان الدرس ليس له دخل في PHP حاليها .. ولكن هو مقدمه جميله لكي ندخل في الدرس الاهم وهو كيفيه استخدام الZendFramework ففي تعلم هذا سيساعدك على كتابه برامج بسرعات لا تتخيلها.