Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Вызов функции child-класса из другого child-класса в PHP5.

15K
10 ноября 2007 года
hel
78 / / 10.11.2007
Сравнительно недавно начал изучать классы в PHP.
Пишу сайт, построенный на классах. Хочу разделить класс на отдельные файлы, содержащие подклассы, которые должны будут отвечать за свои личные действия. Но ума не приложу, можно ли вызвать из parent-класса функцию, находящуюся в child-классе? Либо-же вызвать функцию находящуюся в child-классе из другого child-класса, объединенного одним parent-классом?
Приведу пример, где собранно всё в один файл для удобства, который собственно и нужно починить.
Код:
<?php
class Main{
    var $Template;

    function Set_Template($id){
        $this->Template=$id;
    }
}

class Main_Page extends Main{
    function Create_Main_Page(){
        if(!($text=$this->Load_Template("template/".$this->Template."/Main.tpl",$array_params)))
            return false;
        else
            return $text;
    }
}

class Main_Template extends Main{
    function Load_Template($tpl,$params){
        $tplfile=file($tpl);
        if(!is_array($tplfile))
            return false;
        for($i=0;$i<=count($tplfile);$i++){
            $text.=$tplfile[$i]; // not complete
        }
        return $text;
    }
}
$main=new Main;
$main->Set_Template("default");
echo $main->Create_Main_Page();
?>

Можно вместо $main=new Main; использовать $main=new Main_Page; - однако это тоже не поможет, все-равно надо будет вызвать функцию Load_Template из другого класса, что именно и составляет суть вопроса...
Страницы:
15K
10 ноября 2007 года
hel
78 / / 10.11.2007
Прошу прощения, задача решена, оказывается всё довольно-таки просто было... Профиксенный код выглядит так:
Код:
<?php
class Main{
    var $Template;

    function Set_Template($id){
        $this->Template=$id;
    }
}

class Main_Page extends Main{
    function Create_Main_Page(){
        if(!($text=Main_Template::Load_Template("template/{$this->Template}/Main.tpl",$array_params)))
            return false;
        else
            return $text;
    }
}

class Main_Template extends Main{
    function Load_Template($tpl,$params){
        $tplfile=file($tpl);
        if(!is_array($tplfile))
            return false;
        for($i=0;$i<=count($tplfile);$i++){
            $text.=$tplfile[$i]; // not complete
        }
        return $text;
    }
}
$main=new Main_Page;
$main->Set_Template("default");
echo $main->Create_Main_Page();
?>


