使用正确的工具扩展Laravel软件包

使用正确的工具扩展Laravel软件包,laravel,laravel-5,Laravel,Laravel 5,在我的应用程序中,我安装了这个包来进行http/curl请求 然后,我创建了一个ExternalController来扩展Guzzle包的功能,如下所示: namespace App\Http\Controllers; use GuzzleHttp\Client as GuzzleHttpClient; use GuzzleHttp\Exception\ClientException as ClientException; class ExternalController extends C

在我的应用程序中,我安装了这个包来进行http/curl请求

然后,我创建了一个ExternalController来扩展Guzzle包的功能,如下所示:

namespace App\Http\Controllers;

use GuzzleHttp\Client as GuzzleHttpClient;
use GuzzleHttp\Exception\ClientException as ClientException;

class ExternalController extends Controller
{
    protected $endpoint = '';
    protected $method   = '';

    public function __construct()
    {
        $this->debug = env("APP_DEBUG", false);
    }

    /**
     * Crypts Server call
     */

    public function encodeCall($method = 'GET', $endpoint = "server_status")
    {
        $EXTERNAL_PROTOCOL         = config('myconfig.EXTERNAL_PROTOCOL');
        $EXTERNAL_IP               = config('myconfig.EXTERNAL_IP');
        $EXTERNAL_PORT             = config('myconfig.EXTERNAL_PORT');
        $EXTERNAL_MANAGEMENT_TOKEN = config('myconfig.EXTERNAL_MANAGEMENT_TOKEN');

        //Skip some parameters for security reasons

        $base64hash                = base64_encode($str2hash);

        $request_url = "${EXTERNAL_PROTOCOL}://${EXTERNAL_IP}:${EXTERNAL_PORT}/manage/${endpoint}?salt=${salt}&hash=${base64hash}";

        $requestContent = [
            'headers' => [
                'Accept'       => 'application/json',
                'Content-Type' => 'application/json',
            ],
        ];

        try {

            $client   = new GuzzleHttpClient();
            $curl     = $client->request($method, $request_url, $requestContent);
            $response = json_decode($curl->getBody());

            return response()->json($response);

        } catch (RequestException $RequestException) {

            return response()->json(['message' => (string) $ClientException]);

        }
    }

    /**
     * Returns Server Status
     * @return \Illuminate\Http\Response
     */
    public function getServerStatus()
    {
        $method   = 'GET';
        $endpoint = "server_status";

        return $this->encodeCall($method, $endpoint);
    }

}
//AnotherController.php

$server = new ExternalController;
return $server->getServerStatus();
我需要从另一个控制器调用一些方法,如下所示:

namespace App\Http\Controllers;

use GuzzleHttp\Client as GuzzleHttpClient;
use GuzzleHttp\Exception\ClientException as ClientException;

class ExternalController extends Controller
{
    protected $endpoint = '';
    protected $method   = '';

    public function __construct()
    {
        $this->debug = env("APP_DEBUG", false);
    }

    /**
     * Crypts Server call
     */

    public function encodeCall($method = 'GET', $endpoint = "server_status")
    {
        $EXTERNAL_PROTOCOL         = config('myconfig.EXTERNAL_PROTOCOL');
        $EXTERNAL_IP               = config('myconfig.EXTERNAL_IP');
        $EXTERNAL_PORT             = config('myconfig.EXTERNAL_PORT');
        $EXTERNAL_MANAGEMENT_TOKEN = config('myconfig.EXTERNAL_MANAGEMENT_TOKEN');

        //Skip some parameters for security reasons

        $base64hash                = base64_encode($str2hash);

        $request_url = "${EXTERNAL_PROTOCOL}://${EXTERNAL_IP}:${EXTERNAL_PORT}/manage/${endpoint}?salt=${salt}&hash=${base64hash}";

        $requestContent = [
            'headers' => [
                'Accept'       => 'application/json',
                'Content-Type' => 'application/json',
            ],
        ];

        try {

            $client   = new GuzzleHttpClient();
            $curl     = $client->request($method, $request_url, $requestContent);
            $response = json_decode($curl->getBody());

            return response()->json($response);

        } catch (RequestException $RequestException) {

            return response()->json(['message' => (string) $ClientException]);

        }
    }

