why they are magic? Because they are magically called by PHP when specific actions happen.
The __invoke()
method is called when a script tries to call an object as a function.
<?php class CallableClass { public function __invoke ($x ) { var_dump ($x ); } } $obj = new CallableClass ;$obj (5 );var_dump (is_callable ($obj ));
使用明显的操作方法初始化 例如,当我们有一个提供者时,就会发生这种情况。
aws-sdk-php/src/Endpoint/PatternEndpointProvider.php
public function __invoke (array $args = [] ) { $service = isset ($args ['service' ]) ? $args ['service' ] : '' ; $region = isset ($args ['region' ]) ? $args ['region' ] : '' ; $keys = ["{$region} /{$service} " , "{$region} /*" , "*/{$service} " , "*/*" ]; foreach ($keys as $key ) { if (isset ($this ->patterns[$key ])) { return $this ->expand ( $this ->patterns[$key ], isset ($args ['scheme' ]) ? $args ['scheme' ] : 'https' , $service , $region ); } } return null ; }
它使用 invoke 使用一些参数提供端点。我们如何使用这个类?
public function testReturnsNullWhenUnresolved ( ) { $e = new PatternEndpointProvider (['foo' => ['rules' => []]]); $this ->assertNull ($e (['service' => 'foo' , 'region' => 'bar' ])); }
尝试使用单动作控制器? 控制器应该大而广泛?他们不应该。我们应该有瘦控制器和胖服务。
在这里,invoke 可以帮助我们,因为我们可以定义一个只处理单个动作的控制器,并在其上放置单个 invoke 方法。
这也有助于我们实现单一职责原则,即 SOLID 中的 S,这是前五个面向对象设计 (OOD) 原则的首字母缩写词。
A class should have one and only one reason to change, meaning that a class should have only one job.
在 Laravel 中的例子:Single Action Controllers | laravel :
<?php namespace App \Http \Controllers ;use App \User ;use App \Http \Controllers \Controller ;class ShowProfile extends Controller { public function __invoke ($id ) { return view ('user.profile' , ['user' => User ::findOrFail ($id )]); } }
然后,在注册路由时,我们不需要指定方法名称。只有类名。
<?php Route ::get ('user/{id}' , 'ShowProfile' );
This way we can have Single Action Controllers.
实现回调函数 by GPT class Sorter { public function __invoke ($a , $b ) { return $a <=> $b ; } } $numbers = [3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 , 5 ];usort ($numbers , new Sorter ());print_r ($numbers );
实现函数式编程 by GPT class Adder { private $value ; public function __construct ($value ) { $this ->value = $value ; } public function __invoke ($x ) { return $this ->value + $x ; } } $add5 = new Adder (5 );$result = $add5 (3 );
References – EOF –