Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

PHP. Статические методы

13
29 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Может от того, что я не спал давно, а может умом тронулся, но столкнулся с таким эффектом.
Объявляем класс:
 
Код:
class test
{
  function tellme()
  {
     echo 'OK';
  }
}

Вызываем метод:
 
Код:
test::tellme();

Результат: ОК

"Странно", думаю. Ну всякое бывает, может не углядел в документации, что по умолчанию методы считаются статическими, если не указано явно. Задаем тогда видимость.
 
Код:
class test
{
  public function tellme()
  {
     echo 'OK';
  }
}

Опять вызываем как статический метод, опять работает:
 
Код:
test::tellme();

Результат: ОК

В этом месте меня начало клинить - получается любая функция как ее ни укажи является статической? Попробую вызвать с созданием экземпляра объекта:
 
Код:
$obj = new test();
$obj->tellme();

Результат: ОК

А если вызвать сразу двумя способами??
 
Код:
test::tellme();

$obj = new test();
$obj->tellme();

Результат: ОКОК

Внимание, вопрос: получается, что все функции всегда являются статическими? Хотя последний пример показывает, что она статическая и не статическая одновременно. Как такое может быть? Или я что-то не так делаю? Может пора спать?
Apache 2.2.17, PHP 5.3.5
Страницы:
271
29 июля 2011 года
MrXaK
721 / / 31.12.2002
Судя по комментам там ещё интереснее))

но вообще и твой первый и твой второй и твой последний коды должны кинуть E_STRICT, которое обычно отключают))) включи E_ALL | E_STRICT и увидишь)
10
29 июля 2011 года
Freeman
3.2K / / 06.03.2004
А не может быть так, что функция, не использующая данных из контекста объекта, является статической по факту? Попробуй завести поле (или как там оно в PHP?) и вывести его без создания экземпляра.

Сейчас у тебя вырожденный пример. Да, надо больше спать. :)
13
29 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: Freeman
А не может быть так, что функция, не использующая данных из контекста объекта, является статической по факту?


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

271
29 июля 2011 года
MrXaK
721 / / 31.12.2002
Цитата: Freeman
А не может быть так, что функция, не использующая данных из контекста объекта, является статической по факту? Попробуй завести поле (или как там оно в PHP?) и вывести его без создания экземпляра.



не может)) статик - это то, что объявлено как static... если обратиться к не-static переменной через ::, то вообще кинется фатал, а функциям пофигу, они отработают как бы к ним не обращались, а если внутри нету явно отличающихся обращений (так как внутри static-функций нету $this, там только self) то кинется E_STRICT



Цитата: RussianSpy
Такого быть не должно, я досконально изучил документацию вдоль и поперек - там ни слова об этом. Проверять неохота тем более что вне зависимости от результата проблема остается.



в чём проблема-то? включить уровень E_STRICT и получать в лоб ошибки))

13
29 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: Mr.Hacker
включи E_ALL | E_STRICT и увидишь)


Да вы правы - выводит уведомление...

Цитата:
PHP Strict Standards: Non-static method test::tellme() should not be called statically in /var/www/a.php on line 13


Получается сам язык написан так, чтобы на нем говнокодить... Как-то я даже расстроился - оказывается кидатели какашек в РНР не так уж сильно неправы, как я думал раньше.

13
29 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: Mr.Hacker
в чём проблема-то? включить уровень E_STRICT и получать в лоб ошибки))


Проблема в том, что такого быть не должно. Это неверная реализация ООП. Зачем тогда вообще нужно это объявление static если и так все работает прекрасно? Зачем делать вид, что у нас почти полноценное ООП? Эххх...

8
29 июля 2011 года
mfender
3.5K / / 15.06.2005
Цитата: RussianSpy
Проблема в том, что такого быть не должно. Это неверная реализация ООП. Зачем тогда вообще нужно это объявление static если и так все работает прекрасно? Зачем делать вид, что у нас почти полноценное ООП? Эххх...


А ты попробуй обратное: объяви её static и попробуй использовать как метод объекта. Тогда всё понятнее будет )))

Где-то у меня старенькая книга Котерова кажется, писанная ещё во времена PHP 5.0, там очень подробно излагается, что классы используются в виде библиотек функций, без создания каких-либо объектов. И так прямо и написано, зачем существует определение static - аккурат чтобы уточнить функцию класса, которая никогда не будет методом объекта.

