[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Уроки PHP Урок № 1 Курс № 2 от glock18
glock18
Привет всем.
Первый урок, вводный. Весь курс будет, возможно порядка 6-8 уроков по моим внутренним ощущениям :)

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

Основные термины и понятия:
1. ООП (*)
1.1 "Три кита" ООП
- основа всего ООП. их понимание должно придти обязательно, и чем раньше, тем лучше
1.1.1 Инкапсуляция (*)
1.1.2 Полиморфизм (*)
1.1.3 Наследование (*)

1.2 Класс
- важно понимать что такое класс и объект, и чем они отличаются
Класс представляет собой тип/род/разновидность объектов (кто знаком с биологией, а именно с ботаникой/зоологией, то классом может быть выражена любая из классификаций животных/растений - семейство, царство, класс, род, вид и т.д (*))
Объект представляет собой конкретного представителя класса. в случае с зоологией, это например "лиса - представитель семейства волчьих -> рода лисьих -> вида лиса обыкновенная"

Примечание: пример с лисой представляет еще и наследование.
То есть у нас есть класс "Семейство волчьих", имеющий свои свойства.
Есть класс "Род лисьих", расширяющий свойства семейства так, как характерно только этому роду.
Есть класс "Вид лиса обыкновенная", расширяющий свойства род так, как характерно только этому виду.
Конкретно взятая лиса обыкновенная, живущая в лесу в пригороде Ахтюбинска, является объектом класса (представителем вида, рода, и одновременно семейства)

Понимание ООП дает возможность описать при помощи его средств ЛЮБУЮ систему. Пример с лисой был взят из головы за 30 секунд.

В php классы и объекты можно описывать следующими средствами:
- класс может иметь статические методы и свойства (с ключевым словом static), а так же константы (ключевое слово const), расположенные в его пространстве имен (пространства имен *).
Все классовые константы имеют модификатор видимости public (области видимости, инкапсуляция *). По назначению похожи на константы создаваемые define

- объект может иметь динамические методы и свойства (без ключевого слова static). Все, и динамические и статические, методы и свойства объявляются внутри класса, но используются так, как описано выше.
- методы, не объявленные как статические, могут использоваться как статические как бы то ни было. Но важно понимать и учитывать, что в статическом контексте указатель $this не определен.

- как правило методы используются только в одном контексте (либо статическом, либо динамическом), что является хорошим стилем (в php < 5.3 версии при использовании статически метода не объявленного с static поднимается ошибка уровня E_STRICT). E_STRICT обычно отключен, поэтому ее мало кто видит :)

- использование методов и переменных в динамическом контексте делается так:
$object = new MyClass();
$object->method();
$object->property = 'set';


- в статическом
MyClass::method();
MyClass::$property = 'set'; // обратить внимание на $
MyClass::MY_CONSTANT; // константа, объявленная в контексте этого класса


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

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

1.4 Абстрактный класс (*)
Обычно используются для того, чтобы не позволять создавать объекты класса. Это делается для того
- класс вообще не предназначен для того, чтобы создавать его объекты. иначе говоря, все его свойства и методы являются статическими.
- класс предназначен для того, чтобы наследовать у него логику другим классам.
В случае с лисой, классы "семейство вольчьих" и "род лисьих" являются абстрактными, потому что любой их представитель обязан быть представителем какого-либо вида.

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

Примечание:
класс, содержащие абстрактные методы, должен быть объявлен как абстрактный.

1.5 Наследование в php
Несмотря на то, что наследование в рамках ООП, не имеет ограничений на количество родителей, в php оно есть.
В php класс может иметь только один класс-родитель. Наследование обозначается при помощи ключевого слова extends

1.6 Интерфейс (*)
Еще одно понятие ООП. Интерфейсы как правило используются для "общения" классов друг с другом.
В правильно спроектированной системе никакой класс не должен использовать другие классы напрямую, чтобы не нарушать инкапсуляцию (*).
Интерфейс представляет собой особый вид абстрактного класса (не путать только! - он НЕ является классом).
Интерфейс не может содержать определений методов, а содержит только их объявления (название и аргументы, ничего больше).
Любой класс может реализовывать любое количество интерфейсов. Для этого используется ключевое слово implements, а интерфейсы перечисляются после него через запятую.

Пример:
Имеется класс
1. для работы с базой данных.
2. для работы с файлами.
3. представляющий сущность "новости"

имеем интерфейсы
4. сохранение данных
5. чтение данных

каждый из классов 1 и 2 может реализовывать оба интерфейса по своей логике.
в свою очередь класс 3 может использовать методы интерфейсов для чтения/записи данных.

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

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

2. Шаблоны проектирования
2.1 MVC (*)
- дополнительно Александр Кваст проводит свой курс по MVC отдельно, поэтому теорию здесь затрагивать не буду.
2.2 Синглтон (*)
2.3 Фабрика (*)
2.4 Декоратор (*)
Забыл какие-нибудь, но этого хватит.
В основном пока планирую использовать в уроках первые три паттерна.