Измененные участки кода по сравнению с первым скриптом:
if(!($text=Main_Template::Load_Template("template/{$this->Template}/Main.tpl",$array_params)))
и
$main=new Main_Page;
244
10 ноября 2007 года
UAS
2.0K / / 19.07.2006
Ну это конечно решение, но, по мне, так плохое.. Вот это наследование здесь вообще не нужно
15K
10 ноября 2007 года
hel
78 / / 10.11.2007
Как я уже отметил, эти классы должны быть в разных файлах, чтобы легче было их редактировать потом. Класс ведь нельзя разбить на несколько частей. Именно поэтому я применяю наследования. Главный класс с глобальными переменными, и много дочерних, каждый из которых выполняет строго поставленную функцию и находится в своем отдельном файле. А вот теперь представь, предыдущий мой проект игрового сайта, в котором класс был абсолютно нераздельным, в котором была большая куча функционала: админка, информер, регистрация, авторизация, проверка сессии... Итого 1200 строк в одном файле класса, теперь представь как среди этого безобразия найти то, что надо? Особенно когда надо добавить что-то для увеличения функционала... :(

Если есть какие-то альтернативы моему решению, постите, я для этого собственно тему и создал.
15
10 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Топикстартеру я посоветовал бы для начала почитать что такое ООП.
>>в котором класс был абсолютно нераздельным, в котором была большая куча функционала: админка, информер, регистрация, авторизация, проверка сессии...
Ты выделяешь существительные. Как правило это и есть классы. Класс != файл с функциями. Класс это есть представление сущности в жизни (например класс человек).
Теперь по поводу наследования. Наследование должно быть неким продолжением данной сущности, а не просто "мне нужен функционал этого класса, значит я его должен наследовать". Магнитола есть часть автомобиля, но она не должна наследовать класс автомобиля, а быть частью этого класса и наследовать класс "Музыка", т.к. магнитола есть ЧАСТЬ автомобиля, но она не явдяется автомобилем. От автомобиля можно наследовать "Автобус", "Грузовик" и т.д. Если ты реально хочешь в этом разобраться, то читай. Не одна книга по РНР не раскрывает сути ООП, она лишь показывает инструмент (по крайней мере я прочитал их прилично, но не понял ничего из них... может я и туповат конечно). Если реально хочешь разобраться, то попробуй изучать паттерны и UML. Так же было бы здорово ознакомится с Java или Ruby. Можешь так же поискать мои посты на форуме по поводу ООП, я думаю, что из них ты тоже сможешь что-нить подчерпнуть.
12
10 ноября 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: shaelf
Топикстартеру я посоветовал бы для начала почитать что такое ООП.


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

Так что, имхо, стоит читать не то, что такое ООП (автор это может и так пректасно знать), а именно ознакомиться с проектированием.

15K
10 ноября 2007 года
hel
78 / / 10.11.2007
shaelf:
В твоем случае - наследование это такая схема:
 
Код:
<?php
class Processor{/* глобальные свойства и характеристики процессоров*/}
class Amd extends Processor{/* свойства и характеристики процессора Amd*/}
class Pentium extends Processor{/* свойства и характеристики процессора Pentium*/}
?>


В моём же случае, наследование определяет члены (части) главного класса. Например:
 
Код:
<?php
class Human{/* глобальные свойства и характеристика человека*/}
class Leg extends Human{/* свойства и характеристика ноги человека*/}
class Hand extends Human{/* свойства и характиристика руки человека*/}
?>


Смешно, правда. :) И даже непонятно, какой-же из наших вариантов правильный... А ведь оба они по-своему логичны. :)
15
10 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Не правильно. Нога не может наследовать класс Человек. Она является состовляющей частью человека. Более правильно было бы
 
Код:
class Leg {}

class Human
{
    /**
    * @var Leg
    */

    privat $leg
}

