Форум программистов, компьютерный форум, киберфорум
PHP: ООП
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
107 / 4 / 1
Регистрация: 04.04.2015
Сообщений: 124

Перехват всех методов

01.02.2023, 19:51. Показов 1825. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Помогите пожалуйста.
Есть вот такой кусочек кода.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Test {
    
    private function a () {
        echo "a<br/>";
        $this->b();
    }
    
    private function b () {
        echo "b<br/>";
    }
    
    public function __call ($method, $arguments) {
        echo 'Сейчас будет вызов '.$method.'<br/>';
        $this->$method(...$arguments);
    }
    
}
 
$test = new Test();
$test->a();
Результат:
Code
1
2
3
Сейчас будет вызов a
a
b
Как можно перехватить все вызовы методов?
Сейчас метод A вызывает метод Б
Метод А я перехватываю, а как перехватить в таком случае B?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.02.2023, 19:51
Ответы с готовыми решениями:

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

Перехват всех событий клавиатуры
Доброго времени суток, возникла задача полного перехвата всех нажатий клавиатуры в linux, как в screensaver'ах, в каком направлении стоит...

Перехват всех enum в EditorTemplates
Здравствуйте! Возможно ли создать в EditorTemplates view который будет подставляться вместо любого enum? Если да, то как? Я пробовал...

5
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
02.02.2023, 05:50
Перегрузка срабатывает только при вызове недоступных методов. b доступна из a, поэтому __call никогда не вызовется.

1) Можно переименовать a и b в doA и doB, а вызовы функций оставить как есть. Затем в __call динамически формировать имя метода.

2) Можно из a напрямую вызвать __call:
PHP
1
$this->__call('b', [])
Естественно, проделывать подобное нужно только если вы точно знаете, зачем оно вам.
0
321 / 189 / 78
Регистрация: 04.10.2016
Сообщений: 809
07.02.2023, 07:47
Цитата Сообщение от SkyWeb Посмотреть сообщение
Как можно перехватить все вызовы методов?
попробуйте так:

1. создайте метод, который этим будет заниматься (например: all)
2. метод all будет вызывать все нужные вам методы с помощью подготовленного списка методов (из этого списка исключайте методы all и __call - тут чтобы проблем с рекурсией не возникли)

PHP
1
2
3
4
5
        foreach(get_class_methods(__CLASS__) as $method){
            if(in_array($method, ['all','__call'])) continue;
                
            $this->{$method}();
        }
Добавлено через 2 минуты
и получите ( что то похожее на ваше описание)

PHP
1
2
3
4
5
$a = new A();
$a->a(); // a
$a->b(); // b
$a->all(); // a
           // b
0
3012 / 1446 / 262
Регистрация: 16.03.2008
Сообщений: 6,444
Записей в блоге: 2
07.02.2023, 11:57
Цитата Сообщение от Fart83 Посмотреть сообщение
попробуйте так
Как я понимаю задачу ТС, как раз необходимо отловить все вызовы методов, включая случай когда произвольный существующий метод вызывает другой метод этого же класса. Т.е. вызов $test->a(); должен показывать и вызовы и a() и b()

Тут вообще не очень ясна задача. Если разрешено править класс, почему не добавить необходимый функционал в сами методы? Тем более получается давая доступ к закрытым методам.
Т.е. пришло на ум такое (если трогать класс нельзя) решение (правда приватные методы не получится)
Кликните здесь для просмотра всего текста
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
 
namespace Source {
    class Test
    {
        public function a(): void
        {
            echo "a<br>";
            $this->b();
        }
 
        protected function b(): void
        {
            echo "b<br>";
        }
    }
}
 
namespace Debug {
    class Test extends \Source\Test
    {
        public function a(): void
        {
            $this->log();
            parent::a();
        }
 
        protected function b(): void
        {
            $this->log();
            parent::b();
        }
 
        private function log(): void
        {
            $e = new \Exception();
            $trace = $e->getTrace();
            echo 'Сейчас будет вызов ' . $trace[1]['function'] . "<br>";
        }
    }
}
 
namespace {
    $test = new Debug\Test();
    $test->a();
}
0
132 / 76 / 16
Регистрация: 08.07.2022
Сообщений: 309
07.02.2023, 14:47
https://www.php.net/manual/ru/... t-hook.php
1
3012 / 1446 / 262
Регистрация: 16.03.2008
Сообщений: 6,444
Записей в блоге: 2
07.02.2023, 15:49
xkkx, спасибо. интересная функция. "поигрался":
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
class Test
{
    public function a(): void
    {
        echo '- ', __METHOD__, PHP_EOL;
        $this->b();
        $this->c();
        $this->d();
    }
 
    public function b(): void
    {
        echo '- ', __METHOD__, PHP_EOL;
    }
 
    protected function c(): void
    {
        echo '- ', __METHOD__, PHP_EOL;
    }
 
    protected function d(): void
    {
        echo '- ', __METHOD__, PHP_EOL;
    }
}
 
class Debugger
{
    private array $methods;
    private array $stat = [];
 
    public function addStat(string $name): void
    {
        if (array_key_exists($name, $this->stat)) {
            ++$this->stat[$name];
        } else {
            $this->stat[$name] = 1;
        }
    }
 
    public function showStat(): void
    {
        foreach ($this->stat as $name => $times) {
            echo $name, ' called ', $times, PHP_EOL;
        }
    }
 
    public function __construct(string $class)
    {
        $reflection = new ReflectionClass($class);
        $this->methods = $reflection->getMethods();
    }
 
    public function run(): void
    {
        foreach ($this->methods as $method) {
            $name = sprintf('%s::%s()', $method->getDeclaringClass()->getName(), $method->getName());
            uopz_set_hook(
                $method->getDeclaringClass()->getName(),
                $method->getName(),
                $this->handler($name, $this)
            );
        }
    }
 
    public function stop(): void
    {
        foreach ($this->methods as $method) {
            uopz_unset_hook($method->getDeclaringClass()->getName(), $method->getName());
        }
    }
 
    private function handler(string $name, Debugger $debugger): Closure
    {
        return static function () use ($name, $debugger) {
            $debugger->addStat($name);
            echo $name, PHP_EOL;
        };
    }
}
 
class GrandTest
{
    public function __construct()
    {
        echo 'As child', PHP_EOL;
        (new Test)->b();
    }
}
 
$debugger = new Debugger(Test::class);
$debugger->run();
$test = new Test();
$test->a();
$test->b();
new GrandTest();
$debugger->stop();
echo 'stop', PHP_EOL;
$test->b();
$debugger->showStat();
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.02.2023, 15:49
Помогаю со студенческими работами здесь

Перехват всех http запросов...
Здрасвуйте, возник небольшой вопрос и вот решил обратиться к вам. Как с помощью Delphi 7 (точнее при помощи каких компонентов) можно...

Перехват нажатия клавиш во всех приложениях
Что нужно для того чтобы перехватить нажатия клавиш в системе, чтобы программа реагировала на нажатие и отжатие отдельно. В интернете видел...

Перехват Escape для всех элементов формы
Товарищи - помогите! при открытой форме проекта нужна перехватить нажатие клавиши esc с клавиатуры и вывести при этом сообщение. Писал...

Как сделать в MVC перехват всех входящих запросов
Вопрос написан несколько сумбурно поэтому уточню что именно имелось ввиду. Стоит задача организовать блокировку пользователей по ip. Т.в....

Windows store app перехват всех необработанных исключений
Здравствуйте. Мне необходимо реализовать перехват всех необработанных исключений в приложение, с последующим их логированием. Я нуб в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru