[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: private метод в качестве callback'а
alc99vol
Есть у меня класс для работы с БД, и он большой В какой-то момент я подумал, что было бы неплохо добавить туда такую фишку, как директивы (позже я понял что нечто похожее по-умному называется placeholder'ами), например, чтобы вместо такого:
    $somename="'".mysql_real_escape_string($somename)."'";
db->select('id','tablename',"name=$somename");

можно было б написать так:
    db->select('id','tablename','name=#d',$somename);

где #d - это директива, экранирующая опасные переменные. ну, естественно, не только ради одной директивы.
сделал. удобно, но: дальше я подумал, что было бы неплохо создать отдельный класс и вынести всю работу с директивами туда, дабы не путалось оно в основном большом классе, ибо все равно приватное.
Подумал - сделал, получился небольшой, но хитрый класс directiveProc, который на входе принимает массив параметров функции, ищет и обрабатывает в нем директивы, возвращает обработанный массив. Но, есть нюанс: directiveProc, дабы быть универсальным, должен для обработки директив вызывать какой-то внешний callback, ведь данный класс ничего не может знать о том, каким именно образом директивы нужно обработать.
Ок, callback задал в конструкторе и вызываю через call_user_func_array. Работает, но получилась такая штуковина: есть большой класс для работы с БД, в нем приватный член directiveProc и определена функция processDir, принимающая на входе имя директивы и некие параметры, и, собственно, директиву обрабатывающая. то есть примерно так:
        class bigComplicatedDb{
public function construct(){
...
$this->dirProc=new directiveProc($this, 'processDir');
...

}
....
public function processDir($dirName, $someOtherArg){
//process directive
}
...
private $dirProc=null;
}


функцию processDir, при этом, очень хочется сделать private, т.к. частью интерфейса она никак не является. Но никак - call_user_func_array ругается и говорит что я вызываю приватный метод из вне.
Вопрос: как все-таки скрыть processDir или как по-другому спроектировать классы?
p.s. извините что много текста, надеюсь, что понятно о чем речь.



Спустя 9 минут, 11 секунд (4.04.2012 - 00:56) m4a1fox написал(а):
ИМХО! Первое что в голову пришло - инкапсуляцию зачем придумали? Я бы ее использовал.

Спустя 36 минут, 45 секунд (4.04.2012 - 01:33) alc99vol написал(а):
уточни, пожалуйста, применительно к примеру, что конкретно ты имеешь в виду. инкапсуляция=сокрытие реализации. как оно относится к тому, о чем я написал?

Спустя 9 минут, 32 секунды (4.04.2012 - 01:42) m4a1fox написал(а):
Ну как я представляю это себе... Вот пример (не твой код)

<?
class
logo{

private function dodo(){
return 'aaaaaaaa';
}

public function ShowMePrivate(){
return $this->dodo();
}
}


$obj = new logo();
echo $obj->ShowMePrivate();

?>

Спустя 1 минута, 14 секунд (4.04.2012 - 01:43) caballero написал(а):
PHP идет с открытыми исходниками
понятие скрывать тут весьма условно на самом деле ничего скрыть нельзя.
сделай public и все дела. Хотя я лично не уверен что тут вообще подходит такая конструкция с калбеком.

Спустя 20 минут, 16 секунд (4.04.2012 - 02:04) alc99vol написал(а):
m4a1fox: я, конечно, понимаю что пример привел сложный, но речь там о другом, прочитай, пожалуйста, внимательнее. что такое приват и паблик и как этим пользоваться я вполне представляю и не стал бы об этом спрашивать.

caballero: сокрытие реализации - это вовсе не из желания чего-то скрывать и совсем не связано с открытостью/закрытостью исходников. да, вызывать приватный callback из другого класса - может и не лучшее решение, но как сделать по-другому и лучше я не знаю.

да, в С++ одним(хотя и корявеньким) способом решения было бы занаследовать еще один класс от directiveProc и объявить его friend'ом большого класса. хотя, подозреваю, что тоже не самый хороший способ. Еще, подозреваю, что в С++ было бы возможно что-то хитрое придумать с указателями. Но тут нет ни friend'ов, ни указателей.

Спустя 4 минуты, 19 секунд (4.04.2012 - 02:08) m4a1fox написал(а):
Лады.... я сдаюсь! Я не понимаю в чем проблема! В принципе я ее не понимаю... ты пытаешь упростить процессы SELECT UPDATE INSERT и DELETE? Или нет?

Спустя 6 минут, 24 секунды (4.04.2012 - 02:14) caballero написал(а):
Цитата
сокрытие реализации - это вовсе не из желания чего-то скрывать и совсем не связано с открытостью/закрытостью исходников.

это из желания следовать теории из умных книжек вместо руководстововатся здравым смыслом

Цитата
Еще, подозреваю, что в С++ было бы возможно что-то хитрое придумать с указателями. Но тут нет ни friend'ов, ни указателей.

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

и вообе непонятно зачем directiveProc должен вызывать некий внешний калбак. и что тогда он сам делает?

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

Спустя 23 минуты, 1 секунда (4.04.2012 - 02:37) alc99vol написал(а):
не, тут не в умных книжках дело. ты б видел большие проекты, где этим принципам не следуют - это ппц. хотя, возможно, для масштабов пхп я и перемудрил, не спорю, и проект у меня вовсе не огромный.
вот насчет каллбека и приватной функции - в том то и вопрос. в С++, например, знаю несколько корявых способов, например, объявить функцию или класс friend'ом.

зачем нужно: directiveProc в моем примере занимается только работой со строками и регулярными выраженями, по заранее заданным правилам находит в строках директивы, в примере - #d. но, просто найти директивы - мало, их нужно должным образом обработать (в примере - на место #d подставить следующий параметр, заэкранировав в нем опасные символы). но класс, по сути, занимающийся синтаксическим разбором, знать о правилах экранирования MySql ничего не обязан, потому предусмотрен внешний callback.

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

Спустя 12 минут, 7 секунд (4.04.2012 - 02:50) m4a1fox написал(а):
alc99vol
А вы про pdo слыхали?

Спустя 5 часов, 19 минут, 14 секунд (4.04.2012 - 08:09) glock18 написал(а):
alc99vol
Цитата (alc99vol @ 3.04.2012 - 21:47)
db->select('id','tablename','name=#d',$somename);


это уже давно придумали, обратите внимание на подготовленные запросы. в php есть реализации их в mysqli_lib и pdo_lib. Оставьте подстановку параметров для mysql-клиента

PS: коллбек в принципе не должен быть не public. увы, даже при вызове внутри класса через call_user_func_array protected и private не будут видны. Если мне нужен колбек, то обычно ставлю public и префиксую имя __ на манер private методов в C++. Как бы то ни было, пересмотрите свою задачу, все уже сделано давно, вам просто нужно использовать подготовленные запросы.

Спустя 12 минут, 20 секунд (4.04.2012 - 08:21) alc99vol написал(а):
glock18: да, знаю, что реализации подобного есть, но, как я уже сказал, делаю это не ради одной директивы, я просто привел тут простой пример. но, тем не менее, спасибо за совет. да и проблема, скорее, не в данном конкретном классе, а в подходе, интересно как такое можно правильно реализовать.

Насчет call_user_func_array при вызове внутри класса - как раз таки все работает, и private и protected видны, проверьте. (может, были не видны в более старых версиях пхп, но сейчас работает, у меня 5.3.8)

m4a1fox: про pdo нет, не знаю, но понимаю что есть масса готовых решений. просто, как я говорил, интересна проблема в принципе, а не конкретное решение.

Спустя 13 минут, 26 секунд (4.04.2012 - 08:35) glock18 написал(а):
Цитата (alc99vol @ 4.04.2012 - 05:21)
Насчет call_user_func_array при вызове внутри класса - как раз таки все работает, и private и protected видны, проверьте. (может, были не видны в более старых версиях пхп, но сейчас работает, у меня 5.3.8)


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

Френдов в php нет, к сожалению.

Спустя 3 часа, 21 минута, 10 секунд (4.04.2012 - 11:56) m4a1fox написал(а):
alc99vol
Цитата
готовых решений. просто, как я говорил, интересна проблема в принципе, а не конкретное решение.

Почитайте про ПДО! Это не готовое решение типа CMS или Framework.

Спустя 1 минута, 38 секунд (4.04.2012 - 11:57) glock18 написал(а):
Цитата (m4a1fox @ 4.04.2012 - 08:56)
Почитайте про ПДО! Это не готовое решение типа CMS или Framework.


ну, во-первых, при чем здесь вообще ПДО. а во-вторых, что же это если не готовое решение?

Спустя 1 минута, 17 секунд (4.04.2012 - 11:59) glock18 написал(а):
Цитата (alc99vol @ 4.04.2012 - 05:21)
да, знаю, что реализации подобного есть, но, как я уже сказал, делаю это не ради одной директивы, я просто привел тут простой пример


это нативная возможность mysql-клиента.
Быстрый ответ:

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