вызов метода класса (с конструкторами) без создания экземпляра объекта в php

#php #class #constructor #methods #instantiation

#php #класс #constructor #методы #Создание экземпляра

Вопрос:

Я искал и пробовал, но не могу найти ответ.

Возможно ли в PHP вызвать функцию-член класса (когда этому классу требуется конструктор для получения параметров) без создания ее экземпляра как объекта?

Пример кода (который выдает ошибки):

 <?php

class Test {
    private $end="";

    function __construct($value) {
        $this->end=$value;
    }

    public function alert($value) {
        echo $value." ".$this->end;
    }
}

//this works:
$example=new Test("world");
$example->alert("hello");

//this does not work:
echo Test("world")::alert("hello");

?>
  

Комментарии:

1. Я думал, что echo Test::__construct(«world»)::alert(«hello»); может сработать, но это не так, вздох

2. создание alert() для статической функции выполнит эту работу.

Ответ №1:

К сожалению, в PHP нет поддержки для этого, но вы креативный и ищущий парень: D

Вы можете использовать «фабрику», образец:

 <?php

class Foo
{
   private $__aaa = null;

   public function __construct($aaa)
   {
      $this->__aaa = $aaa;
   }

   public static function factory($aaa)
   {
      return new Foo($aaa);
   }

   public function doX()
   {
      return $this->__aaa * 2;
   }
}

Foo::factory(10)->doX();   // outputs 20
  

Комментарии:

1. Я думаю, что не сработает. Поскольку вы не можете ссылаться на $this без создания какого-либо объекта.

2. @SirajAlam это действительно создает объект — посмотрите на new Foo строку…

Ответ №2:

Просто сделайте это (в PHP >= 5.4):

 $t = (new Test("Hello"))->foo("world");
  

Ответ №3:

Я тоже искал однострочник для выполнения этого как часть единого выражения для преобразования дат из одного формата в другой. Мне нравится делать это в одной строке кода, потому что это единственная логическая операция. Итак, это немного загадочно, но это позволяет вам создавать экземпляр объекта date и использовать его в одной строке:

 $newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');
  

Еще одним способом однострочного преобразования строк даты из одного формата в другой является использование вспомогательной функции для управления OO-частями кода:

 function convertDate($oldDateString,$newDateFormatString) {
    $d = new DateTime($oldDateString);
    return $d->format($newDateFormatString);
}

$myNewDate = convertDate($myOldDate,'F d, Y');
  

Я думаю, что объектно-ориентированный подход классный и необходимый, но иногда он может быть утомительным, требующим слишком большого количества шагов для выполнения простых операций.

Ответ №4:

Вы не можете вызвать метод уровня экземпляра без экземпляра. Ваш синтаксис:

 echo Test("world")::alert("hello");
  

не имеет большого смысла. Либо вы создаете встроенный экземпляр и немедленно отбрасываете его, либо у alert() метода нет неявного this экземпляра.

Предполагая:

 class Test {
  public function __construct($message) {
    $this->message = $message;
  }

  public function foo($message) {
    echo "$this->message $message";
  }
}
  

вы можете сделать:

 $t = new Test("Hello");
$t->foo("world");
  

но синтаксис PHP не позволяет:

 new Test("Hello")->foo("world");
  

который в противном случае был бы эквивалентен. Есть несколько примеров этого в PHP (например, использование индексации массива при возврате функции). Просто так оно и есть.

Комментарии:

1. я создаю встроенный экземпляр и немедленно отбрасываю его. я не понимаю, зачем мне нужно выделять переменную для этого процесса… это просто способ PHP / ООП?

Ответ №5:

Для этого вы можете выполнить

https://www.php.net/manual/en/reflectionclass.newinstancewithoutconstructor.php

отразите свой класс и запустите новый экземпляр без конструктора.

Вот пример кода:

 <?php

class Test {
    private $end="";

    function __construct($value) {
        $this->end=$value;
    }

    public function alert($value) {
        echo $value." ".$this->end;
    }

    public function end($value) {

        $this->end = $value;        

        return $this; // return Test object so that you can chain to other function method.
    }
}

// Solution #1:
// reflect your class.
$reflector = new ReflectionClass('Test');

// Then create a new instance without Constructor.
// This will ignore the constructor BUT it will create a new instance of class Test.
$say = $reflector->newInstanceWithoutConstructor();

// use end method that will return the Test object, then you can chain the alert()
$say->end('World!')->alert("Hello"); // output: Hello World!

?>
  

Ответ №6:

 // this does not work:
echo Test("world")::alert("hello");

// works, as you are calling not to an object of the class, but to its namespace
echo Test::alert("hello");