我遇到了三个问题:
(1) 我没有在这个问题中包含它,但我的签名没有正确创建。
我所做的是 base64_encode(hash_hmac('sha1', $base, $key)); 但我应该将 hash_hmac 第四个参数设置为 true 以返回原始二进制而不是十六进制(十六进制显示为 Twitter 文档中的示例,这就是让我困惑)。因此正确的函数是:base64_encode(hash_hmac('sha1', $base, $key, true));。
(2) cURL 设置不正确。我需要 CURLOPT_HTTPHEADER 来设置授权,并且 CURL_VERBOSE 设置为 true:
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $DST));
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.rawurlencode($status));
curl_setopt($ch, CURLOPT_URL, $url);
(3) 如上面的代码所示,我必须将状态发布为字符串,而不是数组。我在这个问题上找到了解决这个问题的方法:Why can't I authenticate with OAuth?。
所有这些现在都运行良好。此外,请确保您的 Twitter 应用程序中的访问令牌表明访问级别为“读写”。如果没有,请在“设置”中更改权限,然后返回“详细信息”并重新创建您的访问令牌。
完整脚本
<?php
class Tweet {
public $url = 'https://api.twitter.com/1/statuses/update.json';
function the_nonce(){
$nonce = base64_encode(uniqid());
$nonce = preg_replace('~[\W]~','',$nonce);
return $nonce;
}
function get_DST($status){
$url = $this->url;
$consumer_key = $your_consumer_key_here;
$nonce = $this->the_nonce();
$sig_method = 'HMAC-SHA1';
$timestamp = time();
$version = "1.0";
$token = $your_token_here;
$access_secret = $your_access_secret_here;
$consumer_secret = $your_consumer_secret_here;
$param_string = 'oauth_consumer_key='.$consumer_key.
'&oauth_nonce='.$nonce.
'&oauth_signature_method='.$sig_method.
'&oauth_timestamp='.$timestamp.
'&oauth_token='.$token.
'&oauth_version='.$version.
'&status='.rawurlencode($status);
$sig_base_string = 'POST&'.rawurlencode($url).'&'.rawurlencode($param_string);
$sig_key = rawurlencode($consumer_secret).'&'.rawurlencode($access_secret);
$tweet_sig = base64_encode(hash_hmac('sha1', $sig_base_string, $sig_key, true));
$DST = 'OAuth oauth_consumer_key="'.rawurlencode($consumer_key).'",'.
'oauth_nonce="'.rawurlencode($nonce).'",'.
'oauth_signature="'.rawurlencode($tweet_sig).'",'.
'oauth_signature_method="HMAC-SHA1",'.
'oauth_timestamp="'.rawurlencode($timestamp).'",'.
'oauth_token="'.rawurlencode($token).'",'.
'oauth_version="1.0"';
return $DST;
}
function set($status){
$url = $this->url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $this->get_DST($status)));
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'status='.rawurlencode($status));
curl_setopt($ch, CURLOPT_URL, $url);
$result = json_decode(curl_exec($ch));
if(!curl_errno($ch)){
$info = curl_getinfo($ch);
if($info['http_code']!='200'){
//error posting
echo 'Error: '.$result->{'error'};
}else{
//success
echo 'Success! <a href="https://twitter.com/AOKHalifax/status/'.$result->{'id_str'}.'" target="_blank">View Tweet</a>';
}
}else{
//error connecting
echo 'error posting';
}
curl_close($ch);
}
}
/*
Usage example:
$status = new Tweet();
$status->set('checking');
*/
?>