    /**
     * Returns Server Status
     * @return \Illuminate\Http\Response
     */
    public function getServerStatus()
    {
        $method   = 'GET';
        $endpoint = "server_status";

        return $this->encodeCall($method, $endpoint);
    }

}
//AnotherController.php

$server = new ExternalController;
return $server->getServerStatus();
我通常不调用另一个控制器中的控制器,但我不知道足够的Laravel来理解什么是正确的工具


我对Laravel是新手,所以也许我需要创建一个服务提供商来实现这一点?如果是这样,正确的方法是什么?

是的,服务是放置公共代码的好地方,控制器应该使用这些服务,而不是相互调用


很难举一些例子,但我试着解释一下在您的情况下该怎么做:不要创建ExternalController创建ExternalRequests服务,它将准备数据并使用guzzle将请求发送到外部API,并且在您的控制器中只使用该服务。

是,服务是放置公共代码的好地方,控制器应该使用这些服务,而不是互相调用


很难举一些例子,但我试着解释一下在你的例子中该怎么做:不要创建ExternalController创建ExternalRequests服务,它将准备数据并使用guzzle将请求发送到外部API,并且在你的控制器中只使用该服务。

听起来你需要一个服务。我可以将共享代码放入服务中,并从不同的控制器/命令/作业等调用它

服务

控制器A

控制器B


听起来你需要服务。我可以将共享代码放入服务中,并从不同的控制器/命令/作业等调用它

服务

控制器A

控制器B


您完全可以从另一个控制器调用控制器

然而,这并不是控制器要做的。在您的特定情况下,您创建了一个HTTP客户机,并且很可能在多个地方使用它

我会这样做的。首先,我将在App\Services\Http中定义一个HttpClientContract

。。然后我会有一个实现,如下所示:

namespace App\Services\Http;

use GuzzleHttp\Client as GuzzleHttpClient;
use GuzzleHttp\Exception\ClientException as ClientException;

class HttpClient implements HttpClientContract
{
    protected $endpoint = '';
    protected $method   = '';

    public function __construct()
    {
        $this->debug = env('APP_DEBUG', false);
    }

    public function encodeCall($method = 'GET', $endpoint = 'server_status')
    {
        $EXTERNAL_PROTOCOL         = config('myconfig.EXTERNAL_PROTOCOL');
        $EXTERNAL_IP               = config('myconfig.EXTERNAL_IP');
        $EXTERNAL_PORT             = config('myconfig.EXTERNAL_PORT');
        $EXTERNAL_MANAGEMENT_TOKEN = config('myconfig.EXTERNAL_MANAGEMENT_TOKEN');

        //Skip some parameters for security reasons

        $base64hash                = base64_encode($str2hash);

        $request_url = "${EXTERNAL_PROTOCOL}://${EXTERNAL_IP}:${EXTERNAL_PORT}/manage/${endpoint}?salt=${salt}&hash=${base64hash}";

        $requestContent = [
            'headers' => [
                'Accept'       => 'application/json',
                'Content-Type' => 'application/json',
            ],
        ];

        try {

            $client   = new GuzzleHttpClient();
            $curl     = $client->request($method, $request_url, $requestContent);
            $response = json_decode($curl->getBody());

            return response()->json($response);

        } catch (RequestException $RequestException) {

            return response()->json(['message' => (string) $ClientException]);

        }
    }

    public function getServerStatus()
    {
        $method   = 'GET';
        $endpoint = "server_status";

        return $this->encodeCall($method, $endpoint);
    }

}
最后,我们需要在应用程序的服务容器中注册新的Http客户机。 我们将使用服务提供商来实现这一点:

<?php

namespace App\Providers;

use App\Services\HttpClient;
use App\Services\HttpClientContract;
use Illuminate\Support\ServiceProvider;

