شی گرایی(OOP)در پی اچ پی(PHP) – کلاس پایگاه داده

۱۳۹۱/۰۲/۰۴

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

ایجاد یک کلاس برای اتصال و پرسش از پایگاه داده
پی اچ پی خود از اکستنشن ها و کلاس های برای کار با انواع پایگاه داده برخوردار است و خوشبختانه جا برای کسترش کار با پایگاه داده ها وجود دارد. این یک کلاس آموزشی و کوچک است فقط کار با پایگاه داده MySql به کمک اکستنشن mysql را مورد بررسی و اجرا قرار می دهد (شاید چون اکستنشن mysql آشنا تر است).

تعریف اهداف کلاس
اساس کار با پایگاه داده عبارت است از برقراری اتصال، انجام پرسش و قطع اتصال. این کلاس علاوه برای انجام دادن کار های اصلی به عنوان ضروریات می بایست با استفاده از متد هایی کار با پایگاه داده را آسان تر کند. امکاناتی مانند چک کردن وضعیت اتصال، set کردن sql-query جدا از اجرا، انتخاب پایگاه داده مجزا از برقراری اتصال، پوشش بهتر خطا ها، تعامل با توابع اکستنشن mysql را دارا باشد. در این صورت است که یک کلاس کارآممد خواهد بود.
این تعریف به ما کمک می کند تا بدانیم که چه می خواهیم بسازیم. شی ما باید قادر به انجام چه کار هایی باشد و کلاس چگونه پیاده سازی شود. من کلاس رو ایجاد کرده ام و در آخر کد منبع آن را قرار داده ام. اگر شما هم فک می کنید که آنقدر توانایی دارید که خود دست به ساختن بزنید لطفآ این کار رو انجام بدید و بعد کار خود را با کار من مقایسه کنید. من منتظر نظرات و مقایسات شما هستم.

کلاس MysqlDriver :
بر خلاف انتظار شما بجای نام database یا db یا یک نام مشابه از نام MysqlDriver استفاده کرده ام. این یک کلاس دیتابیس نیست اگرچه با دیتابیس کار می کند. در واقع یک کلاس دیتابیس از این کلاس جامع تر و بزرگتر است (مانند یک کتابخانه است). شاید در زمانی که مباحثی چون interface و extends را مرور کردیم بتوانیم یک کتابخانه database ایجاد کنیم. اما فعلا ما دست به ساختن یک کلاس که هدف اصلیش ایجاد ارتباط، پرسش و قطع اتصال به علاوه چند امکان جانبی کوچک دیگر است زده ایم که از اکستنشن mysql استفاده می کند. نام بهتر برای این کلاس MysqlDriver است. اگر ما این کلاس را با اکستنشن mysqli پیاده سازی می کردیم آنگاه این کلاس MysqliDriver نام می گرفت.
به دلیلی سادگی برنامه، مستندسازی طبق استاندارد PHPDoc و خوانایی کد از تشریح خط به خط برنامه صرف نظر می کنم. سوالات رو می تونید در بخش نظرات مطرح کنید.

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

پروپرتی :
پروپتی یک متغییر است که در دسترس متد های کلاس قرار می گیرد. هرگاه مقداری می بایست چنین ویژگی داشته باشد آن را در یک پروپرتی نگهداری کنید.

متد :
سعی کنید متد ها را عمومی تر تعریف کنید. به هر متد فقط یه وظیفه را بسپارید و بقیه وظایف را به متد های دیگر. قبل از استفاده از ورودی ها آنها را چک کنید. استفاده و تعامل با پروپرتی ها را درنظر داشته باشید.

نمونه هایی از استفاده از از این کلاس MysqlDriver

1- درج کردن در پایگاه داده

// insert
$mysql = new MysqlDriver($host, $user, $pass, $dbname);
$mysql->command(“INSERT INTO users (name,email) VALUES (‘$name’, ‘$email’)”);
$mysql->execute();
if($mysql->error()){
        echo ‘connot add user.’;
        exit();
}

2- خواند از پایگاه داده :