3. "Домашка"
Как я говорил уже, каждый урок будет сопровождаться заданиями, которые нужно обязательно делать.
Этот урок вводный, и будет содержать ряд заданий на понимание концепции, приведенной выше.
Если говорить точнее, задания должны помочь вам ее понять.

3.1 написать простой класс для выборки, вставки, обновления и удаления данных в этой таблице:
create table news(
id integer not null auto_increment,
title varchar(255),
description text,
primary key (id)
)
engine=innodb default charset=utf8;


реализовать нужно простейшие варианты этих операций.
вставка, обновление и удаление записей по несколько штук делать не нужно.

3.2 продолжение задания 1. добавляем таблицу
create table article(
id integer not null auto_increment,
title varchar(255),
description text,
primary key (id)
)
engine=innodb default charset=utf8;

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

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

3.4 и снова аналогично 2 заданию. и теперь у нас должно быть три класса, как и во 2.
только при выборке должен возвращаться массив объектов.
поиск производится только через класс родитель, а в зависимости от параметра (имя сущности) возвращается массив соответствующих объектов.
логично передавать параметром имя класса (Article, например). Создавать классы можно с именем, хранимом в переменной -
$obj = new $className();

Пока свойства можно просто присваивать при выборке из базы
$obj->{$propertyName} = $value;

Работа с необъявленными свойствами все же нежелательна, но возможна. Позже мы уйдем от этого.

3.5 аналогично заданию 4. только сейчас классы перестают быть наследниками-родителями.
создаем read/write интерфейс (можно назвать readWrite или еще как), и объявляем в нем методы read и write (удивительно, не правда ли :) )

классом который до этого был родителем реализуем этот интерфейс (оба его метода).
добавляем класс для работы с файловой системой, и реализуем интерфейс для него.
классы News и Article переписываем так, чтобы они работали именно через интерфейс (через его методы то есть).
Проверить является ли переменная объектом реализующим интерфейс можно с помощью конструкции instanceof (*).
Ей так же можно проверять, является ли класс необходимым классом или его потомком (*).

4. Требования к принимаемым работам
- отступы - 4 пробела (настраивается в любом сколько-нибудь нормальном редакторе)
Я в качестве редактора использую NetBeans
- таблицы только innodb
- кодировка везде только utf8 (файлы с исходным кодом, база дата, и соединение)
- демонстрация работы кода не требуется.
- работа должна быть выполнена в одном стиле.
- пока иных требований к оформлению кода нет, но так как здесь же и формируется команда для совместной работы, то после этого урока требования к оформлению будут предъявляться.
- проверка каждой работы не должна занимать больше 5 минут. дело могут спасти смешные комментарии, но только если они по делу :)

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

5. На основании сдаваемых работ, будет определяться уровень усваивания материала.
Если усваивание будет хотя бы какое-то, то уроки будут продолжаться.

Для большинства здесь много нового, поэтому поясню:
Задания подразумевают проверку умения анализировать информацию и делать верные выводы, а так же умение быстро обучаться. Я здесь могу подтолкнуть мысль в нужном направлении.

Отвечу на вопросы по уроку в skype (wasilix).
Задания отправлять мне лично. "Куда" - тоже узнать можно в скайпе (Krevedko, дописал :) ).



Спустя 22 минуты, 18 секунд (20.11.2009 - 19:13) Krevedko написал(а):
Василий-надо как-то придумать, чтобы чужие работы не видеть. Я например хочу сам сделать. Поэтому лучше всего сделать, чтобы в течение двух недель лично тебе сдавали, а не сюда. А потом ты все выложишь с комментариями что где как

Спустя 10 минут, 9 секунд (20.11.2009 - 19:23) glock18 написал(а):
Выкладывать комментарии я не буду. буду писать их лично каждому. это домашка, а не конкурс smile.gif

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

Спустя 7 секунд (20.11.2009 - 19:23) HardWoman написал(а):
Это не конкурс - это обучение - что за фиг вам? Я хочу смотреть и с чего вопросы в личку? Не согласнаааааааа
пусть вопросы здесь - это всем полезно

Спустя 8 минут, 6 секунд (20.11.2009 - 19:31) krasilich написал(а):
Так где работы выкладывать? Лично я намеривался скинуть в скайп Василию.

Спустя 6 минут (20.11.2009 - 19:37) glock18 написал(а):
Я дописал первый пост. Задания высылать мне лично. Куда - можно узнать в скайпе.

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

Флуд буду чистить, а то в нем потом ничего по делу не найдешь.

Спустя 5 часов, 41 минута, 17 секунд (21.11.2009 - 01:18) Krevedko написал(а):
первые три вроде бы знаю как сделать. буду пробовать. остальные-надо гуглить и спрашивать ...

Спустя 12 часов, 44 минуты, 57 секунд (21.11.2009 - 14:03) Greg1978 написал(а):
Я скину свои возражения по поводу начала обучения.
Так как я сам лет так 7 назад начинал изучать другие языки (первый Assembler), я встретил ооочень умную подготовку в книге.
Она начинает разговор об размещении переменных в оперативной памяти и как разные переменные в ней определяются.
Так вот, сколько людей я не учил, вплоть до с самого нуля, проще всего перед этим ОСОБЕННО перед изучением ООП, в каком ни было языке, требуется изучить размещение и типизацию в оперативной памяти.
Что это даёт?
Вот есть у glock18 такое разъяснение внутренней ссылки $this.
Очень тяжело доганяется новичками, да и различность переменных особенно относительно класса. Пока я не обьяснял способы размещения и доступы к ним в оперативной памяти дальнейшее изучение ООП приводило к "обратной петле" - к переменным и ссылкам внутри класса. Ну и соответсвенно к "ссылкам" $this и $self.
Считаю целесообразным для начала провести краткий экскурс в ОП и привязать с подробным обьяснением переменных.
Кстати логичнее класс назвать шаблоном для создания обьекта, который иммет тип "Млекопитающее" и т.д. И из этого вытекает различие шаблона класса и конкретного обьекта и их использование. Знание работы ОП обьяснит наилучшим образом.
Это мой личный опыт, когда я слепо изучал языки программирования, в особенности ООП.
С ув. Greg1978 rolleyes.gif

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

Спустя 10 минут, 48 секунд (21.11.2009 - 14:14) glock18 написал(а):
Greg1978
Спасибо, за высказанное мнение. Вообще я согласен с тем, что размещение переменных в ОП должен знать каждый. Только это действительно нужно долго объяснять, а я упор делаю на тех, кто может из всей кучи информации поданной выше, получить максимум самостоятельно.

Спустя 3 минуты, 17 секунд (21.11.2009 - 14:17) Greg1978 написал(а):
Эту стену очень тяжело пробить.Поверьте.
Поверхностное изучение материала, особенно такого сложного как ООП и затем и паттернов, приведёт к "перегоранию программиста". Сам раз пять начинал с нуля.
Думаю для достижения цели средствами не надо разбрасываться.

Лучше мнение народа. Демократия biggrin.gif

Спустя 45 минут (21.11.2009 - 15:02) Joker написал(а):
Цитата (Greg1978 @ 21.11.2009 - 17:03)
Она начинает разговор об размещении переменных в оперативной памяти и как разные переменные в ней определяются.


Ну во первых все курсы всегда деляться на подкурсы дак вот где и как размещаються переменные это основы программирования, а этот курс направлен на ООП. Возможно вот что стоило сделать это написать какие знания уже нужны конкретно для изучения этого курса.

Спустя 5 минут, 58 секунд (21.11.2009 - 15:08) Sentox написал(а):
ООП это то же подкурс, кстати самый последний.
Согласен с Joker нужны "рекомендуемые требования".
Хотелось бы узнать немного о доступах к переменным в самой ОП.

Спустя 21 час, 55 минут, 19 секунд (22.11.2009 - 13:04) glock18 написал(а):
Объясняю смысл тем, кто еще не понял.

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

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

Касательно хранения в оп, я проведу урок. Но это будет тогда, когда я решу. А пока у вас есть задание. И это знание в нем ни к чему.

Спустя 1 час, 35 минут, 34 секунды (22.11.2009 - 14:39) Krevedko написал(а):
я пасс. вообще ничего не понимаю. даже первое не могу сделать.
наверное это не для меня dry.gif

Спустя 30 минут, 33 секунды (22.11.2009 - 15:10) JetSuit написал(а):
Добрый день. Хочу узнать у вас как у человека знающего своё дело..
С чего всё таки начать изучение ООП? Есть какие то книги посвящённые этой теме написанные в более ли менее доступной для понимания форме.
Сейчас изучаю PHP 5 по Котерову ? (Вы слышали об этом авторе ?)
Заранее спасибо за ответ ! )

Спустя 15 минут, 22 секунды (22.11.2009 - 15:25) Хозяин Огня написал(а):
По ходу "РНР5 в подлиннике" Котерова - лучший вариант для начинающих.
После следует изучиать ООП и переходить на иностранных авторов - Шлосснейгла, Фаулера...

Спустя 2 часа, 58 минут, 40 секунд (22.11.2009 - 18:24) glock18 написал(а):
JetSuit
Я изучал ООП в контексте C++ по книге Герберта Шилдта.

В пыхапэ ООП несколько отличается - в нем разобрался я уже ковыряясь в исходниках MVC фреймворка Yii.

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

Спустя 3 часа, 45 секунд (22.11.2009 - 21:25) Greg1978 написал(а):
Я изучал ООП в контексте C++ по книге Герберта Шилдта.
Весч я тоже +1

Спустя 4 часа, 55 минут, 44 секунды (23.11.2009 - 02:20) JetSuit написал(а):
Вот 3 кита ООП
http://jetsuit.freeoda.com/swf2.php

