Нюансы со static методами в PHP 5.0 ?

slego

Новичок
Нюансы со static методами в PHP 5.0 ?

Есть класс записи логов:
PHP:
class CLog  
{      
    public function __construct() {}
    public function __destruct() {}

    public function set($log) 
    {
        $qr = new CQuery();          
        $qr->execute("INSERT INTO logs (log) VALUES('".$log."')");      
    }            
};
Хочу обратиться к методу класса без создания его объекта, т.е., используя "::". Для этого, по-идее, метод, к которому возникло желание обратиться, должен быть объявлен как статический, т.е., допустим так:
PHP:
public static function set($log)
Как видно из приведенного выше кода - метод самый что нинаесть обычный публичный.... Делаю так

PHP:
CLog::set("user you are looser!");
и все работает - запись добавляется в бд. ПА-ЧЕ-МУ???

Помогите, кто может, помогите... сбит с толку...

php 5.0.4
apache 1.3.31
 

SiMM

Новичок
> и все работает - запись добавляется в бд. ПА-ЧЕ-МУ???
Потому что ты её добавил. А что, не должна?
 

Long

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

slego

Новичок
Похоже вопрос некорректно поставил: Итак, еще раз вопрос:

ПОЧЕМУ, ИСПОЛЬЗУЯ "::" МОЖНО ОБРАТИТЬСЯ К НЕСТАТИЧЕСКОМУ МЕТОДУ КЛАССА, НЕ СОЗДАВАЯ ЕГО ОБЪЕКТ.

Из хелпа понял, что только со статическими такое прокатывает.
 

SiMM

Новичок
slego, он у тебя статический, хоть это и не указано явно (для его работы указатель $this не требуется).
 

BOJIK

Новичок
А вообще ИМХО это оставили что бы была обратная поддержка PHP4, иначе пришлось бы переписывать гору скриптов.
 

slego

Новичок
хм... т.е., грубо говоря, все методы, которые не используют this, указано это явно или нет, являются статическими?

Это такое негласное правило или это просто пхп такое? :)

В с++, например, такое не прокатит.

-~{}~ 12.05.05 17:26:

Всем огромное спасибо.
 

SiMM

Новичок
Почему все? Те, для работы которых $this не требуется.
 

slach

Новичок
ну и вообще
попробуйте в error_reporting E_STRICT добавить... посмотрите будут ли варнинги
 

[sid]

Новичок
Эта ошибка возникает из-за обратной совместимости с ZE1, где не было ключевого слова static. А вот следующее для меня просто загадка.
PHP:
<?php
class Foo
{
    function test()
    {
        echo $this->testMessage;
        echo " ";
        $this->testFunction();
        echo "\nn";
    }
}

class Bar
{
    var $testMessage = 'This is an test message';
    function someFunction()
    {
        Foo::test();
        // Отрабатывает на УРА
        
        $foo = new Foo();
        $foo->test();
        // Fatal Error
    }
    
    function testFunction()
    {
        echo 'This is an test function';
    }
}

$someClass= &new Bar;
$someClass->someFunction();
?>
Как вы могли заметить класс Foo обращается к свойству testMessage и методу testFunction как к своим собственным (через $this), хотя они объявлены в другом классе (Bar). Такое поведение замечено только при вызове метода как статического (PHP4, PHP5 поэтому я не использовал КС static). Если создается экземпляр объекта, и вызов адресуется через объект, то генерируется ошибка.
Вот это уже не просто нюансы...
 

Long

Новичок
[sid], если внимательно посмотреть что происходит, то мы увидим, что когда мы вызываем Foo::test(); никакого нового объекта не создается, в данном случае класс Foo выступает просто как собрание функций, и $this, при данном вызове указывает на класс Bar. а когда мы создаем новый объект $foo = new Foo(); $this уже указывает на объект $foo - а раз у него нет таких методов - получаем ошибку.
т.е. ничего необычного, на мой взгляд, не происходит.
 

[sid]

Новичок
Начнем с того, что если мы вызываем статический метод, то переменной $this вообще существовать не должно. Именно на этом основано предположение о том как определять как был вызван метод, как статический или нет (isset($this)). Тем более, что контекст $this принадлежит только текущему объекту. А статический метод - это по сути "функция (не метод), которая находиться в классе". Попробуйте выполнить то же самое в другом языке программирования и получите кучу ошибок, даже в интерпретируемом.
 

[sid]

Новичок
Long
Вы не понимаете! Я знаю, что это нормальное поведение с точки зрения интерпретатора PHP. Я говорю о том, что это ненормальное поведение с точки зрения здравой логики и парадигмы ООП. Насколько я знаю, болше ни один язык не страдает подобными ляпусами! Вообще подобное поведение может привести к самым непредсказуемым результатам!
 

Screjet

Новичок
[sid]
Глупости. Все что задокументировано = есть правила. Есть смысл изучить контексты ПХП.
По русски: вызов Foo::test() статический, и выполняется в контексте объекта $bar. Иначе какой глубокий смысл был бы _статических_ методов!?
 

Vasya

Guest
http://www.codenet.ru/progr/cpp/ipn.php
Все языки OOP ... основаны на трёх основополагающих концепциях, называемых инкапсуляцией, полиморфизмом и наследованием.
...
Инкапсуляция (encapsulation) - это механизм, который объединяет данные и код, манипулирующий зтими данными, а также защищает и то, и другое от внешнего вмешательства или неправильного использования.
Мне кажется, то пример [sid]'а показывает, что в ПХП нарушается именно этот принцип.
 

Screjet

Новичок
Vasya
Какая может быть инкапсуляция в ПХП4? :)
Пример исключительно гипотетический. Абсолютно нежизнеспособный.
 

tony2001

TeaM PHPClub
Как вы могли заметить класс Foo обращается к свойству testMessage и методу testFunction как к своим собственным (через $this), хотя они объявлены в другом классе (Bar). Такое поведение замечено только при вызове метода как статического (PHP4, PHP5 поэтому я не использовал КС static). Если создается экземпляр объекта, и вызов адресуется через объект, то генерируется ошибка.
Вот это уже не просто нюансы...
если автор догадается объявить статические методы статическими (хинт: static), то всё окажется в порядке.
почему работает так - из-за того, что надо соблюдать backward compatibility.
 
Сверху