// select
$mysql = new MysqlDriver($host, $user, $pass, $dbname);
$mysql->command('SELECT * FROM users');
$mysql->execute();
if($mysql->error()){
        echo ‘connot read user.’;
        exit();
}
while($row = $mysql->fetch()){
        echo $row[‘name’];
        echo $row[‘email’];
}

۳- ویرایش کردن رکورد ها :

// update
$mysql = new MysqlDriver($host, $user, $pass, $dbname);
$mysql->command(“UPDATE users SET name=’$name’”);
$mysql->execute();
if($mysql->error()){
        echo ‘connot edit user.’;
        exit();
}

4- حذف کرن رکورد :

// delete
$mysql = new MysqlDriver($host, $user, $pass, $dbname);
$mysql->command("DELETE FROM users WHERE id=$id");
$mysql->execute();
if($mysql->error()){
        echo 'connot edit user.';
        exit();
}

چهار query پرکاربرد در کار با پایگاه داده به عنوان نمونه قرار داده شد.این کلاس برای بهتر شدن نیاز دارد تا هم رو به پایین ( sql-query ها و نوع داده های خرجی ) و هم رو به بالا (پشتیبانی از سایر اکستشن ها و دیتا بیس ها) گسترش پیدا کند. یک شی زمانی موثر تر است که درون مجموعه ایی از اشیا و به صورت یک عضو در یک سیستم شی گرا قرار بگیرد. زمانی که مباحثی مانند extends و interface مطرح شدند گسترش این کلاس لذبخش تر و ممکن تر خواهد بود.

کد منبع کلاس :


 * @version             1.0 2012-04-20
 * @copyright   phpdevelopers.ir (c) 2012
 * @copyleft    GPLv3
 */
class MysqlDriver
{
        /**
         * database hostname
         * @access      private
         * @var         string
         */
        private $hostname;
        
        /**
         * database username
         * @access      private
         * @var         string
         */
        private $username;
        
        /**
         * database password
         * @access      private
         * @var         string
         */
        private $password;
        
        /**
         * database name
         * @access      private
         * @var         string
         */
        private $database;
        
        /**
         * sql query string
         * @access      private
         * @var         string
         */
        private $command;
        
        /**
         * mysql link
         * @access      private
         * @var         mysql-resource
         */
        private $mysqlLink;
        
        /**
         * mysql resource
         * @access      private
         * @var         mysql-resource
         */
        private $result;
        
        /**
         * error number
         * @access      private
         * @var         int
         */
        private $error;
        
        /**
         * connect state
         * @access      private
         * @var         bool
         */
        private $connected;
        
        /**
         * MysqlDriver Constructor
         * first set properties value
         * @access      public
         * @param       $hostname       string  'the database hostname'
         * @param       $username       string  'the database username'
         * @param       $password       string  'the database password'
         * @param       $database       string  'the database name'
         * @return      void
         */
        public function __construct($hostname, $username, $password, $database=null)
        {
                // set properties
                $this->hostname = $hostname;
                $this->username = $username;
                $this->password = $password;
                $this->database = $database;
                $this->command = '';
                $this->error = -1;
                $this->connected = false;
        }
        
        /**
         * MysqlDriver Destructor
         * free resource at closing connection and unset peroperties
         * @access      public
         * @return      void
         */
        public function __destruct()
        {
                // close connecton
                $this->close();
                
                // unset properties
                unset($this->hostname);
                unset($this->username);
                unset($this->password);
                unset($this->database);
                unset($this->command);
                unset($this->error);
                unset($this->connected);
        }
        
