Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Разное

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Зачем нужны классы?
 
 автор: darkozoid   (05.06.2013 в 09:58)   письмо автору
 
 

Вот все смотрю на них, читаю, но не могу понять зачем они нужны....
это же просто функции которые можно вызвать с определенными параметрами... так?
тогда зачем они нужны? какие преимущества у них перед функциями?
Я скорее всего ошибаюсь в силу незнания, но кто нибудь может мне на пальцах объяснить зачем они нужны (можно с банальными примерами)

Только поймите правильно, это форум, и в этой теме я хотел бы устроить дискуссию, а не просто получить в ответ ссылку на php.su или google.com.
Хотелось бы пообщаться со знающими людьми, понабраться знаний и опыта так сказать )

  Ответить  
 
 автор: psychomc   (05.06.2013 в 10:45)   письмо автору
 
   для: darkozoid   (05.06.2013 в 09:58)
 

хоть какую-то теорию знаете? читали что такое ООП и какие его основные принципы?
*с этой проблемой сталкиваются очень многие, тут очень нужна практика

  Ответить  
 
 автор: darkozoid   (05.06.2013 в 11:34)   письмо автору
 
   для: psychomc   (05.06.2013 в 10:45)
 

чуток знаком, даже написал 1 класс для подключения к БД и выполнение sql запроса, корявенько конечно, но для первого раза достаточно того, что он работает )) код приводить не буду - стыдно )))
Практика нудна - сомнений нет, но если у меня есть какая то задача, то я просто не представляю можно ли решить ее классами или нет и как это сделать, и решаю по старинки. Как следствие - практики 0.

Я бы сходил на курсы, но работая на 2 работах просто некогда, а так как работа моя связана именно с web программированием, то хотелось бы как то научиться...

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

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

Может подкинете простецкую задачку?

  Ответить  
 
 автор: cheops   (05.06.2013 в 22:10)   письмо автору
 
   для: darkozoid   (05.06.2013 в 11:34)
 

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

Более того, нужно не просто решать такие задачи, нужно выдумывать самим, попробуйте помимо пользователей придумать задачу в которой будет несколько объектов, у которых с одной стороны должны быть одинаковый набор методов, а с другой - отличающийся и написать иерархию классов так, чтобы каждый метод встречался только один раз без дублирования. После этого изучение ООП у вас пойдет гораздо веселее.

  Ответить  
 
 автор: darkozoid   (06.06.2013 в 09:11)   письмо автору
 
   для: cheops   (05.06.2013 в 22:10)
 

окей,
Например простая форма входа.
для всех одинаковая, но в зависимости от ранга пользователя будет перемещать его (в случае удачного входа само собой) на различные страницы (кабинет пользователя - для рядового, админка - для админа, Статистика - для сеошника ) - ну или как то так...

Я правильно понял мысль?
и вот тут возникает несколько вопросов....
Создал я класс который в конструкторе получает данные конфига
в нем метод для создания формы входа,
метод проверки данных
и метод для перенаправления на нужный нам раздел в зависимости от ранга...
ну и метод вывода ошибок...

Метод перенаправления получает переменную в которой говорится куда перенаправлять (имя страницы) - берется из базы данных
вопрос 1: как мне пренаправить пользователя на страницу которой фактически нет.
Поясняю
при входе на www.site.ru/test/ - мы попадаем на www.site.ru/index.php и вызываем метод, который выводит данные из некой таблицы БД в поле URL (например) стоит test.
При входе на на www.site.ru/art/ - мы попадаем на www.site.ru/index.php и вызываем метод, который выводит данные из некой таблицы БД в поле URL (например) стоит art.

при этом адрес в браузере должен быть без всяких переменных и index.php

И тот же метод, после авторизации, будет выводить данные для пользователя...

Очень запутал? вот такая вот каша в голове ))

  Ответить  
 
 автор: cheops   (06.06.2013 в 20:48)   письмо автору
 
   для: darkozoid   (06.06.2013 в 09:11)
 

Хранение, обработка формы и представление - это должны быть разные классы. Не нужно все сваливать в один класс, получится сложно, запутанно, а ООП-интерфейсом наоборот должно быть легко пользоваться.

  Ответить  
 
 автор: darkozoid   (07.06.2013 в 09:23)   письмо автору
 
   для: cheops   (06.06.2013 в 20:48)
 

Ладно возьмем попроще пример... класс для запроса select в базу

class main{
  function __construct(){
    require_once"config.php"; // тут устанавливаем константы для доступа к базе
  }
}

class db extends main{
  var base;
  function connect(){
    $base=mysql_connect(_HOST_, _USER_, _PASS_) or die("MySQL сервер недоступен!".mysql_error());
    mysql_select_db(_DB_, $base) or die("Нет соединения с БД".mysql_error());
    $this->base=$base;
  }
  function close($base){
    mysql_close($base);
  }
  function select($sql){
    $this->connect();
    $result=mysql_query($sql);
    $this->close($this->base);
  }
}


какие я допустил ошибки?
не проверял работоспособность, но писал бы именно так...

P.S. тот класс о котором я говорил раньше (который я написал) далеко не такой...

  Ответить  
 
 автор: Sfinks   (07.06.2013 в 10:17)   письмо автору
 
   для: darkozoid   (07.06.2013 в 09:23)
 

Во-первых, класс БД - это классический пример шаблона проектирования Синглтон (Singleton).
Т.е. он в пределах одного вызова скрипта имеет только один экземпляр.

Во-вторых подключение к БД в таком классе производят при созданн, т.е. в функции __construct()

Комбинация 1-го и 2-го позволяет избежать множественных подключений к БД. У вас же при каждом вызове select() создается новое подключение. Это грубейшая ошибка!

Еще недодумка в том, что вы используете ООП, но почему-то игнорируете встроенный класс для работы с MySQL - mysqli. Логично было бы:
class main extends mysqli{}


При этом вы переопределите метод __construct() родителя, значит не забудьте вызвать
parent::__construct()


И не забывайте писать public, private и т.п.
var base - тоже интересно.

  Ответить  
 
 автор: darkozoid   (07.06.2013 в 11:27)   письмо автору
 
   для: Sfinks   (07.06.2013 в 10:17)
 

>Во-первых, класс БД - это классический пример шаблона проектирования Синглтон (Singleton).
>Т.е. он в пределах одного вызова скрипта имеет только один экземпляр.
>
>Во-вторых подключение к БД в таком классе производят при созданн, т.е. в функции __construct()
>
>Комбинация 1-го и 2-го позволяет избежать множественных подключений к БД. У вас же при каждом вызове select() создается новое подключение. Это грубейшая ошибка!
>

Я раньше (еще без всяких классов) тоже подключался к базе в начале скрипта и отключался в конце, но потом где то прочитал, что это плохо при большом трафике, и что лучше часто подключатся но на короткое время, чем 1 раз но надолго... что то связано с лимитом пользователей

>Еще недодумка в том, что вы используете ООП, но почему-то игнорируете встроенный класс для работы с MySQL - mysqli. Логично было бы:
>
class main extends mysqli{}

>
с mysqli я еще тоже не очень знаком... так что учту...
а по поводу того, чтобы main расширял mysqli я бы и не догадался

>При этом вы переопределите метод __construct() родителя, значит не забудьте вызвать
parent::__construct()

>
Ну предположим, что это я подразумевал делать на странице с которой передавал бы запрос
что то типа
$obj=new main; $obj->select($sql);

соответственно и конструктор должен был запустится сам

>И не забывайте писать public, private и т.п.
с этим я еще путаюсь...

>var base - тоже интересно.
в каком смысле? что не так?

  Ответить  
 
 автор: Sfinks   (07.06.2013 в 12:42)   письмо автору
 
   для: darkozoid   (07.06.2013 в 11:27)
 

> Я раньше (еще без всяких классов) тоже подключался к базе в начале скрипта и отключался
> в конце, но потом где то прочитал, что это плохо при большом трафике, и что лучше часто
> подключатся но на короткое время, чем 1 раз но надолго... что то связано с лимитом
> пользователей

Если у вас в скрипте производится одна большая выборка, а потом несколько секунд обрабатывается результат, то так и есть.
Но в подавляющем большинстве случаев, т.е. когда весь скрипт выполняется сотые доли секунды и за это время производится пара десятков запросов - это ошибка. Дело в том, что сама операция подключения довольно медленная и требовательная. Нужно подключиться, проверить логин/пасс, проверить привилегии, и т.п.... И это будет происходить при каждом из нескольких десятков запросов. Не уверен, что сервер от этого станет свободнее.

> Ну предположим, что это я подразумевал делать на странице с которой передавал бы запрос
что то типа
$obj=new main; $obj->select($sql);
> соответственно и конструктор должен был запустится сам

На это вы просто получили бы fatal error, поскольку у класса main нет метода select.

> > var base - тоже интересно.
> в каком смысле? что не так?

Я уж не помню, может в PHP 4 так и было, но сейчас используют:
<?php
public $id;
private static 
$base;
protected 
$name;
// и т.п.

  Ответить  
 
 автор: darkozoid   (07.06.2013 в 13:11)   письмо автору
 
   для: Sfinks   (07.06.2013 в 12:42)
 

>Если у вас в скрипте производится одна большая выборка, а потом несколько секунд обрабатывается результат, то так и есть.
>Но в подавляющем большинстве случаев, т.е. когда весь скрипт выполняется сотые доли секунды и за это время производится пара десятков запросов - это ошибка. Дело в том, что сама операция подключения довольно медленная и требовательная. Нужно подключиться, проверить логин/пасс, проверить привилегии, и т.п.... И это будет происходить при каждом из нескольких десятков запросов. Не уверен, что сервер от этого станет свободнее.
>
Спасибо за пояснение... больше не буду так делать...

>> Ну предположим, что это я подразумевал делать на странице с которой передавал бы запрос
> что то типа
$obj=new main; $obj->select($sql);
> соответственно и конструктор должен был запустится сам

>На это вы просто получили бы fatal error, поскольку у класса main нет метода select.
>
логично )
ну а если так
$obj=new main; $db::select($sql);

то конструктор будет запущен? или мне надо обратится к какому то методу в этом классе (или к самому конструктору)???

>Я уж не помню, может в PHP 4 так и было, но сейчас используют:
<?php
>public $id;
>private static 
$base;
>protected 
$name;
>
// и т.п.


просто где как написано... где то var $i? а где то public $i
а var $i уже не работает? или просто устарело?

  Ответить  
 
 автор: Sfinks   (07.06.2013 в 13:45)   письмо автору
 
   для: darkozoid   (07.06.2013 в 13:11)
 

> ну а если так
$obj=new main; $db::select($sql);
>то конструктор будет запущен? или мне надо обратится к какому то методу в этом классе
>(или к самому конструктору)???


Создавать нужно не предка, а потомка.
Если вы выполните:
$obj=new db();
$obj->select($sql);
то в таком виде, как у вас написано выше, все выполнится. Но только потому, что в классе db метор __construct() не переопределен. Поэтому будет вызван метод предка.
делать так, как я писал выше, то должно быть примерно так.
<?php
  
class db_config extends mysqli{
    public function 
__construct(){
      require_once(
'config.php');
      
parent::__construct(_HOST__USER__PASS__DBNAME_);
    }
  }
  class 
db extends db_config{
    public function 
select($sql){ 
      return 
$this->query($sql);
    }
  }
  
$db = new db();
  
$db->select('......');
Пишу в браузере, возможны опечатки =)
И это все без использования паттерна синглетон. С ним будет еще немного по другому.

>а var $i уже не работает? или просто устарело?
Я не помню работает или не работает, но в любом случае - это не "просто устарело". Все что устарело, рано или поздно удалят. Поэтому лучше этим не пользоваться.

  Ответить  
 
 автор: darkozoid   (07.06.2013 в 15:27)   письмо автору
 
   для: Sfinks   (07.06.2013 в 13:45)
 


<?php 
  
class db_config extends mysqli
    public function 
__construct(){ 
      require_once(
'config.php'); 
      
parent::__construct(_HOST__USER__PASS__DBNAME_); 
    } 
  } 
  class 
db extends db_config
    public function 
select($sql){  
      return 
$this->query($sql); 
    } 
  } 
  
$db = new db(); 
  
$db->select('......');

  return $this->query($sql); 

query($sql) это же не в этом классе, а в родительском? почему $this ???

  Ответить  
 
 автор: Sfinks   (07.06.2013 в 16:57)   письмо автору
 
   для: darkozoid   (07.06.2013 в 15:27)
 

Это называется наследование. Я не мастер теории, поэтому могу только посоветовать читать....

  Ответить  
 
 автор: darkozoid   (07.06.2013 в 17:40)   письмо автору
 
   для: Sfinks   (07.06.2013 в 16:57)
 

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

class a{
public $var;
  function __construct(){
    $this->var='что то очень важное и часто нужное';
  }
  function sd(){
    .....
  }
...
}
class b extends a{
....
}
// потом еще куча кода в котором так сразу и не найти $var 
class n extends a{
  function name($str){
    $this->var=$str;
  }
....
}
class nn extends a{
  function name(){
    print $this->var;
  }
....
}


a::sd; // $var = то что нужно
n::name; // $var = что то новое
nn::r; // $var уже совсем не то что надо


вот если как то так сделать, то переменная var будет перезаписана, и при дальнейшем наследовании ее значение будет уже не тем что нужно... как этого избежать можно?
или я опять не прав где то?

  Ответить  
 
 автор: Гость   (07.06.2013 в 19:03)   письмо автору
 
   для: darkozoid   (07.06.2013 в 17:40)
 

Наследование работает не так как вы думаете. Попробуйте сами свой пример на практике.

  Ответить  
 
 автор: darkozoid   (10.06.2013 в 09:19)   письмо автору
 
   для: Гость   (07.06.2013 в 19:03)
 


<?
class a
public 
$ar
  function 
__construct(){ 
    
$this->ar='что то очень важное и часто нужное'
  } 
  function 
sd(){ 
    print 
$this->ar.".....A::sd<br>"
  }  

class 
extends a
  function 
name($str){ 
    
$this->ar=$str
        print 
$this->ar;
  } 

class 
nn extends a
  function 
name(){ 
    print 
$this->ar
  } 


$obj1=new a;
$obj1->sd(); // $ar = что то очень важное и часто нужное
$obj2=new n;
$obj2->name("что то другое<br>"); // $ar = что то другое
$obj3=new nn;
$obj3->name(); // $ar = что то очень важное и часто нужное
?>


Хм... действительно значение осталось исходным...

тогда возникает вопрос, а как же ее (переменную) можно поменять, так, чтобы она наследовалась с новым значением?

и второй вопрос:
Почему
$obj3=new nn;
$obj3->name(); // $ar = что то очень важное и часто нужное

работает, а

nn::name(); 

нет?

  Ответить  
 
 автор: cheops   (10.06.2013 в 21:29)   письмо автору
 
   для: darkozoid   (10.06.2013 в 09:19)
 

Под новые вопросы лучше заводить новые темы - и ответов будет больше и искать потом вам и другим посетителям будет проще.

  Ответить  
 
 автор: darkozoid   (11.06.2013 в 08:53)   письмо автору
 
   для: cheops   (10.06.2013 в 21:29)
 

окей
http://www.softtime.ru/forum/read.php?id_forum=2&id_theme=89689&page=1

  Ответить  
 
 автор: Гость   (07.06.2013 в 17:10)   письмо автору
 
   для: darkozoid   (07.06.2013 в 15:27)
 

Тебе нужно сперва подтянуть теорию. По поводу разработки класса для работы с бд могу привести очень хороший пример (сам более-менее начал разбираться и понимать ООП после знакомства с книгой). Как обычно рекомендую книжку :) (ну ведь если помогло мне, значит может помочь и вам). "Профессиональное программирование на PHP", автор Джордж Шлосснейгл. Там на первых ста страницах много полезной теории, а главное как пример создается класс для работы с БД, причем все очень хорошо объяснятся - что и зачем делается и как это помогает в работе с кодом в дальнейшем. Книжку найти можно на рутрекере (я счас без проблем загуглил)

  Ответить  
 
 автор: darkozoid   (07.06.2013 в 17:41)   письмо автору
 
   для: Гость   (07.06.2013 в 17:10)
 

Голова моя лопнет )))
спасибо за совет, дельная книга - это хорошо

  Ответить  
 
 автор: darkozoid   (05.06.2013 в 11:34)   письмо автору
 
   для: psychomc   (05.06.2013 в 10:45)
 

упс, случайный дубль... прошу прощения

  Ответить  
 
 автор: cheops   (05.06.2013 в 10:57)   письмо автору
 
   для: darkozoid   (05.06.2013 в 09:58)
 

Это не просто набор функций, это связанный набор данных, над которыми работают функции.

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

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

PS PHP не самый удачный язык для знакомства с объектно-ориентированным подходом (он тут урезан, и не очень удачно реализован, так как вводился уже после того, как язык сложился).

  Ответить  
 
 автор: darkozoid   (05.06.2013 в 11:37)   письмо автору
 
   для: cheops   (05.06.2013 в 10:57)
 

>PS PHP не самый удачный язык для знакомства с объектно-ориентированным подходом (он тут урезан, и не очень удачно реализован, так как вводился уже после того, как язык сложился).

мне то как раз и надо именно в PHP... работа зависит от знаний... особо глубоких не нужно, но хотя бы понимать и уметь работать все же надо... Хотя бы для себя )

  Ответить  
 
 автор: cheops   (05.06.2013 в 22:12)   письмо автору
 
   для: darkozoid   (05.06.2013 в 11:37)
 

Ну ничего страшного, можно и с PHP, только помните, что реализация ООП в нем не есть вершина совершенства и что только такой ООП и должен быть...

  Ответить  
 
 автор: Гость   (06.06.2013 в 14:08)   письмо автору
 
   для: darkozoid   (05.06.2013 в 09:58)
 

У меня была точно та же проблема, когда я начинал познавать ООП. Вроде и понятно как работает, а вот зачем это на практике нужно - представить сложно. С опытом пришло и понимание, мне кажется что примеры, которые вы хотите увидеть - это паттерны. В связи с этим могу порекомендовать книжку "паттерны проектирования" Эрика и Элизабет Фримен. Она не привязана не к какому конкретному языку программирования (хотя примеры кода там на java) и служит отличной иллюстрацией чего можно добиться используя ООП. Возможно книжка написано в несколько "легкомысленном" стиле, но как по мне это идет ей только на пользу.

ссылка на книжку на озоне: http://www.ozon.ru/context/detail/id/20216992/

  Ответить  
 
 автор: darkozoid   (06.06.2013 в 15:18)   письмо автору
 
   для: Гость   (06.06.2013 в 14:08)
 

Спасибо за совет, почитаю на досуге )

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования