问答中心分类: PHP使用Twitter API 1.1版检索user_时间线的最简单PHP示例
0
匿名用户 提问 1月 前

由于推特API 1.0自2013年6月11日,下面的脚本不再有效。

// Create curl resource 
$ch = curl_init(); 
// Set url 
curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/myscreenname.json?count=10"); 
// Return the transfer as a string 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
// $output contains the output string 
$output = curl_exec($ch); 
// Close curl resource to free up system resources 
curl_close($ch);

if ($output) 
{
    $tweets = json_decode($output,true);

    foreach ($tweets as $tweet)
    {
        print_r($tweet);
    }
}

如何以尽可能少的代码获取user_时间线(最近状态)?
我发现:https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline但我得到了以下错误:

"{"errors":[{"message":"Could not authenticate you","code":32}]}"

有很多类,但在尝试了几个之后,由于推特上的这些更新,它们似乎都不起作用,而且其中一些是相当高级的类,具有很多我并不真正需要的功能。
使用PHP获取最近用户状态的最简单/最短方法是什么?

13 Answers
0
Rivers 回答 1月 前

转到dev.twitter。com并创建应用程序. 这将为您提供所需的凭据。这是我最近编写的一个实现PHP卷曲.

<?php
    function buildBaseString($baseURI, $method, $params) {
        $r = array();
        ksort($params);
        foreach($params as $key=>$value){
            $r[] = "$key=" . rawurlencode($value);
        }
        return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
    }

    function buildAuthorizationHeader($oauth) {
        $r = 'Authorization: OAuth ';
        $values = array();
        foreach($oauth as $key=>$value)
            $values[] = "$key=\"" . rawurlencode($value) . "\"";
        $r .= implode(', ', $values);
        return $r;
    }

    $url = "https://api.twitter.com/1.1/statuses/user_timeline.json";

    $oauth_access_token = "YOURVALUE";
    $oauth_access_token_secret = "YOURVALUE";
    $consumer_key = "YOURVALUE";
    $consumer_secret = "YOURVALUE";

    $oauth = array( 'oauth_consumer_key' => $consumer_key,
                    'oauth_nonce' => time(),
                    'oauth_signature_method' => 'HMAC-SHA1',
                    'oauth_token' => $oauth_access_token,
                    'oauth_timestamp' => time(),
                    'oauth_version' => '1.0');

    $base_info = buildBaseString($url, 'GET', $oauth);
    $composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
    $oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
    $oauth['oauth_signature'] = $oauth_signature;

    // Make requests
    $header = array(buildAuthorizationHeader($oauth), 'Expect:');
    $options = array( CURLOPT_HTTPHEADER => $header,
                      //CURLOPT_POSTFIELDS => $postfields,
                      CURLOPT_HEADER => false,
                      CURLOPT_URL => $url,
                      CURLOPT_RETURNTRANSFER => true,
                      CURLOPT_SSL_VERIFYPEER => false);

    $feed = curl_init();
    curl_setopt_array($feed, $options);
    $json = curl_exec($feed);
    curl_close($feed);

    $twitter_data = json_decode($json);

//print it out
print_r ($twitter_data);

?>

这可以从命令行运行:

$ php <name of PHP script>.php
Flatlyn 回复 1月 前

谢谢你的代码片段,工作完美无瑕。唯一的问题是我似乎不知道如何设置post count返回。它只返回20,我想全额,这是200根据推特限制。

PaulSkinner 回复 1月 前

谢谢你这么做。令人沮丧的是,如果不安装应用程序,你就无法再获得人们的推特提要(打折小部件,因为它不具备CSS的灵活性)。

Javier Villanueva 回复 1月 前

你会如何设置screen_namecount用这种方法?我试着把它添加到$url变量,但我得到了一个“无法验证你”的错误。

Zachary Kniebel 回复 1月 前

这太棒了!如果你不介意的话,我想把它作为我的jQuery Twitter插件的示例PHP代码。

kaffolder 回复 1月 前

@zachary kniebel对在Github解决方案中实现缓存支持有何想法?从我所读到的内容来看,将缓存实现到这样的API请求中是一个好主意。我会帮你的,但我对PHP比较陌生。我很想能够使用你的解决方案,但我真的很想在本地缓存一些东西。不确定这是否链接不管有没有帮助,但如果您对如何在PHP脚本中实现缓存有任何想法,请告诉我。

