FlexからPHPを呼び出す

Daisukeh 2009/05/28 14:39 作成
Daisukeh 2009/06/04 08:13 解説
Daisukeh 2009/08/09 10:43 移設

記事一覧

Yahoo! ニューストピック

FlexによるYahoo! JAPANのニュース表示例

<phpinc=swfview.php>
<php>
  echo '<div align="center" style="border:1px silver dotted;">';
  swf_view('/log/newsview.swf', 500, 400);
  echo '</div>';
</php>

 サーバー移管に伴い、ウェブサービスを利用したニュース収集処理を一時中止しております。上の表示サンプルは実際にデータベースに格納されたニュースを表示したサンプル画像です。

Yahoo! JAPAN ウェブ・サービス

 ずっと以前に取得して使わずにいたYahoo! JAPAN デベロッパーネットワークのアカウントを使って、インターネット上に存在するニューストピックからテキストマイニングをしようと思う。このサイトの CMSPukiWikiからDokuWikiに変更する前にも、 RSS 解析の結果から様々なニュース情報をデータベース化し、ビジュアライゼーションするという試みをしていたのだが、 CMS を変更してからその機能を再インプリメントしていなかったので、今度はパブリックデータとして存在していて、ウェブAPIが公開されているYahoo! JAPAN デベロッパーネットワークのウェブ・サービスを利用してみた。

Yahoo! JAPAN デベロッパーネットワーク

 Yahoo! JAPAN デベロッパーネットワークのホームページを見てもらえればわかるとおり、さまざまなウェブ・サービスが提供されている。ニュースだけでなく地図オークションショッピングカテゴリなど、Yahoo! JAPANのポータルサイトで検索したり閲覧できる情報にはすべてアクセスできる仕組みになっている。また、Yahoo! JAPANならではの知恵袋検索、最近広まりつつあるOpenID、そしてウィジェットの製作規定などのドキュメントもそろっているため、ウェブ・プログラミングをする資料には事欠かない。さらにそれぞれのウェブ・サービスではウェブページで閲覧できる情報以外の情報(たとえばニュースであればトピックやキーワード、検索指標など)も抽出することができるため、使い方によっては面白いコンテンツが作れるだろう。提供されるデータはすべてパブリックデータのため、再利用できるという点も安心1)である。

 今回はテキストマイニング(広義にはデータマイニング強化学習にも通じる)の仕掛けを組み込むため、Yahoo! JAPAN デベロッパーネットワークの提供しているニューストピック検索と、テキスト解析サービスの日本語係り受け解析を組み合わせて、ニュースのタイトルや概要の日本語文章を形態素とその関係情報に分離する。ソースとなるニュースデータは、ニュースサービスで取り出せる各カテゴリの情報を毎時取得してデータベースと照合し、更新と追加などの処理をすることとした。今回作ったシステムではテキストマイニングの側面は直接的には少々希薄で、メインとなるのは情報の整理とビジュアライゼーションになっている。抽出したニュースと日本語情報は、集合知として取り出すことを期待して、データベースに蓄積しておこうと思う。

AMF3プロトコル

 情報のビジュアライゼーションをする上でどんなプラットフォームを使えばラピッドでスマートであるか考えることは重要だと思う。一般的な開発言語やフレームワークでも開発は可能だが、フロントエンドのインタラクティビティについて考えたとき、第一にJavascriptという選択肢があることを思い浮かべてしまう。Javascriptのフレームワークやツールキットは数多く存在2)し、またブラウザの実行性能も高速化しているため、Javascriptの需要や重要性は向上している。近年になってXMLに並んでメジャーになりつつあるJSONプロトコルは、Javascriptの隆盛を象徴するインフラなのではなかろうか。だがしかし、もうひとつのインタラクティブ性能を持つメジャーなプラットホームであるAdobe Flashを忘れることはできない。Javascriptと異なりデザイナ重視で容易に高度なコンテンツを作ることができるAdobe Flashは、現在のバージョンになって仮想マシンの実行性能を向上させ、それに伴って内部記述言語であるActionScriptのオブジェクト指向的側面に磨きをかけてきたのだ。ActionScriptでのFlashコンテンツ作成には、正規に手に入れることができるフリーの開発キットがリリースされたため、これまでデザイナの領域だったコンテンツ作成がプログラマも参加できる領域にまで広がったのだ。

 今回は二通りの方法でインプリメントをしてみた。ひとつはPHPで作るニュースページである。このニュースページについてはブログでも紹介したが、Yahoo! JAPAN デベロッパーネットワークのウェブサービスで取得したニュースの検索指標などをもとに、「The New York Times」を模倣した「the_now_yahoo_topics」という新聞のようなページをダイナミックに作成するというものだ。毎時ニュースを取得しているため、その都度ニュースの検索指標が変化し、インターネットにつながっている大衆がどんなニュースに注目しているのか、どんなフラッシュニュースが飛び込んできたのかを見ることができて楽しい。もうひとつはAdobe Flex 3を使ってActionScriptで作るFlashコンテンツである。これはこのトピックの先頭に表示されているものだ。「ニュース」のページにも表示している。見た目は素っ気ないFlashだが、一応バックエンドのスクリプトと通信してリモートメソッドを呼び出したり、間接的にデータベースアクセスしたりしているので、似たようなアプリケーションを作ろうとしている人には参考になるのでないだろうか?

