Автор Тема: Помогите с ООП  (Прочитано 19998 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Алексей

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 176
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите с ООП
« Ответ #30 : 02 Ноября 2004, 13:25:11 »
RomikChef
доступно :)

Оффлайн Макс

  • vir magni ingenii
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3534
  • +0/-0
  • 2
    • Просмотр профиля
Помогите с ООП
« Ответ #31 : 02 Ноября 2004, 15:02:28 »
Алексей
Допустим есть класс у которого есть конструктор и у которого есть какой-то метод.

class {
   function 
__construct() { ... }
    function 
someMethod () { ... }


Теперь есть 2 варианта вызова метода someMethod().
1.
$obj 
= new A();
$obj->someMethod();


2. A::someMethod();

В первом случае будет выполнен конструктор, создан экземпляр объекта ($obj - он же $this, при обращении внутри класса) , и только потом выполнен someMethod()
Во-втором случае будет выполнен только метод.

Чаще используют первый вариант.
Когда используют второй (из того что сейчас помню) :
 - иногда просто схожие по теме функции объединяют в класс (в нем даже конструктор не создают). Получается такое примитивное пространство имен (namespace). Пример http://pear.php.net/package/HTTP
 - Бывают случаи когда  есть какое-то часто используемое применение класса, Эдакая последовательность вызовов методов класса, которая часто используется в программах и на этом работа с классом завершается. Тогда в класс добавляют один статический метод, который внутри себя создает объект своего же класса и выполняет эту последовательность методов. Пример http://pear.php.net/package/HTTP_Download и его метод staticSend()
Пример использования :
http://pear.php.net/manual/en/package.http.http-download.intro.php (первый пример)
 - работа со статическими переменными. Пример мой класс. Я в ЖЖ объяснял, что такой подход был принят по одной причине - я хочу работать с БД везде (в функциях, методах других классов) прозрачно, без передачи экземпляра класса работы с бд. Что и позволяет такой подход (так как классы находятся в глобальном пространстве имен)
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. ( George Carrette )

Оффлайн Алексей

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 176
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите с ООП
« Ответ #32 : 02 Ноября 2004, 19:43:54 »
Макс
большой Спасиб.

Оффлайн NAS

  • Неопытный юзер
  • Администратор
  • Ветеран
  • *****
  • Сообщений: 2951
  • +1/-0
  • 1
    • Просмотр профиля
    • http://nhouse.ru
Помогите с ООП
« Ответ #33 : 03 Ноября 2004, 10:52:47 »
Макс

[OFF]А давай твой пост как статью оформим ?
[/OFF]

Оффлайн fuza

  • Завсегдатай
  • Пользователь
  • **
  • Сообщений: 51
  • +0/-0
  • 0
    • Просмотр профиля
    • http://komptex.narod.ru
Помогите с ООП
« Ответ #34 : 03 Ноября 2004, 13:29:43 »
Люди!!! у меня тоже вопрос по php и точнее по ООП вот смотрите: у меня есть два поля в одном вводиться название фото, в другом, путь к нему, и вот при закачки фотки я ему пишу: echo $this->foto_name; и он мне ничего не выводит, в чем глюк???

и второй вопрос, уже не по ооп. Как сделать что бы в ХР выводились парс ерроры и варнинги и т.п. дела?

Оффлайн Босc всех зон

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 14
  • +0/-0
  • 0
    • Просмотр профиля
Помогите с ООП
« Ответ #35 : 03 Ноября 2004, 15:03:47 »

class Photo
{
  var 
$name = \'name\';
  var $path = \'path\';
  
  function Photo() { /* Constructor */ }
}

$photo =& new Photo;
var_dump($photo->path);


Неужто не выводится?
Есть такая вещь - отладка!

Оффлайн Макс

  • vir magni ingenii
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3534
  • +0/-0
  • 2
    • Просмотр профиля
Помогите с ООП
« Ответ #36 : 03 Ноября 2004, 15:16:46 »
Цитировать
fuza:
Как сделать что бы в ХР выводились парс ерроры и варнинги и т.п. дела?

скорее всего в php.ini надо параметр display_errors включить
или error_reporting = E_ALL сделать

Цитировать
NAS:
А давай твой пост как статью оформим ?

Я подумаю. Дело в том, что здесь нет никаких реальных ПХП-кодов (то что я привел, это упрощенные варианты). Причем у меня пока нет желания публиковать свои классы (к тому же в при использовании этих в реальных проектах я иногда сталкиваюсь с некоторыми неудобствами). Если изложить в статье просто идеи, а реализацию возложить на читателей - то можно.
Есть идеи что добавить, объяснить подробнее ?
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. ( George Carrette )

Оффлайн NAS