Zachary Kniebel 回复 1月 前

@kaffolder——老实说,我不认为在你的站点代码中使用PHP缓存是你想要的。大约一周前,我计算了在不超过上限的情况下,每个费率周期(5分钟)可以提出多少用户时间表请求。假设我只从一个站点进行查询(即内联页面代码,如您所说),我可以大约每隔15秒刷新一次时间线的结果,并且只使用最大请求数的1/2-2/3。缓存应该用于在页面和用户之间不会改变(或者至少不经常)的数据。

Zachary Kniebel 回复 1月 前

@kaffolder-问题是,您需要确保从特定时间开始计算15秒(即,不是用户访问站点的时间)。这里的问题是没有锁定系统,如果两个用户同时访问,他们都会看到是时候用Twitter数据更新缓存了,并且都会发出请求。这将打破你的利率限制。相反,您想要做的是创建一个web服务或拥有一个单独的服务/后端站点(任何人都不应该访问的站点),将您的数据保存在数据库或其他数据库中

Zachary Kniebel 回复 1月 前

@kaffolder-系统,并在指定的时间间隔更新该数据库/系统。然后,你会让你的站点页面每隔15秒查询一次数据库/系统(同样,从指定的时间开始,尽管我建议你在开始时间加上一两秒,只是为了给查询一些回旋的空间),可以使用AJAX,也可以使用来自PHP代码的请求。您可以根据需要查询该系统,因为它将完全独立于您的用户数量和可导航站点。如果您还有任何问题,请在GitHub页面上写评论或发电子邮件给我(contact@zacharykniebel.com)

Jimbo 回复 1月 前

问题是,它太初级了,任何高于基本请求的操作都会失败。例如,试着在开头加一个@来发送推特。post字段和带有负号和逗号的地理查询中的哈希标记如何?在我的帖子中,这一切都是固定的,我们可以共同努力,使这个库易于每个人使用。

shasi kanth 回复 1月 前

有没有办法为请求指定一些属性,比如include\u entities=false?

Chris 回复 1月 前

这段代码很好用!我正在尝试修改它以使用搜索/推文。json api,但我总是得到“无法验证您”的响应-有什么想法吗?

jessicaraygun 回复 1月 前

这篇文章很有帮助。我的代码似乎没有从返回curl_init()虽然我看了一些例子,它们看起来非常简单明了,与这里的代码一模一样。。。我需要安装一些特殊的东西吗?

Rivers 回复 1月 前

您需要在服务器上安装curl,这是大多数PHP托管平台的标准配置。你能发布你的源代码吗?

J82 回复 1月 前

像我这样的白痴怎么在HTML文件中调用这个来显示推文?还是我错过了什么?

Rivers 回复 1月 前

我不理解你的问题。您需要php来使用上述实现。这可以是打印html的php文件,也可以使用javascript调用php文件。

Jamie Hutber 回复 1月 前

我不明白的是,为什么每个人都被搞得血淋淋的$oauth_access_token = "YOURVALUE"; $oauth_access_token_secret = "YOURVALUE";哈哈,快把我逼疯了

rikkitikkitumbo 回复 1月 前

嗯,这似乎对我不起作用:PHP注意:在/home/jeff/twitter-api/get\u tweets中使用未定义的常量CURLOPT\u HTTPHEADER-假设为“CURLOPT\u HTTPHEADER”。php第41行php注意:在/home/jeff/twitter-api/get\u推文中使用未定义的常量CURLOPT\u头-假设为“CURLOPT\u头”。php第43行php注意:在/home/jeff/twitter-api/get\u推文中使用未定义的常量CURLOPT\u URL-假设为“CURLOPT\u URL”。php第44行php注意:在/home/jeff/twitter-api/get\u推文中使用未定义的常量CURLOPT\u RETURNTRANSFER-假设为“CURLOPT\u RETURNTRANSFER”。php第45行

saadk 回复 1月 前

@Rivers在buildBaseString()的返回行中向我发出警告消息“警告:rawurlencode()期望参数1是字符串,数组给定”。。任何解决方案。。PLSS。我对这一切都不熟悉

Maciej Paprocki 回复 1月 前

在twitter API最近的更改之后,这段代码还能工作吗?这对我来说不管用,但我很可能在路上做了一些愚蠢的事。

Rivers 回复 1月 前

我仍然使用相同的实现。给我发推特@nickthedev,以获得最快的回复。

JohnC 回复 1月 前

它在2016年10月26日对我有效。输出比我预期的要复杂一些。

Rivers 回复 1月 前

确实如此@吉

0
lackovic10 回答 1月 前

Rivers粘贴的代码很棒。谢谢!我是新来的,不能发表评论,我只想回答javiervd的问题(你会如何设置screen\u名称并用这种方法计数?),因为我已经浪费了很多时间来解决这个问题。
您需要将两个参数都添加到URL以及签名创建过程。创建签名是那篇帮助我的文章。这是我的代码:

$oauth = array(
           'screen_name' => 'DwightHoward',
           'count' => 2,
           'oauth_consumer_key' => $consumer_key,
           'oauth_nonce' => time(),
           'oauth_signature_method' => 'HMAC-SHA1',
           'oauth_token' => $oauth_access_token,
           'oauth_timestamp' => time(),
           'oauth_version' => '1.0'
         );

$options = array(
             CURLOPT_HTTPHEADER => $header,
             //CURLOPT_POSTFIELDS => $postfields,
             CURLOPT_HEADER => false,
             CURLOPT_URL => $url . '?screen_name=DwightHoward&count=2',
             CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false
           );
Moe 回复 1月 前

我对此投的票太多了。在推特的API文档中,这会盯着你的脸,但它从来都不是超级“明显的”。这种方法会干扰buildAuthorizationHeader作用我单独实现了它。

lackovic10 回复 1月 前

我已经很长时间没有处理这个问题了,所以我不记得了,如果你还没有解决你的问题,我可以在接下来的几天里调查。

perrohunter 回复 1月 前

我一直在尝试调整您的解决方案,以执行状态/更新帖子。如果运气不好,你知道怎么做到吗?

lackovic10 回复 1月 前

@我不知道佩罗亨特会对此进行更多调查。如果你在几天内找不到办法,给我发一条消息,我会尽力帮你。

0
budiDino 回答 1月 前

如其他答案所述,创建一个Twitter应用程序来获取令牌、密钥和机密。$request阵列输入returnTweet()功能)。

function buildBaseString($baseURI, $method, $params) {
    $r = array();
    ksort($params);
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value);
    }
    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth) {
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\"";
    $r .= implode(', ', $values);
    return $r;
}

function returnTweet(){
    $oauth_access_token         = "x";
    $oauth_access_token_secret  = "x";
    $consumer_key               = "x";
    $consumer_secret            = "x";

    $twitter_timeline           = "user_timeline";  //  mentions_timeline / user_timeline / home_timeline / retweets_of_me

    //  create request
        $request = array(
            'screen_name'       => 'budidino',
            'count'             => '3'
        );

    $oauth = array(
        'oauth_consumer_key'        => $consumer_key,
        'oauth_nonce'               => time(),
        'oauth_signature_method'    => 'HMAC-SHA1',
        'oauth_token'               => $oauth_access_token,
        'oauth_timestamp'           => time(),
        'oauth_version'             => '1.0'
    );

    //  merge request and oauth to one array
        $oauth = array_merge($oauth, $request);

    //  do some magic
        $base_info              = buildBaseString("https://api.twitter.com/1.1/statuses/$twitter_timeline.json", 'GET', $oauth);
        $composite_key          = rawurlencode($consumer_secret) . '&' . rawurlencode($oauth_access_token_secret);
        $oauth_signature            = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
        $oauth['oauth_signature']   = $oauth_signature;

    //  make request
        $header = array(buildAuthorizationHeader($oauth), 'Expect:');
        $options = array( CURLOPT_HTTPHEADER => $header,
                          CURLOPT_HEADER => false,
                          CURLOPT_URL => "https://api.twitter.com/1.1/statuses/$twitter_timeline.json?". http_build_query($request),
                          CURLOPT_RETURNTRANSFER => true,
                          CURLOPT_SSL_VERIFYPEER => false);

        $feed = curl_init();
        curl_setopt_array($feed, $options);
        $json = curl_exec($feed);
        curl_close($feed);

    return json_decode($json, true);
}

然后打电话returnTweet()

Theo 回复 1月 前

budidino干得好!已在上创建应用程序dev.twitter。com/应用程序并用oauth\u access\u令牌、oauth\u access\u令牌、consumer\u密钥、consumer\u密钥填充x。*注意*您需要按“创建我的访问令牌”,生成它需要几秒钟,请等待。

anam 回复 1月 前

@budidino dnt我们需要包括任何图书馆??

J82 回复 1月 前

我填好了钥匙,把这个添加到我的functions.php文件在WordPress中,放置<?php echo returnTweet(); ?>在HTML文件中,它输出单词“Array”而不是其他内容。

budiDino 回复 1月 前

@Desi,结果是推特的数组,你应该处理如何显示每个推特。试试print\u r(returnTweet())看看里面有什么。查看这个显示所有推文的示例:主旨github。com/budidino/9681764#file stackoverflow returntweet

budiDino 回复 1月 前

如果你只想获取最新的推文,你应该修改$request数组并将count设置为1。假设您使用$tweet=returnTweet();然后,如果你想显示最新的推文(在本例中是唯一一条),你可以这样写:echo“latest tweet:”$推特[0][“text”];如果你想提取推文的文本以外的内容,一定要查看推文返回的结构(例如$userProfileImageURL=$tweet[0][“user”][“profile\u image\u url”)。dev.twitter。com/docs/api/1.1/get/statuses/user_timeline

0
Frewuill 回答 1月 前

谢谢你,克里斯!
它在不使用参数的情况下对我有效,每当我使用多个参数时,它都会向我显示错误:32无法对您进行身份验证。
对我来说,问题在于符号编码。所以在你的代码中,它是下面一行

$url .= "?".http_build_query($query);

我在下面添加了以下行:

$url=str_replace("&amp;","&",$url);

它使用了两个或多个参数,如screen\u name和count。
整个代码如下所示:

$token = 'YOUR TOKEN';
$token_secret = 'TOKEN SECRET';
$consumer_key = 'YOUR KEY';
$consumer_secret = 'KEY SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '2'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$url=str_replace("&amp;","&",$url); //Patch by @Frewuill

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);

希望它能帮助我遇到同样问题的人。

Sebastian 回复 1月 前

非常感谢,您的代码改进效果很好!关于一个问题:“//建议使用更强的nonce”。那会是什么?时间()?

Kris Reeves 回复 1月 前

谢谢你指出这一点。塞巴斯蒂安:nonce是一次性使用的令牌,应该是加密安全的。mt_rand()太短(32位),不是加密PRNG。从理论上讲,这使得oauth令牌很弱,但为了简化我的原始示例代码,我想使用一些可以交给PHP并且易于理解的东西。

saadk 回复 1月 前

接收错误32。无法验证您的身份。。有什么帮助吗???我用过你上面的代码

vijay 回复 1月 前

@弗赖尔,你是伟大的兄弟,它的工作我像一个魅力,谢谢。

camillo777 回复 1月 前

@frewuill这是最好的答案,它也可以使用参数,我可以确认它甚至可以使用新的2.0 Twitter API!

0
Kris Reeves 回答 1月 前

这个问题对我帮助很大,但并没有让我完全理解需要发生什么。此博客帖子做了一个了不起的工作,带我通过它。
以下是集中在一个地方的重要信息:

  • 如上所述,您必须签署1.1 API请求。如果您正在执行诸如获取公共状态之类的操作,则需要应用程序密钥而不是用户密钥。指向所需页面的完整链接为:https://dev.twitter.com/apps
  • 必须将所有参数散列在一起,包括oauth参数和get参数(或POST参数)。
  • 必须先对参数进行排序,然后再将其还原为经过哈希处理的url编码形式。
  • 有些东西必须多次编码——例如,从参数的url编码值创建一个查询字符串,然后对其进行url编码,并与方法类型和url连接。

我很同情这些令人头痛的事情,下面是一些代码来总结一下:

$token = 'YOUR TOKEN';
$token_secret = 'TOKEN SECRET';
$consumer_key = 'YOUR KEY';
$consumer_secret = 'KEY SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '2'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);