Я хотел бы знать, есть ли способ связать методы для вновь созданного объекта в PHP?
Что-то типа:
class Foo {
public function xyz() { ... return $this; }
}
$my_foo = new Foo()->xyz();
Кто-нибудь знает способ добиться этого?
Я хотел бы знать, есть ли способ связать методы для вновь созданного объекта в PHP?
Что-то типа:
class Foo {
public function xyz() { ... return $this; }
}
$my_foo = new Foo()->xyz();
Кто-нибудь знает способ добиться этого?
В PHP 5.4+ синтаксический анализатор был изменен, поэтому вы можете сделать что-то вроде этого
(new Foo())->xyz();
Заключите экземпляр в круглые скобки и уберите цепочку.
До PHP 5.4, когда вы используете
new Classname();
синтаксис, вы не можете связать вызов метода с экземпляром. Это ограничение синтаксиса PHP 5.3. Как только объект создан, вы можете связать его.
Один из методов, который я видел, чтобы обойти это, - это какой-то статический метод создания экземпляров.
class Foo
{
public function xyz()
{
echo "Called","\n";
return $this;
}
static public function instantiate()
{
return new self();
}
}
$a = Foo::instantiate()->xyz();
Обернув вызов new в статический метод, вы можете создать экземпляр класса с вызовом метода, и затем вы можете свободно связывать его.
Определите глобальную функцию следующим образом:
function with($object){ return $object; }
После этого вы сможете позвонить:
with(new Foo)->xyz();
id()
. Он широко используется в PHP благодаря своему синтаксису и парсеру.
- person hakre; 01.01.2014
@param object $object
+ @return object
, но тогда он не распознает правильный тип данных, и автодополнение/предложения не будут работать.
- person jurchiks; 21.11.2014
В PHP 5.4 вы можете связать вновь созданный объект:
http://docs.php.net/manual/en/migration54.new-features.php
Для более старых версий PHP вы можете использовать решение Алана Шторма.
Этот ответ устарел, поэтому хочу его исправить.
В PHP 5.4.x вы можете связать метод с новым вызовом. Возьмем этот класс в качестве примера:
<?php class a {
public function __construct() { echo "Constructed\n"; }
public function foo() { echo "Foobar'd!\n"; }
}
Теперь мы можем использовать это: $b = (new a())->foo();
И вывод:
Constructed
Foobar'd!
Дополнительную информацию можно найти в руководстве: http://www.php.net/manual/en/migration54.new-features.php
$b
- это то, что возвращает foo()
, а не (обязательно) созданный объект.
- person artfulrobot; 28.01.2015
foo()
, которое в данном случае равно NULL, становится содержимым $b
.
- person Ingwie Phoenix; 28.01.2015
Ну, это может быть старый вопрос, но, как и во многих других вещах в программировании, со временем ответ меняется.
Что касается PHP 5.3, нет, вы не можете напрямую связывать конструктор. Однако, чтобы расширить принятый ответ, чтобы правильно приспособиться к наследованию, вы можете сделать:
abstract class Foo
{
public static function create()
{
return new static;
}
}
class Bar extends Foo
{
public function chain1()
{
return $this;
}
public function chain2()
{
return $this;
}
}
$bar = Bar::create()->chain1()->chain2();
Это будет работать нормально и вернет вам новый экземпляр Bar().
Однако в PHP 5.4 вы можете просто сделать:
$bar = (new Bar)->chain1()->chain2();
Надеюсь, это поможет кому-то наткнуться на вопрос, как я!
Было бы очень полезно, если бы они «исправили это» в будущем выпуске. Я очень ценю возможность цепочки (особенно при заполнении коллекций):
Я добавил метод в базовый класс моего фреймворка с именем create(), который можно связать. Должен работать со всеми классами-потомками автоматически.
class baseClass
{
...
public final static function create()
{
$class = new \ReflectionClass(get_called_class());
return $class->newInstance(func_get_args());
}
...
public function __call($method, $args)
{
$matches = array();
if (preg_match('/^(?:Add|Set)(?<prop>.+)/', $method, $matches) > 0)
{
// Magic chaining method
if (property_exists($this, $matches['prop']) && count($args) > 0)
{
$this->$matches['prop'] = $args[0];
return $this;
}
}
}
...
}
Class::create()->SetName('Крис')->SetAge(36);
Просто для полноты (и для удовольствия...), поскольку никто, кажется, не упомянул решение с самым коротким (и наименее сложным) кодом.
Для часто используемых недолговечных объектов, особенно при написании тестовых случаев, когда вы обычно создаете много объектов, вы можете оптимизировать для удобства ввода (а не для чистоты) и как бы комбинировать метод фабрики Foo::instantiate()
Алана Сторма и with()
глобальный метод Кенании. функциональная техника.
Просто сделайте фабричный метод глобальной функцией с тем же именем, что и у класса!. ;-o (Либо добавьте его как удобную оболочку вокруг правильного статического Foo::instantiate()
, либо просто переместите его туда, пока никто не смотрит.)
class Foo
{
public function xyz()
{
echo "Called","\n";
return $this;
}
}
function Foo()
{
return new Foo();
}
$a = Foo()->xyz();
ЗАМЕТКА: