我必须调用另一个控制器的方法。
我使用以下代码拨打电话。
16.06.2019
这很好。
但是我想尝试使用use函数,这样我就不必重复所有行
app('App\Http\Controllers\ApiUserController')->getList();
我在这里犯了一些错误吗?
答案 0 :(得分:1)
您将需要像这样使用OOP来代替app
函数:
use App\Http\Controllers\ApiUserController;
class MyMethods
{
public function index()
{
$apiUserController = new ApiUserController();
$apiUserController->getList();
但是,正如许多人在这里提到的那样,从另一个控制器中调用一个控制器的方法并不是最佳实践。
因此,如果我在您的位置,我将创建一个助手,在config
中注册其别名,然后使用该助手在两个位置获取列表。
我希望对您有帮助
答案 1 :(得分:0)
从其他控制器或其他对象调用控制器不是一个好习惯。 a good article在这里解释原因。同样,"fat" controllers比“瘦”控制器更不受欢迎。
您应该使用通用逻辑定义服务层对象并使用它。创建服务对象并将其注册到service providers之一。
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Services\YourUserService;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(YourUserService::class);
}
}
之后,您可以使用DI风格的服务。
use App\Services\YourUserService;
class MyMethods
{
protected $userService;
public function __construct(YourUserService $userService)
{
$this->userService = $userService;
}
public function index()
{
$this->userService->foo();
}
}
答案 2 :(得分:0)
我同意学习者上面给出的答案,但是,我不会在代码组织和可测试性方面推荐它。
通过查看代码,我可以看到您需要获取用户列表,这就是为什么必须从另一个控制器调用api用户控制器的原因。但是,您可以轻松地将逻辑提取到服务甚至特征中。
如果要使用特质,则可以执行以下操作,
trait ApiUser {
public function getList()
{
// get the list for users from api
}
}
//Then you can simply use this trait any where you want,
class SomeController
{
// correct namespace for ApiUser trait
use ApiUser;
}
另一种方式,我喜欢根据情况反复使用;坚持编码的原则是接口不要实现。这将是如下的事情。
interface ApiUserInterface
{
public function getList();
}
class ApiUser implements ApiUserInterface
{
public function getList()
{
// logic to get users from api
}
}
确保当应用程序需要接口时,它知道在哪里可以找到其实现。如果您使用Laravel,则可以将接口注册到AppServiceProvider中的类
完成此操作后,您可以在需要合同的任何地方使用此服务。
class OneController
{
protected $apiUserContract;
public function __construct(ApiUserInterface $apiUserContract)
{
$this->apiUserContract = $apiUserContract;
}
public function index()
{
// You can retrieve the list of the contract
$this->apiUserContract->getList();
}
}
// you could also just typehint the contact in method without requiring
// it in constructor and it will get resolved out of IOC i.e. container
class AnotherController
{
public function index(ApiUserInterface $apiUserContract)
{
// You can retrieve the list of the contract
$apiUserContract->getList();
}
}
让我知道您是否需要进一步的解释,希望对您有帮助