私は3つの問題を抱えていました:
(1)この質問には含めませんでしたが、署名が正しく作成されませんでした。
私がやっていたのはbase64_encode(hash_hmac('sha1', $base, $key));
、hash_hmacの4番目のパラメーターを設定して、16true
進数ではなく生のバイナリを返すようにする必要がありました(16進数は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)上記のコードに見られるように、配列ではなく文字列としてステータスを投稿する必要がありました。この質問でこの問題の解決策を見つけました:なぜ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');
*/
?>