А класс человек должен наследовать класс Ребёнок (Рабочий и т.д.).
15K
11 ноября 2007 года
hel
78 / / 10.11.2007
shaelf:
Посидел я тут денек, подумал так... и вроде начал разбираться с ООП... Если не составит труда - полистай мой скрипт, и ответь, правильно ли я понял? Думается у вас опыта больше, может совет какой дадите.
15
11 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Напиши комменты, т.к. без этого понять сложно, ибо есть несколько непонятных для меня моментов
15K
12 ноября 2007 года
hel
78 / / 10.11.2007
shaelf:
Так пойдет? Вообще, я ничего сложного не задумывал в скрипте, прямо наоборот старался. :(
А что к примеру непонятно?
15
12 ноября 2007 года
shaelf
2.7K / / 04.05.2005
 
Код:
if(!($res=$this->Mysql_Conn->query($query,MYSQLI_USE_RESULT))) // Посылаем запрос.
                return false; // Возвращаем false в случае ошибки.
            while($row=$res->fetch_assoc()){
                $Result[$pos]=$row; // записываем результат в Result[].
                $pos++; // Передвигаем позицию указателя массива на 1.
            }
            $res->close;

Никогда так не делай. Ты считаешь, что у тебя всего один запрос на страницу будет?

По поводу панели. Что значит класс "Левая панель"? Нет и не должно быть такого класса. Есть класс Template, который и должен отвечать за вывод. Так же можешь сделать класс "Block" (Action), который и будет отвечать за сборку одного блока.

При работе с БД никогда не возвращай false (в случае ошибки), а возвращай (или пиши в лог) саму ошибку.

Функции news нет и быть не может. Может быть класс News.

Для mysql и mysqli нужны разные классы.

На пока всё, детально не рассматривал, немного занят.
15K
12 ноября 2007 года
hel
78 / / 10.11.2007
1. Непонятно, почему в случае с цитируемый кодом так нельзя делать?
Эта функция посылает запрос и сохраняет результат в отдельный массив, затем освобождает результат. А массив идет по ретурну... Этот класс - своеобразный вспомогательный класс, его задача максимально автоматизировать работу с Mysql. Я вообще ничего плохого в этой функции не вижу. Я могу сделать сколько угодно запросов в БД с помощью этой функции. Если ты думаешь про разность INSERT, SELECT, DELETE, UPDATE, то это учтется в будущем. В любом случае с этим я столкнулся бы в будущем.
2. Если судить по твоим словам в этом случае класс Page тоже не должен быть, Page - часть страницы, так сказать контент сайта. Panel - панель, на которой будет меню навигации и авторизации, всё вместе почти и будет всем сайтом.
3. Конечно, в будущем у меня есть планы на счет лога (в Mysql), пока-что у меня всё на стадии изучения и тестирования.
4. Я тоже так думал, спасибо что поправил.
5. А если подумать логически, то использовать один класс лучше и легче, чем делать проверку какой класс использовать во всех местах, откуда идут запросы, подключения, и отключения, сам подумай сколько это места займет, а тут всё в несколько строчек.

А если в общем - спасибо за наводки и за замечания.
1.9K
12 ноября 2007 года
InterWen
331 / / 16.09.2006
Цитата: hel
5. А если подумать логически, то использовать один класс лучше и легче, чем делать проверку какой класс использовать во всех местах, откуда идут запросы, подключения, и отключения, сам подумай сколько это места займет, а тут всё в несколько строчек.




Не люблю за кого-то отвечать, но, ИМХО, shaelf имел ввиду немного другое.

Лично я, бегло просмотрев код класса mysql_class немного впал в ступор. Да, возможно, "использовать один класс лучше и легче", в дальнейшем даже расширив его функционал для работы с другими БД. Но неужели это необходимо делать "в лоб" через if-конструкции в одном физическом классе? Я бы, к примеру, создал один абстрактный базовый SQL-класс с декларацией необходимых методов и унаследовал от него SQL_MySQL, SQL_PostgreSQL и.т.д. Далее по месту создания экземпляра обьекта для работы с необходимой БД выбирал соответствующий класс.
В итоге получилась бы банальная "расширяемая прослойка", с единым (по возможности) для подмножества БД интерфейсом.



3 минуты спустя: [COLOR="Gray"](перечитал цитату, много думал... :) )[/COLOR]

А почему собственно "во всех местах, откуда идут запросы, подключения, и отключения"? В любом случае речь о выборе класса шла бы только при создании экземпляра (обьекта), но не при обращении к методам (если они однородны/одноименны для нескольких соотв. классов) :confused:

15
12 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Немного поясню:) (2InterWen Спасибо, что присоеденился)
1. Ты считаешь правильно после каждого запроса закрывать соеденение с БД?
2. Левая панель, правая, подвал... Да собсно положить, что это такое, их объеденяет одно - это блок странички. Чем для объекта отличается левая панель от подвала? А если ты навигацию будешь сверху делать, то будешь переделывать её в "Верхняя панель"? Класс "Навигация" может быть, Панель - нет!

3. Проехали

4. Пожалуйста

5. Кто тебе сказал, что лучше? А если потом ты туда оракл засунешь и постгрес?