class HttpClientServiceProvider extends ServiceProvider
{
    /**
    * Register bindings in the container.
    *
    * @return void
    */
    public function register()
    {
        $this->app->bind(HttpClientContract::class, function ($app) {
            return new HttpClient();
        });
    }
}
现在,无论何时,您需要使用它,您只需要从容器中解析它。如果在方法中键入hint依赖项,Laravel将使用反射通过容器自动解析它

public function makeRequest(HttpClientContract $client)
{
    return $client->encodeCall(); 
}
通过这种方式,我们应用了几个OOP原则。 首先,我们将编码到接口,而不是实现

如果您的HTTP客户机的实现在将来发生变化,您只需要简单地绑定新的

我们还将依赖注入到方法中,而不是在方法中实例化它。这允许我们在测试期间交换/模拟HTTP客户机的实现,这对于HTTP客户机来说非常有意义


阅读更多关于和的信息。

您完全可以从另一个控制器调用控制器

然而,这并不是控制器要做的。在您的特定情况下,您创建了一个HTTP客户机,并且很可能在多个地方使用它

我会这样做的。首先,我将在App\Services\Http中定义一个HttpClientContract

。。然后我会有一个实现,如下所示:

namespace App\Services\Http;

use GuzzleHttp\Client as GuzzleHttpClient;
use GuzzleHttp\Exception\ClientException as ClientException;

class HttpClient implements HttpClientContract
{
    protected $endpoint = '';
    protected $method   = '';

    public function __construct()
    {
        $this->debug = env('APP_DEBUG', false);
    }

    public function encodeCall($method = 'GET', $endpoint = 'server_status')
    {
        $EXTERNAL_PROTOCOL         = config('myconfig.EXTERNAL_PROTOCOL');
        $EXTERNAL_IP               = config('myconfig.EXTERNAL_IP');
        $EXTERNAL_PORT             = config('myconfig.EXTERNAL_PORT');
        $EXTERNAL_MANAGEMENT_TOKEN = config('myconfig.EXTERNAL_MANAGEMENT_TOKEN');

        //Skip some parameters for security reasons

        $base64hash                = base64_encode($str2hash);

        $request_url = "${EXTERNAL_PROTOCOL}://${EXTERNAL_IP}:${EXTERNAL_PORT}/manage/${endpoint}?salt=${salt}&hash=${base64hash}";

        $requestContent = [
            'headers' => [
                'Accept'       => 'application/json',
                'Content-Type' => 'application/json',
            ],
        ];

        try {

            $client   = new GuzzleHttpClient();
            $curl     = $client->request($method, $request_url, $requestContent);
            $response = json_decode($curl->getBody());

            return response()->json($response);

        } catch (RequestException $RequestException) {

            return response()->json(['message' => (string) $ClientException]);

        }
    }

    public function getServerStatus()
    {
        $method   = 'GET';
        $endpoint = "server_status";

        return $this->encodeCall($method, $endpoint);
    }

}
最后,我们需要在应用程序的服务容器中注册新的Http客户机。 我们将使用服务提供商来实现这一点:

<?php

namespace App\Providers;

use App\Services\HttpClient;
use App\Services\HttpClientContract;
use Illuminate\Support\ServiceProvider;

class HttpClientServiceProvider extends ServiceProvider
{
    /**
    * Register bindings in the container.
    *
    * @return void
    */
    public function register()
    {
        $this->app->bind(HttpClientContract::class, function ($app) {
            return new HttpClient();
        });
    }
}
现在,无论何时,您需要使用它,您只需要从容器中解析它。如果在方法中键入hint依赖项,Laravel将使用反射通过容器自动解析它

public function makeRequest(HttpClientContract $client)
{
    return $client->encodeCall(); 
}
通过这种方式,我们应用了几个OOP原则。 首先,我们将编码到接口,而不是实现

如果您的HTTP客户机的实现在将来发生变化,您只需要简单地绑定新的

我们还将依赖注入到方法中,而不是在方法中实例化它。这允许我们在测试期间交换/模拟HTTP客户机的实现,这对于HTTP客户机来说非常有意义


阅读更多关于和的信息。

好的,我会尝试一下,并让您知道!好的,我会试试,让你知道!非常感谢你。这太棒了!非常感谢你。这太棒了!