【问题标题】:Using the cURL output使用 cURL 输出
【发布时间】:2012-04-26 16:59:05
【问题描述】:

我计划录制有关特定主题的实时推文。同样,我在 PHP 中使用带有 cURL 的 twitter 流 API。

代码如下:

<?php

$username = "xxxxx";
$password = "xxxxx";


$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://stream.twitter.com/1/statuses/filter.json?         track=SEARCH_PARAMETER');
curl_setopt($ch, CURLOPT_USERPWD, $username.":".$password);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$result = curl_exec($ch);
$jsonOBJ = json_decode ($result);

curl_close($ch);

print_r($jsonOBJ);
?>

我的问题是,如果我将 CURLOPT_RETURNTRANSFER 设置为 0,我可以在终端上看到推文。但我无法存储在变量 $jsonOBJ 中并打印出来。

请帮忙!

【问题讨论】:

  • 使用 sdk for php 和 oauth 会不会更容易?
  • 在尝试解码之前打印出 $result 以查看它的样子。
  • 现在,我直接做这个“echo $result;”。但执行此脚本时没有任何显示。
  • 您正在尝试解码可能达到 10000 或超过 125MB 数据的结果 .... 您应该使用 stream 而不是 curl
  • @Baba 我添加了“curl_setopt($ch, CURLOPT_TIMEOUT, 30);”这样我获得的数据量有限并终止了 cURL 操作。但仍然没有数据存储在变量中。并感谢您的建议。我会研究“流”

标签: php curl twitter-streaming-api


【解决方案1】:

更新:请参阅消息末尾的新代码,这实际上用 cURL 很容易做到,但我第一次做错了。

我无法让 Twitter 流 API 使用 cURL 和 CURLOPT_READFUNCTION 一起工作,但使用 fsockopen()fread() 已经成功。我不确定为什么 readfunction 没有像我之前成功使用它那样工作,但它一定与响应数据是“流式传输”并且不是使用 HTTP 分块编码发送的事实有关。本质上,我的读取函数从未被调用,因此我无法处理数据。

我现在使用的方法:

  • 使用 fsockopen 连接到 ssl://stream.twitter.com
  • 使用fputs发出流数据的基本HTTP请求
  • 使用 HTTP 响应标头并确保没有错误
  • 在无限循环中使用fread读取数量数据
  • 每次读取一大块数据时,我都会调用一个内部缓冲区函数
  • 缓冲区函数将新数据附加到缓冲区中
  • 缓冲区函数然后尝试处理缓冲区中的所有消息(如果我们有 1 条或更多完整消息)
  • 在处理每条消息时,缓冲区会减少,直到它为空,然后函数返回并再次读取数据

我已经让它运行了几个小时,并且没有断开连接,并且我已经处理了超过 30,000 条消息,还没有出现任何错误。

基本上我实现了一个回调系统,以便每次从缓冲区读取完整消息时,它都会使用 json 消息调用用户定义的回调,以便应用程序可以对消息执行任何需要执行的操作(例如插入到数据库)。

我还没有任何简短的 sn-ps 可以在这里发布,但如果您愿意,请访问我的个人资料中列出的网站并填写联系表给我发消息,我很乐意分享。如果有人有兴趣,也许我们可以一起工作。我这样做只是为了好玩,我对 Twitter 没有兴趣,也没有出于经济原因使用它。或许我最终会把它放到 GitHub 上。

编辑:

这里是一些 cURL 代码,它们将连接到流 API 并将 JSON 消息传递给回调函数,因为它们是可用的。本示例使用 gzip 编码来节省带宽。

<?php

$USERNAME = 'youruser';
$PASSWORD = 'yourpass';
$QUERY    = 'nike';

/**
 * Called every time a chunk of data is read, this will be a json encoded message
 * 
 * @param resource $handle The curl handle
 * @param string   $data   The data chunk (json message)
 */
