В PHP вы можете создать экземпляр объекта и вызвать метод в одной строке?


То, что я хотел бы сделать, это что-то вроде этого:

$method_result = new Obj()->method();

Вместо того, чтобы делать:

$obj = new Obj();
$method_result = $obj->method();

Результат на самом деле не имеет значения для меня в моем конкретном случае. Но есть ли способ сделать это?

 99
Author: weotch, 2009-09-10

8 answers

Запрошенная вами функция доступна в PHP 5.4. Вот список новых функций в PHP 5.4:

Http://php.net/manual/en/migration54.new-features.php

И соответствующая часть из списка новых функций:

Добавлен доступ к членам класса при создании экземпляра, например (новый Foo)->панель().

 132
Author: Delian Krustev, 2018-09-02 00:40:53

Вы не можете сделать то, что просите; но вы можете "обмануть", используя тот факт, что в PHP у вас может быть функция с тем же именем, что и у класса; эти имена не будут конфликтовать.

Итак, если вы объявили такой класс:

class Test {
    public function __construct($param) {
        $this->_var = $param;
    }
    public function myMethod() {
        return $this->_var * 2;
    }
    protected $_var;
}

Затем вы можете объявить функцию, которая возвращает экземпляр этого класса - и имеет точно такое же имя, что и класс:

function Test($param) {
    return new Test($param);
}

И теперь становится возможным использовать однострочный, как вы просили - единственное, что вы называете функция, таким образом, не использует новое:

$a = Test(10)->myMethod();
var_dump($a);

И это работает: вот, я получаю:

int 20

В качестве вывода.


И, что еще лучше, вы можете добавить немного phpdoc в свою функцию:

/**
 * @return Test
 */
function Test($param) {
    return new Test($param);
}

Таким образом, у вас даже будут подсказки в вашей IDE - по крайней мере, с Eclipse PDT 2.x; смотрите скриншот:

Http://extern.pascal-martin.fr/so/class-and-function.png



Редактировать 2010-11-30: Просто для информации был создан новый RFC отправлено несколько дней назад, в котором предлагается добавить эту функцию в одну из будущих версий PHP.

См. : Запрос комментариев: Вызов экземпляра и метода/доступ к свойствам

Итак, возможно, подобные действия будут возможны в PHP 5.4 или другой будущей версии:

(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]
 37
Author: Pascal MARTIN, 2010-11-30 20:13:46

Как насчет:

$obj = new Obj(); $method_result = $obj->method(); // ?

: P

 19
Author: Jeff, 2016-04-17 05:42:34

Вы можете сделать это более универсально, определив функцию идентификации:

function identity($x) {
    return $x;
}

identity(new Obj)->method();

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

 18
Author: Tom Pažourek, 2011-07-13 00:43:48

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

Если вы действительно не хотите этого делать, вы можете использовать фабрику, как предлагает ропста:

class ObjFactory{
  public static function newObj(){
      return new Obj();
  }
}
ObjFactory::newObj()->method();
 15
Author: Pim Jager, 2017-06-22 13:19:55

Для создания объекта можно использовать статический фабричный метод:

ObjectFactory::NewObj()->method();
 6
Author: Ropstah, 2009-09-09 22:40:05

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

$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');

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

 3
Author: CodeCavalier, 2011-09-01 15:48:08

Я вижу, что это довольно старый вопрос, но вот что, я думаю, следует упомянуть:

Специальный метод класса, называемый "__call()", может использоваться для создания новых элементов внутри класса. Вы используете его так:

<?php
class test
{

function __call($func,$args)
{
    echo "I am here - $func\n";
}

}

    $a = new test();
    $a->new( "My new class" );
?>

Вывод должен быть:

I am here - new

Таким образом, вы можете обмануть PHP, создав "новую" команду внутри вашего класса верхнего уровня (или любого класса на самом деле), и ввести команду include в функцию __call(), чтобы включить класс, который вы просили.Of конечно, вы, вероятно, захотите проверить $func, чтобы убедиться, что это "новая" команда, которая была отправлена команде __call(), и (конечно) у вас могут быть и другие команды также из-за того, как __call() работает.

 0
Author: Mark Manning, 2016-01-07 06:27:34