AMFプロトコル

 ActionScriptから直接データベースにアクセスすることもできるかもしれない(試したことがない)が、手っ取り早いのはデータベースと親和性の高い言語でインターフェースを作ってしまって、ActionScriptと通信させるというのがアジャイルだと思う。そんなわけでMySQLともActionSctiptとも親和性の高いPHPを利用して、バックエンドの処理をインプリメントすることにした。別のPHPプログラムでウェブ・サービスにアクセスしてデータベースを更新する処理があるため、それと同じ手法でデータベースからニュースを取り出す処理を作るというものだ。一方でActionScriptと通信させなければならないが、幸いにもAdobe社とPHPの親元であるZend社は技術提携を結んでおり、Zend Framework1.8 ではFlashのネイティブなオブジェクト通信プロトコルであるAction Message Format (AMF)プロトコルを実装している。Zend Frameworkは後発ではあるが正統派のPHPフレームワークで、多くの機能を持っていながら互いに疎結合なため、必要な機能だけを require すればよいという、とても使いやすくて強力な武器である。今回はその Zend_Amf_Server クラスを使って AMFプロトコルによるリモートメソッドサーバーを作り、いくつかのメソッドを追加してハンドリングさせた上で、蓄積したニュースデータベースへActionScriptからアクセスできるようにしてみた。以下に、PHPによるデータベースアクセス用リモートメソッドサーバーと、ActionScriptによるユーザーインターフェースのソースコード3)を示す。

news2flex.php

<?php
 
    // AMF3通信セットアップ
    require_once("DB.php");
    require_once("Zend/Amf/Server.php");
    $utf8 = true;
    $server = new Zend_Amf_Server();
    $server->AddFunction("getNews");
    $server->AddFunction("getCategory");
    $server->AddFunction("getKeyword");
    echo $server->handle();
 
    // japanize : 日本語化
    function japanize($text)
    {
        global $utf8;
        if(!$utf8) $text = mb_convert_encoding($text, "UTF-8", "SJIS");
 
        return mb_convert_kana($text, "rnasKV", "UTF-8");
    }
 
    // getNews : ニュース取得
    function getNews()
    {
        global $utf8;
        $db =& DB::connect("mysqli://root:@localhost/web");
        if(PEAR::isError($db)) return null;
        if($utf8) $db->query("set names utf8");
        $res =& $db->execute($db->prepare(
            "select datetime, title, rating, article, summary, ".
            "url, linkurl, imageurl, topicid, categoryid, subcategoryid, keywordid ".
            "from news_log where datetime>? order by datetime desc"),
            array(date("Y-m-d H:i:s", strtotime("now -1 days"))));
        $newslog = array();
        while($res->fetchInto($row))
        {
            $datetime      = $row[ 0];
            $title         = japanize($row[1]);
            $rating        = $row[ 2];
            $article       = japanize($row[3]);
            $summary       = japanize($row[4]);
            $url           = $row[ 5];
            $linkurl       = $row[ 6];
            $imageurl      = $row[ 7];
            $topicid       = $row[ 8];
            $categoryid    = $row[ 9];
            $subcategoryid = $row[10];
            $keywordid     = $row[11];
            if(preg_match("/^\|(.+)\|$/", $keywordid, $mch))
                $keywordid = split("\|", $mch[1]);
            $newslog[] = array(
                "datetime"      => $datetime,
                "title"         => $title,
                "rating"        => $rating,
                "article"       => $article,
                "summary"       => $summary,
                "url"           => $url,
                "linkurl"       => $linkurl,
                "imageurl"      => $imageurl,
                "topicid"       => $topicid,
                "categoryid"    => $categoryid,
                "subcategoryid" => $subcategoryid,
                "keywordid"     => $keywordid,
            );
        }
        $db->disconnect();
 
        return $newslog;
    }
 
    // getTopic : トピック取得
    function getTopic($index, $id) { /* 省略 */ }
 
    // getCategory : カテゴリ取得
    function getCategory($index, $id) { /* 省略 */ }
 
    // getKeyword : キーワード取得
    function getKeyword($index, $id) { /* 省略 */ }
 