  • Неопытный юзер
  • Администратор
  • Ветеран
  • *****
  • Сообщений: 2951
  • +1/-0
  • 1
    • Просмотр профиля
    • http://nhouse.ru
Помогите с ООП
« Ответ #37 : 03 Ноября 2004, 15:19:17 »
Макс Именно идеи, а реализацию оставить на читателя, потом при желании можно будет сделать вторую часть с реализацией.

Оффлайн Макс

  • vir magni ingenii
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3534
  • +0/-0
  • 2
    • Просмотр профиля
Помогите с ООП
« Ответ #38 : 03 Ноября 2004, 18:16:36 »
NAS, напомни мне это на следующей неделе.
Если в армию не заберут, то начну делать :)
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. ( George Carrette )

Оффлайн Алексей

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 176
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите с ООП
« Ответ #39 : 09 Ноября 2004, 16:49:23 »
Вообщем, че то написал, не знаю, правильно или нет. Хочется вашего мнения.

Создал 3 класса - главный класс DB, выполняющий некоторые операции с БД, класс гостевой книги GB, выполняющий лишь обработку ПОСТ-массива от слешей и пробелов и проверку на допустимость пользовательского ввода, и класс "Отстраничиватель":

Многие идеи брал из класса Макса, но у него там всё сложнее намного.. Вот что получилось:

//Main class DB
class DB{
	
private 
$lnk$result$server$username$password$db;
	

	
//Устанавливаем коннект, выбираем БД
	
private function 
connect(){
	
	
if(
is_resource($this->lnk))
	
return 
true;
	
	
//тут определяем парольи и имя сервера - для локалхоста и хостинга...........
	
	

	
	
$this->lnk mysql_connect($this->server$this->username$this->password)
	
	
	
or die(
"Не могу соедениться c MySql");
	
	
mysql_select_db($this->db$this->lnk) or die("Не могу выбрать базу $db");
	
}
	

	
//КОНСТРУКТОР
	
function 
__construct(){
	
	
$this->connect();
	
}
	

	
//ДЕСТРУКТОР
	
function 
__destruct(){
	
	
@
mysql_close($this->lnk);
	
}
	

	
//Выполняет Sql запрос
	
//результатом будет либо возвращённое булево значение, либо ресурс в области видимости класса
	
function 
query($query){
	
	
$what mysql_query($query$this->lnk) or die("Не могу сделать SQL-запрос ($query)");
	
	
if(
is_resource($what))
	
$this->result $what;
	
	
else return 
$what;
	
}
	

	

	
//
	
"Универсальная" функция запросов. 
	
//Принимает строку $query, которая является запросом и флаг $flag
	
//нужно использовать флаг, который может иметь 2 параметра:
	
// ROW && ASSOC. Флаги указывают, как возвращать результат:
	
	
//ROW: Как массив, где каждый элемент массива - массив данных - одна запись из таблицы
	
	
//ASSOC: Ккак массив, где каждый элемент массива - массив содержащий перечисленный массив 
	
	
//данных одного типа
	
//В случаях ошибки возвращает false
	
public function 
get_rezar($query$flag=false){
	
	
$this->connect();
	
	
$this->query($query);
	
	

	
	
if(!
$flag || !is_resource($this->result))
	
return 
false;
	
	
if(!
mysql_num_rows($this->result))
	
return 
false;
	
	

	
	
//Возвращает как массив, где каждый элемент массива - 
	
	
//массив данных - одна запись из таблицы
	
	
if(
$flag=="ROW"){
	
	
	
while(
$temp mysql_fetch_row($this->result))
	
	
	
	
$array[] = $temp;
	
	
	
return 
$array;
	
	
//Возвращает как массив, где каждый элемент массива - 
	
	
//массив содержащий перечисленный массив данных одного типа
	
	
} else if (
$flag=="ASSOC"){
	
	
	
while(
$temp mysql_fetch_assoc($this->result)){
	
	
	
	
foreach(
$temp as $key=>$value)
	
	
	
	
	
$array[$key][] = $value;
	
	
	
}
	
	
return 
$array;
	
	
} else return 
false;
	
}
	

	
//Получает простое единственное значение (не массив) из запроса
	
public function 
get_one($query){
	
	
$this->connect();
	
	
$this->query($query);
	
	

	
	
if(!
is_resource($this->result) || !mysql_num_rows($this->result))
	
	
	
return 
false;
	
	

	
	
$row mysql_fetch_row($this->result);
        return 
$row[0];
	
}
	

	
//получает количество рядов в результате
	
public function 
db_num_rows(){
	
	
return 
mysql_num_rows($this->result);
	
}
}


