Открыть меню    

Пример ООП с PHP и MySql

Если вы найдете критические помарки по переводу, пожалуйста, оставляйте комментарии. Ваши замечания обязательно будут учтены. В любом случае надеюсь, вы найдете данную статью весьма полезной.

класс ооп, php Существует множество различных, простых примеров, в которых приводится принцип работы ООП. Сегодня я решил показать вам, как работает ООП (Объектно-ориентированное, или объектное, программирование) в реальной жизни; особенно данный пример пригодится начинающим программистам. Создав класс под MYSQL CRUD (CRUD —англ. create read update delete — «Создание чтение обновление удаление»), вы сможете легко создавать, читать, обновлять и удалять записи в любых ваших проектах, независимо от того, как спроектирована база данных.

Как только вы поймете, что нам требуется, вы легко создадите скелет для нашего класса. Для начала нам надо включить в класс основные функции для работы с MySQL. Потребуются следующие функции.

  • Select
  • Insert
  • Delete
  • Update
  • Connect
  • Disconnect

Ниже приведено определение нашего класса. Отметьте, что все методы, которые я создал, используют ключевое слово public .

PHP

    class Database
    {
        public function connect()       {   }
        public function disconnect()    {   }
        public function select()        {   }
        public function insert()        {   }
        public function delete()        {   }
        public function update()        {   }
    }  

Функция connect()

Эта функция будет довольно простой, но прежде чем писать функцию, нам потребуется определить несколько переменных. Переменные должны быть доступны только в пределах класса, поэтому перед каждой переменной стоит ключевое слово private (закрытый). Все переменные (хост, имя пользователя, пароль, имя база данных) используются для соединения с базой данных MySQL. После этого мы сможем создать простой MySQL запрос к базе данных. Конечно, как программисты, мы должны ожидать от пользователей все что угодно, и исходя из этого, нам необходимо принять определенные меры предосторожности. Мы можем проверить: если пользователь уже подключен к базе данных, то , соответственно, ему не нужно повторно подключаться к БД. В противном случае, мы можем использовать учетные данные пользователя для подключения.

PHP

private db_host = ‘’;
private db_user = ‘’;
private db_pass = ‘’;
private db_name = ‘’;

    /*
     * Соединяемся с бд, разрешено только одно соединение
     */

public function connect()
    {
        if(!$this->con)
        {
            $myconn = @mysql_connect($this->db_host,$this->db_user,$this->db_pass);
            if($myconn)
            {
                $seldb = @mysql_select_db($this->db_name,$myconn);
                if($seldb)
                {
                    $this->con = true;
                    return true;
                } else
                {
                    return false;
                }
            } else
            {
                return false;
            }
        } else
        {
            return true;
        }
    }

Как видите выше, мы используем базовые функции MySQL и делаем небольшую проверку на ошибки, чтобы все шло по плану. Если пользователь подключился к БД, мы возвращаем true , в ином случае возвращаем false. В качестве дополнительного бонуса устанавливаем переменную ( con ) в true, если соединение установлено.

Общедоступная ( public ) функция disconnect()

Функция проверяет переменную соединения на существование. Если соединение установлено ( con есть), то закрываем соединение с БД MySQL и возвращаем true . Иначе делать ничего не нужно.

PHP

public function disconnect()
{
    if($this->con)
    {
        if(@mysql_close())
        {
                       $this->con = false;
            return true;
        }
        else
        {
            return false;
        }
    }
}

Общедоступная (public) функция select()

Переходим к той части, где все немного усложняется. Мы начинаем работать с аргументами пользователя и возвращаем результаты запроса. У нас нет необходимости использовать результаты прямо сейчас, но нам необходимо создать переменную, в которой мы будем хранить пользовательские результаты по запросам из БД. Кроме того мы также создадим новую функцию, которая будет проверять существует ли данная таблица в БД. Эта функция будет создана отдельно, так как все наши CRUD операции потребуют такой проверки. Таким образом, это немного очистит наш код и в дальнейшем будет способствовать оптимизации кода. Ниже приведена функция для проверки таблиц ( tableExists ) и общедоступная переменная с результатами запросов.

PHP

private $result = array();

    /*
    * Проверяем наличие таблицы при выполнении запроса
    *
    */

