0

Учу ООП в PHP. А зачем PHP нужны объекты? Вопрос задаю на полном серьезе. Есть запросы к базе, если охота поизвращаться с данными - есть многотомные массивы и функции которые применяются к данным перед выводом, а вот объекты зачем нужны? Может ли кто языком дилетанта, и если можно кодом описать их назначение? (Или это альтернатива чем-то?)

P.S. Вот в свое время экраны телефонов росли: 3, 4, 5... - сейчас все думаю нахрена? Вот с ООП мне пока в голову не лезет ни одна возможная ситуация, где нужны объекты в PHP. Прошу помочь встать на путь истиный.

5
  • 2
    Не удержался. Поправил текст на предмет ошибок. 23 мая 2013 в 9:27
  • 2
    @frank а что вы вообще знаете про ООП ? По комментам такое впечатление что ничего. Думаю для начала вам надо разобраться с вопросм "что?" и уже потом спросить "зачем?"
    – zenith
    23 мая 2013 в 9:48
  • Посмотрите тут: <hashcode.ru/questions/170336>.
    – VladD
    23 мая 2013 в 10:10
  • ООП - это подход к решению задачи. Можно использовать и кучи переменных, и массивы и т.д. - как вам будет проще, понятнее, что ли... Простой пример - я играю в шахматы. Играю аккуратно, строю защиту, лишний раз не рискую. Есть те, кто забывает про защиту, сразу идет в атаку. Они по-другому подходят к решению той же задачи. Могут увидеть выигрыш там, где не увижу я, т.к. они атакуют чаще. С другой стороны - они могут не увидеть проигрыш там, где вижу его я, т.к. защищаюсь я чаще. У каждого способа есть плюсы и минусы. Хорошо если знать все - больше возможностей для маневра, больше гибкости.
    – BOPOH
    23 мая 2013 в 10:26
  • чтоб не было DRY кодинга..
    – Vfvtnjd
    23 мая 2013 в 13:32

6 ответов 6

5

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

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

Решается это весьма просто. Создается класс Analyzer, либо интерфейс IAnalyzer, от которого унаследуем класс MyAnalyzer, в котором реализуем логику анализа первого набора данных, и RegionAnalyzer, в котором реализуем логику анализа второго набора данных. Контроллер соответственно, чистится от мусора, бизнес-логика выносится в отдельные бизнес-единицы - классы MyAnalyzer, RegionAnalyzer. Таким образом, контроллеру нужно теперь просто сказать, какой анализатор вызывать, и контроллер вызовет его, передав входящий набор данных. Этим самым у нас получилась в каком то роде модульность, думаю, это можно назвать инкапсуляцией данных, т.к. мы скрыли всю логику аналитики). Теперь другому разработчику достаточно реализовать какой-нибудь третий класс, и не вникать в логику контроллера, чтобы этот его класс работал так-же, как и первые два.

А для манипуляции данными, ООП тоже удобно очень тоже.

Например, у нас есть класс стол (Table), у него есть набор параметров - длина, высота. Если бы вы использовали массивы, оно бы у вас было описано примерно так:

$table = array(
'width' => 10,
'height' => 10,
'length' => 10,
);

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

$foldingTable = array(
'width' => 10,
'height' => 10,
'length' => 10,
'widthFold' => 5,
'heightFold' => 5,
'lengthFold' => 5,
);

т.е., вы напоролись на первые грабли - избыточность данных. Да, это не всегда плохо, но в данном случае это действительно плохо.

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

Теперь представьте, вам необходимо создать 5 экземпляров столов. Да, используя массивы это решается обычным присваиванием:

$tables = array();
for($i=0; $i<5; $i++)
{
    $tables[] = $table;
}

Ясно и просто, но не очень красиво. Давайте теперь добавим метод складывания стола в массив:

$foldingTable = array(
'width' => 10,
'height' => 10,
'length' => 10,
'widthFold' => 5,
'heightFold' => 5,
'lengthFold' => 5,
'isFold' => false,
'fold' => function($table){/* some logic here */},
);

Вызовим его теперь:

$foldingTable['fold']($foldingTable );

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

Давайте теперь сделаем все это, используя ООП:

class Table{
    public $width = 10;
    public $height = 10;
    public $length = 10;
}

Создаем складной стол:

class FoldingTable extends Table{
    public $widthFold = 5;
    public $heightFold = 5;
    public $lengthFold = 5;
    public $isFold = false;

    public function fold()
    {
        if($this->isFold) return false;
        $this->fold = true;
        return true;
    }
}

Теперь сложим стол:

$table = new FoldingTable();
$table->fold();

По сравнению с массивами очень симпатично получилось и вполне читаемо. Мы теперь можем создавать столько столов, сколько нам потребуется, поскольку метод fold является методом класса, нам не нужно в нем контроллировать входящие данные, потому что этот метод гарантированно вызывается из объекта $table типа FoldingTable

Таким образом, можно вполне просто инкапсулировать в объектах доступ К БД. Например, хранить состояние переменной $isFold в БД, а в методе $fold делать запрос к БД, и по результатам запроса уже производить, или не производить какие-то манипуляции.

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

Простите за сумбурность.

3

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

3
  • я вот в свое время на хэшкоде вычитал что такое репликация mysql, думал нужно покупать басейн и плавать в книгах по mysql - в итоге оказалось, что это вроде синхронизации. Так же и по объектам, думал, что то простое скажете. Сейчас думаю, что это какая то замена массива
    – frank
    23 мая 2013 в 9:37
  • 1
    Задачи разные. Массивы - это чисто хранение данных. Объекты вполне могут выполнять эту функцию. Например, синглтон исключительно для этого используется. Однако, уже здесь есть разница. Попытка обновить данные в синглтоне (объекте) окончится неудачей, тогда как данные в массиве затираются легко. Едем дальше. Объекты включают помимо данных методы - функции, характерные исключительно для них. Т.е. сущности в рамках вашего кода разведены и не мешают друг другу. 23 мая 2013 в 9:51
  • Вот это ответ! Хотя методы - на моем языке те же функции, которые прячутся в отдельный файл и не капают на мозги
    – frank
    23 мая 2013 в 9:55
3

ООП в первую очередь средство писать большие проекты, а все остальное: объекты, классы, инкапсуляция, наследование - это следствие этого.

Отсюда вывод: вы просто не писали большие проекты, как только начнете писать большой проект с каким-нить разумным resubility кода - сразу на своей шкуре поймете, что без ООП никуда.

1

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

Например, у нас есть сущность - "машина" и нам надо хранить ее "запчасти" в бд. Их очень много. (Дальше идет архитектура, от каждого своя, можно все детали хранить в одной таблице, можно их группировать по странам, автопромам, типам деталей, маркам машин), но предположим, что все детали храним в одной таблице (колонки: часть1, руль, колеса, часть4, марка машины и еще 20 колонок), соберем с этого машину. Как это сделать в пхп без ооп?

7
  • @Gorets, можно пример? Мне всю жизнь казалось с этим справиться поименованный массив
    – frank
    23 мая 2013 в 9:31
  • // Создаем объект и добавляем некоторую информацию $myCar = new Car(); $myCar->setModel('Ford')->setMark('Focus')->setProdData('2013'); // Читаем информацию $myCar->getInfo('all'); 23 мая 2013 в 9:34
  • @frank, я не умею программировать :) просто хочу посмотреть как ты решишь эту задачу без объектов, вариант @Khvorostin c объектом, вроде бы понятен
    – Gorets
    23 мая 2013 в 9:39
  • не хочу придираться, наоборот хочу понять, почему то, что написал @Khvorostin нельзя сделать так: $arrayCar = array('Ford','Focus','2013'); echo implode(', ',$arrayCar);
    – frank
    23 мая 2013 в 9:52
  • 1
    @frank, а хотя бы потому, что фиг пойми в вашем примере, что за данные входят в массив. Если здесь еще можно догадаться, то при наличии числа дверей и числа подушек безопасности подобный массив становится бесполезным. Ассоциативный массив бы исправил ситуацию. Однако при добавлении новых компонентов вам придется перепроверять весь код, а вот объект с методами-перехватчиками __set() и __get() править не придется. Собственно методов setModel(), setMark()... может и не быть. 23 мая 2013 в 10:05
0

Привет Frank.

Еще 3 недели назад я бы тоже мог задать такой же вопрос тут.

За эти 3 недели я увидел некоторые плюсы:

  1. Методы (Функции) можно структурировать в класс Если у тебя раньше был набор функций для работы со строкой, то сейчас объедени его в класс.

  2. Это может позволить тебе делать такие конструкции:

    $str = new CStr(' Как дела %user%!? '); $array = $str->trim()->replace('%user%','Ваня')->explode(',');

  3. Из функции (метода) можно делать не просто "return true", но и возвращать кое какую инфу Пример

if ($e->ifIsArray('string'))

print 'Да, это массив';

else

print 'Жаль, но это '.$e->getRealType();

За 3 недели больше плюсов не увидел. А как утверждают, то в ООП есть и более вкусные вещи.

Моя личная рекомендация: Только после написания кода я смог сделать какие то вывод об ООП. Все что было в теории, это только разговоры. Если лень читать (как мне), то просто посмотри видео про ООП. Лично после просмотра, я начал писать с нуля какие то задачки, чтобы понять ООП на практике.

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

Просто начни практику и почувствуешь новые возможности PHP.

0

Объекты нужны не PHP, а разработчикам. И нужны они для того, чтобы проще модифицировать код. Дело в том, что как только программа перестаёт помещаться целиком в мускулистом мозгу программиста, ему приходится переключаться между разными частями программы, снова и снова понимать уже написанный код. При таком переключении очень легко запутаться даже в собственном коде. Всё становится ещё хуже, если над проектом работают несколько разработчиков, а часть кода была написана 2 года назад.

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

На самом деле вы уже используете объекты, когда пишите на PHP в процедурном стиле. Взгляните на название функций для работы с mysql: mysqli_connect, mysqli_query, mysqli_stmt_fetch и так далее. Глядя на них, вы понимаете что это про базу данных. Вам не надо гадать что это за query, он из подключенной вами библиотеки или вы определили его сами на 100500 строке этого файла. Благодаря префиксу mysqli_ вы объединяете все эти функции в группу относящуюся к одному объекту. Пока вы не пользуетесь средствами ООП, предоставляемыми языком (типа классов), но ваш мозг уже воспринимает эти функции как имеющие что-то общее.

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

$sth1 = mysqli_prepare($db1, 'select * from `books`;');
$result1 = mysqli_stmt_execute($sth1);
$sth2 = mysqli_prepare($db2, 'select * from `readers`;');
$result2 = mysqli_stmt_execute($sth2);

Обратите внимание на суффиксы 1 и 2, это естественная попытка разделить переменные на относящиеся к одному объекту и к другому. Эти объекты существуют прежде всего в уме разработчика, но средства ООП помогают выразить в коде эти мысли более ясно.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.