【问题标题】:Dynamically updating PHP curl_multi_init URL's based on items within folder directory根据文件夹目录中的项目动态更新 PHP curl_multi_init URL
【发布时间】:2017-01-05 16:01:12
【问题描述】:

我正在尝试从 API 调用信息以检索 $baseURL 中项目的数据。

$url1

用于获取可用性json数据。

$url2

用于获取单个项目的 json 数据。例如:内容、图像、多媒体等。

<?php

 $APIKEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
 $baseURL = 'http://feeds.example.com/v1/';
 $ext =  '.json';

 // calls latest updated items
 $url1   = 'folder';
 // calls specific ID of item with corresponding details
 $url2   = 'folder/item{id}';
 $ch1 = curl_init($baseURL . $url1 . $ext);
 $ch2 = curl_init($baseURL . $url2 . $ext);

 $headers = array();
 $headers[] = 'x-auth-token:' . $APIKEY;
 $headers[] = 'X-Affiliate-Authentication:'. $APIKEY;
 $headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=utf-8';

 curl_setopt($ch1, CURLOPT_USERPWD, $APIKEY);
 curl_setopt($ch1, CURLOPT_HTTPHEADER, $headers);
 curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);

 curl_setopt($ch2, CURLOPT_USERPWD, $APIKEY);
 curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers);
 curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);

 $mh = curl_multi_init();

 curl_multi_add_handle($mh,$ch1);
 curl_multi_add_handle($mh,$ch2);

 $active = null;

 do {
   curl_multi_exec($mh, $active);
 } while ($active);

 $response_1 = curl_multi_getcontent($ch1);
 $response_2 = curl_multi_getcontent($ch2);
 echo "$response_1 $response_2";
 // Add function here

 // Close function here
 curl_multi_remove_handle($mh, $ch1);
 curl_multi_remove_handle($mh, $ch2);

 curl_multi_close($mh);

 ?>

'response_1' 输出(符合预期):

{"data":[{"id":2,"last_update":"2016-08-26 15:43:39"},
{"id":6,"last_update":"2016-08-26 08:57:53"},
{"id":7,"last_update":"2016-08-23 16:49:15"},
{"id":8,"last_update":"2016-08-19 10:20:00"},
{"id":9,"last_update":"2016-08-28 23:44:25"},
{"id":28,"last_update":"2016-08-27 12:45:16"},
{"id":29,"last_update":"2016-08-12 07:55:32"},
{"id":30,"last_update":"2016-07-29 11:00:23"},
{"id":31,"last_update":"2016-07-05 09:48:50"}
. 
.. 
...

'response_2' 输出(这是预期的):

{"data":[
 {
  "id":2,"last_update":"2016-08-26 15:43:39",
  "address":
  {
  "address1":"Foo Bar",
  "address2":"Foo","city":"Bar","state":"FooBar","zip_code":"F00 84R","country":"Foo Bar",
 },
 "details":
 {
 "dwelling_name":"FooBar Hotel","hotel_type":"Big",
 "maximum_capacity":16,
 "base_capacity":16,
 "bedrooms":6,
 "bathrooms":3,
 "currency":"GBP"
 },
 .
 ..
 ...

我需要确定动态更新 $url[] 的最佳方法。以下是我的逻辑,如果你运行它就行不通,因为它当然只是我的笔记......

 // folder/item{id}     
 $url[];
 // Retrieved from 3rd party API for comparison
 $storedUpdate;

  foreach {
   item{id} 
    if $storedUpdate and item{id} matches item{id} from $url1 {
      do nothing
     else {
       POST item{id} data to 3rd party API
       POST $latestUpdate to 3rd party API
     }
   };

我选择 curl_multi_init 是因为它能够(通过阅读它)以异步方式解析数据。由于 item{ids} 很容易超过 3500,将这些手动编码到我的工作中似乎是不合逻辑的,这就是为什么我正在研究动态执行它的合理性。

我一直在搜索互联网、论坛和 php curl 手册,以找到一种动态更新 $url2 的方法,以便它获取所有数据。

我相信我可以使用 $url[] 输入多个网址,但问题似乎仍然存在,因此我必须手动输入这些网址。

feeds.example.com/v1/folder/{id}.json

我不会拐弯抹角,我在很短的时间内就学会了这一点,并且正在努力确定实现目标的最佳实践。

任何帮助将不胜感激。

【问题讨论】:

    标签: php json curl libcurl


    【解决方案1】:

    如果我对您的理解正确,那么您的逻辑有点不对劲。您的第二个请求取决于第一个请求中返回的信息,因此您需要 同步 流而不是 异步 流。异步执行此操作需要...时间旅行。

    如果您仍想获得curl_multi... 函数的好处,则必须将其限制为第二个请求。例如:

    <?php
    
     $APIKEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
     $baseURL = 'http://feeds.example.com/v1/';
     $ext =  '.json';
    
     // calls latest updated items
     $url   = 'folder';
    
     $ch1 = curl_init($baseURL . $url . $ext);
    
     $headers = array();
     $headers[] = 'x-auth-token:' . $APIKEY;
     $headers[] = 'X-Affiliate-Authentication:'. $APIKEY;
     $headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=utf-8';
    
     curl_setopt($ch1, CURLOPT_USERPWD, $APIKEY);
     curl_setopt($ch1, CURLOPT_HTTPHEADER, $headers);
     curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
    
     $response_1 = curl_exec($ch1);
     $response_1_json = json_decode($response_1, true);
     $response_1_data = $response_1_json['data'];
    
     $mh = curl_multi_init();
     $multiHandles = [];
    
     foreach ($response_1_data as $key => $item) {
         $id = $item['id'];
         $multiHandles[$key] = curl_init($baseURL . 'folder/item' . $id . $ext);
         curl_setopt($multiHandles[$key], CURLOPT_USERPWD, $APIKEY);
         curl_setopt($multiHandles[$key], CURLOPT_HTTPHEADER, $headers);
         curl_setopt($multiHandles[$key], CURLOPT_RETURNTRANSFER, true);
         curl_multi_add_handle($mh, $multiHandles[$key]);
     }
    
     $active = null;
    
     do {
       curl_multi_exec($mh, $active);
     } while ($active);
    
     $response_2 = "";
    
     foreach ($response_1_data as $key => $item) {
         $response_2 .= curl_multi_getcontent($multiHandles[$key]);
         curl_multi_remove_handle($mh, $multiHandles[$key]);
     }
    
     echo $response_2;
    
     curl_multi_close($mh);
    
     ?>
    

    我没有机会对此进行测试,因此可能有问题,但希望您能了解我在这里所做的事情的要点。希望这会有所帮助:)

    【讨论】:

    • 为这里的帮助喝彩,对时间旅行感到很失望。在定义“$ch1”时,我将编辑器“$url1”中的一些位更新为“$url”,这很简单。 foreach 循环似乎输出了一个错误,例如:Invalid argument supplied for foreach() 我添加了一个从帖子派生的 if 语句:link by Andy Shellem
    • 评论无效,因为我正在写我的评论,除了我在过去 9 天内从没有 PHP curl 的先验知识中一直在学习这一点之外,我的评论不再有效。我会执行你说的,一会儿回来。
    • 啊,我没有对你的 JSON 给予足够的关注。 $response_1_data = $response_1_json['data']; 行实际上应该是 $response_1_data = $response_1_json-&gt;data;,因为它是一个对象,而不是一个数组。我将编辑代码
    • 我们几乎在同一时间发布了该消息,只需按照我刚才的建议尝试更改行...这应该是您新错误的根源。
    • Notice: Trying to get property of non-object 是上述更改的错误Warning: Invalid argument supplied for foreach() 是因为我删除了前面提到的 IF 语句curl_multi_getcontent() expects parameter 1 to be resource, null given Undefined variable: ch2 这是因为 $url1 已更改为 @ 987654331@ 和因此 $url2 不存在,因此没有将 $ch2 设置为 $baseURL . $url2 . $ext
    猜你喜欢
    • 2018-08-18
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多