SQLの窓

2016年12月11日


jQuery で呼び出した PHP で twitteroauth を使用してツイート(画像も簡単)するサンプル

基本的にブラウザとサーバの直接的なやりとりでサーバに処理をさせるのは、アプリケーションとして必ず複雑になり、メンテナンスにも労力を費やす事となるので、jQuery が前提となる環境では、$.ajax を使用するのが何より簡単になります。

abraham/twitteroauth

twitteroauth を使えば、PHP 側では簡単にツイートが可能になり、画像のアップロードも $.ajax で行えばとてもシンプルに機能を果たす事ができます。

ここでは、全体を説明しませんが、Bootstrap を画面に使用し、スマホ対応が容易になっており、また、だからこそ $.ajax との親和性も高くなっています。

$.ajax 呼び出し部分
	// *************************************
	// 送信ボタン
	// *************************************
	$("#frm").submit( function(event){
		// 本来の送信処理はキャンセル
		event.preventDefault();

		$("#post_check").modal();

	} );


	// **************************************
	// Bootstrap OK ボタン
	// **************************************
	$("#data_post").on("click", function(){

		// エラーメッセージエリアをクリア
		$(".error").next().text( "" );

		// 結果の表示エリアを全てクリア
		$("#result").html( "" );

		// **************************************
		// サーバへ送信
		// **************************************

		// 新規送信用オブジェクト
		var formData = new FormData();

		// 送信フィールド作成
		formData.append("text", $("#row1_fld").val());

		// **************************************
		// サーバ呼び出し
		// **************************************
		$.ajax({
			url: "./post_action.php",
			type: "POST",
			data: formData,
			processData: false,
			contentType: false
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );
			options.info("処理が完了しました");

		})
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
			options.info("アップロードに失敗しました");
		})
		.always(function() {

		})
		;

	});
Bootstrap では、Form ありきで画面設計されているので、その機能を十分に使用できるように、submit イベントで event.preventDefault() を実行し、処理は Bootstrap(JS) のダイアログ側で呼び出しています。

PHP 側の処理は、ツイートするのみの post_action.php が行います。

