А это клавиатура, с помощью которой я творю...
http://kurepin.ru/php/constructor/
Rambler's Top100
Пишем на PHP: На ушко о конструкторах

Вновь хочу занять ваши мозги.

На форуме буквально только что мой тезка Руслан задал вопрос про декларации переменных и про конструкторы в PHP.

Что такое декларация (объявление) переменных? Я об этом писал в одном из первых выпусков курса. Это заявление имени переменной при помощи ключевого слова var.

var $variable_name;

PHP не станет ругаться, если вы не объявите переменную. Вернее, будет, если соответственно настроить это в конфигурационном файле php.ini (php3.ini для PHP3). Но при этом будет обрабатывать ваши переменные, если вы их не декларировали явно.

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

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

Вот так PHP не ругается:

var $variable1="123abc";


а вот так — ругается:

var $variable1="123abc";
var $variable2=$variable1;


Что делать?

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

Насколько я понимаю, PHP не обрабатывает заявления var переменна = переменная по очень просто причине: директива var предписывает транслятору выделить в памяти место под переменную. А как его выделить, когда явно не определен тип переменной и ее размер?

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

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

Вот мы и подошли к понятию "конструктор", которого раньше не касались.

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

Ну и начхать мне на этот конструктор! И вам рекомендую, если вы не теоретик, а практик.

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

Значит так!

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

Вроде бы, полезная штуковина! Запхал в этот самый конструктор все необходимые присвоения и в ус не дуй. Но не тут то было! Есть одно неудобство, которое перевешивает удобство автозапуска.

Предположим, что мы работаем с классом init, у которого есть одноименный конструктор.

В этот конструктор мы запхали все нужные присвоения и нам комфортно.

Потом мы породили от этого класса дочерний — utils, в котором тоже есть переменные, нуждающиеся в присвоении. Что делать? Пихать их в init? Абсурдно, если init — самостоятельный, используемый отдельно класс.

Значит надо создавать конструктор для класса utils? Да, другого выхода нет. Создаем.

Блямс! А конструктор init перестал выполняться после появления конструктора utils! Другими словами, он перестал быть конструктором. Что делать?

Перетаскивать данные из конструктора init в utils? Глупо, тогда init точно перестанет работать самостоятельно.

Тащить данные в обратную сторону тоже не резон, мы это заметили чуть ранее.

Остается один вариант — вызвать выполнение конструктора init из конструктора utils как обычной процедуры.

Фуу-у-у, вытерли пот со лба и продолжили работу. Создали класс sql, в котором тоже можно создать конструктор, сделать в нем свои присвоения, затем вызвать конструктор предыдущего класса.

И так далее, по древу всего проекта.

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

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

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

"Да прибью-ка я вообще эти гребаные конструкторы, какой дурак их так реализовал в PHP?".

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

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

1. Объявление глобальных переменных удобно делать в самом родительском классе. У нас это class_vars.

2. Переменные внутриклассовые надо объявлять вначале данного класса.

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

4. Все присвоения надо производить в теле процедуры, требующей эти самые присвоения.

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

Все!

Хотел написать про конструкторы только во вступлении, а получился целый выпуск.

За сим раскланиваюсь, до завтра!

P.S. Но я вам этого выпуска не писал! ;)

[шаг назад] [печатать] [в начало сайта]



copyright ©2000-2017 Ruslan Kurepin