Форум → Программирование → PHP для идиотов → Копирование метода
Копирование метода
Страницы: ← Следующая страница →
-
11 января 2010 г. 1:33, спустя 9 минут 33 секунды
$obj->newfunc = create_function('$x',' echo $x;');
Можно ли как-то "на ходу" к объекту добавить 1-2 метода? А еще лучше скопировать их из другого объекта. И предел мечтаний, что б это были protected методы
такое не катит? если нет, посмотри в сторону рефлексии может можно чтото сделатьСапожник без сапог -
11 января 2010 г. 2:44, спустя 1 час 11 минут 21 секунду
не, нужно из объекта их вытянуть. С рефлексией не работал и толковых руководств с примерами не встречал (окромя как получать информацию о классах)Спустя 162 сек.есть расширение в PECL для этого
upd: вот оно http://www.php.net/manual/en/function.runkit-method-copy.php -
11 января 2010 г. 2:19, спустя 23 часа 35 минут 24 секунды
Можно ли как-то "на ходу" к объекту добавить 1-2 метода? А еще лучше скопировать их из другого объекта
Абырвалг, если не секрет, то какова должна быть суть этих методов ?
что ты пытаешся сделать ? -
11 января 2010 г. 2:32, спустя 12 минут 56 секунд
множественное наследование protected-методов. Суть такова:
Занимаюсь социалкой. Там есть свой форум (допустим class Module_Forum). Есть также группы (class Module_Groups). В группах есть форум (class Module_Groups_Forum). В последнем классе мне нужно наследовать общий форум и переписать пару методов (getToken, getRedirectUrl и проверить, есть ли пользователь в группе). Кроме того есть несколько методов от класса Module_Groups, которые тоже должны присутствовать.
Короче покопаю в сторону ReflectionMethod::invokeArgs. Ну или попробую пересмотреть архитектуру.Спустя 56 сек.да, я гуглил на эту тему, везде просто подряд пытаются вызвать методы классов-родителей, даже не проверяя их видимость. -
11 января 2010 г. 3:11, спустя 39 минут 5 секунд
протектеды копируешь в наследников? … они разве так недоступны? эмСапожник без сапог -
11 января 2010 г. 3:28, спустя 16 минут 35 секунд
нужно так:родитель1
протектед11
родитель2
протектед22
ребенок наследуй родителя1 и родителя2 -
11 января 2010 г. 10:21, спустя 6 часов 53 минуты 1 секунду
может быть тебе поможет техника "настраиваи…маи…ваемого поведения" см. yii framework
Поведение компонента
Начиная с версии 1.0.2, к компоненту была добавлена поддержка примесей (mixin) и теперь к компоненту можно прикрепить одно или несколько поведений. Поведение — это объект, чьи методы могут быть «унаследованы» компонентом, к которому прикреплены, посредством объединения функционала вместо четкой специализации (как в случае обычного наследования класса). К компоненту можно прикрепить несколько поведений и таким образом получить множественное наследование.
http://www.yiiframework.com/doc/guide/ru/basics.componentСпустя 96 сек.p.s. не уверен, что экспортируемые методы могут быть protected, но поковыряй. может чего пригодится
p.p.s. ну так как в yii все компоненты наследуются от "корневого" класса, то вероятно — да, можно protected
p.p.p.s. интересно было бы обсудить твоё управление правами доступа. сильно интересуюсь такими вещами.ιιlllιlllι унц-унц -
11 января 2010 г. 10:46, спустя 24 минуты 38 секунд
может быть тебе поможет техника "настраиваи…маи…ваемого поведения" см. yii framework
да, очень может быть. Я вчера нашел аналогичное от Симфони ман: http://www.symfony-project.org/book/1_0/17-Extending-Symfony , код: http://trac.symfony-project.org/browser/branches/1.4/lib/plugins/sfPropelPlugin/lib/addon/sfMixer.class.phpp.s. не уверен, что экспортируемые методы могут быть protected, но поковыряй. может чего пригодится
надеюсь на это, проверюp.p.p.s. интересно было бы обсудить твоё управление правами доступа. сильно интересуюсь такими вещами.
прав доступа еще нету. Пока писать могут только участники группы. А создатель группы может тереть их сообщения. -
11 января 2010 г. 11:36, спустя 50 минут 21 секунду
Абырвалг, приглашаю в новую тему для обсуждения прав. наверное у тебя есть какие-то идеи.ιιlllιlllι унц-унц -
11 января 2010 г. 16:20, спустя 4 часа 44 минуты 9 секунд
да, тему ту обсудим.
Через рефлексию вызвать протектед нельзя<?php
class A
{
public function __construct() {}
public function ma()
{
echo "call A->ma\n";
}
protected function m()
{
echo "call A->m\n";
}
}
class B
{
public function __construct() {}
protected function mb()
{
echo "call B->ma\n";
}
protected function m()
{
echo "call B->m\n";
}
}
class AB
{
protected $objects = array();
public function __construct()
{
$this->objects[] = new A;
$this->objects[] = new B;
}
public function __call($method, $args)
{
foreach ($this->objects as &$object) {
if (method_exists($object, $method)) {
$m = new ReflectionMethod(get_class($object), $method);
return $m->invokeArgs($object, $args);
//return call_user_func_array(array($object, $method), $args);
}
}
die('Method ' . $method . ' doesn\'t exists');
}
}
$object = new AB();
$object->ma();
$object->mb();
$object->m();call A->ma
<!–error–><br />
<b>Fatal error</b>: Uncaught exception 'ReflectionException' with message 'Trying to invoke protected method B::mb from scope ReflectionMethod' in Z:\home\localhost\*\index.php:54
Stack trace:
#0 Z:\home\localhost\*\index.php(54): ReflectionMethod->invokeArgs(Object(B), Array)
#1 [internal function]: AB->__call('mb', Array)
#2 Z:\home\localhost\*\index.php(64): AB->mb()
#3 {main}
thrown in <b>Z:\home\localhost\*\index.php</b> on line <b>54</b><br />
<script language=JavaScript src='/errors/phperror_js.php'></script>
Но есть у меня одна идейка как это обойти… -
11 января 2010 г. 16:27, спустя 6 минут 42 секунды
а ты думал что можно просто так вызвать метод протектед из класса который не наследует владельца метода? хуйна 100% получится и получилась
да и вообще я думал что ты хочешь именно УНАСЛЕДОВАТЬ двух родителей, а ты просто "адаптер" с небольшими изменениями реализуешь.
зы рефлексия для того, что ты делаешь даже не нужна обычный call_user_func_arr будет работать почти уверен что быстрее и будет работать, для протектедов естественно нет, и не долженСапожник без сапог -
11 января 2010 г. 16:50, спустя 23 минуты 4 секунды
ну ты видел мою простыню кода? там же так:return $m->invokeArgs($object, $args);
//return call_user_func_array(array($object, $method), $args);
просто я думал, что рефлексия - это такая особая хуйня, которая может абсолютно все. Оказалось, что нет.
про адаптеры: вот мне именно нужно унаследовать. Я не понимаю тех людей, которые пишут мануалы по множественному наследованию, где они вызывают паблик методы. Нахрена мне наследовать паблик методы тогда? я ж могу сам экземпляр класса создать и обращаться к нему -
11 января 2010 г. 16:53, спустя 3 минуты 5 секунд
просто я думал, что рефлексия - это такая особая хуйня, которая может абсолютно все. Оказалось, что нет.
аха, и зенд обходить из prepend_file файла … рефлексия ваще мега штука! чо хочешь, то и делаешь!
нет конечно. посмотреть список и информацию о объектах можно, а делать что угодно с ними … нахуй тогда вообще вводить все эти приваты, протектеды и прочие глупости, ага? :)Спустя 49 сек.про адаптеры: вот мне именно нужно унаследовать. Я не понимаю тех людей, которые пишут мануалы по множественному наследованию, где они вызывают паблик методы. Нахрена мне наследовать паблик методы тогда? я ж могу сам экземпляр класса создать и обращаться к нему
вот тут ты прав. я вообще ненавижу людей которые пишут хуйню, которую минимум не понимаютСапожник без сапог -
11 января 2010 г. 17:37, спустя 44 минуты 32 секунды
Вха-ха! написал прототип. С первого раза скомпилировалось и отработало с ожидаемыми результатами:
// родитель, которого собираются наследовать должен реализовывать этот интерфейс
interface MultipleInheritanceInterface
{
//TODO: methods for __get, __set
public function invoke($method, $args);
}
// если вам лень реализовывать этот интерфейс - просто наследуйте этот класс
abstract class MultipleInheritanceBase implements MultipleInheritanceInterface
{
// через этот метод мы будем вызывать protected-методы
public function invoke($method, $args)
{
call_user_func_array(array($this, $method), $args);
}
}
// а этот класс должен наследовать потомок
abstract class MultipleInheritance
{
private $objects = array();
//TODO: public?
final protected function extend($object)
{
if (! $object instanceof MultipleInheritanceInterface)
throw new Exception();
$this->objects[get_class($object)] = $object;
}
public function __call($method, $args)
{
foreach ($this->objects as &$object) {
if (method_exists($object, $method)) {
return call_user_func_array(array($object, 'invoke'), array($method, $args));
}
}
throw new Exception('Method ' . $method . ' doesn\'t exists');
}
}
тесты:
// первый родитель. Интерфейс не реализовываю, просто наследую уже готовую реализацию
class A extends MultipleInheritanceBase
{
public function __construct() {}
public function ma()
{
echo "call A->ma\n";
}
protected function m()
{
echo "call A->m\n";
}
}
// второй родитель
class B implements MultipleInheritanceInterface
{
public function __construct() {}
// самостоятельно реализовываю интерфейс
public function invoke($method, $args)
{
echo "call B->invoke\n";
call_user_func_array(array($this, $method), $args);
}
protected function mb()
{
echo "call B->mb\n";
}
protected function m()
{
echo "call B->m\n";
}
}
class AB extends MultipleInheritance
{
public function __construct()
{
// наследываю классы.
$this->extend(new A);
// класс
$this->extend(new B);
}
protected function pmab()
{
echo "call AB->pmab\n";
}
public function mab()
{
$this->pmab();
echo "call AB->mab\n";
}
}
$object = new AB();
$object->ma(); // public
$object->mb(); // protected
$object->m(); // protected overloaded
$object->mab(); // public, свой
есть небольшой баг: сейчас у нас FIFO, а нужно сделать стек. Мы сначала наследовали A а потом B. Класс B переписал метод m, но выполнился m из A.
Кроме того нужно реализовать поддержку полей. Но мне лень.
Страницы: ← Следующая страница →
Пожалуйста, авторизуйтесь, чтобы написать комментарий!