А вот классы и обьекты
http://jetsuit.freeoda.com/swf.php




Спустя 11 часов, 28 минут, 57 секунд (23.11.2009 - 13:49) glock18 написал(а):
Напоминаю всем, что у урока есть "домашка". Пока из всех мне показал только один человек свое первое задание. Желающих было порядка 15, а заданий 5.

Советую не затягивать

Спустя 37 минут, 40 секунд (23.11.2009 - 14:27) tata написал(а):
JetSuit, очень наглядно smile.gif спасибо.
Только не поняла, извините, - зачем объявлять абстрактный метод печати? Абстрактный класс должен содержать все возможные методы? Или для наглядности?
в производных классах не могут появиться дополнительные методы?

P.S.
А объект ХозяинСобаки - он является свойством класса МояСобака?
Тогда МояСобака.ХозяинСобаки.имя="Василий"? или как?

Спустя 37 минут, 13 секунд (23.11.2009 - 15:04) JetSuit написал(а):
Как я понял из прочитаного Абстрактный класс должен содержать в себе максимум методов и свойств а производные уже будут дополнять его функционал...
Поидее если метод или свойство (которое будет использовано для многих функций) можно определить в Абстрактном классе то лучше его там и определить ... Если же это свойство или метод являеться одиночным проявлением функционала конкретного обекта класса то лучше будет определить его в производном классе.
p.s Сам ещё плаваю во всём этом (так что строго не судите если не правильно изложил свои мысли )

Спустя 7 минут, 30 секунд (23.11.2009 - 15:12) glock18 написал(а):
JetSuit
Очень неплохо smile.gif Все верно подмечено smile.gif

Спустя 1 час, 27 минут, 47 секунд (23.11.2009 - 16:39) Joker написал(а):
Krevedko дак если не можешь ты попроси помощи мы же не враги это не какой то конкурс всегда откликнемся подскажем наше мнение. Когда чему то учишся в какой то группе в этом всегда есть плюсы помимо того что можно спросить у учителя можно спросить еще и у однокурсников)

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

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

Спустя 35 минут, 42 секунды (23.11.2009 - 17:15) glock18 написал(а):
всего заданий пять smile.gif извини, если это подействовало деморазилующе.

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

Спустя 11 минут, 5 секунд (23.11.2009 - 17:26) glock18 написал(а):
Это проблема всех, когда обучение только перевалило за "начало".

Всем известно, что в самом начале успехи ошеломляют ("ну да, мы же уже умеем выводить hello world и настраивать apache"). Однако, потом в любом случае следует спад. Все что нужно, чтобы избежать этого, подходить к обучение сугубо практически. Всегда обдумывать все, что содержит метку "обучающий материал", осмысливать и делать это последовательно.

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

Спустя 6 часов, 21 минута, 31 секунда (23.11.2009 - 23:48) HardWoman написал(а):
Возник вопрос - допустим есть два абстрактных класса, совершенно разные - но которые используют абсолютно одинаковые методы. Как пример можно взять ту структуру над которой мы работаем в совместном проекте.

Например создание сущности. Абстрактный класс предполагает некую модульность решения.
Возьмем, например модуль новости и модуль доска объявлений. Два абстрактных модульных класса используемых в одном приложении.
И оба используют метод создания сущности.

Тогда получается даже если создать отдельный класс методы и туда поместить имеющиеся методы получается для абстрактных классов мы будем вызывать одинаковые методы из класса Методы.
Вопрос можно ли из не производного класса вызывать методы? То есть из чужого класса? Или их можно как то копировать. А может даже и нужно?


Спустя 23 минуты, 26 секунд (24.11.2009 - 00:11) glock18 написал(а):
Почти ничего не понял smile.gif

По пунктам:
1.
Цитата
допустим есть два абстрактных класса, совершенно разные - но которые используют абсолютно одинаковые методы

говоря по делу - в чем тогда между ними разница?

2.
Цитата
Например создание сущности. Абстрактный класс предполагает некую модульность решения.
Возьмем, например модуль новости и модуль доска объявлений. Два абстрактных модульных класса используемых в одном приложении.
И оба используют метод создания сущности.

Создание сущности - конструктор и контекст в котором он вызывается. Например, метод создает сущность/несколько (паттерн фабрика), либо сам по себе конструктор?

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


можно использовать, почему бы нет? если они объявлены как public. другое дело, что иногда public их делать не очень то правильно. в C++ есть такая фича как friendly function/class, позволяющая открыть доступ к закрытым методам/членам класса другому классу/функции.

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

Спустя 16 минут, 33 секунды (24.11.2009 - 00:28) HardWoman написал(а):
Цитата (HardWoman @ 23.11.2009 - 23:48)
говоря по делу - в чем тогда между ними разница?


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


Цитата (HardWoman @ 23.11.2009 - 23:48)
Например, метод создает сущность