post_action.php
<?php
// *************************************
// キャラクタセット
// *************************************
header( "Content-Type: application/json; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();


// *************************************
// ライブラリ 
// https://twitteroauth.com/
// *************************************
require "twitteroauth/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
 
// *************************************
// API 情報
// https://apps.twitter.com
// *************************************
$consumer_key			= "";
$consumer_secret		= "";
$access_token			= "";
$access_token_secret	= "";
 
// *************************************
// POST
// *************************************
$connection = new TwitterOAuth($consumer_key, $consumer_secret, $access_token, $access_token_secret);
$result = $connection->post("statuses/update", ["status" => $_POST['text'] ]);

// *************************************
// POST 画像
// *************************************
/*
$connection = new TwitterOAuth($consumer_key, $consumer_secret, $access_token, $access_token_secret);
$media1 = $connection->upload('media/upload', ['media' => 'images/image1.png']);
$media2 = $connection->upload('media/upload', ['media' => 'images/image2.png']);
$parameters = [
	'status' => '画像投稿です https://twitteroauth.com/ サンプルそのまま',
	'media_ids' => implode(',', [$media1->media_id_string, $media2->media_id_string])
];
$result = $connection->post('statuses/update', $parameters);
*/

$_POST['result'] = $result;
 

// *************************************
// PHP の結果を result キーで
// JSON としてブラウザに返す
// *************************************
print json_encode($_POST , JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT );


?>

ソースコードを解りやすくするために、コメント内で固定の画像を含めたツイートの処理があります。(実際は、画像データが jQuery の $.ajax で送られて来るようにします。)

API 情報は、Twitter のページの右下にあるリンクの『開発者』から移動し、My apps でアプリケーションを作成して Keys and Access Tokens のタブより取得するわけですが、昔は無かったモバイルの登録が必要になります。

モバイルの登録は、元の Twitter のページの『設定』にありますが、ソフトバンクのスマホから電話番号を登録する場合は注意が必要です。

デフォルトでは海外から通信を遮断している

My Softbank の設定で海外からの受信の拒否を解除する必要がありますが、やはり海外からは拒否したいのが普通ですから、登録後は元に戻しておいたほうがいいと思います。

迷惑メールフォルダ機能を使っている場合

登録されていないところからのメールは迷惑フォルダに入って気が付かない可能性もあるので注意です。



タグ:jquery twitter PHP
posted by lightbox at 2016-12-11 02:08 | Comment(0) | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年11月26日


Twitter の検索結果の JSONのフォーマット を PHP の クラスを使って出力(エミュレート)する

ある機械部品やソフトウェアを動作させるのに、オリジナルのシステムを用意するのが難しい場合に、オリジナルと全く同じ動作をするより簡便なシステムを用意することがある。この装置をエミュレータと言う
Twitter の検索結果を Java や C#(mvvmのバインドでは必須) で一覧表示する場合、JSON の構造をクラスで定義しておいて読み込む事が一般的だと思いますが、そのような仕様で動作しているアプリケーションでは、Twitter の検索結果ではなく自前のデータベースで置き換える事によって独自の検索アプリケーションへと比較的簡単に転換する事ができます(既に定義済みのクラス構造を転用する)。 その場合の PHP を使って同様のフォーマットを出力したい場合のサンプルコードです
<?php
header( "Content-Type: application/json; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

class Twitter_Base {

	public $statuses;

}

class Twitter_User {

	public $id;
	public $name;

}

class Twitter_Search {

	public $user;
	public $text;

}

for( $i = 0; $i < 10; $i++ ) {

	$body = new Twitter_Search();
	$user = new Twitter_User();

	$user->id = ($i+1);
	$user->name = "名前".($i+1);

	$body->user = $user;
	$body->text = "本文".($i+1);
	$records[] = $body;

}

$base = new Twitter_Base();
$base->statuses = $records;

print json_encode($base);

?>


▼ 出力したもの
{"statuses":[{"user":{"id":1,"name":"\u540d\u524d1"},"text":"\u672c\u65871"},{"user":{"id":2,"name":"\u540d\u524d2"},"text":"\u672c\u65872"},{"user":{"id":3,"name":"\u540d\u524d3"},"text":"\u672c\u65873"},{"user":{"id":4,"name":"\u540d\u524d4"},"text":"\u672c\u65874"},{"user":{"id":5,"name":"\u540d\u524d5"},"text":"\u672c\u65875"},{"user":{"id":6,"name":"\u540d\u524d6"},"text":"\u672c\u65876"},{"user":{"id":7,"name":"\u540d\u524d7"},"text":"\u672c\u65877"},{"user":{"id":8,"name":"\u540d\u524d8"},"text":"\u672c\u65878"},{"user":{"id":9,"name":"\u540d\u524d9"},"text":"\u672c\u65879"},{"user":{"id":10,"name":"\u540d\u524d10"},"text":"\u672c\u658710"}]}

▼ 整形したもの
{
    "statuses": [
        {
            "user": {
                "id": 1,
                "name": "名前1"
            },
            "text": "本文1"
        },
        {
            "user": {
                "id": 2,
                "name": "名前2"
            },
            "text": "本文2"
        },
        {
            "user": {
                "id": 3,
                "name": "名前3"
            },
            "text": "本文3"
        },
        {
            "user": {
                "id": 4,
                "name": "名前4"
            },
            "text": "本文4"
        },
        {
            "user": {
                "id": 5,
                "name": "名前5"
            },
            "text": "本文5"
        },
        {
            "user": {
                "id": 6,
                "name": "名前6"
            },
            "text": "本文6"
        },
        {
            "user": {
                "id": 7,
                "name": "名前7"
            },
            "text": "本文7"
        },
        {
            "user": {
                "id": 8,
                "name": "名前8"
            },
            "text": "本文8"
        },
        {
            "user": {
                "id": 9,
                "name": "名前9"
            },
            "text": "本文9"
        },
        {
            "user": {
                "id": 10,
                "name": "名前10"
            },
            "text": "本文10"
        }
    ]
}
関連記事

PHP+MySQLの考えられる最もシンプルなソースコード


posted by lightbox at 2013-11-26 21:54 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年10月24日


PHP : Twitter 検索 + jQuery UI Tabs テンプレート

SkyDrive へ移動


ファイル一覧

twitter_search.php( メイン )
common.php( 共通 )
debug_lib.php( デバッグ表示用 )
view.php( 画面 )

概要

簡単な MVC 型で構成されており、common.php にご自分のアクセストークンを埋め込むだけですぐ使えます。
jQuery の主要部分は、Google のホスティングを使い、jQuery UI の CSS 部分のみこちらでホスティングしています。



common.php
<?php
session_start();

$_SESSION['consumer_key'] = "";
$_SESSION['consumer_secret'] = "";
$_SESSION['access_token'] = "";
$_SESSION['access_token_secret'] = "";

require_once("debug_lib.php");

header("Content-type: text/html; charset=utf-8");
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );


// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

function twitter_search( $apikey, $secret, $token, $token_secret, $userid ) {
	// **********************************************************
	// API
	// **********************************************************
	$twitter_url = 'https://api.twitter.com/1.1/search/tweets.json';
	$count = 20;

	// **********************************************************
	// 認証データ
	// **********************************************************
	$oauth_consumer_key = $apikey;
	$oauth_consumer_secret = $secret;
	$oauth_token = $token;
	$oauth_secret = $token_secret;
	
	// 毎回変化するランダムな文字列
	$mt = microtime();
	$rand = mt_rand();
	$oauth_nonce = md5($mt . $rand);
	
	$oauth_signature_method = "HMAC-SHA1";
	$oauth_timestamp = time();
	$oauth_version = "1.0";
	
	// *********************************************************
	// シグネチャ用ベース文字列作成
	/*
	  httpMethod + "&" +
	  url_encode(  base_uri ) + "&" +
	  sorted_query_params.each  { | k, v |
	      url_encode ( k ) + "%3D" +
	      url_encode ( v )
	  }.join("%26")
	*/
	// *********************************************************
	$base_string = "GET";
	$base_string .= "&" . urle($twitter_url);
	$base_string .= "&";
	
	$base_string .= "count%3D{$count}%26";
	$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
	$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
	$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
	$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
	$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
	$base_string .= urle("oauth_version")."%3D".urle($oauth_version);
	$base_string .= "%26q%3D".urle(urle($userid));
	
	// *********************************************************
	// シグネチャ作成
	/*
	url_encode( consumer_secret ) + "&" +
	url_encode( oauth_token_secret || nil )
	*/
	// *********************************************************
	$oauth_signature = 
	base64_encode( hash_hmac(
		"sha1",
		$base_string,
		$oauth_consumer_secret . "&" . $oauth_secret,
		true
	));
	
	// *********************************************************
	// curl 処理
	// *********************************************************
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url . "?q=" . urle($userid) . "&count={$count}"  );

	// *********************************************************
	// http ヘッダ作成
	// *********************************************************
	$header = array();
	$header[] = 'Expect:';
	
	$header[] = "Authorization: OAuth ".
	urle("oauth_consumer_key")."=\"".urle($oauth_consumer_key)."\",".
	urle("oauth_token")."=\"".urle($oauth_token)."\",".
	urle("oauth_nonce")."=\"".urle($oauth_nonce)."\",".
	urle("oauth_timestamp")."=\"".urle($oauth_timestamp)."\",".
	urle("oauth_signature_method")."=\"".urle($oauth_signature_method)."\",".
	urle("oauth_version")."=\"".urle($oauth_version)."\",".
	urle("oauth_signature")."=\"".urle($oauth_signature)."\"";
	
	curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
	
	// *********************************************************
	// https 用 ( https://api.twitter.com 利用時に必要 )
	// *********************************************************
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
	
	// *********************************************************
	// 戻された http ヘッダの出力
	// *********************************************************
	$handle = fopen("./header.txt", "w");
	curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
	
	// *********************************************************
	// 送信
	// *********************************************************
	$result = curl_exec($curl);
	
	// *********************************************************
	// 結果
	// *********************************************************
	$ret = true;
	if($result === false) {
		$ret = false;
	}
	curl_close($curl);

	return $result;

}

// URL をアンカーに変換
function url2a( $target ){

	$target = str_replace("http", " http", $target );

	if ( preg_match( "/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/", $target ) ) {
		preg_match_all( "/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/", $target, $pattarn );
		foreach ( $pattarn[0] as $key => $val ){
			$replace[] = "<a href=\"{$val}\" target=\"_blank\">{$val}</a>";
		}
		$target = str_replace( $pattarn[0], $replace, $target );
	}
	return $target;
}


?>

ソース全体





posted by lightbox at 2013-10-24 00:36 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年09月23日


PHP : 少し強引ですが、twitteroauth の画像アップロード対応( statuses/update_with_media )

$_POST['image_path'] = "c:\\user\\_img.png";
$_POST['image_status'] = "画像アップロード投稿";

と、こんな感じでテストしました。画面があれば、二つのフィールドを作ればいいでしょう。image_path は、PHP スクリプトから見たパスなんで、実際問題として PHP で画像アップロードって使いどころがあまり無いですが、ローカルからバッチ処理なら意味あると思います。
  /**
   * Make an HTTP request
   *
   * @return API results
   */
  function http($url, $method, $postfields = NULL) {
    $this->http_info = array();
    $ci = curl_init();
    /* Curl settings */
    curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
    curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
    curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
    curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
//    curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:'));
    curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
    curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
    curl_setopt($ci, CURLOPT_HEADER, FALSE);

    switch ($method) {
      case 'POST':
        curl_setopt($ci, CURLOPT_POST, TRUE);
        if (!empty($postfields)) {

if ( $_POST['image_path'] != '' ) {

	// postfields から認証情報を取り出して、ヘッダーを作成
	// ※ 呼び出し時には、フィールドは指定しない
	$wk = explode("&", $postfields);
	$data = array();
	$header_oauth = "";
	for( $i = 0; $i < count($wk); $i++ ) {
		$wk2 = explode("=", $wk[$i]);
		if ( $wk2[0] != '' ) {
			if( $header_oauth == '' ) {
				$header_oauth .= "Authorization: OAuth " . "{$wk2[0]}={$wk2[1]}";
			}
			else {
				$header_oauth .= ", " . "{$wk2[0]}={$wk2[1]}";
			}
		}
	}
	curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:', $header_oauth));

	$file_post_data = array();
	$file_post_data["media[]"] = "@" . $_POST['image_path'];
	$file_post_data["status"] = $_POST['image_status'];

          curl_setopt($ci, CURLOPT_POSTFIELDS, $file_post_data);
}
else {
          curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}

        }
        break;
      case 'DELETE':
        curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
        if (!empty($postfields)) {
          $url = "{$url}?{$postfields}";
        }
    }

    curl_setopt($ci, CURLOPT_URL, $url);
    $response = curl_exec($ci);
    $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
    $this->http_info = array_merge($this->http_info, curl_getinfo($ci));
    $this->url = $url;
    curl_close ($ci);
    return $response;
  }
