Одновременно двоеточие и $this-> невозможно?

nefexus

Новичок
Если внутри класса под названием ClassName обращение к свойствам класса и методам происходит через двоеточие (self::my_func(), например), то это значит, что таким классом можно будет воспользоваться только через двоеточие, т.е. ClassName::my_func() и будет возникать ошибка при попытке использования через
$cl = new ClassName();
$cl->my_func();

Т.е. если писать через двоеточие, а потом появится необходимость использовать класс через $cl = new ClassName();, то класс придётся переписывать?
 

nefexus

Новичок
PHP:
class MyClass
{
    public static $a = 'value';
}

print MyClass::$a;

$MyClass = new MyClass();
print $MyClass->a;
Должен напечатать переменную 2 раза, но печатает только 1 раз.

PHP:
class MyClass
{
    public $a = 'value'; //Если убрать static
}

print MyClass::$a; //Если не закоментить эту строку, то будет ошибка Fatal error: Access to undeclared static property: MyClass::$a in <..>\test.php on line 8. Если закоменить, то напечатается значение переменной $a на строке 11.

$MyClass = new MyClass();
print $MyClass->a;
Т.е. в итоге получается, что если класс пишется для использования через двоеточие, то в дальнейшем через -> уже использовать не получится?
И наоборот - если пишется под использование через ->, то дальше через двоеточие уже не получится использовать?
 
Последнее редактирование:

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
Ты путаешь статические свойства класса и не статические. Поставь в начале скрипта error_reporting(-1); и иди читать книгу!

PS: А, не путаешь, просто хочешь странного. PHP тоже не дурак и говорит тебе об этом.
 

nefexus

Новичок
Ты путаешь статические свойства класса и не статические. Поставь в начале скрипта error_reporting(-1); и иди читать книгу!

PS: А, не путаешь, просто хочешь странного. PHP тоже не дурак и говорит тебе об этом.
Да вроде почитал статьи. Если переменной не поставить static, то её нельзя будет использовать через MyClass::$a. Если поставить, то нельзя будет использовать через print $MyClass->a;. Вот и пытаюсь понять, что логика такая, что работать надо либо через MyClass::$a, либо через $MyClass = new MyClass(); - но одновременно чтобы работали оба варианта использования класса не получится.
 

AnrDaemon

Продвинутый новичок
Твоя проблема в том, что ты пытаешься понять что-то не то.
Тебе не надо ничего из этого, вообще.
У статических переменных и методов есть своя чётко определённая область применения. В реальных условиях практически не применяемая. (Да, да. Нет правил без исключения.)
 

nefexus

Новичок
Твоя проблема в том, что ты пытаешься понять что-то не то.
Тебе не надо ничего из этого, вообще.
У статических переменных и методов есть своя чётко определённая область применения. В реальных условиях практически не применяемая. (Да, да. Нет правил без исключения.)
Т.е. static редко используется?

Почитал мануал:
http://php.net/manual/ru/language.oop5.static.php - здесь про static.
http://php.net/manual/ru/language.oop5.visibility.php - здесь про var, public, protected, private.
 

AnrDaemon

Продвинутый новичок
Как вы изволили заметить, они даже описываются в разных местах, так как у них совершенно разное назначение.
Давайте подойдём с другой ситороны. Вы скажете, что вы хотите получить в итоге, а мы попробуем объяснить, почему так не надо делать…
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@nefexus, да, static нужен достаточно редко, и только для того, чтобы создавать объекты. Если нет понимания зачем - так делать не надо.
В php сами по себе ни статические вызовы, ни объекты не нужны, это не java. Если нет понимания зачем нужен именно объект - стоит писать функции, они просты и универсальны.
 

hell0w0rd

Продвинутый новичок
В php сами по себе ни статические вызовы, ни объекты не нужны, это не java. Если нет понимания зачем нужен именно объект - стоит писать функции, они просты и универсальны.
ШТА!? Ты что, как так просто функция? А интерфейсы написать? Простые функции. Ишь что удумал.
 

AnrDaemon

