CMS Eleanor - Поиск
Полная версия этой страницы: Официальный форум Eleanor CMS » Странное поведение PHP
Официальный форум Eleanor CMS » Для вебмастеров и владельцев сайтов » Комната программистов
Собственно я уже ничего не понимаю.

Вот написал такой код:


<?php
abstract class Base
{
	public function __call($n,array$p)
	{
		echo __METHOD__.' says: '.$n;
	}
}

class Main extends Base
{
	public function __construct()
	{
		self::Launch();
	}
}

$M=new Main;
?>


Кто-нибудь подскажет, почему вызывается метод Base::__call() ? Что вообще происходит. почему это вообще возможно?)
Нашёл что-то подомное в приписках к мануалу: self и this
Alexander
wizard993, ну все правильно. Ведь класс Main наследует класс Base, а значит и все его методы. И небольшой вам совет: пишите что ожидаете и что получаете.
Цитата (Alexander @ 2013-04-05, 22:51)
пишите что ожидаете и что получаете.

ожидаю, что должен вызываться __callStatic(). а почему __call() вызывается понять не могу
Почему вообще self работает внутри динамических методов? какое значение он принимает - имя класса в контексте вызова?
Alexander
wizard993, а почему вдруг self не должен работать внутри динамических методов? Как тогда вызывать статических методы из динамических? :)

Цитата (wizard993 @ 2020-12-04 15:12)
ожидаю, что должен вызываться __callStatic()

Что-то я не вижу у вас в коде __callStatic() . Вот и вызывает php у вас метод call.
Цитата (Alexander @ 2013-04-06, 0:34)
Как тогда вызывать статических методы из динамических? :)

Всё-всё-всё этот момент я понял. Вчера сидел, размышлял. Спасибо большое :)

Цитата (Alexander @ 2013-04-06, 0:34)
Что-то я не вижу у вас в коде __callStatic() . Вот и вызывает php у вас метод call.

1. Где регламентируется такое поведение, что если в статическом контексте вызывают несуществующий метод, а __callStatic() не существует, то перебрасываем обращение в __call()?
Кстати добавил в код __callStatic() - игнорируется он. Всё равно идёт вызов в __call()

2. Это раньше когда не было __callStatic() вызов несуществующего метода из любого контекста обращался в __call().

3. Тут, похоже, дело в другом. Я пошёл в мануал почитать ещё раз о перегрузке __call и callStatic().
Вот выдержка:
Цитата
public mixed __call ( string $name , array $arguments )
public static mixed __callStatic ( string $name , array $arguments )

В контексте объекта при вызове недоступных методов вызывается метод __call().

В статическом контексте при вызове недоступных методов вызывается метод __callStatic().


Прошу мне объяснить тогда, что такое статический контекст. И почему в выше приведённом коде self::Launch(); не является в статическом контекстом?

Пока в голову приходит только мысль, что раз вызов self::Launch(); осуществляется из контекста объекта, то каким образом мы вызываем метод - нам неважно, контекст так и будет контекстом объекта. Но я не видел нигде пояснений такого поведения.
Alexander
Почитал я багтрекер. Там таких проблем валом, но их не спешат исправлять. Вот, что нашел:
https://bugs.php.net/bug.php?id=51176
Цитата (Alexander @ 2013-04-06, 18:53)
Попробуйте запостить сию информацию в ихний багтрекер. Могу сделать это за вас.

Если вас не затруднит отправьте им репорт. Мне кажется, у вас лучше получится обозначить проблему

Цитата
Почитал я багтрекер. Там таких проблем валом, но их не спешат исправлять. Вот, что нашел:
https://bugs.php.net/bug.php?id=51176


Спасибо.... фигово, конечно, что ещё сказать...
Alexander
wizard993, поправил я свой пост, т.к. нашел много подобных багов в багтрекере PHP . Статус этой ошибки "Not a bug", тоесть это не является багом, а вот и пояснение:
Цитата
This is ridiculous- this bug is not bogus, it's completely legitimate, unexpected behavior, and totally non documented. As a reasonable programmer, one expects a static call to behave the same inside of a class as well as outside of a class.

How can we bring the "desired" behavior up for vote? I think that it's insane to not fix it.
Цитата (Alexander @ 2013-04-06, 19:18)
Статус этой ошибки "Not a bug"


Как всегда, философия php: если вы находите баг, то это не баг, а фича :)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.