要点は二つあって、CURLOPT_HTTPHEADER でヘッダをセットするので、追加で認証情報をするところです。もう一つは、ファイルのアップロード用データとして、連想配列でデータを作成して、ファイルのパスの前に @ をセットして CURLOPT_POSTFIELDS にセットするところです。

認証情報には、oauth_ 以外は使われないので、twitteroauth には、URL しか渡さないようにします。
( ※ 他のオプションは試していません )

ちなみに、PHP 5.5.0 以降、@ プレフィックスは非推奨になったと PHP マニュアルには書かれています。どーすんだとか思ったら、CURLFile というクラスがあるからそれを使えという事です。



posted by lightbox at 2013-09-23 01:41 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年09月22日


Twitter の API は、Authorization ヘッダが必要だとばかり思っていました。

twitteroauth のソースコードを眺めていたのですが、どこをどう見ても Authorization ヘッダをセットしていないので、もっと良く見たら、フィールドに全部含めているようなので、自分でも試してみたら動作しました。

思い込みなんでしょうか、結構へこみました。OAuth ツールでは、Signature base string、Authorization header として、別々に記述されてますし、実際これで動いていたんですし。でも、ヘッダ無いほうがはるかにコードが簡単になります( VS2012 C# や、VS2010 C# や Java 等 )
// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

function twitter_update( $apikey, $secret, $token, $token_secret, $text ) {
	// **********************************************************
	// API
	// **********************************************************
	$twitter_url = 'https://api.twitter.com/1.1/statuses/update.json';

	// **********************************************************
	// 認証データ
	// **********************************************************
	$oauth_consumer_key = $apikey;
	$oauth_consumer_secret = $secret;
	$oauth_token = $token;
	$oauth_secret = $token_secret;
	
	// 毎回変化するランダムな文字列
	$mt = microtime();
	$rand = mt_rand();
	$oauth_nonce = md5($mt . $rand);
	
	$oauth_signature_method = "HMAC-SHA1";
	$oauth_timestamp = time();
	$oauth_version = "1.0";
	
	// *********************************************************
	// シグネチャ用ベース文字列作成
	// *********************************************************
	$base_string = "POST";
	$base_string .= "&" . urle($twitter_url);
	$base_string .= "&";
	
	$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
	$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
	$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
	$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
	$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
	$base_string .= urle("oauth_version")."%3D".urle($oauth_version);
	
	$base_string .= "%26status" . "%3D" . urle(urle($text));
	
	file_put_contents( "base_string.log", $base_string );

	// *********************************************************
	// シグネチャ作成
	// *********************************************************
	$oauth_signature = 
	base64_encode( hash_hmac(
		"sha1",
		$base_string,
		urle($oauth_consumer_secret) . "&" . urle($oauth_secret),
		true
	));

	$base_fields = "oauth_consumer_key=" . urle($oauth_consumer_key);
	$base_fields .= "&oauth_nonce=" . urle($oauth_nonce);
	$base_fields .= "&oauth_signature=" . urle($oauth_signature);
	$base_fields .= "&oauth_signature_method=" . urle($oauth_signature_method);
	$base_fields .= "&oauth_timestamp=" . urle($oauth_timestamp);
	$base_fields .= "&oauth_token=" . urle($oauth_token);
	$base_fields .= "&oauth_version=" . urle($oauth_version);
	$base_fields .= "&status=" . urle($text);

	file_put_contents( "base_fields.log", $base_fields );

	// *********************************************************
	// curl 処理
	// *********************************************************
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url);
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, $base_fields);
	
	// *********************************************************
	// http ヘッダ作成
	// *********************************************************
	$header = array();
	$header[] = 'Expect:';
	
//	$header[] = "Authorization: OAuth ".
//	urle("oauth_consumer_key")."=\"".urle($oauth_consumer_key)."\",".
//	urle("oauth_token")."=\"".urle($oauth_token)."\",".
//	urle("oauth_nonce")."=\"".urle($oauth_nonce)."\",".
//	urle("oauth_timestamp")."=\"".urle($oauth_timestamp)."\",".
//	urle("oauth_signature_method")."=\"".urle($oauth_signature_method)."\",".
//	urle("oauth_version")."=\"".urle($oauth_version)."\",".
//	urle("oauth_signature")."=\"".urle($oauth_signature)."\"";
	
	curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
	
	// *********************************************************
	// https 用 ( https://api.twitter.com 利用時に必要 )
	// *********************************************************
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
	
	// *********************************************************
	// 戻された http ヘッダの出力
	// *********************************************************
	$handle = fopen("./header.log", "w");
	curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
	
	// *********************************************************
	// 送信
	// *********************************************************
	$result = curl_exec($curl);
	
	// *********************************************************
	// 結果
	// *********************************************************
	$ret = true;
	if($result === false) {
		$ret = false;
	}
	curl_close($curl);

	return $result;

}


twitteroauth の curl 部分
  function http($url, $method, $postfields = NULL) {
    $this->http_info = array();
    $ci = curl_init();
    /* Curl settings */
    curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
    curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
    curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
    curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:'));
    curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
    curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
    curl_setopt($ci, CURLOPT_HEADER, FALSE);

    switch ($method) {
      case 'POST':
        curl_setopt($ci, CURLOPT_POST, TRUE);
        if (!empty($postfields)) {
          curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
        }
        break;
      case 'DELETE':
        curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
        if (!empty($postfields)) {
          $url = "{$url}?{$postfields}";
        }
    }

    curl_setopt($ci, CURLOPT_URL, $url);
    $response = curl_exec($ci);
    $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
    $this->http_info = array_merge($this->http_info, curl_getinfo($ci));
    $this->url = $url;
    curl_close ($ci);
    return $response;
  }

Expect しかセットしていません。getHeader は、何もせず、変数に現在の状態をセットしているだけです。


posted by lightbox at 2013-09-22 01:03 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年09月16日


PHP : Twitter の APIを使った投稿ツール

※ こちらから利用できます


SkyDriveへ(ツール全てのソースコード)


Twitter のアカウントがあれば、アプリを登録して API キーを取得すれば、PHP 等の言語から独自の投稿アプリを作成する事ができます。

■ Twitter アプリの登録方法と、API キーの利用 

ただ、この記事の最後でソースコードで紹介する内容は自分自身のアクセストークンを使用して自分専用の投稿アプリを作成する事しかできません。本来は、Twitter に登録したアプリを使って不特定多数の他のユーザが投稿処理等の API を Twitter のサイト以外で実行できるようにする事が目的です。
Consumer key : Twitter アプリ固有
Consumer secret : Twitter アプリ固有
Access token : ユーザ固有
Access token secret : ユーザ固有
ユーザ固有のトークンは、ユーザ本人が処理しないと取得する事ができません。Twitter アプリ を登録した人が、アプリケーションを作って公開する事によって、他の人が利用してその人固有のアクセストークンを取得する事になります。 このアクセストークンを取得する際に、Twitter アプリ を承認する事になり、その際ユーザのアカウントにそのアプリが登録されます。ですから、アクセストークンを無効にしたければ、その登録されたアプリを削除すれば、仮にそのアクセストークンが外部に流出しても、アプリごと削除すればいいので安心です。 ( 通常、アクセストークンはどこかに保存されていますが、ユーザには解りません ) その手順として最初に行うのが、『アクセストークンのリクエスト』です(https://api.twitter.com/oauth/request_token) WEB 上に用意したツールから、『アクセストークンのリクエスト』を行えるようになっています。その場合必要なのは、Consumer key と Consumer secret だけですが、セッションに保存する必要があるので、最初の Twitter 投稿ページで 投稿データを未入力で投稿して下さい ▼ Consumer key と Consumer secretのみで未入力投稿した場合、こうなります そうすれば、『Twitter リクエスト』のページから一連の処理を実行する事ができます 実際に自分の Twitter アプリを使う場合の注意として、Callback フィールドには何らかの URL を入力しておく必要があります( 後から変更できます )。未入力にすると、WEB アプリ以外の処理でのフローに変更されてしまいます
<?php
session_start();

header( "Content-type: text/html; charset=utf-8");
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

$_SESSION['twitter_keys'] = $_POST['keys'];

$_POST['keys'] = str_replace("\r","",$_POST['keys']);
$_POST['keys'] = str_replace("\n","",$_POST['keys']);
$twitter_keys = explode(",", $_POST['keys'] );

$result = twitter_update(
		$twitter_keys[0],
		$twitter_keys[1],
		$twitter_keys[2],
		$twitter_keys[3],
		$_POST['tpost']
);

$_SESSION['consumer_key'] = $twitter_keys[0];
$_SESSION['consumer_secret'] = $twitter_keys[1];
$_SESSION['access_token'] = $twitter_keys[2];
$_SESSION['access_token_secret'] = $twitter_keys[3];

print "<a href='twitter.php?tpost=" . urlencode($_POST['tpost']) . "'>戻る</a>";
print "<pre>";
print_r(json_decode($result));
print "</pre>";

// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

function twitter_update( $apikey, $secret, $token, $token_secret, $text ) {
	// **********************************************************
	// API
	// **********************************************************
	$twitter_url = 'https://api.twitter.com/1.1/statuses/update.json';
	
	// **********************************************************
	// 認証データ
	// **********************************************************
	$oauth_consumer_key = $apikey;
	$oauth_consumer_secret = $secret;
	$oauth_token = $token;
	$oauth_secret = $token_secret;
	
	// 毎回変化するランダムな文字列
	$mt = microtime();
	$rand = mt_rand();
	$oauth_nonce = md5($mt . $rand);
	
	$oauth_signature_method = "HMAC-SHA1";
	$oauth_timestamp = time();
	$oauth_version = "1.0";
	
	// *********************************************************
	// シグネチャ用ベース文字列作成
	// *********************************************************
	$base_string = "POST";
	$base_string .= "&" . urle($twitter_url);
	$base_string .= "&";
	
	$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
	$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
	$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
	$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
	$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
	$base_string .= urle("oauth_version")."%3D".urle($oauth_version);
	
	$base_string .= "%26status" . "%3D" . urle(urle($text));
	
	file_put_contents( "base_string.log", $base_string );

	// *********************************************************
	// シグネチャ作成
	// *********************************************************
	$oauth_signature = 
	base64_encode( hash_hmac(
		"sha1",
		$base_string,
		urle($oauth_consumer_secret) . "&" . urle($oauth_secret),
		true
	));
	
	// *********************************************************
	// curl 処理
	// *********************************************************
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url);
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, "status=" . urle($text));
	
	// *********************************************************
	// http ヘッダ作成
	// *********************************************************
	$header = array();
	$header[] = 'Expect:';
	
	$header[] = "Authorization: OAuth ".
	urle("oauth_consumer_key")."=\"".urle($oauth_consumer_key)."\",".
	urle("oauth_token")."=\"".urle($oauth_token)."\",".
	urle("oauth_nonce")."=\"".urle($oauth_nonce)."\",".
	urle("oauth_timestamp")."=\"".urle($oauth_timestamp)."\",".
	urle("oauth_signature_method")."=\"".urle($oauth_signature_method)."\",".
	urle("oauth_version")."=\"".urle($oauth_version)."\",".
	urle("oauth_signature")."=\"".urle($oauth_signature)."\"";
	
	curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
	
	// *********************************************************
	// https 用 ( https://api.twitter.com 利用時に必要 )
	// *********************************************************
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
	
	// *********************************************************
	// 戻された http ヘッダの出力
	// *********************************************************
	$handle = fopen("./header.log", "w");
	curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
	
	// *********************************************************
	// 送信
	// *********************************************************
	$result = curl_exec($curl);
	
	// *********************************************************
	// 結果
	// *********************************************************
	$ret = true;
	if($result === false) {
		$ret = false;
	}
	curl_close($curl);

	return $result;

}
?>

テキストエリアに、カンマ区切りで入力された四つのキーを使って投稿しています。最後に結果を JSON 文字列を PHP 用のオブジェクトに変換して text/html 内(HTMとして)の PRE 内で表示しています。


posted by lightbox at 2013-09-16 15:35 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

POST oauth/request_token で、PHP の cURL 関数が 400 Bad Request になる原因( Content-Length: -1 )

昔はうまくいっていたコードが動かなくて、GET で処理すると正しく動作しましたが、POST で行う場合に POST データを空文字で指定する必要がありました。

実際ログ取って見てみると、CURLOPT_POSTFIELDS を指定しないと Content-Length: -1 になります。これを Bad Request とする仕様であると言う事みたいです。

この理由から、GET で処理すると問題無く動くという事です。

▼ エラーになるコード
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url);
	curl_setopt($curl, CURLOPT_POST, 1);

▼ 正しく動作するコード
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url);
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, "");

この違いで考えられる事はだいたい想像は付きますが、実際に WWW サーバーに送ってログ見ないと解らないです。


タグ:トラブル
posted by lightbox at 2013-09-16 14:41 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年08月28日


PHP で GET statuses/user_timeline を使って何か作る為のテンプレート

GET statuses/user_timeline