//Класс ГОСТЕВАЯ КНИГА
class gb extends DB{
public 
$err;
	
//Очищает POST - убивает пробелы и магические кавычки
	
function 
clearPost(){
	
foreach(
$_POST as $key=>$value)//clearPost-a код не привожу....
	
	
$_POST[$key]=clearPost($value);
	
}
	

	
//Метод проверяет введённые POST-данные, и если они верны, то делает выполняет запрос $query
	
//Если всё ок, возвращает true, наче - false
	
function 
add($query){
	
global 
$user_is_login$ml_user_message;
	
if(!
$user_is_login)
	
	
$this->err[] = "<li>Вы не являетесь зарегестрированным пользователем.
Вероятно, Вы начинающий кулхацкер? Хе-хе...</li>"
;
	
if(!
$_POST["user_message"])
	
	
$this->err[] = "<li>Вы не ввели сообщение.</li>";
	
else if(
$t bad_max_length($_POST["user_message"],$ml_user_message))
	
	
$this->err[] = "<li>Введённое Вами сообщение слишком велико. Удалите $t символов.</li>";
	
if(
is_referer())
	
	
$this->err[] = "<li>Форма, с которой отправляется запрос, должна находиться на сервере.</li>";
	
	

	
	
if(
count($this->err)) return false;
	
	
else return 
$this->query($query);
	
}
}


//Класс "отстраничиватель"
class Pages{
private 
$startLimit$stopLimit;
	

	
//Принимает число, символизирующее количество записей, которые нужно вывести
	
function 
__construct($in){
	
$this->stopLimit $in;
	
}
	

	
//Возвращает стартовый лимит для SQL-оператора LIMIT
	
//(конечный предел объявляется при инициализации класса).
	
public function 
get_start_limit(){
	
$_GET["page"] = !isset($_GET["page"]) ? $_GET["page"];
	
if(!
$_GET["page"] = intval($_GET["page"]))
	
return 
1;
	
return (
$_GET["page"]-1) * $this->stopLimit;
	
}
	

	
//Возвращает верхний предел для цикла...
	
public function 
get_fornum($count){
	
	
return 
ceil($count/$this->stopLimit);
	
}
}


А вот гостбух:

$myGB = new gb;


if(
$_SERVER["REQUEST_METHOD"]=="POST")
{
	

	
//Очищаем ПОСТ от пробелов и слешей, если магические кавычки включены
	
$myGB->clearPost();
	

	
//Если все ПОСТ-значения верны, т.е. нет ошибок, то выполняем этот запрос
	
if(
$myGB->add("INSERT INTO gb VALUES(NULL, $_COOKIE[user_id], \'".mysql_escape_string($_POST["user_message"])."\', NOW(), \'\', 0)")){
	
//и сразу - релоад на себя
	
header("Location: ./?".time());
	
exit;
	
}
	
//Тут ошибки - красиво оформлем:
	
else 
$err "<div class=\\"alert\\">Ошибка!<ul class=\\"error_mesage\\">".implode("",$myGB->err)."</ul></div>";
}
	
$_POST["user_message"] = "";



//инициализируем класс "Отстраничиватель"
$myPages = new Pages($gb_limit);
//Получаем стартовый лимит для SQL-запроса, конечный предел - $gb_limit
$start_limit $myPages->get_start_limit();

//Получаем общее кол-во записей в "гостевой"
$count $myGB->get_one("SELECT COUNT(*) FROM gb");

$fornum[1] = $myPages->get_fornum($count);

//В массив DHTML заношу значения - записи в таблице гостевой книги
$DHTML $myGB->get_rezar("SELECT gb.user_id, user_name, user_message, date_add,
WEEKDAY(date_add) as weekday, DAYOFMONTH(date_add) as day, MONTH(date_add) as month, YEAR(date_add) as year, DATE_FORMAT(date_add, \'%H:%i:%s\') as time, user_active 
FROM gb, user_data, user_main 
WHERE  gb.user_id=user_data.user_id AND gb.user_id=user_main.user_id 
ORDER BY gb.message_id desc LIMIT 
$start_limit$gb_limit""ASSOC");

//Количество рядов в результате
$fornum[0] = $myGB->db_num_rows();

//Далее всё это (DHTML-ассив) выводим

Оффлайн Макс

  • vir magni ingenii
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3534
  • +0/-0
  • 2
    • Просмотр профиля
Помогите с ООП
« Ответ #40 : 09 Ноября 2004, 18:48:10 »
ты писал для ПХП 5 ?

По классам особо придираться не могу. По мелочам :
1. код
$this->connect(); во всех методах кроме конструктора можно убрать.

2. Классы желательно делать как можно более автономными от среды использования, поэтому желательно не использовать global-ы и самописные функции (эти самописные функции лучше определять в виде методов класса)

3. ИМХО то что класс gb наследуется от класса DB не совсем логично. То есть более правильной я считаю такую реализацию :

class GB {
......
    private 
$db null;
   function 
__construct($db) {
         
$this->db $db;
   }
   
// и внутри класса GB работать с базой
   /// $this->db->query(\'SELECT ...\');
}
// а пример использования
$db = new DB();
$gb = new GB($db);
// дальше работаешь с классом gb
 


4. ИМХО формирование INSERT-запроса на лету - более красивое решение, чем напрямую написать его в коде.
На крайний случай, можно просто в методе gb::add() в его коде прописать этот запрос. Или у тебя в метод add() могут попадать разные INSERT-запросы ?

4. зачем в Pages  $startLimit ? Вообще можно пофантазировать и сделать этот класс более функциональным
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. ( George Carrette )

Оффлайн Алексей

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 176
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите с ООП
« Ответ #41 : 10 Ноября 2004, 11:37:31 »
Ой, Максим, большое тебе спасаибо!

Только вот вопросы возникли на твои ответы:

2) Понятно. А если нужно например какие-то параметры для функции указать, например 3 целых числа? В классе их объявлять? Просто я думал, что когда все параметры в конфигурационном файле хранятся, их удобнее отслеживать и изменять...

3) хм.. интересно.. как этот приём называется? и в чем отличие от наследования? Не вижу принципиальной разницы, если честно...

4) А как это, на "лету"?
Цитировать
Или у тебя в метод add() могут попадать разные INSERT-запросы ?

нет

5)
Цитировать
зачем в Pages $startLimit ?


...LIMIT $start_limit$gb_limit...
« Последнее редактирование: 10 Ноября 2004, 11:53:56 от Алексей »

Оффлайн Макс

  • vir magni ingenii
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3534
  • +0/-0
  • 2
    • Просмотр профиля
Помогите с ООП
« Ответ #42 : 11 Ноября 2004, 17:17:31 »
2. я в одном из предыдущих постингов писал, что  единственным "глобальным" объектом в системе у меня является Регистр Объектов (и то, он не через global попадает в функции а через параметры).
Я просто создал класс Settings (настройки), который доступен через регистр объектов.
В общем, так как написал ты, тоже иногда пишут, но я считаю это плохим стилем.

3. композиция. Мне сложно написать чем отличается композиция от наследования. Что использовать композицию или наследование - этот вопрос поднимается часто, и об этом часто пишут в книгах

4. у меня в классе (см код в ЖЖ) есть метод insert - который генерирует INSERT-запрос и выполняет его. Правда я не использую встроенных mysql-функций (типа now()). С ними он работать не будет
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. ( George Carrette )

Оффлайн Алексей

  • Фанат форума
  • Постоялец
  • ***
  • Сообщений: 176
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Помогите с ООП
« Ответ #43 : 11 Ноября 2004, 17:27:22 »
Макс
Ну понятно... вообщем, спасибо тебе большое за все эти ответы!!!

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28