2010/03/03
iPhoneの「Ustream Broadcaster」使ってみたけど、すげぇ簡単にライブ配信できる。 自分のiPhoneで早速試してみた(^_^)                                  justinは完全に差をつけられた感じだなぁ。       Ustreamはかなり技術力あってSoftbankも出資したし、ストリーミングは「Ustream」一本で間違いないだろう。 って訳で、このサイトも「Ustream」対応しようかと。 ちなみに、CMSとかでHTML出力するブロガーなら、JSやFlashガジェットタグ貼り付けるだけっす。 このサイトみたくフルFlashや自作でガジェット作りたい人は、公式サイトに「Ustream API」を利用。 パッと見だけど、わかりやすくてよく出来てると思う。 ■Ustream APIデベロッパー登録 http://developer.ustream.tv/ 登録すると「API Key」がゲットできます。 ■Ustream APIドキュメント(英語) http://developer.ustream.tv/data_api/docs html,json,xml,phpのモードがあるけど、汎用性考えるとJSONっすね。 (PHPはsirializeで返ってくるけど、JSON使えればあんま意味ない気も) しかも「Flash Client API」まで公開されてる! ■Flash Client API ▽ドキュメント http://developer.ustream.tv/external/flash/ ▽SVN http://svn.ustream.tv/flash/rsls/ クロスドメイン制限してないのかな? 後々試してみます。 ■API例 ▽チャンネル一覧 http://api.ustream.tv/json/user/yohei/listAllVideos?key=API Key ■動作確認用のサンプル [as3] class UStreamService extends Service { public function getChannels() { $params->user = UstreamのユーザID; $params->channel = Ustreamチャンネル名; $url = $this->getChannelListURL($params); $result = file_get_contents($url); $results = json_decode($result); return $results } private function getChannelListURL($params, $mode="json") { $url = USTREAM_API_URL."/{$mode}/user/{$params->user}/listAllVideos?key=".USTREAM_API_KEY; return $url; } } [/as3] 仕様決まれば簡単にファイル分離できそうです。 本家サンプルではcurl使ってるけど、この程度ならfile_get_contentsで十分かな?

  2010/03/03
おぉ!GoogleMapAPIのFlex用ライブラリーがswc形式でGoogle本家にあがってます(^_^)/ これで、わざわざFlashとJavaScriptの連携しなくてもよさげ? 3分クッキングで作成してみた。 ■google_map.swf htmlTextは機能ダメダメだけど、imgタグでswfを直で読めるんだぁ・・・ (^_^)つ ペタッ まだクラスの中身を詳しく見てないけど、swf間で通信(LocalConnection等)を実装すれば色んなことできそうです。 ■Google Maps API for Flash - FlexBuilder ▽チュートリアル http://code.google.com/intl/ja/apis/maps/documentation/flash/tutorial-flexbuilder.html ▽ダウンロード http://maps.googleapis.com/maps/flash/release/sdk.zip ■Maps API キーの取得 ドメイン毎にMapsAPIキーを生成できます。 http://code.google.com/intl/ja/apis/maps/signup.html ドメイン毎に発行なので、開発環境と本番ではキーを別々にしなければいけません。 プログラムは、クラス実装さえわかれば難しいことはなさげです。 「ARK-Web」にわかりやすくまとめられています。 実践編ではFlexとJavaScript連携でやってますが、Flexオンリーでやった方が軽そうだけど、 HTML派に考慮しての事かと思います。 ■動作確認サンプル ▽ソース これだけで、あっさり表示されます。 [as3] import com.google.maps.controls.ZoomControl; import com.google.maps.controls.MapTypeControl; import com.google.maps.controls.PositionControl; import com.google.maps.LatLng; import com.google.maps.Map; import com.google.maps.MapEvent; import com.google.maps.MapType; private var map:Map; private var locateX:Number = 35.728912; private var locateY:Number = 139.7095082; private function onInitialize(event:Event):void { map = new Map(); map.key = GoogleMapキー; map.addEventListener(MapEvent.MAP_READY, onMapReady); mapContainer.addChild(map); } private function onResize(event:Event):void { map.setSize(new Point(mapContainer.width, mapContainer.height)); } private function onMapReady(event:Event):void { map.setCenter(new LatLng(locateX, locateY), 14, MapType.NORMAL_MAP_TYPE); map.addControl(new ZoomControl()); map.addControl(new PositionControl()); map.addControl(new MapTypeControl()); } [/as3] locateX、locateYの位置指定は、GoogleMapのパラメータを直接埋め込んでますが、 各パラメータをGoogleからシームレスにやり取りできるかですね。 只今、このサイトと連動できるよう作成中で、何だか面白くなってきました。

  2010/03/01