基本的には、API 制限があるので( 300/app )たいした事はできませんが、個人的に楽しむぶんには十分使えると思います。投稿に関しては weetDeck 等の公式クライアントを使ったほうがいいと思いますが、PHP で投稿する方法はこちら

使用方法は、アプリを作って『Consumer key、Consumer secret、Access token、Access token secret』を手に入れてテキストエリアに1行づつ入力し、5行目にユーザの表示名( ログイン用の文字列 ) を入力します
<?php
header("Content-type: text/html; charset=utf-8");
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

$result = '';
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
	$token = explode("\r\n", $_POST['text']);
	$result = twitter_user_timeline(
		$token[0],
		$token[1],
		$token[2],
		$token[3],
		$token[4]
	);
}

?>
<!doctype html>
<html lang="ja">
<head>
<title>SkyDrive Word</title>
<meta charset="utf-8">
<style>
body {
	margin: 0px;
	padding:10px 0 30px 30px;
}
.entry {
	width: 600px;
	border-top: solid 1px #000000;
	padding: 5px;
	font-size:16px;
	font-family: Arial, Helvetica, Verdana, "ヒラギノ角ゴPro W3", "Hiragino Kaku Gothic Pro", Osaka, "メイリオ", Meiryo, "MS Pゴシック", sans-serif;
}
textarea {
	width:540px;
	height:100px;
}
</style>
</head>
<body>

<form method="post">
<textarea name="text" style='float:left'><?= $_POST['text'] ?></textarea>
<input type="submit" value="送信" style='float:left;'>
</form>
<br style='clear:left'><br>

<?
if ( $result != '' ) {
	$obj = json_decode($result);
	$cnt = count($obj);
	for( $i = 0; $i < $cnt; $i++ ) {
		if ( $i == 0 ) {
			print "<div class='entry'>";
			print "<img src='{$obj[$i]->user->profile_image_url}'>";
			print "</div>";
		}
		print "<div class='entry'";

		// ***************************************************
		// リツイート
		// ***************************************************
		if ( $obj[$i]->retweeted_status ) {
			print  " style='background-color:#D6B6CE'>";
			print "<div style='float:left;width:60px;'><img style='width:48px;' src='{$obj[$i]->retweeted_status->user->profile_image_url}'></div>";
			// URL をアンカーに変換
			$work = url2a($obj[$i]->text);
			print "<div style='float:left;width:530px'>{$work}</div>";
		}
		else {
			// *******************************************
			// 返信
			// *******************************************
			if ( $obj[$i]->in_reply_to_screen_name ) {
				print  " style='background-color:#B6D6D6'>";
			}
			// *******************************************
			// 通常
			// *******************************************
			else {
				print  ">";
			}
			// URL をアンカーに変換
			print url2a($obj[$i]->text);
			print "<br>";
		}

		// ***************************************************
		// 画像がある場合
		// ***************************************************
		if ( $obj[$i]->entities->media ) {
			print "<br>";
			print "<div style='clear:left;'><img src='{$obj[$i]->entities->media[0]->media_url}' style='width:200px;'></div>";
		}
		else {
			print "<br style='clear:left;'>";
		}

		print "</div>";
	}

print "<pre>";
//print_r($obj);
print "</pre>";

}
?>
</body>
</html>
<?

// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

function twitter_user_timeline( $apikey, $secret, $token, $token_secret, $userid ) {
	// **********************************************************
	// API
	// **********************************************************
	$twitter_url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';

	// **********************************************************
	// 認証データ
	// **********************************************************
	$oauth_consumer_key = $apikey;
	$oauth_consumer_secret = $secret;
	$oauth_token = $token;
	$oauth_secret = $token_secret;
	
	// 毎回変化するランダムな文字列
	$mt = microtime();
	$rand = mt_rand();
	$oauth_nonce = md5($mt . $rand);
	
	$oauth_signature_method = "HMAC-SHA1";
	$oauth_timestamp = time();
	$oauth_version = "1.0";
	
	// *********************************************************
	// シグネチャ用ベース文字列作成
	/*
	  httpMethod + "&" +
	  url_encode(  base_uri ) + "&" +
	  sorted_query_params.each  { | k, v |
	      url_encode ( k ) + "%3D" +
	      url_encode ( v )
	  }.join("%26")
	*/
	// *********************************************************
	$base_string = "GET";
	$base_string .= "&" . urle($twitter_url);
	$base_string .= "&";
	
	$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
	$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
	$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
	$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
	$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
	$base_string .= urle("oauth_version")."%3D".urle($oauth_version);
	$base_string .= "%26screen_name%3D".urle($userid);
	
	// *********************************************************
	// シグネチャ作成
	/*
	url_encode( consumer_secret ) + "&" +
	url_encode( oauth_token_secret || nil )
	*/
	// *********************************************************
	$oauth_signature = 
	base64_encode( hash_hmac(
		"sha1",
		$base_string,
		$oauth_consumer_secret . "&" . $oauth_secret,
		true
	));
	
	// *********************************************************
	// curl 処理
	// *********************************************************
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url . "?screen_name=" . urle($userid));

	// *********************************************************
	// http ヘッダ作成
	// *********************************************************
	$header = array();
	$header[] = 'Expect:';
	
	$header[] = "Authorization: OAuth ".
	urle("oauth_consumer_key")."=\"".urle($oauth_consumer_key)."\",".
	urle("oauth_token")."=\"".urle($oauth_token)."\",".
	urle("oauth_nonce")."=\"".urle($oauth_nonce)."\",".
	urle("oauth_timestamp")."=\"".urle($oauth_timestamp)."\",".
	urle("oauth_signature_method")."=\"".urle($oauth_signature_method)."\",".
	urle("oauth_version")."=\"".urle($oauth_version)."\",".
	urle("oauth_signature")."=\"".urle($oauth_signature)."\"";
	
	curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
	
	// *********************************************************
	// https 用 ( https://api.twitter.com 利用時に必要 )
	// *********************************************************
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
	
	// *********************************************************
	// 戻された http ヘッダの出力
	// *********************************************************
	$handle = fopen("./header.txt", "w");
	curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
	
	// *********************************************************
	// 送信
	// *********************************************************
	$result = curl_exec($curl);
	
	// *********************************************************
	// 結果
	// *********************************************************
	$ret = true;
	if($result === false) {
		$ret = false;
	}
	curl_close($curl);

	return $result;

}

// URL をアンカーに変換
function url2a( $target ){

	$target = str_replace("http", " http", $target );

	if ( preg_match( "/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/", $target ) ) {
		preg_match_all( "/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/", $target, $pattarn );
		foreach ( $pattarn[0] as $key => $val ){
			$replace[] = "<a href=\"{$val}\" target=\"_blank\">{$val}</a>";
		}
		$target = str_replace( $pattarn[0], $replace, $target );
	}
	return $target;
}
?>

関連する記事

PHP + cURL で、Twitter API 1.1 の search/tweets を呼び出して、RSS に変換する



posted by lightbox at 2013-08-28 16:34 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年07月11日


PHP : Twitter 投稿関数( twitter_update ) / cURL 関数

cURL 関数を使った単純な投稿用です。( windows では、php.ini で extension=php_curl.dll を有効にして下さい )