8
29 июля 2011 года
mfender
3.5K / / 15.06.2005
Что меня больше всего убивает в ООП PHP - невозможность overload'а… (((((
Уже настолько привык в Delphi писать кучу методов с одним именем, но разными параметрами, что в PHP без этого счастья как-то обломно.
13
29 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Самое обидное в этой ситации, что и мигрировать особо некуда. Perl - дикий нечитабельный синтаксис, медленный, неудобный язык, с которого я огромной радостью 9 лет назад пересел на РНР. Python - жутко бесит своими обязательными отступами. Ruby - просто не нравится в силу особой идеологии. Остальные языки либо редко встречаются на хостингах, либо очень неудобны для веб-разработки (С++, Java), либо работают только под какую-то определенную платформу (тот же C# к примеру). Есть еще конечно node.js но это особая песня тк серверный javascript тоже явление редкое...
8
29 июля 2011 года
mfender
3.5K / / 15.06.2005
Потому, Старичуля, PHP - оптимум считается )))) Наверное это правильно )))
271
29 июля 2011 года
MrXaK
721 / / 31.12.2002
Цитата: RussianSpy
Python - жутко бесит своими обязательными отступами.



вы не представляете, какое это на самом деле счастье))) всё аккуратненко, никаких однострочников, которые потом сто лет искать) и скобок, скобок фигурных нет. и ; нет. это конфетка, а не язык)))

13
29 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: Mr.Hacker
вы не представляете, какое это на самом деле счастье))) всё аккуратненко, никаких однострочников, которые потом сто лет искать) и скобок, скобок фигурных нет. и ; нет. это конфетка, а не язык)))



Терпеть не могу, когда какие-то чуваки непонятные решили за меня как выглядеть моему коду. Годы проведенные в С/С++ приучили меня к красивому и четкому коду поэтому у меня и без всяких Пайтонов все оформлено. Лично для меня фигурные скобки - каждая на отдельной строке, отступы по 3 пробела - все это намного нагляднее, чем отступы в пайтоне. Возможно привычка - не спорю.

12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: RussianSpy

"Странно", думаю. Ну всякое бывает, может не углядел в документации, что по умолчанию методы считаются статическими, если не указано явно. Задаем тогда видимость.


Эээ... По всей видимо только меня смущает тот факт, что в контексте статического метода упоминается видимость?

Областью видимости метода как внутри, так и снаружи управляют через public, private, protected. Принадлежность метода к самому классу или к инстансу объекта определяет наличие static. Наличие static при объявлении класса говорит лишь о том, что метод принадлежит к классу, а не объекту и вызван может быть без создания экземпляра класса (но ни как не управляет видимостью). Особенность тут в том, что внутри кода класса обратиться к методу придется через self, а не через this ибо экземляра то класса у нас может и не быть. А может и быть. Поэтому ни чего проблемного тут нет.

Да, вызывать не статический метод статически конечно же неправильно, но PHP нам об этом вообще то говорит (Static Keyword):

Цитата:

Calling non-static methods statically generates an E_STRICT level warning.

12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: mfender
Что меня больше всего убивает в ООП PHP - невозможность overload'а… (((((
Уже настолько привык в Delphi писать кучу методов с одним именем, но разными параметрами, что в PHP без этого счастья как-то обломно.


А тебе какой overloading? Все вроде есть. Хочешь на уровень объектов, велкам: Overloading (к примеру в твоем случае используя __call). Не устраивают встроенные функции, так и на них управа найдется через APD: override_function (но использовать не рекомендую).

12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: RussianSpy
Терпеть не могу, когда какие-то чуваки непонятные решили за меня как выглядеть моему коду. Годы проведенные в С/С++ приучили меня к красивому и четкому коду поэтому у меня и без всяких Пайтонов все оформлено. Лично для меня фигурные скобки - каждая на отдельной строке, отступы по 3 пробела - все это намного нагляднее, чем отступы в пайтоне. Возможно привычка - не спорю.


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

ЗЫ. Покапайся в эрланге, может понравится.

13
30 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: alekciy
Эээ... По всей видимо только меня смущает тот факт, что в контексте статического метода упоминается видимость?


Была мысль, что если не указана видимость, то метод по умолчнанию считается static public. Однако это не подтвердилось. Как бы там ни было РНР реализует корявую неверную модель. Если метод задан как нестатик, то он не должен вызываться через ::. В итоге получается простор для быдлокодинга. Объявление таким образом вообще теряет какой-либо смысл. Ну вывод он там какое-то предупреждение, которое в 99% случаев отключено и не показывается. Хотя для protected и private он реализует верную модель - не дает использовать методы там где их быть не должно. Почему реализация статических методов такая кривая и убогая я лично так и не смог выяснить. Я расстроен((

8
30 июля 2011 года
mfender
3.5K / / 15.06.2005
Цитата: alekciy
А тебе какой overloading? Все вроде есть. Хочешь на уровень объектов, велкам: Overloading (к примеру в твоем случае используя __call). Не устраивают встроенные функции, так и на них управа найдется через APD: override_function (но использовать не рекомендую).


Пример в Delphi:

Код:
TObj = class(TObject)
  private
    procedure AnyProc(var AData: string); overload;
    procedure AnyProc(var AData: TStrings); overload;
  end;
implementation
{TObj}

procedure TObj.AnyProc(var AData: string);
begin
.................
end;

procedure TObj.AnyProc(var AData: TStrings);
begin
.................
end;

end;

А вот в PHP хрен так сделаешь.
274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: mfender
Пример в Delphi:
Код:
TObj = class(TObject)
  private
    procedure AnyProc(var AData: string); overload;
    procedure AnyProc(var AData: TStrings); overload;
  end;
implementation
{TObj}

procedure TObj.AnyProc(var AData: string);
begin
.................
end;

procedure TObj.AnyProc(var AData: TStrings);
begin
.................
end;

end;

А вот в PHP хрен так сделаешь.



если очень нужно - сделаешь.
но я не вижу смысла.

278
30 июля 2011 года
Alexander92
1.1K / / 04.08.2008
Lone Wolf, смысл в реальном удобстве. Когда есть набор функций, которые выполняют одну и ту же задачу, но с разными аргументами, сидеть и придумывать для каждой из них уникальное имя - не самое приятное занятие. И когда компилятор берет на себя разрешение перегрузок, реально говоришь ему спасибо. =)
274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: Alexander92
Lone Wolf, смысл в реальном удобстве. Когда есть набор функций, которые выполняют одну и ту же задачу, но с разными аргументами, сидеть и придумывать для каждой из них уникальное имя - не самое приятное занятие. И когда компилятор берет на себя разрешение перегрузок, реально говоришь ему спасибо. =)



а что мешает обьявить ОДИН метод, который принимает ЛЮБОЙ аргумент, и в зависимости от типа действует по другому? Это ПХП, ему фиолетово что вы передадите, масив, екземпляр класса или число - главное потом правильно обработать

 
Код:
public function print_array($mixed) {
    if(!is_array($mixed))
         $arr[0]=$mixed;
    else
         $arr=$mixed;
   foreach($arr as $a)
       echo $a;
}
13
30 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Это вы еще забыли про перегрузку операторов, которой вообще даже близко в РНР нет и скорее всего никогда не будет.
274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: RussianSpy
Это вы еще забыли про перегрузку операторов, которой вообще даже близко в РНР нет и скорее всего никогда не будет.



еще множественное наследование вспомните :)

13
30 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Ну, я никогда не был сторонником ООП в РНР и до сих готов доказывать, что в 99.99% случаев никакие абстрактные методы, интерфейсы, наследование и прочее не требуются для разработки веб-приложений на РНР, что все это гонка за модной тенденцией. Тем не менее в ряде случаев перегрузка операторов была бы полезна. А уж как полезно было бы иметь возможность задавать тип переменных - про это я вообще молчу.
274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
а кто тебе мешает задавать тип переменных?
Хочешь задавай.

Конечно согласен есть мааленькое ограничение. Задавание типов работает только с массивами и объектами. Но все же.

 
Код:
--> cat test.php
<?php
function f(array $a) {
    print_r($a);
}
$b =2;
f($b);
?>
`--> php test.php
Catchable fatal error: Argument 1 passed to f() must be an array, integer given, called in /home/lonewolf/test.php on line 6 and defined in /home/lonewolf/test.php on line 2
12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: RussianSpy
Была мысль, что если не указана видимость, то метод по умолчнанию считается static public. Однако это не подтвердилось. Как бы там ни было РНР реализует корявую неверную модель. Если метод задан как нестатик, то он не должен вызываться через ::. В итоге получается простор для быдлокодинга. Объявление таким образом вообще теряет какой-либо смысл. Ну вывод он там какое-то предупреждение, которое в 99% случаев отключено и не показывается. Хотя для protected и private он реализует верную модель - не дает использовать методы там где их быть не должно. Почему реализация статических методов такая кривая и убогая я лично так и не смог выяснить. Я расстроен((


Ты просто думаешь о static как о сущности привязанной к видимости. Но это не так. static это одна сущность, public, private, protected другая. Они ни как между собой не связаны.

278
30 июля 2011 года
Alexander92
1.1K / / 04.08.2008
alekciy, да не в том дело. static действительно отличается от public, private, protected, но речь о том, что они все определяют ООП-стиль языка. И грустно, что функционал public, private и protected реализован правильно, а функционал static'а - через одно место. RussianSpy, я правильно вас понял?
274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
все правильно реализовано, фигня только в типе ошибке которую генерит попытка вызова динамического метода, статически
8
30 июля 2011 года
mfender
3.5K / / 15.06.2005
Нихрена вы не поняли вообще никто никого )))))

static - любая функция в классе. Ну так в PHP заложено. И она будет static ровно до того момента, пока нерадивый человек не станет внутри неё использовать поля и методы объекта, который якобы сконструирован.
12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: mfender

А вот в PHP хрен так сделаешь.


Почему? О_о

Код:
<?php

class TObject
{
    public function AnyProc($AData)
    {
        if (is_string($AData)) {
            return $this->_string($AData);
        } elseif (is_array($AData)) {
            return $this->_array($AData);
        }

        return false;
    }

    private function _string($string)
    {
        return 'STRING';
    }

    private function _array($array)
    {
        return 'ARRAY';
    }
}

$obj = new TObject();

$str = 'string';
$arr = (array) $str;

var_dump($obj->AnyProc($str)); // string(6) "STRING"
var_dump($obj->AnyProc($arr)); // string(5) "ARRAY"


PHP не строго типизированный язык, поэтому тут все зависит только от тебя. Ты просто в контексте дельфи привык думать в плоскости "хочу в метод передать аргумент типа Х, поэтому делаем перегрузку ранее объявленного метода, но с типом аргумента Y", имхо. Но тут нужно просто взять и написать метод. Код обработки в зависимости от типа аргумента можно написать как в этом методе, так и, к примеру, вынести в приватные методы как с мое примере.

Я замечу, что писать на одном языке в стиле другого - прямая дорога к быдлокодерству. Язык - инструмент, со своими плюсами и минусами, на сколько эффективно этот инструмент используется зависит только от самого программера. Вворачивать шурупы всегда будет эффективнее отверткой, чем молотком.
12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: RussianSpy
Тем не менее в ряде случаев перегрузка операторов была бы полезна.


Вполне возможно: pecl - operator.

8
30 июля 2011 года
mfender
3.5K / / 15.06.2005
Вот ты молодец!!! )))))
Ты видел, чколько написано в Delphi и сколько усилий для overload нужно сделать? Там ровно две процедуры. Ты приводишь пример откровенно через жопу, уж извини. )))) Никогда такой overload не стану делать. Мне проще два метода раздельно написать. Так хоть код понятный будет, а не рыскать по всем условным местам что и кто в каком случае мне сделает ))))
12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: Alexander92
alekciy, да не в том дело. static действительно отличается от public, private, protected, но речь о том, что они все определяют ООП-стиль языка. И грустно, что функционал public, private и protected реализован правильно, а функционал static'а - через одно место.


А у нас есть где-то библия ООП в которой сказано, какой путь ведет нас в светлое будущее, а какой в гиену огненную? Нужно просто понимать, что есть какая то идея, концепт, а есть реализация этой идеи. А как наиболее правильно реализовать идею виднее все же реализующим.

278
30 июля 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: alekciy
А у нас есть где-то библия ООП в которой сказано, какой путь ведет нас в светлое будущее, а какой в гиену огненную? Нужно просто понимать, что есть какая то идея, концепт, а есть реализация этой идеи. А как наиболее правильно реализовать идею виднее все же реализующим.



Это да, но все же PHP изначально не был объектно-ориентированным языком, он погнался за новыми языками, в которых это уже было реализовано. А коли так - разумнее было бы сделать, чтобы программист, который в 2-3 языках уже привык к некоторой "общепринятой" реализации некоторых концепций, не ломал себе голову, а почему же в PHP она другая. Не согласны?

12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: mfender
Вот ты молодец!!! )))))
Ты видел, чколько написано в Delphi и сколько усилий для overload нужно сделать? Там ровно две процедуры. Ты приводишь пример откровенно через жопу, уж извини. )))) Никогда такой overload не стану делать. Мне проще два метода раздельно написать. Так хоть код понятный будет, а не рыскать по всем условным местам что и кто в каком случае мне сделает ))))


Я так и думал, что ты попытаешься сделать упор именно в этом строну. Между тем он не сильно больше примера на дельфи, просто он кажется больше из-за форматирования. По логике там ровно на один метод больше.

А пример да, через жопу, тебе это очевидно и это отлично. Я его и привел как демонстрацию того, что не нужно писать на одном языке категориями другого. В зависимости от типа аргумента требуется два куска кода, ну так и нужно выделять это в два отдельных метода. Не нужно протаскивать идею перезагрузки из дельфи в пхп.

8
30 июля 2011 года
mfender
3.5K / / 15.06.2005
Да я как-то и не протаскиваю. Просто заметил с неудовольствием, что в PHP невозможно сделать привычным образом overload ))))

Overload - чертовски удобная штука, замечу. Дело даже не в сочинении имён методам, а как раз в образе жизни. Всё таки ООП - программирование, максимально приближённое к человеческой логике. И вариации на тему входящих подробностей, от которых плясать наиболее нам, человекам, близки.
13
30 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: alekciy
Ты просто думаешь о static как о сущности привязанной к видимости. Но это не так. static это одна сущность, public, private, protected другая. Они ни как между собой не связаны.



Алексей - неужели вы думаете что по прошествии стольких лет я до сих пор не понимаю что такое статик и паблик? Еще раз: я думал что если не указывается ни статик, ни область доступности метода, то методу присваивается по дефолту статик паблик. Я решил провести эксперимент - не перестанет ли метод быть статиком, если ему задать область доступности явным образом? Вот и все, не более того.

Весь смысл топика в том, что внезапно выяснилось, что в РНР есть только статик методы и нестатиком их можно сделать только если внутрь метода запихать $this. Тогда метод обвалится с ошибкой. В других случаях как ни выкручивайся метод будет статиком. Хоть там и выводится какая-то ошибка, но она всегда отключена и имеет уведомительный характер.

274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: mfender
Нихрена вы не поняли вообще никто никого )))))

static - любая функция в классе. Ну так в PHP заложено. И она будет static ровно до того момента, пока нерадивый человек не станет внутри неё использовать поля и методы объекта, который якобы сконструирован.



это с как?
Да если октлючена генерация E_STRICT, динамический метод можна вызвать статически и он выполнится. Причем всегда. но до той точки где обращаешся к $this и сказать что это статический метод - нельзя.
Это тоже самое что называть табуретку стулом, до тех пор пока ты непытаешся облакатится на спинку.

12
30 июля 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: Alexander92
Это да, но все же PHP изначально не был объектно-ориентированным языком, он погнался за новыми языками, в которых это уже было реализовано. А коли так - разумнее было бы сделать, чтобы программист, который в 2-3 языках уже привык к некоторой "общепринятой" реализации некоторых концепций, не ломал себе голову, а почему же в PHP она другая. Не согласны?


В идеальном мире перфекционистов стоило бы согласиться, но я инженер работающий с реальными системами и посему не согласен.

Любая система которая существует какое то время и развивается содержит в себе атавизмы, возрастающую энтропию кода, костыли эволюции которые возникли потому что первоначальная архитектура не была рассчитана на будущие изменения и кучу другого исторического наследия. При поддержании жизненного цикла продукта приходится думать и об этом. Если авторы решили, что им удобнее реализовать так или иначе это их решение. Кому оно кажется неправильным, неправославным берут и используют другой инструмент или вовсе пытаются создать свой.

Можно конечно выбросить весь предыдущий код и написать все с нуля, по православному, но как оплатить такую разработку и кому в итоге она понадобиться?

А общепринятой реализации нет как и нет серебряной пули. Есть идея которая, замечу, так же эволюционировала и есть различные реализации этой идеи.

13
30 июля 2011 года
RussianSpy
3.0K / / 04.07.2006
Цитата: Lone Wolf
Причем всегда. но до той точки где обращаешся к $this и сказать что это статический метод - нельзя.


Именно так. Если $this нет в коде, то метод фактически является статиком (ну что с того что он каком-то там особом режиме создает нотайс).

274
30 июля 2011 года
Lone Wolf
1.3K / / 26.11.2006
ладно. тут спор насчет терминологии пошел..
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог