Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> callback, не могу разобраться 
:(
    Опции темы
SqueeZe
Дата 8.1.2008, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Здравствуйте. 

Разбираюсь сейчас с обратными вызовами (callback) в php. И не очень понимаю, для чего его нужно использовать!?

В книге "PHP5 для профессионалов (Новицки, Коув)" он используется для реализации позднего инстанцирования в классе Collection.
Но в том примере я считаю можно обойтись и без него... (но видимо ошибаюсь smile ). Поэтому хочу попросить привести какой-либо пример, четко и просто описывающиее его, callback'а, применение.

Спасибо.
PM MAIL ICQ   Вверх
Daevaorn
Дата 8.1.2008, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: нет
Всего: 70



PM MAIL WWW   Вверх
vasac
Дата 8.1.2008, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1060
Регистрация: 4.5.2006

Репутация: 8
Всего: 36



PM WWW   Вверх
SqueeZe
Дата 8.1.2008, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



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

Либо я дурак...  smile 

Это сообщение отредактировал(а) SqueeZe - 8.1.2008, 17:37
PM MAIL ICQ   Вверх
flashaa
Дата 8.1.2008, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 19
Всего: 25



Цитата(SqueeZe @  8.1.2008,  17:19 Найти цитируемый пост)
Поэтому хочу попросить привести какой-либо пример, четко и просто описывающиее его, callback'а, применение.

Применений может быть очень много, поэтому четкое применение его callback'а сформулировать сложно - вообщем, это сделано для гибкости, чтобы можно было вызвать исполнение ф-ции, зная её имя, при этом чтобы можно было сократить код.
Элементарный пример:
Код

$array = array(...); // есть какой-либо массив
$array = array_filter($array, 'trim'); // отфильтровываем элементы, состоящие только из пробелов. trim - саllback ф-ция

PM MAIL   Вверх
SqueeZe
Дата 8.1.2008, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



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

Меня интересует организация позднего инстанцирования методом обратного вызова.

// Многократные извинения за неправильно заданный вопрос.
PM MAIL ICQ   Вверх
flashaa
Дата 8.1.2008, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 796
Регистрация: 7.3.2006

Репутация: 19
Всего: 25



Цитата(SqueeZe @  8.1.2008,  17:58 Найти цитируемый пост)
Меня интересует организация позднего инстанцирования методом обратного вызова.

Читал я эту книгу, ту,которую описали в первом посте, сейчас оставил на работе.. С завтрашнего дня снова буду там (до свидания, выходные :( ), открою эту главу и вспомню, если будет ещё актуально, отпишусь.
PM MAIL   Вверх
SqueeZe
Дата 8.1.2008, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



О! До меня кажется доперло!!!

Сейчас приведу 2 примера. 1й - без использования обратного вызова, 2й - с использованием. 

1й
Код

<?php

class A 
{
    public $a;
    
    function __construct()
    {
        $a = new Collection();
    }
    
    function load() 
    {
        print 'Здесь получаем инфу из базы и пишем в Collection';
        $a->addItem(new B(1));
        $a->addItem(new B(2));
    }
}

class B
{
    public $b;
    
    function __construct($c)
    {
        $this->b = $c;
    }
}


$aa = new A();

$aa->load(); // чтобы вывести далее количество элементов, используем этот метод.

print $aa->a->length(); // выводит кол-во элементов

?> 


И 2й
Код

class A 
{
    public $a;
    
    function __construct()
    {
        $a = new Collection();
        $a->setLoadCallback('load', $this); // Говорим, что перед вызовом любого метода типа length нужно подгрузить инфу
    }
    
    function load() 
    {
        print 'Здесь получаем инфу из базы и пишем в Collection';
        $a->addItem(new B(1));
        $a->addItem(new B(2));
    }
}

class B
{
    public $b;
    
    function __construct($c)
    {
        $this->b = $c;
    }
}

$aa = new A();

// Теперь этот вызов НЕ нужен!!! Вот в чем соль : )
// $aa->load();

print $aa->a->length();  // выводит кол-во элементов

?> 


Это сообщение отредактировал(а) SqueeZe - 8.1.2008, 18:26
PM MAIL ICQ   Вверх
FractalizeR
Дата 11.1.2008, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: 2
Всего: 4



И где тут позднее инстанцирование?


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
SqueeZe
Дата 11.1.2008, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Здесь позднее инстанцирование достигается путем наполнения экземпляра класса Collection (который грубо говоря является массивом объектов), ТОЛЬКО при обращении к этому экземпляру.

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

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



PM MAIL ICQ   Вверх
vasac
Дата 12.1.2008, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1060
Регистрация: 4.5.2006

Репутация: 8
Всего: 36



Цитата(SqueeZe @  8.1.2008,  17:36 Найти цитируемый пост)
Немного не в ту сторону. Я знаю эти функции, но не могу понять, где это можно использовать!? Для какой задачи!

В документации ссылки на которую дал, после описания функций идет множество комментариев с примерами использования.
PM WWW   Вверх
FractalizeR
Дата 12.1.2008, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: 2
Всего: 4



Цитата(SqueeZe @ 11.1.2008,  21:48)
Здесь позднее инстанцирование достигается путем наполнения экземпляра класса Collection (который грубо говоря является массивом объектов), ТОЛЬКО при обращении к этому экземпляру.

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

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

Это позднее инстанцирование только применительно к классу B. А по отношению к классу А - это просто загрузка по требованию. Так я понимаю.


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
SqueeZe
Дата 12.1.2008, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Класс B я использовал только для того, чтобы его экземплярами заполнять Collection класса A. Можно убрать вообще этот класс и вместо:

Код

$a->addItem(new B(1));
$a->addItem(new B(2));


заполнять Collection строками:

Код

$a->addItem('string1');
$a->addItem('string2');


Но просто при использовании такого класса, как Collection (я кстати привел его в соседней теме [>>]), не имеет смысла заполнять его строками.

Это сообщение отредактировал(а) SqueeZe - 12.1.2008, 14:48
PM MAIL ICQ   Вверх
SqueeZe
Дата 12.1.2008, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Решил для наглядности привести еще один пример, уже с более осмысленными классами. И сам получше разберусь, авось и другим помогу =)

Рассмотрим сначала следующую заготовку.

Код

class Club
{
    public $name;    
    
    public $singers;
    
    public function __construct()
    {
        $this->name = 'Memory Club';        
        
        $this->singers = new Collection();
    }
    
    public function loadSingers() {
        // здесь инфа об исполнителях грузится из базы
        
        $this->singers->addItem(new Singer('John',75));
        $this->singers->addItem(new Singer('Steve',60));
        $this->singers->addItem(new Singer('Vanessa',70));
    }
}


Код

class Singer 
{
    public $name;
    public $rating;
    
    public function __construct($name, $rating)
    {
        $this->name = $name;
        $this->rating = $rating;
    }
}


С помощью того, что уже есть мы можем инстанцировать наш клуб и вывести его имя.

Код

$club = new Club();
print $club->name; 


Но нам еще нужно получать информацию об исполнителях, но пока параметр $singers пуст, так как нигде не вызывается метод loadSingers(). Здесь возникает вопрос, где его вызывать. К примеру можно вызвать его в конструкторе класса Club

Код

public function __construct()
    {
        $this->name = 'Memory Club';        
        
        $this->singers = new Collection();
        #####################
        $this->loadSingers();
        #####################
    }

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

Второй вариант - вызов метода loadSingers() перед обращением к коллекции исполнителей.

Код

$club = new Club();
$club->loadSingers();
print $club->singers->length(); // Выводит количество исполнителей в клубе


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

Чего же мы хотим? Хотим обращаться к коллекции таким образом

Код

$club = new Club();
print $club->name; // Просто вывод имени, без всяких подгрузок
print $club->singers->length(); // Подгрузка и вывод количества элементов


Класс Collection предоставляет возможность выполнять указанную функцию перед вызовом одного из методов (getItem(), keys(), length()) при помощи встроенного метода setLoadCallback() и выполняет контроль над тем, чтобы функция была вызвана только один раз.

Конечная реализация:

Код

class Club
{
    public $name;    
    
    public $singers;
    
    public function __construct()
    {
        $this->name = 'Memory Club';        
        
        $this->singers = new Collection();
        #####################
        $singers->setLoadCallback('loadSingers', $this); // $this указывает на класс, из которого вызывается метод.
        #####################
    }
    
    public function loadSingers() {
        // здесь инфа об исполнителях грузится из базы
        
        $this->singers->addItem(new Singer('John',75));
        $this->singers->addItem(new Singer('Steve',60));
        $this->singers->addItem(new Singer('Vanessa',70));
    }
}

class Singer 
{
    public $name;
    public $rating;
    
    public function __construct($name, $rating)
    {
        $this->name = $name;
        $this->rating = $rating;
    }
}

$club = new Club();
print $club->name; // Просто вывод имени, без всяких подгрузок
print $club->singers->length(); // Подгрузка и вывод количества элементов


Это сообщение отредактировал(а) SqueeZe - 12.1.2008, 15:39
PM MAIL ICQ   Вверх
FractalizeR
Дата 12.1.2008, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: 2
Всего: 4



Цитата(SqueeZe @ 12.1.2008,  14:47)
Класс B я использовал только для того, чтобы его экземплярами заполнять Collection класса A. Можно убрать вообще этот класс и вместо:

Код

$a->addItem(new B(1));
$a->addItem(new B(2));


заполнять Collection строками:

Тогда это вообще не инстанцирование. Инстанцирование - это создание экземпляра класса, а не заполнение его информацией. Позднее инстанцирование - позднее создание экземпляра класса тогда, когда это необходимо.


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1085 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.