<?php
header("Content-type: text/html; charset=utf-8");

$result = twitter_update(
		"Consumer key",
		"Consumer secret",
		"Access token",
		"Access token secret",
		"PHPより投稿しています"
);

print "<pre>";
print_r(json_decode($result));
print "</pre>";

// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

function twitter_update( $apikey, $secret, $token, $token_secret, $text ) {
	// **********************************************************
	// API
	// **********************************************************
	$twitter_url = 'https://api.twitter.com/1.1/statuses/update.json';
	
	// **********************************************************
	// 認証データ
	// **********************************************************
	$oauth_consumer_key = $apikey;
	$oauth_consumer_secret = $secret;
	$oauth_token = $token;
	$oauth_secret = $token_secret;
	
	// 毎回変化するランダムな文字列
	$mt = microtime();
	$rand = mt_rand();
	$oauth_nonce = md5($mt . $rand);
	
	$oauth_signature_method = "HMAC-SHA1";
	$oauth_timestamp = time();
	$oauth_version = "1.0";
	
	// *********************************************************
	// シグネチャ用ベース文字列作成
	/*
	  httpMethod + "&" +
	  url_encode(  base_uri ) + "&" +
	  sorted_query_params.each  { | k, v |
	      url_encode ( k ) + "%3D" +
	      url_encode ( v )
	  }.join("%26")
	*/
	// *********************************************************
	$base_string = "POST";
	$base_string .= "&" . urle($twitter_url);
	$base_string .= "&";
	
	$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
	$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
	$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
	$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
	$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
	$base_string .= urle("oauth_version")."%3D".urle($oauth_version);
	
	$base_string .= "%26status" . "%3D" . urle(urle($text));
	
	// *********************************************************
	// シグネチャ作成
	/*
	url_encode( consumer_secret ) + "&" +
	url_encode( oauth_token_secret || nil )
	*/
	// *********************************************************
	$oauth_signature = 
	base64_encode( hash_hmac(
		"sha1",
		$base_string,
		$oauth_consumer_secret . "&" . $oauth_secret,
		true
	));
	
	// *********************************************************
	// curl 処理
	// *********************************************************
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
	curl_setopt($curl, CURLOPT_HEADER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
	curl_setopt($curl, CURLOPT_URL, $twitter_url);
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, "status=" . urle($text));
	
	// *********************************************************
	// http ヘッダ作成
	// *********************************************************
	$header = array();
	$header[] = 'Expect:';
	
	$header[] = "Authorization: OAuth ".
	urle("oauth_consumer_key")."=\"".urle($oauth_consumer_key)."\",".
	urle("oauth_token")."=\"".urle($oauth_token)."\",".
	urle("oauth_nonce")."=\"".urle($oauth_nonce)."\",".
	urle("oauth_timestamp")."=\"".urle($oauth_timestamp)."\",".
	urle("oauth_signature_method")."=\"".urle($oauth_signature_method)."\",".
	urle("oauth_version")."=\"".urle($oauth_version)."\",".
	urle("oauth_signature")."=\"".urle($oauth_signature)."\"";
	
	curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
	
	// *********************************************************
	// https 用 ( https://api.twitter.com 利用時に必要 )
	// *********************************************************
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
	
	// *********************************************************
	// 戻された http ヘッダの出力
	// *********************************************************
	$handle = fopen("./header.txt", "w");
	curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);
	
	// *********************************************************
	// 送信
	// *********************************************************
	$result = curl_exec($curl);
	
	// *********************************************************
	// 結果
	// *********************************************************
	$ret = true;
	if($result === false) {
		$ret = false;
	}
	curl_close($curl);

	return $result;

}
?>

関連する記事

Twitter API の自分のアプリのトークンを使って投稿するだけの class VS2010_Twitter

Twitter API の自分のアプリのトークンを使って投稿するだけの class Android_Twitter

Twitter API の自分のアプリのトークンを使って投稿するだけの class VS2012_Twitter

WSH : VBScript と JavaScript で Twitter に投稿する

Twitter アプリの登録方法と、API キーの利用


posted by lightbox at 2013-07-11 21:11 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2013年06月02日


PHP + cURL で、Twitter API 1.1 の search/tweets を呼び出して、RSS に変換する

自分のアプリケーションで検索するなら、制限的には 450 となっているので、『自分専用』として運用も可能なので、他のアプリから呼び出す為のテスト用として作成しました。

search.twitter.com/search は、https://dev.twitter.com/blog/api-v1-retirement-date-extended-to-june-11 では、6月11日には、使えなくなるとの事です。
Requests to search.twitter.com/search.* will receive HTTP 410 Gone. Use GET search/tweets instead.
<?php
// **********************************************************
// Twitter API 1.1 search/tweets => RSS
// **********************************************************
header( "Content-Type: text/xml; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **********************************************************
// OAuth 用の urlencode 関数
// **********************************************************
function url_rfc3986( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無く、rawurlencode で OK
	return str_replace('%7E', '~', rawurlencode($str));
}

// **********************************************************
// API
// **********************************************************
$twitter_url = 'https://api.twitter.com/1.1/search/tweets.json';

// **********************************************************
// 認証データ
// **********************************************************
$oauth_consumer_key = "";
$oauth_consumer_secret = "";
$oauth_token = "";
$oauth_secret = "";

// 毎回変化するランダムな文字列
$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);

$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = time();
$oauth_version = "1.0";

if ( $_POST['q'] != '' ) {
	$query = $_POST['q'];
}
else {
	$query = "進撃の巨人";
}
if ( $_POST['c'] != '' ) {
	$count = $_POST['c'];
}
else {
	$count = 20;
}

// *********************************************************
// シグネチャ用ベース文字列作成
// *********************************************************
$base_string = "GET";
$base_string .= "&" . url_rfc3986($twitter_url);
$base_string .= "&count%3D{$count}%26";

$base_string .= url_rfc3986("oauth_consumer_key")."%3D".url_rfc3986($oauth_consumer_key)."%26";
$base_string .= url_rfc3986("oauth_nonce")."%3D".url_rfc3986($oauth_nonce)."%26";
$base_string .= url_rfc3986("oauth_signature_method")."%3D".url_rfc3986($oauth_signature_method)."%26";
$base_string .= url_rfc3986("oauth_timestamp")."%3D".url_rfc3986($oauth_timestamp)."%26";
$base_string .= url_rfc3986("oauth_token")."%3D".url_rfc3986($oauth_token)."%26";
$base_string .= url_rfc3986("oauth_version")."%3D".url_rfc3986($oauth_version)."%26";
$base_string .= "q%3D". url_rfc3986(url_rfc3986($query));

// *********************************************************
// シグネチャ作成
// *********************************************************
$oauth_signature = 
base64_encode( hash_hmac(
	"sha1",
	$base_string,
	url_rfc3986($oauth_consumer_secret) . "&" . url_rfc3986($oauth_secret),
	true
));

// *********************************************************
// curl 処理
// *********************************************************
$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $twitter_url . "?q=". url_rfc3986($query) . "&count={$count}" );