がちょーん!!FlashCSだけに「FlvPlayback」等の便利なVideoコンポーネントがあるw Flexにないコンポーネントってあるんだねぇ(^_^;) どうりで最近動画プレイヤーが出回ってると思ったら・・・。 ■FlashのVideoコンポーネント(Flexには標準で未実装) ビデオプレイヤーの再生・停止は勿論、シークやボリューム等もGUIだけで作れちゃうん。 これならデザイナーさんには重宝されますなぁ(^_^) とは言っても、外部ビデオファイル取得とか他とのマッシュアップとかの処理は、結局ガリガリかかないといけないが・・・。 しかし、こんな便利なもんあるなら俺もFlashで作ろうか?と。 けど「fl.video」パッケージを探せば何とかなるんじゃね?と調べたら、ありました! ■Adobe Flash Media Server productivity tool FMS用のツールなんだけど、Flexでも使えそうです。 Adobe本家から「Adobe Flash Media Server productivity tool」をダウンロードできます。 https://www.adobe.com/cfusion/entitlement/index.cfm?event=custom&sku=FS0000503&e=fms35 FMS用のツールで、他にもやら面白げなライブラリーがある。 「Dynamic Streaming Class」って何?何?これ??(^_^) もしかして動的にAS書き出せちゃうのか???(違うか。。。) とりあえず後回しで「FLVPlayback2.5」を使ってみる。                 サンプルでスキンもswfで用意されている。 欲を言えば、スキンはswfでなくてas + 素材で欲しかったなぁ。 FlashCSみたくカスタムコンポーネント化すれば、もっと便利かも ■サンプルソース [as3] private function playTopVideo():void { var video:FLVPlayback = new FLVPlayback(); var ui:UIComponent = new UIComponent(); view.topVideo.addChild(ui); ui.addChild( video ); video.width = 320; video.height = 240; video.source = "movie/empire.mp4"; video.skinBackgroundColor = 0x666666; video.skin = "swf/FLVPlaybackSkins/SkinUnderAll.swf"; video.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO; video.skinAutoHide = false; } [/as3]

  2010/02/25
かなり煩雑なコードになってきたので、クラス化と言う名のリファクタリング。 意地でもPEARや他のライブラリは使わないぞw ■修正内容 VoiceService ver0.2 (1) MixiVoice、Twitterクラス化・ファイル整理

VoiceService | getVoices() | MixiVoice --> HTTPService Twitter --> HTTPService

(2) HTTPサービスクラス「HTTPService」作成 「HTTPRequestService」の命名の方が正しいかも!? (3) 同時投稿機能追加 とり合えず最低限の実装 ・Twitterは、Basic認証でなくてtokenにするのが今後の課題 ・Mixiは、htmlパースとログイン処理が課題 ■VoiceService(抜粋) ファイル分離して非常にわかりやすくなったv(^_^)v
    /**
     * mixi & Twitterボイス取得
     **/
    public function getVoices()
    {
        $mixi_voice = new MixiVoice();
        $voices['mixi'] = $mixi_voice->getVoices();

        $twitter = new Twitter();
        $voices['twitter'] = $twitter->getUserTimeline();

        $results = $this->_marge_voices($voices);
        dump($results);
        return $results;
    }

    /**
     * mixi & Twitterボイス同時投稿
     **/
    public function postVoice($values)
    {
        if ($values->message && $values->password == VOICE_PASSWORD) {
            $mixi_voice = new MixiVoice();
            $is_mixi = $mixi_voice->postMessage($values->message);

            $twitter = new Twitter();
            $is_twitter = $twitter->postMessage($values->message);

            return ($is_mixi && $is_twitter);
        }
    }
