В 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().