PS Главной особенностью ООП является простота поддержки и доработки (ИМХО), а у тебя не объектный подход, а сборище процедур/функций которые объеденены в файл. Если хочешь понять основы, то запомни одну вещь (а лучше почитай книгу "UML за 24 часа"), каждое существительное является либо классом либо свойством класса, каждый глагол - методом. В данном случае мы имеем 2 существительных - mysql и mysqli. Это разные библиотеки, значит и классы должны быть разные.
15K
12 ноября 2007 года
hel
78 / / 10.11.2007
InterWen:
Я бы наверное так бы давно и сделал. Только вот, увы, скилла не хватает. Я сам люблю всё делать как можно более лёгким способом. Я уже много научным тыком перетыкал, пользуясь родным php мануалом, и если честно многие примеры в нём меня просто поражают... Особенно вся ветка о классах... Это каким гением надо быть чтобы понять что и как работает? Ни тебе объяснений, ни разбора примеров... Так и не мог понять, к примеру, для чего нужны интерфейсы, абстрактные классы, и многие магические методы.
Очень бы хотел почитать подробнее по классам, собсно классы моё наиболее слабое место, так как эта тема сравнительно недавно начала мною изучаться. Может посоветуйте какой-нибудь мануал, или сайт по классам?

PS: Разговор однако далеко ушёл из под сабжа... Модераторы, переименуйте тему, пожалуйста, на что-нибудь более подходящее.
15
12 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Мануал РНР не должен раскрывать ООП, а всего лишь должен показать его реализацию.
15K
12 ноября 2007 года
hel
78 / / 10.11.2007
shaelf:
1. ??!! В данном случае идёт "закрытие" объекта с результатом, коннект держится на $Mysql_Conn переменной класса и никуда не пропадает. В данном случае в конце запроса закрывается $res, которому присвоен результат запроса. Смотрим пример указанный в мануале:
 
Код:
/* Select queries return a resultset */
if ($result = $mysqli->query("SELECT Name FROM City LIMIT 10")) {
    printf("Select returned %d rows.\n", $result->num_rows);

    /* free result set */
    $result->close();
}

2. Мало что понятно, если честно из твоего объяснения. :)

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

Цитата:
Мануал РНР не должен раскрывать ООП, а всего лишь должен показать его реализацию.


Реализация без объяснения, это всё-равно что первокласнику показать уравнение из 11 класса и сказать "решай". :)
Мазохизм одним словом...

15
12 ноября 2007 года
shaelf
2.7K / / 04.05.2005
1. Да, понял. Прошу прощения. Просто не работал с mysqli.
ООП, АОП, процедурное, функциональное... Это лишь подходы к программированию. Они общие для всех и для этого существует отдельная литература.
2. Нету никакого "Главного интерфейса для управления базами данных", есть "База Данных".
PS Учи паттерны.
1.9K
13 ноября 2007 года
InterWen
331 / / 16.09.2006
(2 shaelf всегда пожалуйста)


Цитата: hel
Так и не мог понять, к примеру, для чего нужны интерфейсы, абстрактные классы, и многие магические методы.



Лично у меня, понимание этого частично пришло с необходимостью использования.
[COLOR="gray"]НЕТ, я ни кого не призываю сидеть, сложа руки и ждать озарения свыше. Та самая необходимость является следствием практики написания кода и чтения различной литературы, вне рамок официальных мануалов к средствам разработки.[/COLOR]


Цитата: hel
если сделать классы раздельными, то в сайте будет много лишних проверок на то, какой же класс использовать, именно поэтому я юзаю один класс со всеми необходимыми проверками.



А вот теперь я точно не засну.
Ну ПОЧЕМУ? В каких именно "местах сайта" будет то самое "МНОГО лишних проверок"?
Я, конечно, не отрицаю, можно наварить каши, когда при вызове каждого метода созданного экземпляра придется писать switch на 20 пунктов для каждой предполагаемой БД, но для этого, ИМХО, скилла надо куда поболее, чем для более-менее грамотной реализации :)