※「$this->_marge_voices($voices)」は、MixiVoiceとTwitterデータをマージしてJSON化してる ■MixiVoice(抜粋) 「HTTPService->request」を実装して、paramsをオブジェクトで渡すようにした。 とりあえず、こんなもんかな?
    /**
     * mixiボイス取得
     **/
    public function getVoices()
    {
        $this->login();

        $params->url = MIXI_ECHO_LIST_URL;
        $params->method = 'POST';

        $html = $this->request($params);
        $results = $this->parseVoice($html);
        return json_encode($results);
    }
■Twitter(抜粋) このクラス名だと、また膨大になりそうな予感だけど。。。 これもパラメータをオブジェクトで渡すようにした。
    /**
     * Twitter投稿
     **/
    public function postMessage($message)
    {
        if (!$message) return;

        $posts['status'] = $message;

        $params->posts = $posts;
        $params->url = TWITTER_UPDATE_JSON_URL;
        $params->basic->id = TWITTER_USER_NAME;
        $params->basic->password = TWITTER_PASS;

        $results = $this->curlRequest($params);
        return $results;
    }
■HTTPService(抜粋) これが肝のクラス。 なので、頭が整理できてなずサッパリ(T_T) cokkie処理やBasic認証が両立できなくて、とりあえず「curl」と「file_get_contents」の併用です。 ▽各メリット ・curl:細かいことができそうで速い ・file_get_contents:ソースが短くできそう 最終的にはcurlで統一するかな?
    /**
     * HTTPリクエスト(curl)
     **/
    public function curlRequest($params)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $params->url);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        //POST
        if ($params->posts) {
            $posts = http_build_query($params->posts, '', '&');
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $posts);
        }

        //cookies
        //TODO 
        //curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie");

        //BASIC認証
        if ($params->basic) {
            curl_setopt($ch, CURLOPT_USERPWD, "{$params->basic->id}:{$params->basic->password}");
            dump($params->basic);
        }
        $results = curl_exec($ch);
        curl_close($ch);
        return $results;
    }

    /**
     * HTTPリクエスト(file_get_contents)
     **/
    public function request($params) {
        $headers[] = 'Content-Type: application/x-www-form-urlencoded';

        if (is_array($params->posts)) {
            $content = http_build_query($params->posts, '', '&');
            $content_length = strlen($content);
            $headers[] = "Content-Length: {$content_length}";
            $requests['http']['content'] = $content;
        }

        //Basic認証
        if ($params->basic) {
            $basic = base64_encode("{$params->basic->id}:{$params->basic->password}");
            $header[] = "Authorization: Basic ".$basic;
        }

        //cokkie
        //TODO paramsかセッションにする?
        if ($this->cookie) {
            $headers[] = "Cookie: {$this->cookie}";
        }

        if ($params->method) {
            $method = $params->method;
        } else {
            $method = 'GET';
        }
        $requests['http']['method'] = $method;
        $requests['http']['header'] = implode("\r\n", $headers);

        $context = stream_context_create($requests);
        $contents = file_get_contents($params->url, false, $context);

        //cookie取得・設定
        if ($http_response_header) {
            $this->setCookieForHttpResponseHeader($http_response_header);
        }
        return $contents;
    }
※「$this->setCookieForHttpResponseHeader」は、HTTPヘッダーをパース

  2010/02/24
FlashのhtmlTextの機能、何とかならんかね~>Adobe せめて画像の回り込みぐらい(T_T) さて、Androido本を買ってみた(もち会社経費でw)。 「Google Androidプログラミング入門 (大型本)」 豆蔵社員が作ってて、本質的な基礎部分に触れていて結構わかりやすいと思う。 出版不況とは言えども、こう言う専門書籍とかは手に持ってみたい感じがする。 ざっと見た感じ、 (1) ファイル構成 (2) Actibity、イベント (3) Intentによるデータ管理 この辺の概念を抑えればとり合えずアプリは作れそうだ。 サンプルアプリ作ってみたけど、結構わかりやすいと思う。 とは言っても、コンポーネントやサービスが膨大っぽいし、実機を持ってないからなぁ・・・。 なんかAndroidの実機が欲しくなってきたこの頃(^^) ■個人的感想 ・Javaベースなので入りやすい →iPhone SDKみたく「Objective-C」覚えなくて良い ・思想がMVCっぽくて、階層がわかりやすい →人によって作り方が大きく変わることがない感じ  これは重要 ・XMLの定義は、FlexのMXMLと基本概念は同じ →UIベースで定義できるのでスピーディー  ただ、第一印象では機能的に物足りない感(機能を知らないだけかも知れんが) ・データバインディングが面倒くさい感  →ソースベースでしかできないのかな?  「WebObjects」や「iPhone SDK」のInterfaceBuilder機能が搭載されれば、かなりスピーディーになると思う ・「自動ビルド」に設定しておくと、ビルドエラーが多発  →原因調べないと・・・ ・イベント監視が面倒くさそう  →モバイルフォンだから仕方ないが・・・

  2010/02/18