Да именно когда метод создает сущность. Конструктор пока не трогаем.
Некий конструктор по сути сам является классом.

И из этого класса - Конструктор - нужно вызвать один лишь метод для двух абстрактных классов.
Остальное понятно

Спустя 2 часа, 27 минут, 22 секунды (24.11.2009 - 02:55) Krevedko написал(а):
Цитата (HardWoman @ 23.11.2009 - 21:28)
Цитата (HardWoman @ 23.11.2009 - 23:48)
говоря по делу - в чем тогда между ними разница?


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

Насколько я знаю (из моих скудных)..создается три класса.
Первый класс-с этими двумя методами. И два класса, каждый из которых наследует первый + добавляются методы, присущие данному классу. Вроде как-то так.

Спустя 9 часов, 25 минут, 20 секунд (24.11.2009 - 12:20) Greg1978 написал(а):
Цитата (HardWoman @ 23.11.2009 - 21:28)
Цитата (HardWoman @ 23.11.2009 - 23:48)
говоря по делу - в чем тогда между ними разница?


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

.....

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

Спустя 11 часов, 13 минут, 55 секунд (24.11.2009 - 23:34) VolCh написал(а):
Цитата
класс должен быть абстрактным. так же, как и классы из первых двух заданий, потому что не требуют работы с сущностью, как таковой (новости и статьи возвращаются просто массивом)

Вот этот момент я не понял. Просто пустые функции в классах, без обращений к БД во всех примерах надо, или все как положено делать начиная с установки соединения? Или промежуточный вариант какой-то?

Спустя 6 минут, 24 секунды (24.11.2009 - 23:41) glock18 написал(а):
В общем, каждый метод из 1-3 заданий, работает только с текущими значениями.

Например, select получает id, возвращает массив. На этом причастность класса заканчивается.
Можно конечно, в 1-2 делать класс обычный, и создавать объект, но это совершенно не требуется. В 3 же требуется, чтобы класс был объявлен как абстрактный. Соответственно все методы должны быть статическими, и к вызовам этих методов должен быть добавлен параметр "таблица" или что-то типа этого.

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

Спустя 28 минут, 47 секунд (25.11.2009 - 00:09) VolCh написал(а):
Хм, а можно служебный класс-обертку (синглтон для закрепления теории smile.gif ) с парой публичных методов типа execute и fetch сделать для для MySQL? rolleyes.gif

Спустя 32 минуты, 59 секунд (25.11.2009 - 00:42) glock18 написал(а):
VolCh
пожалуйста smile.gif но можете не слишком усердствовать, остальные уроки тоже будут домашку иметь. постараюсь чтобы она была не менее интересной smile.gif впрочем, как я уже сказал, абсолютно не против таких вещей, хотя и не требую их.

Спустя 16 минут, 22 секунды (25.11.2009 - 00:59) VolCh написал(а):
glock18, просто самому интересно, да и копипастить код не люблю блоками smile.gif

Спустя 2 дня, 13 часов, 29 минут, 27 секунд (27.11.2009 - 14:28) glock18 написал(а):
Напоминаю участникам, что желательно сдать работы к сроку. До него осталась еще одна неделя.

Тех, кто передумал учиться здесь, прошу сообщить об этом сразу.

Свернутый текст
Следующий урок, вероятно, буду составлять не только я. И, возможно, он будет
а) полезней
б) проще


Спустя 2 часа, 28 минут, 21 секунда (27.11.2009 - 16:57) Krevedko написал(а):
если даже таким зубрам как Джокер не все понятно, то как ты думаешь, уложимся мы в две недели или нет ? blink.gif

Спустя 1 минута, 6 секунд (27.11.2009 - 16:58) Joker написал(а):
Мну зубром назвали blink.gif biggrin.gif biggrin.gif

Спустя 3 часа, 10 минут, 26 секунд (27.11.2009 - 20:08) Хозяин Огня написал(а):
Пока всё время забирает курс twin' а. Но я сто пудов возьмусь и за этот курс. Надеюсь, начну с той недели.

з.ы. скрытый текст не работает...

Спустя 7 минут, 5 секунд (27.11.2009 - 20:15) Хозяин Огня написал(а):
Я вот всё не могу понять, почему "Урок № 1 Курс № 2 от glock18", а где первый курс?

Спустя 2 часа, 7 минут, 34 секунды (27.11.2009 - 22:23) VolCh написал(а):
Курс №1 от twin'a. Сегодня, кстати тему подняли - каждому курсу отдельный подраздел - имхо, было бы удобнее

Спустя 15 часов, 29 минут, 43 секунды (28.11.2009 - 13:53) Krevedko написал(а):
Цитата (Joker @ 27.11.2009 - 13:58)
Мну зубром назвали blink.gif  biggrin.gif  biggrin.gif

ну по сравнению со мной например smile.gif


Я пока только первое задание сдал blink.gif Работку доделаю-приступлю ко второму