Цитата: hel
Реализация без объяснения, это всё-равно что первокласнику показать уравнение из 11 класса и сказать "решай". :)
Мазохизм одним словом...



[COLOR="Gray"](начинается зуд в руках; не будите во мне мастера безсмысленных аналогий :-)[/COLOR]

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

Мануал лишь приводит к сведенью де-факто существующие функции, конструкции, описывает синтаксис языка; он не в состоянии вдохновить на создание грамотно структурированной иерархии классов, научить "правильно" использовать ту или иную концепцию, подход в программировании, это, можно сказать, уже из области искусства, и тут, как уже отмечал shaelf, на помощь придут совершенно другие авторы и их "более художественные" [COLOR="gray"](в сравнении с формальным изложением мануалов, разумеется)[/COLOR] произведения.

12
13 ноября 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: hel
InterWen:
Я бы наверное так бы давно и сделал. Только вот, увы, скилла не хватает. Я сам люблю всё делать как можно более лёгким способом. Я уже много научным тыком перетыкал, пользуясь родным php мануалом, и если честно многие примеры в нём меня просто поражают...


Рекомендую почитать:
PHP 5 - объектно-ориентированный язык
Правда её почему то сейчас убрали с сайта, может временные трудности. Если что прилагаю в аппаче MHT копию.

15K
13 ноября 2007 года
hel
78 / / 10.11.2007
alekciy:
Вот это уже более-менее понятнее вроде как. Благодарю. :)

InterWen:
Ну прямо таки-обругали. Придётся поднапрячься поискать литературу, статейки по вопросу использования ООП. А то ваши объяснения слабо перевариваются моим мозгом. :)
240
13 ноября 2007 года
aks
2.5K / / 14.07.2006
Почитай Буча хоть чтоли для начала.
15
13 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Для начала?))) Мне кажется на нём всё и закончится))) Дядька рульный, но не для новичков:)
240
13 ноября 2007 года
aks
2.5K / / 14.07.2006
Э. а для кого же? Вот уж где где а у него все с азов и с картинками для самых новичков рассписанно ))
15
13 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Я ООП изучал вообще на связке паттернов + uml. UML учило выявлять потребности в классах и их деление, а паттерны их использование:))
PS В UML тоже всё в картинках)))))
240
13 ноября 2007 года
aks
2.5K / / 14.07.2006
Ну UML мне кажется стоит изучать уже имея некоторые познания в ООП, когда уже принимаешся за овладевание объектным проектированием и дизайном.

А в картинках там все только в графическом представлении конкретных диаграм. )

Опять же по UML есть хорошие книжки опять же от создателей типа Буча. )
15
13 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Значит я всё через одно место делал... :) Но мне важен результат)
PS Если честно, то начал Буча (когда начинал) - не осилил :)
PSS У каждой крепости есть несколько ходов через энное место, если их найти, то можно получить тот-же результат, но проще... Каждому своё)
15K
14 ноября 2007 года
hel
78 / / 10.11.2007
Всё-таки я люблю придерживаться стандартов... После того как я получил первый ответ на этом форуме - я понял, что принимал ООП за совершенно другое. Сейчас я уже получил некое прозрение, огромное спасибо alekciy за то что выложил отличный мануальчик по ООП и другим отписавшимся. ;)

Раньше я использовал классы как "удобный пакет с функциями", что было также неудобно использовать, как и обычным процедурным путём, сейчас уже понимаю, что сделав грамотную картину из объектов, продумать их взаимоотношение - то получится много более качественный результат, например модульная система, которая будет несложно дорабатываться сторонними разработчиками, да и сам я буду меньше путаться в коде и находить ошибки.

Мануалы с картинками мне не надо. Я не тупой вроде, просто как и всем остальным новичкам здесь - мне просто нужен пинок в нужном направлении с некоторыми пояснениями, если что-то непонятно. :)

