В PHP вы можете создать экземпляр объекта и вызвать метод в одной строке?
То, что я хотел бы сделать, это что-то вроде этого:
$method_result = new Obj()->method();
Вместо того, чтобы делать:
$obj = new Obj();
$method_result = $obj->method();
Результат на самом деле не имеет значения для меня в моем конкретном случае. Но есть ли способ сделать это?
8 answers
Запрошенная вами функция доступна в PHP 5.4. Вот список новых функций в PHP 5.4:
Http://php.net/manual/en/migration54.new-features.php
И соответствующая часть из списка новых функций:
Добавлен доступ к членам класса при создании экземпляра, например (новый Foo)->панель().
Вы не можете сделать то, что просите; но вы можете "обмануть", используя тот факт, что в 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]
Как насчет:
$obj = new Obj(); $method_result = $obj->method(); // ?
: P
Вы можете сделать это более универсально, определив функцию идентификации:
function identity($x) {
return $x;
}
identity(new Obj)->method();
Таким образом, вам не нужно определять функцию для каждого класса.
Нет, это невозможно.
Вам нужно назначить экземпляр переменной, прежде чем вы сможете вызвать любой из ее методов.
Если вы действительно не хотите этого делать, вы можете использовать фабрику, как предлагает ропста:
class ObjFactory{
public static function newObj(){
return new Obj();
}
}
ObjFactory::newObj()->method();
Для создания объекта можно использовать статический фабричный метод:
ObjectFactory::NewObj()->method();
Я тоже искал однострочный вариант для выполнения этого как часть единого выражения для преобразования дат из одного формата в другой. Мне нравится делать это в одной строке кода, потому что это одна логическая операция. Итак, это немного загадочно, но позволяет создавать и использовать объект даты в одной строке:
$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');
Я думаю, что объектно-ориентированный подход классный и необходимый, но иногда он может быть утомительным, требующим слишком много шагов для выполнения простых операций.
Я вижу, что это довольно старый вопрос, но вот что, я думаю, следует упомянуть:
Специальный метод класса, называемый "__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() работает.