private function tableExists($table)
    {
        $tablesInDb = @mysql_query('SHOW TABLES FROM '.$this->db_name.' LIKE "'.$table.'"');
        if($tablesInDb)
        {
            if(mysql_num_rows($tablesInDb)==1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

Эта функция просто проверяет наличие нужной таблицы в БД. Если таблица существует, вернет true , иначе вернет false .

PHP


    /*
    * Выборка информации из бд
    * Требуется: table (наименование таблицы)
    * Опционально: rows (требуемые колонки, разделитель запятая)
    *           where (колонка = значение, передаем строкой)
    *           order (сортировка, передаем строкой)
    */

    public function select($table, $rows = '*', $where = null, $order = null)
    {
        $q = 'SELECT '.$rows.' FROM '.$table;
        if($where != null)
            $q .= ' WHERE '.$where;
        if($order != null)
            $q .= ' ORDER BY '.$order;
        if($this->tableExists($table))
       {
        $query = @mysql_query($q);
        if($query)
        {
            $this->numResults = mysql_num_rows($query);
            for($i = 0; $i < $this->numResults; $i++)
            {
                $r = mysql_fetch_array($query);
                $key = array_keys($r);
                for($x = 0; $x < count($key); $x++)
                {
                    // Sanitizes keys so only alphavalues are allowed
                    if(!is_int($key[$x]))
                    {
                        if(mysql_num_rows($query) > 1)
                            $this->result[$i][$key[$x]] = $r[$key[$x]];
                        else if(mysql_num_rows($query) < 1)
                            $this->result = null;
                        else
                            $this->result[$key[$x]] = $r[$key[$x]];
                    }
                }
            }
            return true;
        }
        else
        {
            return false;
        }
        }
else
      return false;
    }

На первый взгляд выглядит устрашающе, но при этом здесь мы делаем целую кучу важных вещей. Функция принимает четыре аргумента, один из которых обязательный. Функция вернет результат при наличии единственного аргумента - имени таблицы. Однако вы можете расширить количество аргументов и добавить новые аргументы, которые вы сможете использовать при работе с БД; ведь корректное исполнение функции зависит от одного аргумента – имени таблицы. Код в пределах функции служит для компиляции всех аргументов в select запрос. Как только запрос будет составлен, понадобится проверка на наличие в БД нужной таблицы – для этого используется функция tableExists . Если таблица найдена, то функция будет продолжена и запрос будет отправлен. Иначе все застопорится.

В следующей секции приведен действительно магический код. Суть в следующем: собрать данные запрошенные из таблицы. Затем присваиваем наш результат переменной. Чтобы упростить результат для конечного пользователя вместо числовых ключей будем использовать имена столбцов. В случае если количество строк таблицы больше единицы, на выходе вы получите двумерный массив, в котором первый ключ - это число (инкремент), второй ключ - это название колонки. Если в таблице всего одна строка, будет возвращен одномерный массив, название ключей которого соответствует именам столбцов таблицы. Если строк в таблице не найдено, переменной result будет присвоено значение null . Как я сказал ранее, все выглядит немного запутанным, но стоит вам разбить код на отдельные секции все станет гораздо проще и понятнее.

Общедоступная ( public ) функция insert()

Эта функция немного проще, чем предыдущие. Она просто позволяет вставить информацию в БД. Таким образом, помимо имени таблицы нам потребуются дополнительные аргументы. Нам потребуется переменная, которая будет содержать соответствующие для вставки в таблицу значения. Затем мы просто отделим каждое значение запятой. Также мы проверяем при помощи функции tableExists наличие нужной таблицы и составляем insert запрос, манипулируя аргументами, переданными в функцию insert() . Затем отправляем наш запрос по нужному адресу.

PHP



    /*
    * Вставляем значения в таблицу
    * Требуемые: table (наименование таблицы)
    *            values (вставляемые значения, передается массив  значений, например,
    * array(3,"Name 4","this@wasinsert.ed"); )
    * Опционально:
    *             rows (название столбцов, куда вставляем значения, передается строкой,
    *            например, 'title,meta,date'
    *
    */

    public function insert($table,$values,$rows = null)
    {
        if($this->tableExists($table))
        {
            $insert = 'INSERT INTO '.$table;
            if($rows != null)
            {
                $insert .= ' ('.$rows.')';
            }
            for($i = 0; $i < count($values); $i++)
            {
                if(is_string($values[$i]))
                    $values[$i] = '"'.$values[$i].'"';
            }
            $values = implode(',',$values);
            $insert .= ' VALUES ('.$values.')';
            $ins = @mysql_query($insert);
            if($ins)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

Как видите эта функция довольно простая, по сравнению с составлением запросов select к БД. На самом деле функция delete будет еще проще.

Общедоступная ( public ) функция delete()

Эта функция просто удаляет таблицу или строки из нашей БД. Таким образом, нам надо передать в функцию имя таблицы и опциональный аргумент определяющий условие where . В условии следующим за ключевым словом WHERE следует уточнение: удалить строку, строки или всю таблицу. Если условие where опущено, то будут удалены все строки. Затем составляется запрос delete и следует выполнение запроса.

PHP


    /*
    * Удаяем таблицу или записи удовлетворяющие условию
    * Требуемые: таблица (наименование таблицы)
    * Опционально: где (условие [column =  value]), передаем строкой, например, 'id=4'
    */

    public function delete($table,$where = null)
    {
        if($this->tableExists($table))
        {
            if($where == null)
            {
                $delete = 'DELETE '.$table;
            }
            else
            {
                $delete = 'DELETE FROM '.$table.' WHERE '.$where;
            }
            $del = @mysql_query($delete);
            if($del)
            {
                return true;
            }
            else
            {
               return false;
            }
        }
        else
        {
            return false;
        }
    }

Наконец перейдем к нашей последней основной функции. Эта функция служит для обновления строки в БД новой информацией. Данная функция на первый взгляд сложна для понимания, однако, это не совсем так. Мы будем использовать все те же принципы, что и раньше. Например, аргументы будут использоваться для составления запроса update . Также мы проверим наличие таблицы при помощи метода tableExists . Если таблица существует, обновим надлежащую строку. Самая сложная часть, конечно, та, где мы занимаемся составлением запроса update . Поскольку оператор update имеет правило за раз обновлять все строки, нам необходимо учесть это и правильно отрегулировать этот момент. Итак, я решил условие where передавать как простой массив. Первый аргумент в этом массиве - имя столбца, следующий аргумент значений столбца. Таким образом, каждый четный номер (включай 0) соответствует имени колонки, а каждый нечетный номер содержит нечетное значение. Соответствующий код приведен ниже:

PHP

 for($i = 0; $i < count($where); $i++)
            {
                if($i%2 != 0)
                {
                    if(is_string($where[$i]))
                    {
                        if(($i+1) != null)
                            $where[$i] = '"'.$where[$i].'" AND ';
                        else
                            $where[$i] = '"'.$where[$i].'"';
                    }
                }
            }
            $where = implode($condition,$where);

В следующей секции мы создадим часть update оператора, настраивая переменные. Поскольку вы можете изменить любое числовое значение, я предпочел массив с ключами по названию столбца и новыми значениями. Таким образом, нам останется сделать проверку на тип значения и где нужно поставить запятую. Теперь, когда мы составили две основных части оператора update , завершить составление оператора update не составит труда, код представлен ниже:

PHP

public function update($table,$rows,$where,$condition)
    {
        if($this->tableExists($table))
        {
            // Parse the where values
            // even values (including 0) contain the where rows
            // odd values contain the clauses for the row
            for($i = 0; $i < count($where); $i++)
            {
                if($i%2 != 0)
                {
                    if(is_string($where[$i]))
                    {
                        if(($i+1) != null)
                            $where[$i] = '"'.$where[$i].'" AND ';
                        else
                            $where[$i] = '"'.$where[$i].'"';
                    }
                }
            }
            $where = implode($condition,$where);
            $update = 'UPDATE '.$table.' SET ';
            $keys = array_keys($rows);
            for($i = 0; $i < count($rows); $i++)
           {
                if(is_string($rows[$keys[$i]]))
                {
                    $update .= $keys[$i].'="'.$rows[$keys[$i]].'"';
                }
                else
                {
                    $update .= $keys[$i].'='.$rows[$keys[$i]];
                }
                // Parse to add commas
                if($i != count($rows)-1)
                {
                    $update .= ',';
                }
            }
            $update .= ' WHERE '.$where;
            $query = @mysql_query($update);
            if($query)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }

Итак, мы закончили создание последней функции и наш класс для работы с CRUD можно считать законченным. Теперь вы можете создавать новые записи, читать отдельные записи из БД, обновлять записи и удалять. Кроме того, начав повторно использовать данный класс, вы обнаружите, что существенно экономите время и строчки код. То есть вы почувствуете эффективность и преимущество ООП.

ооп, класс для работы с mysql

Использование

Итак, мы создали наш класс, но как его использовать? Тут все просто. Давайте начнем с создания простой БД, в которой протестируем наш класс. Я создал базу данных test и составил простой mysql оператор. Вы можете поместить его в любую БД.

создаем и заполняем таблицу в бд

Первая строка закомментирована, так как она не всегда необходима. Если вам необходимо запустить предыдущий код более одного раза, вам потребуется раскомментировать первую строку, чтобы быть уверенным, что таблица создана.

Теперь, когда наша таблица создана и заполнена, самое время запустить несколько простых запросов.

PHP

<?php
include('crud.php');
$db = new Database();
$db->connect();
$db->select('mysqlcrud');
$res = $db->getResult();
print_r($res);
?>

Если все сделано корректно, вы увидите следующие:

результат выборки из  бд

Аналогичным образом мы можем запустить запрос на обновление и вывести результаты.

PHP

<?php;
$db->update('mysqlcrud',array('name'=>'Changed!'),array('id',1),"=");
$db->update('mysqlcrud',array('name'=>'Changed2!'),array('id',2),"=");
$res = $db->getResult();
print_r($res);
?>

На выходе:

результат выборки из  бд, данные обновлены

Теперь просто вставим запись:

PHP

<?php;
$db->insert('mysqlcrud',array(3,"Name 4","this@wasinsert.ed"));
$res = $db->getResult();
print_r($res);
?>
результат выборки из  бд, после вставки новой записи

Источник

Комментарии к статье

аватарка пользователя
2013-03-22
SquiD

В методе delete() в случае очистки всей таблицы неверен запрос. Правильно будет "DELETE FROM $table"

аватарка пользователя
2013-06-04
Eugeny

в запросах на удаление и обновление нужно жестко указывать лимит, LIMIT 1

аватарка пользователя
2013-07-17
Саня

в запросах на удаление и обновление нужно жестко указывать лимит, LIMIT 1

ходу добавить на всё нужно добавить парамер LIMIT и применять например выбрать из таблы лимит 30 полей или выбрать из таблы с 30 по 90 и тд.
P.S идея хорошая но сыроватая .требует дороботок.для новичка это как урок но не для использования :)

аватарка пользователя
2013-07-17
dnzl

конечно, требуется подумать немного доработать и использовать, как и все и везде

аватарка пользователя
2013-07-27
-_-

Интересный класс. Но я нигде не увидел описание метода getResult() которым вы успешно пользуетесь.... если можете добавьте. Я начинающий ООП программист и мне интересно как он реализовывается . Заранее спасибо

аватарка пользователя
2013-07-27
dnzl

private $result0 = array(); // Результат возвращаемый от запроса
/*
* Returns the result set
*/
public function getResult()
{
return $this->result0;
}

аватарка пользователя
2013-10-23
F0X

Вообще класс пост, все красиво разложено.
Краше бы смотрелось:

public function __construct() {

if (!$this->link = mysql_connect(DB_HOST, DB_USER, DB_PASS)) {
trigger_error('Error: Could not make a database link using ' . DB_USER . '@' . DB_HOST);
return FALSE;
} else {
if (!mysql_select_db(DB_NAME, $this->link)) {
trigger_error('Error: Could not connect to database ' . DB_NAME);
return FALSE;
} else {
mysql_query("SET NAMES 'utf8'", $this->link);
mysql_query("SET CHARACTER SET utf8", $this->link);
mysql_query("SET CHARACTER_SET_CONNECTION=utf8", $this->link);
mysql_query("SET SQL_MODE = ''", $this->link);
return TRUE;
}
return TRUE;
}
}
<----------тут остальные методы------------>

public function __destruct() {
if (!mysql_close($this->link)){
return FALSE;
} else {
return TRUE;
}
}

тогда можно упростить инициализацию до
$db = new MySQL();
$res = $db->query('Select * from user');

а в select() красивее:
$i=0;
while ($row = mysql_fetch_assoc($res)) {
foreach ($row as $key => $value) {
$ret[$i][$key] = $value;
}
$i++;
}

Автору респектище!

аватарка пользователя
2013-10-23
F0X

Хотелось бы подписочку на новости!)

аватарка пользователя
2013-11-08
chakopss

или в Select даже так if($query)
{
$this->numRows = mysql_num_rows($query);
$mass = Array();

for($i=0; $i<$this->numRows; $i++)
{
$r = mysql_fetch_assoc($query);
$mass[$i] = $r;

}

}
return $mass

аватарка пользователя
2013-11-08
chakopss

я знаю что метод destruct() работает не совсем противоположно методу construct(). диструктор посылает запрос на уничтожение объекта а php машина в по очереди удаляет объекты! Поэтому думаю не очень удачный пример с диструктором! Если проект маленький и объектов немного, то да! но если объектов много , могут возникнуть проблемы!

аватарка пользователя
2014-01-05
Alfaroma

Добрый день, в чем разница если мы будем использовать просто пользовательский функции для работы с БД? Почему удобнее использовать объекты в классе?
Спасибо!

аватарка пользователя
2014-01-05
Костя

Alfaroma, самый существенный плюс: этим вы СУЩЕСТВЕННО сократите объем своего кода, остальные не упомню, так как с php практически не работаю

аватарка пользователя
2014-02-02
Александр

Может я чего не понимаю, но смысл с такого класса, если данные возвращаются либо в многомерном, либо в одномерном массивах, которые приходится проверять, и выводить данные соответствующим способом, чтобы не получить "крякозябру". Или может какой-то магические способ есть, который одинаково хорошо работает и для многомерных и для одномерных массивов?

аватарка пользователя
2014-04-19
YAzz

В функции select вместо отбора только ассоциативного массив,
if(!is_int($key[$x]))
не проще изначально добавить константу на выборку:
mysql_fetch_array($result, MYSQL_ASSOC)

аватарка пользователя
2014-10-04
cy

I'm trying to create alike class, but using PDO (as PDO provides built-in security stuff against SQL injections). Check it out:
class db {
private $db_name = "";
private $username = "";
private $password = "";

private function dsn() {
return 'mysql:host=localhost;dbname='.$this->db_name.';charset=UTF8';
}

public function connect() {
$con = NULL;
try{
$con = new PDO($this->dsn(), $this->username, $this->password);
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
print 'ERROR: ' . $e->getMessage();
}
$this->con = $con;
}

public function con() {
return $this->con;
}

public function query($query, $params = null) {
$this->result = NULL;
try {
$stmt = $this->con->prepare($query);
if($params != NULL) {
foreach($params as $key=>$val) {
$stmt->bindParam($key+1, $val);
}
}
$stmt->execute();
$this->rowCount = $stmt->rowCount();
while ($result = $stmt->fetch(PDO::FETCH_NUM)) {
$this->result[] = $result;
}
$stmt = NULL;
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
}

Usage example:
$db = new db;
$db->connect();
$params[] = '2';//this value could be received from POST or GET. No need to be escaped. PDO does it for Y with bindParam() method.
$q = "select field, field1, field2 from mytable where field=?";
$db->query($q,$params);

аватарка пользователя
2014-11-26
noise

Скажите, пожалуйста,как получить значения самого массива ?
Как изменить
<?php
include('crud.php');
$db = new Database();
$db->connect();
$db->select('mysqlcrud');
$res = $db->getResult();
print_r($res);
?>
чтобы получить значения?

аватарка пользователя
2015-01-19
Константин

В коде очень много нелепых синтаксических ошибок. Значит этот код не запускался и не решал реальные задачи.

аватарка пользователя
2015-01-19
dnzl

Константин, код используется, но вы правы, пришлось немного дорабатывать, а вообще-то это перевод и исходный код я не менял в переводе

аватарка пользователя
2015-02-03
Артем

Здравствуйте!

Подскажите, пожалуйста, как построчно вывести данные ?
То есть я хочу их выводить как отдельные блоки, а не массивом.

аватарка пользователя
2015-02-03
Артем

Я имею ввиду этот участок

for ($i = 0; $i < $this->numResults; $i++) {
$r = mysql_fetch_array($query);
$key = array_keys($r);
for ($x = 0; $x < count($key); $x++) {
// Sanitizes keys so only alphavalues are allowed
if (!is_int($key[$x])) {
if (mysql_num_rows($query) > 1) {
$this->result[$i][$key[$x]] = $r[$key[$x]];

} else if (mysql_num_rows($query) < 1) {
$this->result = null;
} else {
$this->result[$key[$x]] = $r[$key[$x]];
}
}
}
}

Процедурным кодом я понимаю, как это сделать. но на ооп застрял

аватарка пользователя
2015-02-03
Артем

Разобрался.
Если кому интересно:

нужно заменить это:
$r = mysql_fetch_array($query);
$key = array_keys($r);
for($x = 0; $x < count($key); $x++)
{
// Sanitizes keys so only alphavalues are allowed
if(!is_int($key[$x]))
{
if(mysql_num_rows($query) > 1)
$this->result[$i][$key[$x]] = $r[$key[$x]];
else if(mysql_num_rows($query) < 1)
$this->result = null;
else
$this->result[$key[$x]] = $r[$key[$x]];
}
}

на это
$r = mysql_fetch_assoc($query);
echo 'id:' . $r['id'] . ', <br>имя: ' . $r['name'] . ',<br>Адрес:' .$r['email'] . '<br />';

И есть вопрос:
Можно как-то эти данные передавать в другую функцию?

Добавить комментарий