何か勉強してる時間がない。。。 と言い訳はしたくないから、無理にでもやるw まずは環境整備から。 「Android SDK + Eclipse ADT」で構築してみる。 とりあえず、「Android Developers」を見ながらインストール。 ちょうど「Android 2.1 API Level 7」がリリースされてた。 そもそも、Ver1.xから何が違うのかすらわからない状態だが(笑) 基本は、 (1) SDKのパスとおして (2) Eclipse Plugin入れて (3) EclipseでSDK Componentsをインストール 自宅はMac、会社ではWindows版を。 自分メモ ■SDK (1) ダウンロード android-sdk_r04-windows.zip (2) インストール先はC直下にした。 C:\air2_b1_sdk_win_111709 (3) toolsへのPath追加 C:\android-sdk-windows\tools ■ADT Plugin for Eclipse - 設定マニュアル http://developer.android.com/sdk/eclipse-adt.html (1) Eclipse 3.4 (Ganymede)なので、以下のインストールURL https://dl-ssl.google.com/android/eclipse/ (2) ウィンドウ > 設定 > Androido (3) SDKロケーション設定して【適用】 C:\android-sdk-windows この時点で、パッケージはインストールされてなかったので、 (4) ウィンドウ > Android SDK and AVD Manager > Avalible Pakages (5) パッケージを選択して【Install Selected】 ちょい時間がかかる。 全部入れる必要はなかったかな?w (6) Virtual Devicesもとり合えず設定 ■動作確認でプロジェクト作成 基本は通常のプロジェクト作成と同じ (1) ファイル > 新規 > Androidプロジェクト (2) 各項目設定 - BuildTarget:とり合えず最新の2.1(API Level7)を選択 - アプリケーション名:Hello - パッケージ:jp.co.telepath(任意) - Create Activity:Activityを継承するクラス名 ※Activity = Androidアプリ画面 Androidアプリ作成の基本“Activity”とは何か? (3)【完了】 で、ここでBuildエラーw Eclipseで自動ビルドにしておくと、genがうまく作成されないらしい(ホント?) なんで、 ■genのクリーンアップ (1)「自動的にビルド」のチェック外す (2) genディレクトリ削除 (3) プロジェクト > クリーン 一応、コンパイルされた。 ■確認 (1) HelloWorld的なw [java] package jp.co.telepath; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class Hello extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("OKOKOK"); setContentView(tv); } } [/java] onCreateはイベントハンドラっぽいな。 Activityの状態遷移に記載されてるのが全てなのかな? 何かイベント管理が大変そうだけど。。。 その前にActivityクラス等のソース見れるようにしないとw (2) 実行 バーチャル携帯の起動遅い・・・結構ストレスかもw てな訳で次は、まずAndoroidの基礎知識から!

  2010/02/08

iPhoneがFlashを載せない理由

Flashはバギーだし、HTML5で十分

やっとRIAが業界全体が動き始めた実感。
「Flash vs HTML5」って文字を良く見るけど、個人的にはどっちでも同じかなぁ?と思う。
どっちを選択しようと、デベロッパ的にはやる事は変わらないと思う。

問題は、FlashであろうとHTML5であろうと、デザイナーとデベロッパの境界線が更にグレーになる。
個人的には、FlashもHTML5(JS・CSS含む)もWebデザイナーで全部作ってくれと言いたいが・・・
多分、この中間層の人材需要が増えるんじゃないかな?と思う。
さて、HTML5優位とはいいつつ、現状はFlashに劣っている部分は否めないと思う。

■現状のHTML5 + JSの問題点・疑問点

(1) ブラウザ依存しすぎ  これが一番懸念されてることすよね。
(2) ライブラリが規格統一されてない jQuery、PrototypeJs、YUIと選択肢が多すぎてこの先どうなるのか?
(3) 開発標準環境が確立されてない  これはまだ仕方ないけど、時間短縮は開発ツールが命だからねえ。  JSに関してはせめてヒエラルキーを追えるツール探さなきゃ(Eclipse Pluginとかあるのかな?)
(4) 既にActionScript3.2で実現可能

JSでしかできない秀逸な機能が今のところ見当たらない FlashPlayer10.1 & Air2.0はかなり面白いのだが、どうなるのかなぁ? どちらにしろHTML5、JSのクラス実装くらいは把握しておかないと死ねる。 あとAndroido、XCodeは手をつけておかないと。

  2010/02/06
PHPライブラリは誰かの「twitter2mixivoice.php」もあったけど、 (1) PEAR依存 (2) 自前だと修正・拡張ができる なんで、ライブラリも自前で。 ■問題点 (1) mixiボイスのAPIがない →よって、無理矢理ログインしてHTMLパース以外方法なし (2) クロスドメイン制限 →swfで直接通信が理想なんだけど、mixiもtwitterもクロスドメイン制限があるので断念  サーバかまして処理する事に ■主なポイント (1) AMF通信 →高速かつFlexとオブジェクトの親和性が高いAMFを採用  JSON、XML変換できるけど、今は必要なし  てか、XMLって遅いし面倒だし通信においてメリットあるのか?といつも疑問に思う。 (2) データのマージ  twitterはJSON、mixiはテキスト取得して日付ソートしながらデータマージ  (超暫定で最低限のタイトルと日付だけ) とりあえずデータ取得&マージまで作ったので、あとはマルチ投稿の仕様考える。 ある程度まとったら機能毎にクラス化へ。 途中までのソース うーん、デザイン的にコードは別途コンポーネント作った方がいいなw swf側ソースは、色々ネタが多いので別途記事にする予定(?) ■VoiceService.php
require_once 'Service.php';

class VoiceService extends Service {

    /**
     * データ取得
     **/
    public function getVoices() {
        $voices['mixi'] = $this->mixi_voices();
        $voices['twitter'] = $this->twitter_user_timeline();
        $results = $this->_marge_voices($voices);
        return $results;
    }

    /**
     * Twitterタイムライン取得
     **/
    private function twitter_user_timeline()
    {
        $this->_twitter_auth();
        $url = "http://twitter.com/statuses/user_timeline/{$this->twitter_user_name}.json";
        $url.= "?since=".urlencode(date('D, d M Y G:i:s GMT', strtotime('-10 day')));
        $results = $this->_twitter_request($url);
        return $results;
    }

    /**
     * Twitter投稿
     **/
    private function post_twitter()
    {
        if ($_POST['message']) {
            $this->_twitter_auth();
            $message = rawurlencode($_POST['message']);
            $url = "http://twitter.com/statuses/update.json";
            $posts = "status={$message}";
            $results = $this->_twitter_request($url, $posts);
            return $results;
        }
    }

    /**
     * mixiボイス取得
     **/
    private function mixi_voices()
    {
        $this->_mixi_login();
        $url = 'http://mixi.jp/list_echo.pl';
        $headers[] = "Cookie: {$this->cookie}";

        $html = $this->_mixi_request($url, $headers, 'POST');
        $results = $this->_parse_mixi_voice($html);
        return json_encode($results);
    }

    /**
     * mixiボイス投稿
     **/
    private function post_mixi_voice()
    {
        $this->_mixi_login();
        $url = 'http://mixi.jp/list_echo.pl';
        $headers[] = "Cookie: {$this->cookie}";
        $html = $this->_mixi_request($url, $headers, 'GET');
        $post_key = $this->_get_mixi_voice_post_key($html);

        $url = 'http://mixi.jp/add_echo.pl';
        $body = 'てすとー'.date('Y/m/d H:i');
        $posts = array(
            'body' => $body,
            'post_key' => $post_key,
            'redirect' => 'recent_echo',
            'default_value' => $body,
        );
        $html = $this->_mixi_request($url, $headers, 'POST', $posts);
        $results = mb_convert_encoding($html, 'UTF-8', 'EUC-JP');
        echo($results);
    }

