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));
int(5)
bool(true)
例如,当我们有一个提供者时,就会发生这种情况。
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
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return View
*/
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.
– EOF –