Спустя 21 час, 58 минут, 29 секунд (29.11.2009 - 11:51) Argnist написал(а):
А когда продолжение то?)

Спустя 1 час, 2 минуты, 3 секунды (29.11.2009 - 12:53) Joker написал(а):
когда пройдут 2 недели при условии что будут сданы дом. задания.

Спустя 28 минут, 33 секунды (29.11.2009 - 13:22) glock18 написал(а):
Argnist
в этом уроке есть задание, которое между прочим обязательно для выполнения, а не является факультативом. Следующий урок будет опубликован через 5 дней, а соответственно будет опубликована домашка и к нему, и лучше не затягивать с тем, что осталось еще по первому уроку.

Все это написано в первом посте.

Спустя 1 день, 8 часов, 58 минут, 19 секунд (30.11.2009 - 22:20) Хозяин Огня написал(а):
Цитата
но теперь делаем родительский класс, в который переносим основную логику выборки, а потомки определяют только название таблицы. пока так.


Я извиняюсь конечно, но что это значит? Нужно делать новый класс, а тот, что сделали в первом задании, становится его потомком, или как?

glock18, с первым заданием у меня получилось?

Спустя 18 минут, 35 секунд (30.11.2009 - 22:38) glock18 написал(а):
Только сейчас мыло проверил. Там нет аттача, файла то есть smile.gif

Спустя 19 минут, 15 секунд (30.11.2009 - 22:58) Хозяин Огня написал(а):
Тьфу блин. Отправил заново)

Спустя 15 минут, 25 секунд (30.11.2009 - 23:13) glock18 написал(а):
По случаю того, что последнее время мою спам-защиту многие не смогли пройти, что достаточно печально, я ее отключил на время приема работ. Подвергаю себя спаму добровольно ради того, чтобы все могли работы свои сдать smile.gif

Спустя 2 минуты, 38 секунд (30.11.2009 - 23:16) Хозяин Огня написал(а):
И да, повторю вопрос:

Цитата
Я извиняюсь конечно, но что это значит? Нужно делать новый класс, а тот, что сделали в первом задании, становится его потомком, или как?

Спустя 2 минуты, 53 секунды (30.11.2009 - 23:19) glock18 написал(а):
Хозяин Огня
теорию не почитал. потомок - родитель = наследование. с такими вопросами в асю или скайп плиз.

Спустя 7 часов, 4 минуты, 35 секунд (1.12.2009 - 06:23) VolCh написал(а):
Что-то зарылся на втором задании... примерный код

abstract class Posts {
abstract static protected function getTable();

// куча кода smile.gif

/**
* Удаляет все записи
*/

static public function deleteAll() {
//...
$query = sprintf("TRUNCATE TABLE `%s`", self::getTable());
//...
}
}

/**
* Класс для работы с новостями
*/

class News extends Posts {
static protected function getTable() {
return 'news';
}
}



News::deleteAll() вызывает ошибку Fatal error: Cannot call abstract method Posts::getTable() in .../lesson1-2.php on line 87, то есть пытается вызвать метод, описанный в Posts, а не в News, как было задумано. Если инстанцировать объект (и self заменить на $this и убрать static все), то все ОК.

Что-то ничего в голову не лезет кроме костыля в виде передачи методам параметра self из потомков, то есть что-то вроде

abstract class Posts {
abstract static protected function getTable();

// куча кода smile.gif

/**
* Удаляет все записи
*/

static public function deleteAll($self) {
//...
$query = sprintf("TRUNCATE TABLE `%s`", $self::getTable());
//...
}
}

/**
* Класс для работы с новостями
*/

class News extends Posts {
static protected function getTable() {
return 'news';
}
static public function deleteAll() {
return parent::deleteAll(self);
}
}



И то работать это будет только в PHP >= 5.3.0

Третий день сижу и никак не врубиться wacko.gif

Спустя 1 час, 52 минуты, 24 секунды (1.12.2009 - 08:16) glock18 написал(а):
VolCh
неплохо smile.gif а что мешает вместо имени класса передавать имя таблицы в родитель?

на самом деле для 5.3 можно использовать ключевое слово static вместо self так:
$query = sprintf("TRUNCATE TABLE `%s`", static::getTable());

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

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

предлагаю пока любой из вариантов - использовать фичи 5.3 или передавать в парент имя таблицы.

PS: поскольку пока нет возможности избавить от метода deleteAll в потомке, могу предложить еще использование call_user_func() внутри него - это определенного рода альтернатива обращения к методу класса, если имя является переменной.

Спустя 1 минута, 38 секунд (1.12.2009 - 08:17) Argnist написал(а):
Абстрактный метод не реализуется для класса, в котором описан, однако должен быть реализован для его неабстрактных потомков.

Спустя 40 минут, 40 секунд (1.12.2009 - 08:58) VolCh написал(а):
glock18
мешает то, что это практически третье задание будет rolleyes.gif

Argnist
это к чему? unsure.gif

Спустя 1 час, 28 минут, 18 секунд (1.12.2009 - 10:26) glock18 написал(а):
VolCh
практически, но нет. для конечного использования smile.gif

Спустя 3 часа, 28 минут, 48 секунд (1.12.2009 - 13:55) Argnist написал(а):
я тут заметил, что мой пхпмайадмин все равно сделал таблицу в MyISAM, в чем может быть проблема?

Спустя 1 день, 7 часов, 1 минута, 47 секунд (2.12.2009 - 20:57) Хозяин Огня написал(а):
Цитата (VolCh @ 1.12.2009 - 08:23)
Что-то зарылся на втором задании... примерный код

Это получается мы будем обращаться к функции deleteAll() класса-потомка? А deleteAll() в свою очередь обращается к одноимённой функции в классе-родителе?
Только не пойму что значит и какая связь между
deleteAll(self),
deleteAll($self) и
$self::getTable()

Что за параметр такой...?

Спустя 25 минут, 30 секунд (2.12.2009 - 21:22) krasilich написал(а):
Цитата (Argnist @ 1.12.2009 - 12:55)
я тут заметил, что мой пхпмайадмин все равно сделал таблицу в MyISAM, в чем может быть проблема?

Denwer?

Иди в my.cnf и закоментируй строчку skip innodb