?>

PEARも使ってます

 そういえばデータベース(MySQL)のアクセスにはPEARライブラリのDBを使っている。PHPは本来的にMySQLへのアクセス関数(たとえばmysql_connectなど)を持っているが、PEAR::DBを使うと、接続文字列にターゲットデータベースエンジンやアカウント情報を記述するだけで、データベースアクセスを抽象化できるという点で、とても有用なライブラリだと思う。ところで、その接続時やデータ取得時に $db =& DB::connect(”<接続文字列>”); といった記述をするのだが、この =& という演算子はPHPには存在しない。 &= は論理積代入演算子として意味をもっているけれど、それをオーバーライドしたものではないのだ。何か違和感を感じてしまうのは僕だけだろうか?Googleで検索してもなかなかいい結果が得られなかったのだが、日本PHPユーザ会のメーリングリストによると、どうやら ポインタ代入演算子 だとのことらしい。引用になるが、通常の代入演算子を使うとデータやオブジェクトのコピーが代入されるが、 =& を使えば参照(つまりオブジェクトならその参照そのもの)が代入されるということらしい。クラスのインスタンスを作成した場合、通常の代入演算子( = )を使うとそのインスタンスのコピーが代入されるのを避けるため、このポインタ代入演算子( =& )を使うとよい、というふうに書いてあった。なるほど。PHPのドキュメントをしらべてみたが、クラスの基礎という項目に書いてあった。ちゃんと勉強しなきゃダメだね。

 以下のコードはActionScriptで作ったFlashコンテンツのソースである。正確にはMXMLで記述している。ActionScriptでベタ書きすることも可能だが、コントロールの配置や簡単なデザインとイベント記述などをするなら、MXMLでスケルトンを作成してしまってから、コードは Script タグに記述(もちろんActionScriptで。)すればいい。

newsview.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #FFFFFF]" borderColor="#FFFFFF" color="#000000" width="500" height="400" creationComplete="onCreationComplete(event);">
    <mx:DataGrid x="10" y="26" width="480" height="256" editable="false" id="dtgrdNewsLog" change="onNewsChange(event);">
        <mx:columns>
            <mx:DataGridColumn headerText="日時" dataField="datetime" width="140"/>
            <mx:DataGridColumn headerText="記事" dataField="article"/>
            <mx:DataGridColumn headerText="注目" dataField="rating" width="40"/>
        </mx:columns>
    </mx:DataGrid>
    <mx:Text x="10" y="290" width="480" height="100" id="txtNewsSummary"/>
    <mx:Script>
        <![CDATA[
            import mx.events.ListEvent;
            import mx.controls.listClasses.BaseListData;
            import mx.collections.ArrayCollection;
 
            private function onCreationComplete(event:Event):void
            {
                txtNewsSummary.text = "";
                var url:String = this.url.match(/^[a-z]+:\/\/[^\/]*\//g).toString();
                if(url.search(/^[htps]+:/) < 0) url = "http://localhost/";
                url += "log/news2flex.php";
                var net:NetConnection = new NetConnection();
                net.objectEncoding = ObjectEncoding.AMF3;
                net.connect(url);
                net.call("getNews", new Responder(onRequestResult, onRequestFault));
                net.close();
            }
 
            private function onRequestResult(result:Object):void
            {
                txtNewsSummary.text = "Yahoo!ニューストピックの24時間以内に注目されたニュースを閲覧できます。";
                var newsary:ArrayCollection = new ArrayCollection();
                var newslog:Array = result as Array;
                for(var index:int = 0; index < newslog.length; index ++)
                    newsary.addItem(newslog[index]);
                dtgrdNewsLog.dataProvider = newsary;
            }
 
            private function onRequestFault(fault:Object):void
            {
                txtNewsSummary.text = "データベースに接続できませんでした。";
            }
 
            private function onNewsChange(event:ListEvent):void
            {
                var news:Object = dtgrdNewsLog.selectedItem;
                txtNewsSummary.htmlText = 
                    "<p> " +
                    news.summary +
                    linktag("本文", news.url     ) +
                    linktag("関連", news.linkurl ) +
                    linktag("画像", news.imageurl) +
                    "</p>";
            }
 
            private function linktag(name:String, url:String):String
            {
                if(url == null) url = "";
                if(url != ""  ) url = " <a href=\"" + url + "\" target=\"_blank\">【" + name + "】</a>";
                return url;
            }
 
        ]]>
    </mx:Script>    
    <mx:Label x="10" y="0" text="Yahoo! ニューストピック" width="480" textAlign="center"/>
</mx:Application>

Flexは楽しい?

Adobe Flex  ActionSctiptを使ってAMF3プロトコルで透過的にPHPのリモートメソッドにアクセスする方法はとても簡単である。ネットワークオブジェクトにプロトコルとアドレスを指定するだけで、Responderにイベント(成功、失敗)を受け取るコールバックを指定するだけという、逆に不安になるほど簡潔である。これはActionScriptのクラスライブラリとプログラミング言語の柔軟性が成せる業だと思う。こういったネットワーク・プログラミングはつい最近まで例外処理だらけで難易度が高かったが、Microsoft.NETJavaPHPPythonRubyなどの、ある程度の規模のクラスライブラリを持っているプログラミング言語のパラダイムで、急速にその難易度が下がって一般化してきたように思う。特にネットワークに限らない通信系プログラムは煩雑になる傾向がある(相手が常に存在するとは限らない、あるいは接続が中断する可能性がある、などが原因である。)のだが、上記のActionScriptの例のような最小限の構成(成功/失敗のコールバック、あるいは一段だけの例外処理など)でアプリケーションを作成できるである。

 そんなネットワーク・プログラミングが簡単に作れて、こうやってブログやサイトにペタッと簡単に貼り付けられるのだから、 時代は変わったものだなぁ なんて思ってしまう。

1) もちろん商業利用や二次配布などに関する規定があるので、それを厳守した上で利用することは言うまでもない。
2) PrototypejQueryscript.aculo.usなど。個人的にはjQueryが簡潔で好きである。
3) ただし一部のコーディングを省略

