|
|
|
| Добрый день!
Вот недавно начал изучать ОО, и еще не очень все понимаю как реализовать.
Для начал чтоб проверить как усвоился материал параллельно делал новостную ленту.
Так вот, меньше слов больше к теме вопроса.
Вот сам мой пример):
News.php
<?PHP
include "config.php";
class News
{
public $idnews; // Індитифікатор новини
public $idrybruka; // Індитифікатор рубрики
public $iduser; // Індитифікатор автора
public $title; // Заголовок
public $text; // Текст
public $date; // Дата private
function __construct($idnews, $idrybruka, $iduser, $title, $text, $date)
{
$this->idnews = $idnews;
$this->idrybruka = $idrybruka;
$this->iduser = $iduser;
$this->title = $title;
$this->text = $text;
$this->date = $date;
}
}
class NewsBD
{
private $outPut;
function __construct()
{
$this->outPut = array();
}
function Select($news_id = False)
{
$sql = "SELECT `idnews`, `idrybruka`, `iduser`, `title`, `min_text`, `max_text`, `date` FROM `news` WHERE `active`='1'";
($news_id) ? $sql.= "AND `idnews`='{$news_id}'" : $sql.= "ORDER BY `idnews` DESC";
$query = mysql_query($sql);
while($row = @mysql_fetch_array($query))
{
($news_id) ? $opus = $row['max_text'] : $opus = $row['min_text'];
$outPut[] = new News($row['idnews'], $row['idrybruka'], $row['iduser'], $row['title'], $opus, $row['date']);
}
return $outPut;
}
}
?>
|
index.php
<?PHP
require_once "includes/functions.php";
require_once "includes/News.php";
// Створуємо об'єкт Новини
$obj = new NewsBD();
$news_id = (int)$_GET['id'];
$news = $obj->Select($news_id);
echo (empty($news)) ? "(новини не існує)" : false;
for($i=0; $i<count($news); $i++)
{
echo
"<strong>{$news[$i]->title}</strong><br>",
"{$news[$i]->text}<br>",
"<code>Дата: {$news[$i]->date}</code><br>",
"<a href=\"".(empty($news_id) ? "index.php?id={$news[$i]->idnews}" : redirect())."\">".(empty($news_id) ? "Детальніше" : "Назад")."</a><hr>";
}
?>
|
Вопрос:
1. В файле News.php в классе NewsBD, создаем объект News, и соответствующими параметрами, вопрос состоит в том рентабельно ли создавать объект в цикле For, или лутше создание объекта News, в классе NewsBD перед циклом For, переписать класс так чтоб каждое свойство имело свой метод, и обращаться уже не к объект, а к его методам.
2. Не знаю как правильно это назвать, правильно ли я написал дизайн(паттерн) кода по отношнию к ООП.
Зарание спасибо! | |
|
|
|
|
|
|
|
для: Fedak.o.b
(11.10.2011 в 14:32)
| | Если каждый элемент массива должен быть независимым объектом класса News, то да, так и следует поступать. | |
|
|
|
|
|
|
|
для: Fedak.o.b
(11.10.2011 в 14:32)
| | 2. Опишите подробнее, где используется класс News и где NewsBD? Планируется ли от них наследовать какие-то другие классы? | |
|
|
|
|
|
|
|
для: cheops
(13.10.2011 в 16:23)
| | Да есть планы)
Но пока только планы), как я говорил я только начал изучать ООП и ищо не понимаю как правильно конструировать страницу сайта.
То есть какая информация должна быть в index.php, где должны храница html, понимаю что отдельно должно быть визуальное представление. Но не понимаю как реализовать полноценную конструкцию с подгрузкой файлов, раньше я использовал оператор swich
swich($_GET['page']){
case "news":
include("temple/page_login.php");
break;
...
}
|
А вот уже с использование ОО, не представляю как правильно подключать статичные и динамические страницы.
Хотелось бы увидеть простой сайтик-визитку, чтобы понять как все устроено, ка нужно конструировать. Нонятно что ОО для визитки нерентабельно, даже не полько позагружености, а так как много будет кода, но для примере как раз то что нужно))
Что то многовато говорю)
Так вот к ближе к тебе.
Я вот не понимаю, какие классы можно унаследовать в дальнейшем у класса News, если приставить что есть такие например классы:
1.Класс Категория - может подходить не только для новостей, а и для других нужд, так что думаю его не нужно унаследовать.
2. Класс Рейтинг - тоже самое рейтинг может быть и в новостях и в статях... для него тоже не нужно унаследование.
3. Класс Количество просмотров - аналогично к предыдущим классам, может подходить как для подсчета просмотров в новости или стати, или даже профиля пользователя.
4. Класс Количество комментариев - аналог подсчет комментариев можно вести как в новостях, статях, комментарии к профилю пользователя...
Это я так считаю)) если не прав скажите.
И по етому я не понимаю или этим классам нужно унаследовать от класса News или не нужно, но по крайной мере, я сделал без унаследования, смотрите пожалуйста мой пример, и скажите правильно ли я сделал, если есть замечания говорите.
И так видоизменился файл index.php
<?PHP
require_once "includes/functions.php";
require_once "includes/News.php";
require_once "includes/Rybruka.php";
require_once "includes/Pereglad.php";
require_once "includes/Comentar.php";
// Створуємо об'єкт Новини
$obj = new NewsBD();
// Створуємо об'єкт Рубрика
$ryb = new Rybruka();
// Створуємо об'єкт Перегляд
$per = new Pereglad();
// Створуємо об'єкт Коментар
$com = new Comentar();
$news_id = (int)$_GET['id'];
$news = $obj->Select($news_id);
echo (empty($news)) ? "(новини не існує)" : false;
for($i=0; $i<count($news); $i++)
{
//print_r($news[$i]);
$ryb->setRybruka($news[$i]->idrybruka);
$per->setPereglad($news[$i]->idnews);
$com->setCountComentar($news[$i]->idnews);
echo
"<strong>{$news[$i]->title}</strong><br>",
"Рубрика: <i>{$ryb->getRybruka()}</i><br>",
"{$news[$i]->text}<br>",
"<code>Дата: {$news[$i]->date}</code><br>",
"<u>Переглядів</u>: {$per->getPereglad()}<br>",
"<u>Коментарів</u>: {$com->getCountComentar()}<br>",
"<a href=\"".(empty($news_id) ? "index.php?id={$news[$i]->idnews}" : redirect())."\">".(empty($news_id) ? "Детальніше" : "Назад")."</a><hr>";
}
?>
|
Rybruka.php
<?PHP
class Rybruka
{
private $idpage; // Індитифікатор сторінки
private $name; // Назва рубрики
function setRybruka($rybruka_id)
{
for($i=0; $i<count($rybruka_id); $i++)
{
$row = mysql_fetch_array(mysql_query("SELECT `name` FROM `rybruka` WHERE `idrybruka`='{$rybruka_id[$i]}'"));
$this->name = $row['name'];
}
}
function getRybruka()
{
return $this->name;
}
}
?>
|
Pereglad.php
<?PHP
class Pereglad
{
private $pereglad_count; // Сума переглядів
function setPereglad($news_id)
{
$row = mysql_fetch_array(mysql_query("SELECT count(idpereglad) as `pereglad_count` FROM `pereglad` WHERE `idnews`='{$news_id}'"));
$this->pereglad_count = $row['pereglad_count'];
}
function getPereglad()
{
return $this->pereglad_count;
}
}
?>
|
Comentar.php
<?PHP
class Comentar
{
private $comentar_count; // Сума коментарів
function setCountComentar($news_id)
{
$row = mysql_fetch_array(mysql_query("SELECT count(idcomentar) AS `comentar_count` FROM `comentar` WHERE `idnews`='{$news_id}'"));
$this->comentar_count = $row['comentar_count'];
}
function getCountComentar()
{
return $this->comentar_count;
}
}
?>
|
Вот так добавились новые файлы: News.php, Rybruka.php, Pereglad.php, Comentar.php
Как видите только 4 файла, 5 файл, с классом Рейтинг, я не прикреплял, так как он думаю пока не уместен. Файл News.php можно посмотреть в первом посте!
Благодарю за внимания!))
Буду очень рад вашей помощи! | |
|
|
|
|
|
|
|
для: Fedak.o.b
(13.10.2011 в 23:27)
| | Нет, оператор switch в случае ООП это плохо. ООП для того и создавался, чтобы избегать switch-ей. Вместо него следует использовать полиморфизм, т.е. так проектировать ваши блоки, чтобы методы их отображения назывались одинаково. Тогда вам не нужен будет switch - нужно будет просто вызвать одни и те же методы (а уж что это будет новости, статьи, форум - значения иметь не будет). | |
|
|
|
|
|
|
|
для: Fedak.o.b
(13.10.2011 в 23:27)
| | >1.Класс Категория - может подходить не только для новостей, а и для других нужд, так что думаю
>его не нужно унаследовать.
Специально ничего наследовать не нужно. Вы создайте класс Категория и пользуйтесь им на здоровье... пусть он обслуживает соответствующую таблицу в базе данных, расширяйте его методами сортировки, измения позиции категории относительно других. Рано или поздно наступит момент, когда эту таблицу нужно будет видоизменить, добавить столбцы или сортировать не по алфавиту, а по другим критериям... вот тогда вам и пригодиться наследование - не нужно будет переписывать класс полностью, обрекая старый код на несовместимость, не нужно будет все делать с нуля - всего-то нужно будет унаследовать новый класс и добавить пару методов, где нужны изменения. | |
|
|
|
|
|
|
|
для: Fedak.o.b
(13.10.2011 в 23:27)
| | >И по етому я не понимаю или этим классам нужно унаследовать от класса News или не нужно,
>но по крайной мере, я сделал без унаследования, смотрите пожалуйста мой пример, и скажите
>правильно ли я сделал, если есть замечания говорите.
Нет, наиболее общие классы должны быть ниже по иерархии наследования. От класса News разумно наследовать только другие классы, которые будут еще более специализироваться на новостях. Т.е. допустим есть у вас класс новостей, который обслуживает простой блок Новости, захотели ввести разбивку новостей по категориям, унаследуйте от News новый класс NewsCategory, в котором будет возможность публиковать новости, помечая их разными категориями. Это будет правильно. Наследовать от News категории, постраничную навигацию и другие компоненты - не очень разумно. | |
|
|
|
|
|
|
|
для: cheops
(14.10.2011 в 19:11)
| | хм интеесно, хоть я новичок в ООП но почитав о полиморфизме и был в шоке) что конкретно почти никто не может обяснть что ето такое и как эго кушать. И тода я обратился к другу в реале, он правда не веб-прогер, но все же парень толковый помог осмыслить для че такое полиморфизм).
Правда в теории понимаю но на практике ищо далеко и пониманию))
И так как я тебе все приставляю подгрузку класов и приставления используя ООП.
Приставте есть классы новости, книга-поситителей, класс меню сайта...
Они находяца в папке /class/
Приставте что все класы должны иметь приставление.
Они находяца в папке /templates/
Я их соединил таким образом.
index.php
<?
define('SERVER', 'http://' . $_SERVER['HTTP_HOST']);
define('DOCUMENT_ROOT', $_SERVER['DOCUMENT_ROOT']);
// Папка з шаблоном
define('STYLE', 'default_style');
/**
* Загрузка классов (волшебная функция __autoload)
*
* @return возвращает файл объявленного объекта,
* только тогда когда, имя объявленного объекта совпадает с именем файла в котором
* содержится объявлен класс
*/
function __autoload($class_name)
{
$dir = DOCUMENT_ROOT."/class/";
$pref = "class.";
$class_name = strtolower($class_name);
$ext_class = ".php";
$path = $dir.$pref.$class_name.$ext_class;
if(file_exists($path))
{
return require_once($path);
}
else
{
return die('Файла не знайдено.');
}
}
/**
* Загрузка представления (контент)
*
* Функция загружает шаблон
*
* @return возвращает представление загруженного класса
*/
function loadFile($pageFiles)
{
$path = DOCUMENT_ROOT."/template/".STYLE."/page/";
$name = strtolower($pageFiles);
$paths = $path.$name.".php";
if(file_exists($paths))
{
return require_once($paths);
}
else
{
return require_once($path.'404.php');
}
}
require_once DOCUMENT_ROOT.'/template/'.STYLE.'/index.php';
?>
|
Вот такое содержимое у моего главного index.php
Если присмотрется до последней строки файла
require_once DOCUMENT_ROOT.'/template/'.STYLE.'/index.php';
|
то можно понять, что это загрузка шаблона.
В index.php шаблона, кроме html, содержится такие даные:
<?
// подгрузка стилей или каритнок
<link href="<?="template/".STYLE."/"?>style.css" rel="stylesheet" type="text/css" />
/* Создано два объекта, потому что два разных меню на главной страницы шаблона */
$obj = new Menu;
$obj2 = new Menu;
$menu_header = $obj->Select(); // стандатное ХЕДЕР-меню
$menu_slide = $obj2->Select(1); // правое-верхнее меню
for($i=0; $i<count($menu_header); $i++)
{
echo "<li class=\"active\"><a href=\"index.php?page={$menu_header[$i]->url}\">{$menu_header[$i]->name}</a></li>";
}
for($i=0; $i<count($menu_slide); $i++)
{
echo "<li><a href=\"index.php?page={$menu_slide[$i]->url}\">{$menu_slide[$i]->name}</a></li>";
/* Загрузка контента */
loadFile($_GET['page']);
}
?>
|
Уважаемый cheops!
Конечно что есть ошибки, хотелось бы их услышать.
1. Скажите пожалуйста верно ли я проектирую написания оператора switch и сайта?
3. Если посмотреть на главную страницу то можно понять что на главной используеца больше функциональное програмирование чем объектное, как мне правильно переделать в объектный вид с приминением полиморфизму?
4. В функции loadFile вроде допущена груба ошибка, с помощю которой можно читать содержымое некоторыех докуметов на сайте.
Предварительно спасибо! | |
|
|
|
|