P.S про домашку то я и забыл=(

Спустя 11 минут, 39 секунд (2.12.2009 - 21:34) glock18 написал(а):
Цитата
Только не пойму что значит и какая связь между
deleteAll(self),
deleteAll($self) и
$self::getTable()


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

Спустя 32 минуты, 53 секунды (2.12.2009 - 22:07) Хозяин Огня написал(а):
Ничего не понял, но соорудил вот что: (ошибок не показывает, но и записи не удаляет)

abstract class SecondClass
{


public $query;

function sSelect($tabname)
{
$this->query = mysql_query("DELETE * FROM ".$tabname);
}
}



class ArticleTable extends SecondClass
{
public $tabName = 'irbis_news';
public function sSelect()
{
return parent::sSelect($this->tabName);
}
}


$obj = new ArticleTable;
$obj -> sSelect();

Спустя 3 минуты, 1 секунда (2.12.2009 - 22:10) Joker написал(а):
а это для какого задания?

Спустя 32 секунды (2.12.2009 - 22:10) glock18 написал(а):
1. ошибка есть
методы не совместимы у парент и потомка
2. если создается объект, то ни к чему передавать его родителю, потому что через $this его там можно получить.
3. как следствие проще всего убрать метод sSelect из потомка. а родитель заставить использовать имя таблицы через сам объект.

Спустя 17 минут, 27 секунд (2.12.2009 - 22:28) Хозяин Огня написал(а):
Joker, задание 2...

Спустя 14 минут, 41 секунда (2.12.2009 - 22:43) Хозяин Огня написал(а):
Нет, что-то я совсем не вкуриваю(( Буду завтра читать теорию, если там ничего не найду, снова приду сюда изводить вас вопросами smile.gif

Спустя 15 часов, 27 минут, 36 секунд (3.12.2009 - 14:10) Guest написал(а):
Если я правильно понимаю, всё должно быть предельно просто - что-то вроде:

abstract class SecondClass
{


public $query;

function sSelect($tabname)
{
$this->query = mysql_query("DELETE * FROM ".$tabname);
}
}



class ArticleTable extends SecondClass
{
public function tabName()
{
call_user_func("SecondClass::sSelect",'irbis_news');
}
}


$obj = new ArticleTable;
$obj -> tabName();


Выдаёт ошибку
Цитата
Warning: call_user_func(SecondClass::sSelect) [function.call-user-func]: First argument is expected to be a valid callback in X:\home\oop.ru\www\index.php on line 54

Как правильно задать имя функции sSelect в call_user_func?

Спустя 2 минуты, 47 секунд (3.12.2009 - 14:13) Хозяин Огня написал(а):
Если я правильно понимаю, всё должно быть предельно просто - что-то вроде:

abstract class SecondClass
{


public $query;

function sSelect($tabname)
{
$this->query = mysql_query("DELETE * FROM ".$tabname);
}
}



class ArticleTable extends SecondClass
{
public function tabName()
{
call_user_func("SecondClass::sSelect",'irbis_news');
}
}


$obj = new ArticleTable;
$obj -> tabName();




Выдаёт ошибку

Цитата
Warning: call_user_func(SecondClass::sSelect) [function.call-user-func]: First argument is expected to be a valid callback in X:\home\oop.ru\www\index.php on line 54


Как правильно задать имя функции sSelect в call_user_func?

Спустя 13 минут, 39 секунд (3.12.2009 - 14:27) glock18 написал(а):
array($className, $method) |
array($object, $method);

Спустя 6 часов, 28 минут, 1 секунда (3.12.2009 - 20:55) VolCh написал(а):
И снова я понимаю, что чего-то не понимаю smile.gif

Цитата
3.4 и снова аналогично 2 заданию. и теперь у нас должно быть три класса, как и во 2.
только при выборке должен возвращаться массив объектов. поиск производится только через класс родитель, а в зависимости от параметра (имя сущности) возвращается массив соответствующих объектов.



Не могу врубиться даже в отношения этих трех классов. Вот есть класс, например, "Table", реализующий работу с таблицей. Есть у него метод readAll, читающий все строки таблицы. В 3.2 он возвращал у меня массив ассоциированных массивов. Переписать его так, чтобы возвращал массив объектов - не проблема, но... Класс Table и производные от него логически представляют собой таблицу (или коллекцию, или массив, или множество) однородных объектов. Возвращать из метода readAll массив таблиц (не строк) - ну, в принципе можно, но как-то совсем не тру не должен, по-моему, класс и так представляющий собой множество, возвращать множество своих потомков. Класс Table, по-моему, должен возвращать множество объектов Row (или его потомков), но не другие Table. По идее иерархия классов должна быть примерно такой для этого задания:

Table
+-->News
+-->Articles

Row
+-->New
+-->Article

И Table (и его потомки) работать с экземплярами Row (и его потомками)

Или я не прав в чём-то?

Спустя 7 дней, 7 часов, 33 минуты, 56 секунд (11.12.2009 - 04:29) VolCh написал(а):
Задания ещё принимаются? rolleyes.gif

Спустя 3 часа, 57 минут, 49 секунд (11.12.2009 - 08:26) glock18 написал(а):
Да, принимаются

Спустя 6 дней, 14 часов, 57 секунд (17.12.2009 - 22:27) ancient mariner написал(а):
Можно услышать замечания по этому коду? Данные записываются, выборка присходит.


class sql_query
{
var $query;
function sql_insert ($text)
{
$this -> query = $text;
mysql_query($text);
$result = mysql_query ("select * from `news`");
}
function get_query()
{
$result = mysql_query ("select * from `news`");
while ($row = mysql_fetch_assoc($result))
{
$table .= "<table><tr bgcolor=\"#E4E4E4\" height='100px'>\n";

$table .= "<td width='100px'>". $row['id']. " </td>\n";
$table .= "<td width='70px'>" .$row['title']. "</td>\n";
$table .= "<td width='400px' style='white-space:normal'><br /> <br />" .$row['description']. "</td>\n";

$table .= "</tr></table>\n";
}
echo $table;
}
}

$sql_test = new sql_query;
$sql_test -> sql_insert ("insert into `news` values ('', 'титл', 'описание текста')");
echo $sql_test -> get_query ();</span>

Спустя 1 час, 59 минут, 48 секунд (18.12.2009 - 00:27) VolCh написал(а):
А что это за код? Похож на мой служебный класс, который написал для решения заданий из этого урока smile.gif

Спустя 23 часа, 19 минут, 39 секунд (18.12.2009 - 23:47) Greg1978 написал(а):
А почему не в PHP5?

Спустя 4 дня, 15 часов, 34 минуты, 33 секунды (23.12.2009 - 15:21) A.V. написал(а):
Наконец нашлось время, чтобы вернуться сюда - к заданиям 3-4. Но опять же не могу понять кое-что.
Задание 4.
1. Мы создаём класс, в котором через функции SELECT и, допустим, mysql_fetch_assoc формируем массив с выборкой данных из таблицы БД. Так? А затем?
2. В задании сказано:
Цитата
...только при выборке должен возвращаться массив объектов. поиск
производится только через класс родитель, а в зависимости от параметра
(имя сущности) возвращается массив соответствующих объектов.


Массив всех объектов классов-потомков? Или каких объектов? И в зависимости от каких параметров?

Цитата
Создавать классы можно с именем, хранимом в переменной -
$obj = new $className();


Нужно написать некую функцию, которая бы формировала бы этот массив + возвращала бы имя класса?

Не могу понять порядок. И что именно должно быт ьна выходе функции и в классе (классах).

Спустя 1 минута, 31 секунда (23.12.2009 - 15:23) A.V. написал(а):
to glock18,

а решения первых трёх заданий от меня дошли?

Спустя 5 минут, 3 секунды (23.12.2009 - 15:28) glock18 написал(а):
A.V.
на почте не вижу. куда они должны были придти?

по 4 заданию

mysql_fetch_assoc возвращает ассоциативный массив, где ключ - имя свойства, а значение, собственно, его значение.

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

Спустя 31 минута, 13 секунд (23.12.2009 - 15:59) A.V. написал(а):
Цитата
на почте не вижу. куда они должны были придти?


На ящик, что на gmail'е. Адрес получил на номер ICQ 314004958.
Кажется, почти неделю как отправил...


Спустя 45 минут, 58 секунд (23.12.2009 - 16:45) glock18 написал(а):
A.V.
нашел, попали в спам.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.