В PHP вы можете создать экземпляр объекта и вызвать метод в той же строке? - PullRequest
113 голосов
/ 10 сентября 2009

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

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

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

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

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

Ответы [ 8 ]

150 голосов
/ 09 апреля 2012

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

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

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

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

37 голосов
/ 10 сентября 2009

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

image



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

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

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

(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]
19 голосов
/ 10 сентября 2009

Как насчет:

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

: P

18 голосов
/ 13 июля 2011

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

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

identity(new Obj)->method();

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

15 голосов
/ 10 сентября 2009

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

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

class ObjFactory{
  public static function newObj(){
      return new Obj();
  }
}
ObjFactory::newObj()->method();
6 голосов
/ 10 сентября 2009

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

ObjectFactory::NewObj()->method();
3 голосов
/ 01 сентября 2011

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

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

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

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

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

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

0 голосов
/ 07 января 2016

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

Специальный метод класса с именем "__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 (). 1009 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...