Я бы хотел сделать следующее:
$method_result = new Obj()->method();
Вместо того, чтобы делать:
$obj = new Obj(); $method_result = $obj->method();
Результат в действительности не имеет значения для меня в моем конкретном случае. Но есть ли способ сделать это?
Запрошенная функция доступна на PHP 5.4. Вот список новых функций в PHP 5.4:
http://docs.php.net/manual/en/migration54.new-features.php
И соответствующая часть из списка новых функций:
Добавлен доступ члена класса к экземпляру, например (новый Foo) -> bar ().
Вы не можете делать то, что вы просите; но вы можете «обмануть», используя тот факт, что в 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; см. screeshot:
http://img.ruphp.com/php/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]
Вы можете сделать это более универсально, определив функцию идентификации:
function identity($x) { return $x; } identity(new Obj)->method();
Таким образом, вам не нужно определять функцию для каждого класса.
Как насчет:
$obj = new Obj(); $method_result = $obj->method(); // ?
:П
Нет, это невозможно.
Вам нужно назначить экземпляр переменной, прежде чем вы сможете вызвать любой из ее методов.
Если вы действительно не хотите этого делать, вы можете использовать завод, как предлагает ropstah:
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 (), чтобы включить класс, о котором вы просили. Конечно, вы, вероятно, захотите проверить $ func, чтобы убедиться, что это «новая» команда, которая была отправлена команде __call (), и (конечно) вы могли бы иметь и другие команды из-за того, как работает __call ().