function writeCallback($handle, $data)
{
    /*
    echo "-----------------------------------------------------------\n";
    echo $data;
    echo "-----------------------------------------------------------\n";
    */

    $json = json_decode($data);
    if (isset($json->user) && isset($json->text)) {
        echo "@{$json->user->screen_name}: {$json->text}\n\n";
    }

    return strlen($data);
}

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://stream.twitter.com/1/statuses/filter.json?track=' . urlencode($QUERY));
curl_setopt($ch, CURLOPT_USERPWD, "$USERNAME:$PASSWORD");
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'writeCallback');
curl_setopt($ch, CURLOPT_TIMEOUT, 20); // disconnect after 20 seconds for testing
curl_setopt($ch, CURLOPT_VERBOSE, 1);  // debugging
curl_setopt($ch, CURLOPT_ENCODING,  'gzip, deflate'); // req'd to get gzip
curl_setopt($ch, CURLOPT_USERAGENT, 'tstreamer/1.0'); // req'd to get gzip

curl_exec($ch); // commence streaming

$info = curl_getinfo($ch);

var_dump($info);

【讨论】:

  • 非常感谢您的建议。现在,我通过使用搜索推特 API 找到了解决方法。当我再次使用流式 API 时,我一定会与您联系。
  • @Rubie_Newbie 我添加了一个使用 cURL 的流 API 的工作示例。我在 C# 中也有一个工作版本。这个 php 类 phirehose 你可能也会感兴趣,虽然它不支持 gzip。
【解决方案2】:

我也在做同样的事情 :) 问题是当你在终端中做这件事时,它是一个流,所以连接会保持活动状态,直到你杀死它。 (即 curl_exec() 没有完成)

尝试查看 CURLOPT_PROGRESSFUNCTION 和 CURLOPT_READFUNCTION。他们可能会给你一些提示。

【讨论】:

  • 我添加了“curl_setopt($ch, CURLOPT_TIMEOUT, 30);”杀死 curl_exec()。但是变量中仍然没有存储数据。
  • 这 30 秒内有推文吗?
  • 是的。我可以通过将其打印到终端来查看它们。
  • 老实说,我正在尝试解决同样的问题。问题是我们不能每 30 秒连接一次推特,他们会阻止我们。只要我们打算读取流,我们就需要为它们打开一个连接。所以它可能必须在后台运行,将其写入另一个流,然后网页读取第二个流......或者可能有一种我没有想到的更简单的方法。
【解决方案3】:

@Reza Sanaie 和其他可能觉得这很有帮助的人。

我使用了 SEARCH TWITTER API 并获得了实时推文。所以这可能会有所帮助。 代码如下:

<?php
$query = "SEARCH_PARAMETER";
$request = "http://search.twitter.com/search.json?q=".urlencode($query);
$response = file_get_contents($request);
$jsonobj = json_decode($response);
 print_r($jsonobj);
?>

我还设置了 MySQL 连接以将其推送到数据库中,并且此脚本被添加到 crontab 中以自动化整个过程。

【讨论】:

    【解决方案4】:

    我只是在赶时间给你一个答案。看起来应该可以了。

    下面是我使用的一个函数,我将一个 URL 和一些 XML 数据传递给它,它返回一个关联数组,表示成功或失败,返回值作为字符串。

    function do_curl($url, $data)
        {
        $ch = curl_init();    
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $result = curl_exec ($ch);
    
        $curl_return=array();
    
        if (!is_string($result))
            {
            $curl_return['STATUS'] = FALSE;
            $curl_return['ERRMSG'] = curl_error($ch);
            }
        else
            {
            $curl_return['STATUS'] = TRUE;
            $curl_return['RESPONSE'] = $result;
            }
        curl_close($ch); 
        return $curl_return;
        }
    

    【讨论】:

      猜你喜欢
      • 2018-05-06
      • 1970-01-01
      • 2014-04-25
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      相关资源
      最近更新 更多