如何在不使用 curl 和 guzzle 的情况下从控制器 Laravel 调用 API,因为它不起作用 [关闭]

Posted

技术标签:

【中文标题】如何在不使用 curl 和 guzzle 的情况下从控制器 Laravel 调用 API,因为它不起作用 [关闭]【英文标题】:How to call API from controller Laravel without using curl and guzzle as its not working [closed] 【发布时间】:2019-09-27 23:34:53 【问题描述】:

如何在 laravel 中使用帮助程序从控制器调用 API,而不使用 curl 和 guzzle,因为两者都没有返回任何内容。我在邮递员中测试过,api 工作正常,但在 laravel 中没有。 我需要从不同的控制器调用多个 API,那么有什么好方法可以做到这一点?我应该建立一个帮手吗?

我使用 curl,但它总是给我一个错误的响应。

编辑:

我正在寻找一种可靠的方法来对各种 url 进行 api 调用,而不必为我要使用的每个 api 重写发送和接收代码。 最好是实现“干”(不要重复自己)原则的解决方案,并将作为任何 api 特定逻辑的基础(解析模型的响应/翻译)。那东西会扩展这个基础。

【问题讨论】:

那么,为什么不为此编写一些代码呢?没有一种“最佳方式”可以做到这一点 @NicoHaase 是的,但我的意思是我需要一个助手,所以我应该为此创建一个助手。 @MahendraPratap 在 laravel 中没有最适合帮助的地方。我总是把它们放在 App\Helpers “在哪里”是什么意思?您是否尝试过查找该主题?使用 Google,我找到了大量教程 - 如果它们与您的用例不匹配,您应该说明原因 最佳实践是最适合您的。下一个最佳实践是其他人所描述的方式 - 到目前为止你发现了什么,你为什么要为你发现的东西苦苦挣扎? 【参考方案1】:

更新 Laravel 7.x 和 8.x。现在我们可以使用内置的 Http(Guzzle HTTP) 客户端了。

docs:: https://laravel.com/docs/8.x/http-client#making-requests

use Illuminate\Support\Facades\Http;

$response = Http::get('https://jsonplaceholder.typicode.com/posts');

$response = Http::post('https://jsonplaceholder.typicode.com/posts', [
    'title' => 'foo',
    'body' => 'bar',
    'userId' => 1
]);

$response = Http::withHeaders([
    'Authorization' => 'token' 
])->post('http://example.com/users', [
    'name' => 'Akash'
]);

$response->body() : string;
$response->json() : array|mixed;
$response->object() : object;
$response->collect() : Illuminate\Support\Collection;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->failed() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;

对于 Laravel

文档:https://docs.guzzlephp.org/en/stable/index.html

安装

composer require guzzlehttp/guzzle

获取

$client = new \GuzzleHttp\Client();
$response = $client->get('https://jsonplaceholder.typicode.com/posts'); 
return $response;

发布

$client = new \GuzzleHttp\Client();
$body = [
    'title' => 'foo',
    'body' => 'bar',
    'userId' => 1
]; 
$response = $client->post('https://jsonplaceholder.typicode.com/posts', ['form_params' => $body]); 
return $response;

一些有用的方法

$response->getStatusCode(); 
$response->getHeaderLine('content-type');  
$response->getBody();  
我们也可以添加标题
$header = ['Authorization' => 'token'];
$client = new \GuzzleHttp\Client();
$response = $client->get('example.com', ['headers' => $header]); 

此方法的助手

我们可以为这些方法创建一个通用助手。

在 app 文件夹中创建 Helpers 文件夹
app\Helpers
然后在 Helpers 文件夹中创建一个文件 Http.php
app\Helpers\Http.php
在 Http.php 中添加这段代码
<?php

namespace App\Helpers;

use GuzzleHttp;

class Http


    public static function get($url)
    
        $client = new GuzzleHttp\Client();
        $response = $client->get($url);
        return $response;
    


    public static function post($url,$body) 
        $client = new GuzzleHttp\Client();
        $response = $client->post($url, ['form_params' => $body]);
        return $response;
    



现在,您可以在控制器中使用此助手。
<?php

namespace App\Http\Controllers;
 
use Illuminate\Routing\Controller as BaseController;
use App\Helpers\Http;

class Controller extends BaseController


    /* ------------------------ Using Custom Http Helper ------------------------ */
    public function getPosts()
    
        $data = Http::get('https://jsonplaceholder.typicode.com/posts');
        $posts = json_decode($data->getBody()->getContents());
        dd($posts);
    


    public function addPost()
    
        $data = Http::post('https://jsonplaceholder.typicode.com/posts', [
            'title' => 'foo',
            'body' => 'bar',
            'userId' => 1
        ]);
        $post = json_decode($data->getBody()->getContents());
        dd($post);
    


没有助手

在主控制器中我们可以创建这些函数
<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController


    public function get($url)
    
        $client = new GuzzleHttp\Client();
        $response = $client->get($url);
        return $response;
    


    public function post($url,$body) 
        $client = new GuzzleHttp\Client();
        $response = $client->post($url, ['form_params' => $body]);
        return $response;
    

现在我们可以在控制器中调用
<?php

namespace App\Http\Controllers;
   
class PostController extends Controller

    public function getPosts()
    
        $data = $this->get('https://jsonplaceholder.typicode.com/posts');
        $posts = json_decode($data->getBody()->getContents());
        dd($posts);
    


    public function addPost()
    
        $data = $this->post('https://jsonplaceholder.typicode.com/posts', [
            'title' => 'foo',
            'body' => 'bar',
            'userId' => 1
        ]);
        $post = json_decode($data->getBody()->getContents());
        dd($post);
    

【讨论】:

您能否进一步解释一下如何使用这段代码很好地查询多个控制器中的多个 API,仍然遵循 DRY? @NicoHaase 感谢您的建议。当然我会做更多的解释 不过,这对我来说只是一个关于如何使用 Guzzle 的教程。关于如何提供在多个控制器中使用多个 API 的最佳方式的最初问题仍然悬而未决。是否应该将此代码复制到每个单独的控制器? @NicoHaase 我按照你的建议编辑了我的答案

以上是关于如何在不使用 curl 和 guzzle 的情况下从控制器 Laravel 调用 API,因为它不起作用 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

PHP - 为啥使用 Guzzle 而不是 cURL?

如何在不使用 CURL 的情况下运行 HTTP 请求

如何在不使用服务器端缓存的情况下调用 cURL?

如何使用Curl将这个mailchimp API请求转换为使用PHP的Guzzle?

如何在 Guzzle 通话中通过登录屏幕

使用 Guzzle 捕获 CUrl 超时异常