Продвинутый новичок
Кстати, интересную штуку тут недавно накопал. static переменные нельзя перекрыть в потомках. Всегда будет действовать та, что определена первой.
 

WMix

герр M:)ller
Партнер клуба
ШТА!? Ты что, как так просто функция? А интерфейсы написать? Простые функции. Ишь что удумал.
@hell0w0rd, ну тебе ли, человеку из мира js этого не понимать? говоришь как будто там все interface'ами обставленно ;) все на callbacks и hashtables.

чуешь как душа обратно в просится? бросай этот js ))
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Кстати, интересную штуку тут недавно накопал. static переменные нельзя перекрыть в потомках. Всегда будет действовать та, что определена первой.
что значит перекрыть?
PHP:
<?php
class A{
static $x;
}
class B extends A{
static $x;
}
B::$x = 1;
var_dump(A::$x); //NULL
 

Absinthe

жожо

AnrDaemon

Продвинутый новичок
Ни капельки не стыдно. Там нет ни одного примера с переменными.
 

AnrDaemon

Продвинутый новичок
@grigori, а теперь попробуй инициализировать сначала потомка, а потом предка. И обратиться к статику в обоих классах.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@AnrDaemon, прости, а что значит "инициализировать сначала потомка"?
я и так присваиваю сначала потомку B::$x
PHP:
<?php
class B extends A{
static $x;
}
class A{
static $x;
}
B::$x = 1;
A::$x = 2;
var_dump(A::$x,B::$x);

# php test.php
int(2)
int(1)
дай пример что-ли
 

AnrDaemon

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

AnrDaemon

Продвинутый новичок
Вот…
PHP:
<?php

abstract class Universe
{
  protected $PropertyNames = '["id"]';
  static $_names;

  /*

  From the PHP documentation:

    Note:

    PHP implements a superset of JSON - it will also encode and decode scalar
    types and NULL. The JSON standard only supports these values when they are
    nested inside an array or an object.

  Here we are trying to utilize this "superset decoding" to simplify the code.
  In case it may fail in the future, the generic exception is stuffed behind a
  decoding result check.
  (In case you fail the inheritance, you're the one to be blamed.)

  */
  public function __construct()
  {
    var_dump($this->PropertyNames);
    if(!is_array(self::$_names))
    {
      if(!is_array($names = json_decode($this->PropertyNames)))
        throw new Exception('PHP/JSON "superset decoding" failed.');
      self::$_names = array_map('ucfirst', $names);
    }
  }

  public function __call($method, $arguments)
  {
    return print_r(self::$_names, true);
/*
    if(substr_compare($method, 'get', 0, 3) === 0)
    {
      $property = substr($method, 3);
      if(in_array($property, $this->_names))
        return $this->properties[$property];
    }
    else if(substr_compare($method, 'set', 0, 3) === 0)
    {
      $property = substr($method, 3);
      if(in_array($property, $this->_names))
      {
        $this->properties[$property] = $arguments[0];
        return $this;
      }
    }

    throw new BadMethodCallException('Our magic was not strong enough to make it happen. But still, we have tried!');
*/
  }
}

class Galaxy extends Universe
{
  protected $PropertyNames = '["id","name"]';
  static $_names;

  public function __construct($id, $name)
  {
    parent::__construct();
    // $this->setId($id);
    // $this->setName($name);
  }
}

class Starsystem extends Galaxy
{
  protected $PropertyNames = '["id","name","coords","parent"]';
  static $_names;
}

$g = new Galaxy(1, 'Galaxy');
$s = new Starsystem(2, 'Starsystem');

var_dump($s->x());
Чисто для саморазвития, хотелось бы понимать, что происходит.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Чисто для саморазвития, хотелось бы понимать, что происходит.
нарушение инкапсуляции, Лисковой и открытости/закрытости, что же еще?
в конструкторе статическое поле заполняется на основе значения защищенного поля, которое переопределяется в потомке,
отличный кандидат на пункт в статье "как писать код, который никто не сможет поддерживать"
 
Сверху