    /**
     * データ形式の統一
     **/
    private function _marge_voices($values)
    {
        if (is_array($values)) {
            foreach ($values as $type => $value) {
                $voices = json_decode($value);
		foreach ($voices as $key => $voice) {
                    $time = strtotime($voice->created_at);
                    $sort_times['time'] = $time;
                    $result['type'] = $type; 
                    $result['time'] = $time;
                    $result['created_at'] = date('Y-m-d H:i:s', $time);
                    $result['text'] = $voice->text;
                    $results[] = $result;
               }
            }
        }
	if (is_array($result)) {
            array_multisort($sort_times, SORT_DESC, $results);
	    json_encode($results);
	    return $results;							}
    }

    /**
     * twitter認証設定
     **/
    private function _twitter_auth()
    {
        $this->twitter_user_name = TWITTER_USER_NAME;
        $this->twitter_email = TWITTER_EMAIL;
        $this->twitter_password = TWITTER_PASS;
    }

    /**
     * mixi認証設定
     **/
    private function _mixi_auth()
    {
        $this->mixi_id = MIXI_ID;
        $this->mixi_email = MIXI_EMAIL;
        $this->mixi_password = MIXI_PASS;
    }

    /**
     * mixiログイン処理
     **/
    private function _mixi_login()
    {
        $this->_mixi_auth();

        $posts = array(
                'email' => $this->mixi_email,
                'password' => $this->mixi_password,
                'next_url' => 'http://mixi.jp/home.pl'
            );
        $headers[] = 'Content-Type: application/x-www-form-urlencoded';
        $url = 'http://mixi.jp/login.pl';
        $this->_mixi_request($url, $headers, 'POST', $posts);
    }

    /**
     * mixiボイスpost_key取得
     **/
    private function _get_mixi_voice_post_key($html)
    {
        if ($html) {
            $html = mb_convert_encoding($html, 'UTF-8', 'EUC-JP');
        }
        $rows = explode("\n", $html);
        if (is_array($rows)) {
            foreach ($rows as $key => $row) {
                $pattern = '|]+>(.*)]+>|U';
                preg_match("{$pattern}", $row, $values);

                preg_match('/post_key=(.+)&/', $row, $params);
                if ($params) {
                    $post_key = $params[1];
                    if ($post_key) {
                        return $post_key;
                    }
                }
            }
        }
    }

    /**
     * mixiボイスパース
     **/
    private function _parse_mixi_voice($html)
    {
        if ($html) {
            $html = mb_convert_encoding($html, 'UTF-8', 'EUC-JP');
        }
        $rows = explode("\n", $html);
        if (is_array($rows)) {
            foreach ($rows as $key => $row) {
                $pattern = '|]+>(.*)]+>|U';
                preg_match("{$pattern}", $row, $values);

                $pattern_posttime = '';
                if (preg_match("{$pattern_posttime}", $values[0])) {
                    $voice['created_at'] = $values[1];
                    $voice['type'] = 'mixi';
                }

                $pattern_body = '';
                if (preg_match("{$pattern_body}", $values[0])) {
                    $voice['text'] = $values[1];
                    $voices[] = $voice;
                    $voice = null;
                    $values = null;
                }
            }
        }
        return $voices;
    }

    /**
     * mixi共通リクエスト
     **/
    private function _mixi_request($url, $headers, $method, $posts=null) {
        if (is_array($posts)) {
            $content = http_build_query($posts, '', '&');
            $content_length = strlen($content);
            $headers[] = "Content-Length: {$content_length}";

            $params['http']['content'] = $content;
        }

        $params['http']['method'] = $method;
        $params['http']['header'] = implode("\r\n", $headers);

        $context = stream_context_create($params);
        $contents = file_get_contents($url, false, $context);

        //cookie設定
        $this->_set_cokkie_for_response_header($http_response_header);
        return $contents;
    }

    private function _set_cokkie_for_response_header($http_response_header) {
        if (is_array($http_response_header)) {
            foreach ($http_response_header as $r) {
                if (strpos($r, 'Set-Cookie') === false) {
                    continue;
                }
                $params = explode(' ', $r);
                $this->cookies[] = str_replace(';', '', $params[1]);
            }
	    if (is_array($this->cookies)) {
               $this->cookie = implode('; ', $this->cookies);
            }
        }
    }

    /**
     * twitter共通リクエスト
     **/
    private function _twitter_request($url, $posts=null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($posts) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $posts);
        }
        curl_setopt($ch, CURLOPT_USERPWD, "{$this->twitter_email}:{$this->twitter_password}");
        $results = curl_exec($ch);
        curl_close($ch);
        return $results;
    }

    // WSSE Authentication
    function _mixi_wsse_authentication_header() {
        $nonce       = pack('H*', sha1(md5(time().rand().posix_getpid())));
        $created     = date('Y-m-d\TH:i:s\Z');
        $digest      = base64_encode(pack('H*', sha1($nonce . $created . $this->mixi_password)));
        $wsse_format   = 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"';
        $wsse = sprintf($wsse_format, $this->mixi_email, $digest, base64_encode($nonce), $created);
        $header = "X-WSSE: {$wsse}";

        return $header;
    }		
}

  2010/02/05
自宅←→会社の作業での個人プロジェクト共有のお話 ファイル転送ソフトとかいい加減馬鹿らしいので、SVNをyoo-s.comに構築している。 と記事にするまでもないネタだったのだが・・・ http経由でソースをオール公開していたのだが、 個人設定情報も去年から丸見えだった!事に今日気づくw mixiとtwitterはおろか、Googleアカウントまで乗っ取られるとこだった((*_*)) 取り合えずBasic認証をかける。 やっぱライブラリ系以外のソース公開は無理だな。 ■Apache設定
 #vi /etc/apache2/mods-available/dav_svn.conf
<Location /svn>
  DAV svn
  SVNParentPath /var/svn
  AuthType Basic
  AuthName "Subversion Repository"
  AuthUserFile /etc/apache2/dav_svn.passwd
  AuthzSVNAccessFile /etc/apache2/dav_svn.authz
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    Require valid-user
  </LimitExcept>
</Location>
■Basic認証設定 - ユーザファイル
 #vi /etc/apache2dav_svn.authz

* = r ユーザ名 = rw

- htpassword
 #htpasswd -c dav_svn.passwd ユーザ名
<< Top < Prev Next > Last >>
git push git pull にブランチ指定せずに実行する
git pull や git push できなくなったとき
Docker のコンテナからホストOS に接続
Mac で ローカル IP アドレス(ipv4)のみを表示する
ホストOS から Docker の MySQLコンテナに接続
caching_sha2_password のエラー
node-config で環境設定ファイルを利用する
rootパスワードを初期化(再設定)する
Git から clone したときのエラー対処
Mac に MySQL をインストール
Mac に PostgreSQL をインストール
Laravel 環境構築 - Mac ネイティブ編
Firebase 入門 - Firebase とは
Firebase 入門 - CLI インストールとデータベースの設定
AWS 無料枠(t2.micro)で容量とメモリエラー
Cloud9 を起動する -初心者編-
gcloud で GCEインスタンスを起動してみる
AWS CLI と jq でインスタンス一覧を整形して表示
React と Laravel7 のプロジェクトを作成する
Homebrewインストール-2020年版
3直線で囲まれた範囲塗りつぶし
PuLP で線形最適化問題を解く
カスタムのペジネーションを作る
node-sass を使って sass をコンパイルする
Log ファサードでSQLログを分離して書き出す
いちから始める Docker - 複数のコンテナを使う - (2020年)
いちから始める Docker - docker-compose を使う - (2020年)
AWS ECR を使ってみる
Laravel7 でマルチ認証
Mac に AWS Client を設定する
Laravel7 リリース
v-html でHTML表示する
Laravel で Nuxt.js を使ってみる(Docker環境)
Laravel で Vue コンポーネントを使う
いちから始める Docker -コンテナをビルド- (2020年)
いちから始める Docker -起動してみる- (2020年)
Mac で MySQL(8系)
composer で vendor がインストールできない
Eloquent の日付を Carbon で扱う
webpack 4 入門(npm編)
[Mac]容量を減らす
DIコンテナはじめ
freee SDKを Laravel で使ってみる
freee API を使ってみる
Segueを利用しない画面遷移
Xcode11.3 で XVim2 を利用する
Codable で JSONを読み込み
Webpack入門(yarn編)
MacからLaradock PostgreSQLで接続エラー
Mac で Laradock の構築