        /**
         * open mysql databse connection
         * if connected then returned
         * @access      public
         * @return void
         */
        public function open()
        {
                // check exists connect to databse
                if($this->connected){
                        return;
                }
                
                // connect to databse
                $this->mysqlLink = @mysql_connect($this->hostname, $this->username, $this->password);
                if(!$this->mysqlLink){
                        $this->setError(11);
                        return;
                }
                
                // select database
                if(isset($this->database){
                        $this->setDatabase($this->database);
                }
                
                // set connected property at true value
                $this->connected = true;
        }
        
        /**
         * close mysql databse connection
         * if not connected then returned
         * @access      public
         * @return      void
         */
        public function close()
        {
                // free mysql result
                if(is_resource($this->result) && $this->connected){
                        mysql_free_result($this->result);
                }
                
                // chech exists connect
                if(!$this->connected){
                        return;
                }
                
                // close connection and new set properties
                @mysql_close($this->mysqlLink);
                $this->connected = false;
                $this->mysqlLink = null;
                $this->result = null;
        }
        
        /**
         * set and select database name
         * @access      public
         * @param       $database       string  'the database name'
         * @return      void
         */
        public function database($database)
        {
                // if not connect then set error
                if(!this->connected){
                        $this->setError(21);
                        return;
                }
                
                // select database
                @mysql_select_db($database, $this->mysqlLink);
                if(mysql_errno($this->mysqlLink)){
                        $this->setError(22);
                        return;
                }
        }
        
        /**
         * execute sql query
         * @access      public
         * @return      void
         */
        public function execute()
        {
                // if not connenct then connect
                if(!$this->connected){
                        $this->open();
                }
                
                // if not command exists then set error and return
                if($this->command == ''){
                        $this->setError(31);
                        return;
                }
                
                // get query and set result
                $this->result = @mysql_query($this->command, $this->mysqlLink);
                if(mysql_errno($this->mysqlLink)){
                        $this->setError(32);
                }
        }
        
        /**
         * fetch result from databse
         * @access      public
         * @param       $fetchMode      int     'set fetch mode'
         * @return      array
         */
        public function fetch($fetchMode=MYSQL_ASSOC)
        {
                // check mysql result
                if(!is_resource($this->result)){
                        $this->setError(41);
                        return;
                }
                
                // check fetch mode
                if(!in_array($fetchMode, array(MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH)){
                        $this->setError(42);
                        return;
                }
                
                // fetch from database
                $read = @mysql_fetch_array($this->result, $fetchMode);
                if(mysql_errno($this->mysqlLink)){
                        $this->setError(43);
                        return;
                }
                
                // return read row
                return $read;
        }
        
        /**
         * set sql query
         * @access      public
         * @param       $command        string  'the sql query'
         * @return      void
         */
        public function command($command)
        {
                $this->command = $command;
        }
        
        /**
         * get sql query
         * @access      public
         * @return      string
         */
        public function getCommand()
        {
                return $this->command;
        }
        
        /**
         * get mysql link
         * @access      public
         * @return      mysql-resource
         */
        public function getMysqlLink()
        {
                return $this->mysqlLink;
        }
        
        /**
         * get mysql resource
         * @access      public
         * @return      mysql-resource
         */
        public function getResult()
        {
                return $this->result;
        }
        
        /**
         * set error number
         * @access      private
         * @param       $errorNumber    int     'the error number'
         * @return      void
         */
        private function setError($errorNumber)
        {
                $this->error = $errorNumber;
        }
        
        /**
         * check exists error
         * @access      public
         * @return      bool
         */
        public function isError()
        {
                return ($this->error > 0);
        }
        
        /**
         * get error number
         * @access      public
         * @return      int
         */
        public function error()
        {
                return $this->error;
        }
        
        /**
         * get connect state
         * @access      public
         * @return      bool
         */
        public function connected()
        {
                return $this->connected;
        }
}

9 دیدگاه در “شی گرایی(OOP)در پی اچ پی(PHP) – کلاس پایگاه داده

  1. خیلی عالی و خوب
    ممنون امین جان
    تموم شد سری آموزش های شی گرایی؟
    یا هنوز قراره ادامه بدی؟
    امیدوارم ادامه بدی :دی

    پاسخ
  2. من هم قبلا ها یه کلاس مشابه این نوشتم. با هاش کار می کردم.
    کارتون خوب بود. امیدوارم ادامه بدهید.
    ——

    پاسخ
  3. سلام
    از آموزش خوبتون نهایت تشکر را می کنم و امید وارم تو این زمینه موفق باشی

    پاسخ
  4. سلام
    مطالب خوب و مفیدی بود
    ممنون
    ولی حیف شد ادامه ندادین
    کاش ادامه میدادین

    پاسخ

پاسخ دهید

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

شما می‌توانید از این دستورات HTML استفاده کنید: