#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");