// *********************************************************
// http ヘッダ作成
// *********************************************************
$header = array();
//$header[] = 'Expect:';
$header[] = 'Authorization: OAuth '.
url_rfc3986("oauth_consumer_key")."=\"".url_rfc3986($oauth_consumer_key)."\",".
url_rfc3986("oauth_nonce")."=\"".url_rfc3986($oauth_nonce)."\",".
url_rfc3986("oauth_signature")."=\"".url_rfc3986($oauth_signature)."\",".
url_rfc3986("oauth_signature_method")."=\"".url_rfc3986($oauth_signature_method)."\",".
url_rfc3986("oauth_timestamp")."=\"".url_rfc3986($oauth_timestamp)."\",".
url_rfc3986("oauth_token")."=\"".url_rfc3986($oauth_token)."\",".
url_rfc3986("oauth_version")."=\"".url_rfc3986($oauth_version)."\"";

curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

// *********************************************************
// https 用
// *********************************************************
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);

// *********************************************************
// 送信
// *********************************************************
//curl_setopt($curl, CURLOPT_VERBOSE, true);	// デバッグ
//$handle = fopen("./debug.txt", "w");
//curl_setopt($curl, CURLOPT_STDERR, $handle);
//$handle2 = fopen("./ret_header.txt", "w");
//curl_setopt($curl, CURLOPT_WRITEHEADER, $handle2);

$result = curl_exec($curl);


// *********************************************************
// 結果
// *********************************************************
if($result === false) {
	// $json = 'Curl error: ' . curl_error($curl);
	$json = json_decode("{}");
}
else {
	// echo 'Operation completed without any errors';
	$json = json_decode($result);
}
curl_close($curl);
//fclose($handle2);
//fclose($handle);


print '<?xml version="1.0" encoding="UTF-8"?>';
?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<?php

if ( $json->statuses ) {
foreach($json->statuses as $tweet) {

$str = <<<ITEM
<item>
	<title>{$tweet->user->name}</title>
	<link/>
	<description>{$tweet->text}</description>
	<pubDate>{$tweet->created_at}</pubDate>
	<guid>{$tweet->id_str}</guid>
	<dc:creator>{$tweet->user->screen_name}</dc:creator>
	<dc:date>{$dc_date}</dc:date>
	<media:thumbnail url="{$tweet->user->profile_image_url}" />
	<media:content url="{$tweet->user->profile_image_url}" />
</item>
ITEM;

	print $str;

}
}
else {

$str = <<<ITEM
<item>
	<title>error</title>
	<link/>
	<description/>
	<pubDate/>
	<guid/>
	<dc:creator/>
	<dc:date/>
	<media:thumbnail url="" />
	<media:content url="" />
</item>
ITEM;

	print $str;
}

?>
</channel>
</rss>



posted by lightbox at 2013-06-02 01:28 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2011年06月12日


PHP : Twitter への投稿 : バージョン2

PHP : Twitter への投稿 : バージョン1 では、自分専用のアプリケーションとしてテストしていたので、トークンは直接 Twitter アカウント内から取りだして、「クライアント型」で実行していましたが、本来 Twitter アプリケートションは自分以外の人が使う為に、その人用のトークンを動的に取得するようになっています。

その為のパッケージです。


まず、アプリケーションの設定で「ブラウザ型」に変更します。その際、コールバックする為の http:// から始まる通常の URL を書く必要がありますが、実在している必要はありません。プログラムで変更して指定するので自分のサイトの好きなところでもかまいません

サンプルのプロセスは、3つになりますが、実際は二つです。この場合は途中の値を見る為に、コールバック以降を二つにしています。また、一旦取得したトークンを以降もWEB上で継続して使えるようにするために localStorage に保存しています。ここでは作成していませんが、ログアウトする処理も必要です。

トークンを PC に保存するので、盗まれる可能性はありますが、その場合は正式アカウントから、ユーザーがそのアプリケーションを削除すればそのトークンは無効になります。それでも心配な場合は、毎回 Twitter で認証させる必要があります。
<?php
session_start();
$_SESSION['oauth_token_secret'] = '';
// **********************************************************
// Twitter への投稿 : バージョン2
// **********************************************************
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

// **********************************************************
// 投稿 API
// **********************************************************
//$twitter_url = 'http://api.twitter.com/1/statuses/update.json';
// **********************************************************
// トークン要求 API ( SSL is recommended )
// **********************************************************
$twitter_url = 'https://api.twitter.com/oauth/request_token';

// **********************************************************
// 認証データ
// **********************************************************
$oauth_consumer_key = "アプリケーションページより取得";
$oauth_consumer_secret = "アプリケーションページより取得";
$oauth_token = "";
$oauth_secret = "";

// 毎回変化するランダムな文字列
$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);

$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = mktime();
$oauth_version = "1.0";

// コールバックする URL
$path_parts = pathinfo($_SERVER['PHP_SELF']);
$oauth_callback = "http://localhost{$path_parts['dirname']}/callback_test.php";

// *********************************************************
// シグネチャ用ベース文字列作成
/*
  httpMethod + "&" +
  url_encode(  base_uri ) + "&" +
  sorted_query_params.each  { | k, v |
      url_encode ( k ) + "%3D" +
      url_encode ( v )
  }.join("%26")
*/
// *********************************************************
$base_string = "POST";
$base_string .= "&" . urle($twitter_url);
$base_string .= "&";

// 投稿用
//$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
//$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
//$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
//$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
//$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
//$base_string .= urle("oauth_version")."%3D".urle($oauth_version);

$base_string .= urle("oauth_callback")."%3D".urle(urle($oauth_callback))."%26";
$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
$base_string .= urle("oauth_version")."%3D".urle($oauth_version);

// **********************************************************
// 投稿データ
// **********************************************************
// POST データは2度 urlencode する
//$text = "Twitter への投稿 : バージョン1 : nonce=" . $oauth_nonce;
//$text .= " : timestamp=" . $oauth_timestamp;
//$base_string .= "%26status" . "%3D" . urle(urle($text));

// *********************************************************
// シグネチャ作成
/*
url_encode( consumer_secret ) + "&" +
url_encode( oauth_token_secret || nil )
*/
// *********************************************************
$oauth_signature = 
base64_encode( hash_hmac(
	"sha1",
	$base_string,
	$oauth_consumer_secret . "&",
	true
));

// *********************************************************
// curl 処理
// *********************************************************
$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $twitter_url);
curl_setopt($curl, CURLOPT_POST, 1);

// *********************************************************
// http ヘッダ作成
// *********************************************************
$header = array();
$header[] = 'Expect:';
$header[] = 'Content-Length:';

$header[] = 'Authorization: OAuth '.
urle("oauth_nonce")."="".urle($oauth_nonce)."",".
urle("oauth_callback")."="".urle($oauth_callback)."",".
urle("oauth_signature_method")."="".urle($oauth_signature_method)."",".
urle("oauth_timestamp")."="".urle($oauth_timestamp)."",".
urle("oauth_consumer_key")."="".urle($oauth_consumer_key)."",".
urle("oauth_signature")."="".urle($oauth_signature)."",".
urle("oauth_version")."="".urle($oauth_version).""";

curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

// *********************************************************
// https 用 ( https://api.twitter.co 利用時に必要 )
// *********************************************************
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);

// *********************************************************
// 戻された http ヘッダの出力
// *********************************************************
$handle = fopen("./header1.txt", "w");
curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);

// *********************************************************
// 送信
// *********************************************************
$result = curl_exec($curl);


// *********************************************************
// 結果
// *********************************************************
print "<br>";

if($result === false) {
	print '送信処理にエラーが発生しました: ' . curl_error($curl);
}
else {
	print '送信処理は正常に終了しました';
}
curl_close($curl);

// *********************************************************
// 結果表示
// *********************************************************
print "<br>";

parse_str($result,$arr);
print "<pre>";
print_r( $arr );
print "</pre>";

$_SESSION['oauth_token_secret'] = $arr['oauth_token_secret'];

?>
<a href="https://twitter.com/oauth/authorize?oauth_token=<?= $arr['oauth_token'] ?>"
>Twitterで許可する為のページ</a>

このコードは、Twitter で認証させる為のリンクを用意するページです。まだ一時的なリクエスト用のトークンしか取得できていません。'oauth_token_secret' は、コールバック先で使用する為に、セッションで引き渡しています。

コールバックするページはテストの為に localhost を使用していますが、通常は自分のサイト上( 他のユーザがアクセスできる場所 ) を指定します


Twitter で投稿する為のトークンを取得するコールバック後のデータ表示
Twitter で投稿する為のトークンを取得するコールバック後の Twitter アクセス



posted by lightbox at 2011-06-12 12:53 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする

2011年04月16日


PHP : Twitter への投稿 : バージョン1

Twitter のアカウントが必要です。New Twitter Application | dev.twitter.com よりアプリケーションを登録します。


※ アプリケーションのWEBサイトは適当に自分゛管理する URLをセットします
( 省略できません )
※ この時点で、コールバックは必要ありません

登録されたアプリケーションの情報を元に、自分でアクセスします( 実行すると、連携アプリとして登録されます )。この情報は本来ログインで一時的に取得できるものが含まれていますが、自分のアプリケーションには登録時に一つ用意されています。それを使うのでログインは必要ありません。( 連携アプリを削除すると My Access Token はリセットされます )

以下のサンプルでは、$text に投稿データを UTF-8 でセットするようになっています。FORM の テキストエリアから投稿したい場合は、データをセットし直して下さい。

関連する記事

PHP をテストする為の初心者用フォーム
<?php
// **********************************************************
// Twitter への投稿 : バージョン1
// **********************************************************
header( "Content-Type: text/html; Charset=utf-8" );
header( "pragma: no-cache" );
header( "Expires: Wed, 31 May 2000 14:59:58 GMT" );
header( "Cache-control: no-cache" );

// **********************************************************
// AOuth 用の urlencode 関数
// **********************************************************
function urle( $str ) {
	// php 5.3.x 〜 ではこの変換は必要無い
	return str_replace('%7E', '~', rawurlencode($str));
}

// **********************************************************
// API
// **********************************************************
$twitter_url = 'http://api.twitter.com/1/statuses/update.json';

// **********************************************************
// 認証データ
// **********************************************************
$oauth_consumer_key = "アプリケーションページより取得";
$oauth_consumer_secret = "アプリケーションページより取得";
$oauth_token = "My Access Token ページより取得";
$oauth_secret = "My Access Token ページより取得";

// 毎回変化するランダムな文字列
$mt = microtime();
$rand = mt_rand();
$oauth_nonce = md5($mt . $rand);

$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = mktime();
$oauth_version = "1.0";


// *********************************************************
// シグネチャ用ベース文字列作成
/*
  httpMethod + "&" +
  url_encode(  base_uri ) + "&" +
  sorted_query_params.each  { | k, v |
      url_encode ( k ) + "%3D" +
      url_encode ( v )
  }.join("%26")
*/
// *********************************************************
$base_string = "POST";
$base_string .= "&" . urle($twitter_url);
$base_string .= "&";

$base_string .= urle("oauth_consumer_key")."%3D".urle($oauth_consumer_key)."%26";
$base_string .= urle("oauth_nonce")."%3D".urle($oauth_nonce)."%26";
$base_string .= urle("oauth_signature_method")."%3D".urle($oauth_signature_method)."%26";
$base_string .= urle("oauth_timestamp")."%3D".urle($oauth_timestamp)."%26";
$base_string .= urle("oauth_token")."%3D".urle($oauth_token)."%26";
$base_string .= urle("oauth_version")."%3D".urle($oauth_version);

// **********************************************************
// 投稿データ
// **********************************************************
// POST データは2度 urlencode する
$text = "Twitter への投稿 : バージョン1 : nonce=" . $oauth_nonce;
$text .= " : timestamp=" . $oauth_timestamp;
$base_string .= "%26status" . "%3D" . urle(urle($text));

// *********************************************************
// シグネチャ作成
/*
url_encode( consumer_secret ) + "&" +
url_encode( oauth_token_secret || nil )
*/
// *********************************************************
$oauth_signature = 
base64_encode( hash_hmac(
	"sha1",
	$base_string,
	$oauth_consumer_secret . "&" . $oauth_secret,
	true
));

// *********************************************************
// curl 処理
// *********************************************************
$curl = curl_init();
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $twitter_url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, "status=" . urle($text));

// *********************************************************
// http ヘッダ作成
// *********************************************************
$header = array();
$header[] = 'Expect:';

$header[] = "Authorization: OAuth ".
urle("oauth_consumer_key")."="".urle($oauth_consumer_key)."",".
urle("oauth_token")."="".urle($oauth_token)."",".
urle("oauth_nonce")."="".urle($oauth_nonce)."",".
urle("oauth_timestamp")."="".urle($oauth_timestamp)."",".
urle("oauth_signature_method")."="".urle($oauth_signature_method)."",".
urle("oauth_version")."="".urle($oauth_version)."",".
urle("oauth_signature")."="".urle($oauth_signature).""";

curl_setopt($curl, CURLOPT_HTTPHEADER, $header);

// *********************************************************
// https 用 ( https://api.twitter.co 利用時に必要 )
// *********************************************************
//curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
//curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);

// *********************************************************
// 戻された http ヘッダの出力
// *********************************************************
$handle = fopen("./header.txt", "w");
curl_setopt($curl, CURLOPT_WRITEHEADER, $handle);

// *********************************************************
// 送信
// *********************************************************
$result = curl_exec($curl);


// *********************************************************
// 結果
// *********************************************************
print "<br>";

if($result === false) {
	print '送信処理にエラーが発生しました: ' . curl_error($curl);
}
else {
	print '送信処理は正常に終了しました';
}
curl_close($curl);

// *********************************************************
// 結果表示
// *********************************************************
print "<br>";

$result = json_decode( $result );

print "<pre>";
print_r( $result );
print "</pre>";

?>


アプリケーション一覧ページ
※ 上のページでアプリケーションのアイコンをクリックすると個別のアプリケーションページです
※ そのページの右サイドのメニューに My Access Token へのリンクがあります



posted by lightbox at 2011-04-16 14:54 | PHP + Twitter | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します


Windows
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり