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

Что бы я хотел сделать, это примерно так:

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

Вы не можете делать то, что просите; но вы можете "обманывать", используя тот факт, что в 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);
}

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

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

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

int 20

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


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

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

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

FcnRR.png



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

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

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

(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]

Ответ 3

Как насчет:

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

: р

Ответ 4

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

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

identity(new Obj)->method();

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

Ответ 5

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

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

class ObjFactory{
  public static function newObj(){
      return new Obj();
  }
}
ObjFactory::newObj()->method();

Ответ 6

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

ObjectFactory::NewObj()->method();

Ответ 7

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

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

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

Ответ 8

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

Специальный метод класса, называемый "__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(), чтобы включить класс, который вы просили. Конечно, вы, вероятно, захотите проверить $func, чтобы убедиться, что это "новая" команда, которая была отправлена ​​команде __call(), и (конечно) вы могли бы иметь и другие команды из-за того, как работает __call().