Перейду собсно к вопросу:
Начал изучать полиморфизм и абстрактные классы. Но немного непонятно, если честно... Вроде вижу плюсы (удобочитаемость, легкое расширение, в абстрактном классе объявленны все функции, с комментариями, в результате не нужно в каждом подклассе морочится с комментами к каждому методу), но... Вопрос: как вызвать нужный объект, исходя из предпочтения пользователя? Допустим в конфиге будет переменная $dbclient='mysql', как мне основываясь на этой переменной вызвать нужный подкласс DbClient'а? Делать выборку через case чтоли? Хорошо бы получить подсказку куда надо копать. :)

Вот мой пример скрипта, для удобства привёл только один экземпляр класса DbClient:
Код:
<?php
$dbclient="mysql";
$db["DbHost"]="127.0.0.1";
$db["DbUser"]="root";
$db["DbPass"]="";
$db["DbBase"]="test";

abstract class DbClient{
    protected $DbConn;
    protected $DbHost;
    protected $DbUser;
    protected $DbPass;
    protected $DbBase;
   
    function __construct($db){
        if(!is_array($db)){
            exit();
        }
        else{
            $this->DbHost=$db["DbHost"];
            $this->DbUser=$db["DbUser"];
            $this->DbPass=$db["DbPass"];
            $this->DbBase=$db["DbBase"];
        }
    }
   
    /* Метод Connect, отвечает за соединение с базой. */
    abstract public function Connect();
    /* Метод Query, отвечает за посылку запроса в базу и запись результата в отдельный массив. */
    abstract public function Query($query);
    /* Метод Close, отвечает за закрытие подключения  с базой. */
    abstract public function Close();
   
    function __destruct(){}
}

class MysqlClient extends DbClient{
    public function Connect(){
        if(!($this->DbConn=mysql_connect($this->DbHost,$this->DbUser,$this->DbPass))){
            exit();
        }
        else{
            if(!mysql_select_db($this->DbBase,$this->DbConn)){
                exit();
            }
        }
        return true;
    }
   
    public function Query($query){
        $pos=0;
        if(!($res=mysql_query($query,$this->DbConn)))
            exit();
        while($row=mysql_fetch_assoc($res)){
            $Result[$pos]=$row;
            $pos++;
        }
        mysql_free_result($res);
        return $Result;
    }
   
    public function Close(){
        mysql_close($this->Mysql_Conn);
    }
}

function UseDbClient($object){
    if($object instanceof DbClient){
        // Операции с объектом?
    }
    else{
        exit();
    }
}
// Это понятно, напрямую вызывается нужный объект, а как вызвать
// предпочитаемый объект в зависимости от $dbclient?
$DbClient=new MysqlClient($db);
UseDbClient($DbClient);
?>
244
14 ноября 2007 года
UAS
2.0K / / 19.07.2006
Имхо надежней через case; ну или тогда на худший случай ч/з eval(); но я бы таким не пользовался бы никогда.

Или переменная
 
Код:
$class="Mysql";
include("class.".$class.".php");

// файл class.Mysql.php
$DbClient=new MysqlClient($db);

но я бы через case делал - понятней будет



и ещё одно:
Код:
<?php
$dbclient="mysql";
$db["DbHost"]="127.0.0.1";
$db["DbUser"]="root";
$db["DbPass"]="";
$db["DbBase"]="test";

abstract class DbClient{
    function __construct($db){
        if(!is_array($db)){
            exit();
        }
        else{
            $this->DbHost=$db["DbHost"];
            $this->DbUser=$db["DbUser"];
            $this->DbPass=$db["DbPass"];
            $this->DbBase=$db["DbBase"];
        }
    }


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


и ещё:
 
Код:
if(!is_array($db)){
            exit();
        }

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

Так же рекомендую почитать про try {} catch()
15
14 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Код:
<?php
interface IDataBase
{
    public function connect(array $config);
   
