Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.07.2008, 15:18   #1
Choo
 
Регистрация: 31.07.2008
Сообщений: 6
По умолчанию Правильная организация класса для работы с таблицей mysql

У меня, собственно, такой вопрос. Сейчас занимаюсь написанием небольшой CMS для сайта, поставил себе целью по максимуму использовать ООП. Хочу получить правильные с логической точки зрения классы для работы с таблицами.

Для примера. Есть у меня таблица pages, которая состоит из полей id, title, и текст и нужна для вывода статических страниц на сайте. Мне нужен класс, который будет выполнять следующие функции:
-добавление записи;
-редактирование записи;
-удаление записи;
-сбор данных и вывод существующей записи.

Получилось вот что, но я думаю, что это не совсем правильно:

PHP код:
<?
class Page {
    var 
$id;
    var 
$title;
    var 
$text;    
    
    function 
select_page($id) {
        
$id=int($id);
        
$this->id=$id;
    }
    
    function 
init_page() {
        
$query="SELECT * FROM `pages` WHERE `id`='$this->id'";
        
$result=mysql_query($query);
        if(
mysql_num_rows($result)==0) {
            return 
FALSE;
        }
        else {
            
$row=mysql_fetch_array($result);
            
$this->title=$row['title'];
            
$this->text=$row['text'];
            return 
TRUE;
        }
    }
    
    function 
delete_page() {
        
$query="DELETE FROM `pages` WHERE `id`='$this->id'";
        if(
mysql_query($query)) return TRUE;
        else return 
FALSE;
    }
    
    function 
edit_page($title$text) {
        
$query="UPDATE `pages` SET title='$title', text='$text' WHERE `id`='$this->id'";
        if(
mysql_query($query)) return TRUE;
        else return 
FALSE;
    }
    
    function 
add_page($title$text) {
        
$query="INSERT INTO `pages` (`title`, `text`) values ('$title', '$text')";
        if(
mysql_query($query)) return TRUE;
        else return 
FALSE;
    }
}
?>
Дело в том, что это мой первый опыт работы с ООП и я пока не полностью себе представляю все принципы работы. По поводу того как это будет работать у меня претензий нет, а вот правильно ли это логически?

Метод select_page($id) выбирает id страницы, с которой будем работать.
Метод init_page() загружает остальные данные по уже определённому id.
Метод delete_page() удаляет загруженную страницу.
Метод edit_page() редатирует её.

Сомнения возникли, когда стал писать метод add_page. Как то нелогично выходит, определять id мы не будем. Вобщем метод работает как функция, которой могло бы и не быть в классе. Как правильно? Может быть создавать объект, задавать его данные, а потом уже делать что-то вроде add_page()? Но это ставит под вопрос остальные мои методы.

Вобщем ситуация простая, хотелось бы спросить у компетентных людей, как бы они организовали эту несложную задачу.
Choo вне форума Ответить с цитированием
Старый 31.07.2008, 16:21   #2
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 16,218
По умолчанию

Цитата:
поставил себе целью по максимуму использовать ООП
Для начала, определитесь с версией PHP. То, что Вы написали - это под 4-ю версию. Если хотите максимально использовать ООП, ориентируйтесь на php5 и изучите различия в подходе к ООП в этих двух версиях PHP.

А вообще в такой задачи трудно что-либо предложить, сделайте, например так:
PHP код:
<?php

class Page
{
    public function 
select_page($id)
    {
        
$query="SELECT * FROM `pages` WHERE `id`='$id'";
        
$result=mysql_query($query);
        if(
mysql_num_rows($result)==0) {
            return 
FALSE;
        }
        else return 
mysql_fetch_array($result);
    }
  
    public function 
delete_page($id) {
        
$query="DELETE FROM `pages` WHERE `id`='$id'";
        if(
mysql_query($query)) return TRUE;
        else return 
FALSE;
    }
    
    public function 
edit_page($id$title$text) {
        
$query="UPDATE `pages` SET title='$title', text='$text' WHERE `id`='$id'";
        if(
mysql_query($query)) return TRUE;
        else return 
FALSE;
    }
    
    public function 
add_page($title$text) {
        
$query="INSERT INTO `pages` (`title`, `text`) values ('$title', '$text')";
        if(
mysql_query($query)) return TRUE;
        else return 
FALSE;
    }
}

?>
Нет смысла каждый раз вызывать отдельный метод для выбора id страницы, проще его передавать. В итоге получается просто набор функций, оформленных в класс.

Последний раз редактировалось Arigato; 31.07.2008 в 16:24.
Arigato на форуме Ответить с цитированием
Старый 01.08.2008, 16:07   #3
Choo
 
Регистрация: 31.07.2008
Сообщений: 6
По умолчанию

Это не совсем то, что мне хотелось бы видеть... Использование классов получается нецелесообразным. Может кто-то может подсказать общую структуру и суть класса, который бы использовался для работы с SQL в целом? Функции: добавление, удаление, редактирование, просмотр. Просто он же должен работать с разными таблицами и полями - как это сделать удобнее всего?
Choo вне форума Ответить с цитированием
Старый 01.08.2008, 16:47   #4
SkyM@n
Laravel/Vue expert
Старожил Подтвердите свой е-майл
 
Аватар для SkyM@n
 
Регистрация: 08.08.2007
Сообщений: 2,832
По умолчанию

Кстати, смотрите:
PHP код:
$mypage = new $Page();
$mypage->id "'; drop pages /*";
$mypage->init_page

Последний раз редактировалось SkyM@n; 01.08.2008 в 16:50.
SkyM@n вне форума Ответить с цитированием
Старый 01.08.2008, 17:06   #5
Choo
 
Регистрация: 31.07.2008
Сообщений: 6
По умолчанию

Мне пришла в голову некоторая идея, хочу у вас узнать имеет ли она право на жизнь. Хочу сделать класс для работы с MySQL. Методы - подключение к БД, выбор таблицы, отключение, удаление, редактирование, добавление. Для редактирования и добавления в кач-ве аргумента подавать массив пар поле-значение или 2 массива - один с полями, другой со значениями и потом основываясь на этом генерировать запрос. Также можно для удобства сделать метод, который будет готовить эти массивы для методов добавления-редактирования.

Нормально?
Choo вне форума Ответить с цитированием
Старый 01.08.2008, 17:26   #6
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 16,218
По умолчанию

Посмотри прикрепленный файл. Давно использую нечто подобное в своих проектах.
Есть базовый класс: db_base.
В нем реализованы методы либо абстрактно, либо те, которые не привязаны к конкретной СУБД.
Есть класс, драйвер конкретной СУБД, например: MySQL.php, класс db extends db_base
В этом классе реализованы только те методы, которые зависят от выбора конкретной СУБД (MySQL, PostgreSQL и т.п.), т.е. это драйвер конкретной СУБД.
Есть еще скрипт с набором функций: db.php
В нем создается объект класса db (выбранного драйвера СУБД) и реализована оболочка для всех функций класса.
Например:
PHP код:
$r db_select ("kernel_cron""cron_func, cron_type""cron_time<=" time(), "cron_type");
while ( 
$f db_fetch_assoc ($r) )
{
...
}
db_free_result ($r); 
Т.е. выборка данных.
Зачем надстройка над классом? Да это что бы не писать что-то типа такого:
PHP код:
global $db;
$db->select (...);
... 
Вложения
Тип файла: rar db.rar (3.4 Кб, 48 просмотров)
Arigato на форуме Ответить с цитированием
Старый 01.08.2008, 18:03   #7
Choo
 
Регистрация: 31.07.2008
Сообщений: 6
По умолчанию

Спасибо.
Форма и способы мне сейчас не так интересны, как суть.
Т.е. ход мыслей правильный?
Есть класс для работы с БД. Т.е. все методы, нужные для обработки данных, не привязанных к какому-то типу БД. Потом расширенные классы для работы с каждой БД в отдельности. Я понимаю, что вы сейчас сказали то же самое, но мне хотелось описать это своими словами и получить подтверждение. За файлы и текст спасибо, но мне в данный момент хочется написать все самому, без оглядки на существующие готовые классы.
Choo вне форума Ответить с цитированием
Старый 01.08.2008, 18:10   #8
Choo
 
Регистрация: 31.07.2008
Сообщений: 6
По умолчанию

Очень понравился ваш вариант, но копипастить смысла нет - хочется до всего дорасти самому, но, безусловно, оглядка на такой продукт в моменты сомнений будет очень полезна. Ещё раз спасибо.
Choo вне форума Ответить с цитированием
Старый 01.08.2008, 19:57   #9
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 16,218
По умолчанию

Цитата:
Есть класс для работы с БД. Т.е. все методы, нужные для обработки данных, не привязанных к какому-то типу БД. Потом расширенные классы для работы с каждой БД в отдельности.
Да, Вы все правильно поняли. Уверен, что с таким подходом у Вас будут большие перспективы.

P.S. пример не для копипаста, а для демонстрации подхода.
Можете еще глянуть, как такое реализуется в готовых движках, например, в phpBB2 реализован похожий подход (но мне он не очень понравился).
Привязывать код к работе только с конкретной СУБД (например, MySQL) не дальновидно. Завтра может потребоваться другая СУБД, а переписывать все скрипты - неоправданно трудная задача.
Arigato на форуме Ответить с цитированием
Старый 08.08.2008, 08:48   #10
crazy horse
ios developer
Старожил
 
Аватар для crazy horse
 
Регистрация: 16.11.2007
Сообщений: 2,885
По умолчанию

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

Код:
<?php

/**
 * Прокси-класс к Mysql серверу
 **/

class SqlProxy{

    private $dbhost;    //Mysql-server
    private $dbname;    //Имя базы данных
    private $dbuser;    //Логин
    private $dbpassword;//Пароль
    private $link;      //указатель на подключение
    private $sql;       //Запрос
    private $result;    //Результат Запроса

    /**
    * Constructor
    * @access public
    **/
    public function SqlProxy($dbuser,$dbpassword)
    {
        $this->setDbhost("localhost");
        $this->setDbname("ez_report");
        $this->setDbuser($dbuser);
        $this->setDbpassword($dbpassword);
    }


    /**
    * геттеры и сеттеры
    * */
    private function setDbhost($dbhost)
    {
        $this->dbhost=$dbhost;
    }

    private function getDbhost()
    {
        return $this->dbhost;
    }

    private function setDbname($dbname)
    {
        $this->dbname=$dbname;
    }

    private function getDbname()
    {
        return $this->dbname;
    }

    private function setDbuser($dbuser)
    {
        $this->dbuser=$dbuser;
    }

    private function getDbuser()
    {
        return $this->dbuser;
    }

    private function setDbpassword($dbpassword)
    {
        $this->dbpassword=$dbpassword;
    }

    private function getDbpassword()
    {
        return $this->dbpassword;
    }

    /**
    * Устанавливает строку запроса
    * */
    public function setSql($sql)
    {
        $this->sql=$sql;
    }

    private function getSql()
    {
        return $this->sql;
    }

    private function setResult($result)
    {
        $this->result=$result;
    }

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

    /**
    * Подключение к базе, сеттер $link
    * */
    private function setLink()
    {
        $this->link=mysql_connect($this->getDbhost(),$this->getDbuser(),$this->getDbpassword());
        mysql_query('SET NAMES utf8',$this->getLink()) or trigger_error("ошибка при установке кодовой страницы:".mysql_error());
        mysql_query ("set character_set_client='utf8',$this->getLink()") or trigger_error("ошибка при установке кодовой страницы:".mysql_error());        mysql_query ("set character_set_results='utf8'");
        mysql_query ("set collation_connection='utf8_bin',$this->getLink()") or trigger_error("ошибка при установке кодовой страницы:".mysql_error());

     }

    private function getLink()
    {
        return $this->link;
    }

    /**
    * Преобразование ответа mysql в массив.
    * @returns $raw - массив с результатом sql-запроса
    * */
    public function resultToArray()
    {
		    $raw=array();
		    while($raw[]=mysql_fetch_array($this->getResult(),MYSQL_ASSOC));
	        array_pop($raw);
	        return $raw;
    }




    /**
    * Выполнение SQL запроса.
    * */
    public function sqlExec()
    {
        $this->setLink();
        mysql_select_db($this->getDbname(),$this->getLink());
        //mysql_query($this->getSql(),$this->getLink());
        $res=mysql_query($this->getSql(),$this->getLink()) or trigger_error("error executing sql: ".mysql_error());
        $this->setResult($res);
        mysql_close($this->getLink());
    }
}
Делайте что хотите, но чтобы через полчаса в лесу было светло, сухо и медведь!
crazy horse вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Правильная работа из под Win с прерываниями в МАСМ Stilet Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 10 10.06.2008 15:19
MySQL нужна библ. для Visual C++ (MySql++) Alexoid Visual C++ 8 07.05.2008 18:29
как создать субд в Delphi для работы с MySqL Savl БД в Delphi 1 12.03.2008 14:10
Правильная программа? Надюха Помощь студентам 10 28.09.2007 14:40
Работа с таблицей без БД Гр_ БД в Delphi 3 06.06.2007 16:31