掲示板

, 2012/08/27 11:34
-1'
, 2012/08/27 11:34
1
, 2012/08/27 11:34
1
, 2012/08/27 11:34
1
, 2012/08/27 11:34
1
, 2012/08/27 11:34
1
, 2012/08/27 11:34
1
, 2012/08/27 11:34
1
, 2013/01/30 08:30
-1'
, 2013/01/30 08:30
1
, 2013/01/30 08:30
1
, 2013/01/30 08:30
1
, 2013/01/30 08:30
1
, 2013/01/30 08:30
1
, 2013/01/30 08:30
1
, 2013/01/30 08:30
1
, 2018/11/06 05:43
日本超人気スーパーコピーブランド時計激安通販専門店
2018年最高品質時計コピー、国際ブランド腕時計コピー、
業界唯一無二.世界一流の高品質ブランドコピー時計。
, 2018/11/07 21:24
2018モデルブランド
iwcスーパーコピー
日本最高級スーパーコピーブランド時計激安通販専門店,高品質時計コピー,
2018最新作、国際ブランド腕時計コピー、業界唯一無二.世界一流の高品質ブランドコピー時計,
当店はスーパーコピー時計専門店,
販売以下世界一流ブランドコピー時計:ロレックスコピー、ウブロコピー、オメガコピー、シャネルコピー...
最高品質スーパーコピーN級品時計新作最新入荷,
信用第一 なので、ご安心ください,全国送料無料!
歓迎新旧顧客お願いします
, 2018/11/09 12:10
ルイヴィトン - N級バッグ、財布 専門サイト問屋
弊社は販売ルイ・ヴィトン) バッグ、財布、 小物類などでございます。
弊社は「信用第一」をモットーにお客様にご満足頂けるよう、
送料は無料です(日本全国)! ご注文を期待しています!
下記の連絡先までお問い合わせください。
是非ご覧ください!
激安、安心、安全にお届けします.品数豊富な商
商品数も大幅に増え、品質も大自信です
100%品質保証!満足保障!リピーター率100%!
Enter your comment
 
 
programming/network/flexからphpを呼び出す.txt · 最終更新: 2009/08/09 10:47 by daisukeh
 

Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS
Driven by DokuWiki Powered by Google do yourself a favour and use a real browser - get firefox ! GIMP is the GNU Image Manipulation Program. Adobe Flex smarty : Template Engine