    public function query($sql);
}

class DB
{
    public static function getDriver($driver, array $config)
    {
        $className = 'DB_' . ucfirst($driver);
        $da = new $className($config);
        if($da instanceof IDataBase) {
            return $da;
        } else {
            throw new Exception('Драйвер должен реализовывать IDataBase');
        }
    }
}

class DB_Mysql implements IDataBase
{
    public function connect($config)
    {
        //Подклюаемся к БД
    }
   
    public function query($sql)
    {
        //что-то делаем с запросом
    }
}

//Использование
$dbo = DB::getDriver('mysql', $config);
$dbo->connect()
//И т.д.

И ещё. Абстрактный класс сделан не для того, чтобы потом комментарии не писать.
ЗЫ Про die забудь вообще. Это пережиток 4 версии. Лучше последуй совету UAS
15K
14 ноября 2007 года
hel
78 / / 10.11.2007
UAS:
1. Как я и думал... реализация только перечислением через case, ладно, покопаем, может и другие пользователи чем-то подсобят...
2. По моему мнению массив легче передавать в функцию через global, да и просто это такая привычка моя. Но если подумать, то в чем-то ты прав, для меня это может в порядке вещей, а как быть с другими программистами? Они то не знают моей чудовищной логики. :)
3. Отладочные сообщения, примитивные, с путем к методу (не бэктрейс) у меня есть. Для того чтобы они не резали глаза я их убрал перед тем как запостить код.
4. Надо почитать. Насколько я понимаю с помощью этого можно сделать бэктрейс к обнаруженной ошибке.

shaelf:
Огромнейшее спасибо за пример. Этот пример, насколько я понял, использует паттерн? Довольно понятный пример даже без комментариев. Красота. :)
Насчет абстрактного класса, его роль примерно такая-же как и в интерфейсе? Примерно улавливаю суть, но, блин, просто не могу сформулировать на примере.

Насчет die() ясно. Как я понял, мне нужно научится работать с эксепшенами и изучить try и catch.

ЗЫ: Спасибо что помогаете, такими темпами я очень скоро смогу овладеть полной базой по ООП. :)
12
14 ноября 2007 года
alekciy
3.0K / / 13.12.2005
Цитата: hel

Раньше я использовал классы как "удобный пакет с функциями", что было также неудобно использовать, как и обычным процедурным путём,


Собственно по этому поводу вспомнил высказывание: "Си программист даже на ОО языке пишет процедурно". Собственно твой пример как раз подтверждает это правило очень сильно.

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

Как говорить моя тренерша по АТ: "практикс, практикс..." :D

15
15 ноября 2007 года
shaelf
2.7K / / 04.05.2005
2alekciy АТ - Активные Телодвижения?))))
>>Насчет абстрактного класса, его роль примерно такая-же как и в интерфейсе?
Интерфейсы используются для описания чего-то, чему следует следовать (во ляпнул:)). Т.е. у тебя есть например класс log который записывает в файл. Ты можешь поступить с ним точно так же как и я с БД. Интерфейс же позволит точно гарантировать тебе, что они реализуют точно так же твой функционал (например там точно будет write(), который в зависимости от типа драйвера будет писать в ошибку в файл, бд, выводить на экран и т.д.) и ты можешь смело его применять везде. Название драйвера лучше всего вынести в конфиг и оттуда его забирать, так как в этом случае точно будешь знать, что его нужно поменять всего в одном месте. Что касается абстрактных... Фактически это те же интерфейсы, только они реализуют какой-то общий для все классов функционал... Например тебе нужно описать сотрудников фирмы. Там есть менеджеры, директора, уборщики. Все они люди и что-то делают одинаково и что-то делают своё. Ты можешь в классе Работник реализовать базовый функционал и скажем метод выполнитьРаботу. Все последующие классы должны его реализовать (этот метод), т.к. скажем ходят они одинаково, а вот работу выполнять должны разную.
240
15 ноября 2007 года
aks
2.5K / / 14.07.2006
Цитата: hel

Мануалы с картинками мне не надо. Я не тупой вроде, просто как и всем остальным новичкам здесь - мне просто нужен пинок в нужном направлении с некоторыми пояснениями, если что-то непонятно. :)


Ну если мануалы с картинками - это ты про того же Буча, то это ты зря. Это не какие то мануалы, а все же классика введения в ООП. А Буч один из старейших идеологов ООП и создателей UML.
А после осиливания рекомендовал бы почитать книжку Паттерны проектирования от банды четырех. Раз уже сейчас начинаешь видеть их красоту. )

15K
15 ноября 2007 года
hel
78 / / 10.11.2007
aks:
Ты неправильно меня понял... просто вы так говорите, будто я ничего не пойму без картинок. Мало еще видео не предложили, слава богу. :)
Мануал Буча я обязательно поищу, заинтриговали.

shaelf:
И опять-же, спасибо за объяснение. :)
240
15 ноября 2007 года
aks
2.5K / / 14.07.2006
Цитата: hel
aks:
Ты неправильно меня понял... просто вы так говорите, будто я ничего не пойму без картинок. Мало еще видео не предложили, слава богу. :)


Ну я такого не говорил ) А картинки там в тему )

244
15 ноября 2007 года
UAS
2.0K / / 19.07.2006
Таааак. Есть небольшой вопросик по интерфейсам)

Ща короче интерфейсик пишу. Проблема в следующем. Раньше просто писал что-то, наподобии:
 
Код:
interface A {
function B();
}


сейчас решил уточнить - написать типы, т.е. хочу увидеть такое:
 
Код:
interface A {
protected function B();
abstract function C();
}
Но такое делать нельзя, выдает ошибку. А хотелось бы видеть в таком виде. Намного понятней. Кто-нибдуь сталкивался с таким? Или придется в комментах к функции все так и оставлять???



Вообщем вот проблема на конкретном примере:
 
Код:
interface IBase {
    public function setHost(string $host);
}

abstract class Main implements IBase {
    final public function setHost($host) {
        $this->host=$host;
    }
}

в этом случае выдается ошибка: Fatal error: Declaration of Main::setHost() must be compatible with that of IBase::setHost(). Решается это элементарно добавлением string перед $host. Final на ошибку не влияет. Воот.

Хочется чего - чтобы в интерфейсе метод описывался как final public function setHost(string $host). Но так нельзя. И в интерфейсе может определяться только public-методы, что так же неудобно. И не указывать типы пережаваемых перменных в методе классе (ну это не обязательно).

Можно ли этого доиться? А то чет не догоню
240
16 ноября 2007 года
aks
2.5K / / 14.07.2006
А ты вобще понял зачем нужны интерфейсы? Тогда такоих вопросов бы не возникало. Интерфейс - это по сути публичное описание поведения объекта (ну блин это и есть интерфейс если вдуматься в смысл слова). Это то, что будет исспользоваться из других мест для доступу к объекту удовлетворяющему этому интерфейсу. Поэтому очевидно что методы в нем должны быть публичные, переопределяемые и соответсвенно при переопределение конечно иметь ту же самую сигнатуру.
15
16 ноября 2007 года
shaelf
2.7K / / 04.05.2005
Да, и ещё, описать тип переменной в аргуметах множно только для массива и объекта, для остальных (string, int и т.д.) это не прокатывает, он (интерпретатор) будет искать класс с таким именем.
244
16 ноября 2007 года
UAS
2.0K / / 19.07.2006
Спс) Ладно) Не все так, как хотелось бы. Но делать нечего=) Просто раньше с интерфейсами особо сильно вообще не работал

Добавлено: всё. Разобрался) Не правильно понял смысл интерфейса
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог