[ カテゴリー » 開発日誌 » PHP ]

短縮URLの元を知る その2

category-icon

 こんにちは。前回のエントリーのコメントで「生ログ」の「リンク元」にも「expand」アイコンをとの要望がありましたので、そうしました。ついでに、短縮URLのサービスホストを判定するロジックの精度を少しばかり高めました。単に、文字列の長さのみで判定すると、p2b(笑)だとか、twitterとかも短縮URLサイトと判定してしまうので。

 具体的には、ホワイトリストのホスト名を配列で指定するようにして、そうでなければ「expand」アイコンを付けるという感じです。現状、以下のようになっていますが、適宜追加しても良いでしょう。

$not_shortening_hosts = array('twitter', 'www', 'p2b');

 これは、view.phpの78行目で指定しています。

 ブラックリスト方式でやろうとすると、どうやら100以上のサイトLink を指定する必要がありそうで、ちょっとシャレになりません。

 最新版を添付しておきます。

添付ファイル: view.phpattachedIcon 

— posted by martin at 01:40 am   commentComment [2]  pingTrackBack [0]

短縮URLの元を知る

category-icon

 おはようございます、martinです。WC、初戦勝ちましたねぇ。正直期待していなかっただけに喜びも倍増といったところ。決勝トーナメント進出!なんて日が来るのでしょうか。

 さて、今回は前回のアクセス解析の続きみたいなものです。前回のエントリーで、短縮URLの元を知るサイトとして、http://knowurl.com/Link を紹介しましたが、他にもいくつかありますね。LongURLLink なんかもそうです。LongURLは、Firefoxの拡張版Link もあるようですね。APILink も公開されているようでjQueryのプラグインとかもあるようです。APIがあるんで、ppBlogでも使える様なJavaScriptを書いても良いですが、仕組みは結構単純なので、外部のAPIに頼らずともppBlogのみで完結できそうです。

 まずは、短縮URLがどのような仕組みになっているのか知る必要があります。短縮URLを提供しているサイトはいくつもあります(現時点で動いているのは bit.ly、j.mp、cli.gs、Short.ie、Idek.net、is.gd、sn.im、u.nuあたり)が、これら殆どのサイトでやっていることはリダイレクトです。PHPを使えば、その辺りの情報は簡単に取得出来ます。例えば、http://bit.ly/aKhZ1GLink は、http://p2b.jp/201006-get-html5-fileuploading-moduleというリンクの短縮形ですが、PHP経由でアクセスしてみると、リダイレクト先の情報などが入手出来ます。PHP5であれば、get_headers()Link 関数が使えます。便利ですね。この関数を使って以下を実行すると、

<?php
$url = 'http://bit.ly/aKhZ1G';
print_r(get_headers($url, 1));
?>
大まかには、以下のようになります。
Array(
 [0] => HTTP/1.1 301 Moved  /* Permanentlyと続くこともある */
 [Location] => http://p2b.jp/201006-get-html5-fileuploading-module /* リダイレクト先がある! */
 [MIME-Version] => 1.0
 [Content-Length] => 313
 [X-Powered-By] => PHP/5.1.6
)
[Location]の項目に短縮URLの元リンクが収められていますね。なので、配列からこれを取り出せばOKです。じゃPHP5ではないサーバーではどうするか。fsockopen()関数Link を使います。以下のような記述で行けるでしょう。
$url = 'http://bit.ly/aKhZ1G';
$_url = parse_url($url);
$port = isset($_url['port']) ? $_url['port'] : 80;
$host = isset($_url['host']) ? $_url['host'] : '';
$path = (isset($_url['path']) ? $_url['path'] : '/').(isset($_url['query']) ? '?'.$_url['query'] : '');
$request  = "GET ".$path." HTTP/1.1¥r¥n";
$request .= "Host: ".$host."¥r¥n";
$request .= "Connection: Close¥r¥n¥r¥n";

if($fp = fsockopen($host, $port, $errno, $errstr, $timeout=3)){
  stream_set_timeout($fp, 3);
  $ret = '';
  fputs($fp, $request);
  do {
   $ret .= fgets ($fp, 4096);
  } while (strpos($ret, "¥r¥n¥r¥n") === FALSE); // ヘッダー部分で十分
  fclose($fp);
}

これを実行すると、以下のような感じになります。

HTTP/1.1 301 Moved
Server: xxxx/0.7.42
Date: Tue, 15 Jun 2010 02:46:59 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Set-Cookie:xxxx
Location: http://p2b.jp/201006-get-html5-fileuploading-module /* これが欲しい */
MIME-Version: 1.0
Content-Length: 313

これから、Location:の部分を取り出す正規表現は、以下のような感じでしょうか。

$redirectURL = preg_replace('{^.+?Location:¥s([^¥n]+?)¥n.+$}s', '$1', $ret);
これで、$redirectURLにhttp://p2b.jp/201006-get-html5-fileuploading-moduleという文字列が入ることになります。

 以上のことをやると、リダイレクト先が分かるのでppBlogのアクセス解析に組み込んでみました。「リンク元」の項目で、短縮URLっぽいものには、下のショットにあるように「expand」というアイコンみたいなやつが付くようになります。

shot1
短縮URLなので一体どこへのリンクなのか分からない

 そしてこれをクリックすると、Ajax経由で情報をゲットして以下のような表示に変わります。

shot2
その場でリダイレクト先のアドレスが表示される

 リダイレクト先があれば、これがその場で表示されます。これはリンクになっていますが、そのサイトへのリンクではなくて、グーグルでそのリンクを調べるようになっています。それで怪しげなサイトであればブラウザでアクセスするのを避けることが出来るわけです。

 ちなみに、Ajax部分は、以下のような関数で実現しています。思ったよりシンプルに出来ました:)

  var expand = function(url){
   var target = o(oParts.evt.target);
   var loader = oParts.create('IMG').src('../Images/loader.gif'); /* ローディングアニメーション */
   target.addAfter(loader);
   oParts.server.get('view.php?expand=' + url, function(ret){ /* これがAjax部分 */
    loader.away();
    if(ret == url){
     target.css('color:gray; cursor: default').html('redirect 0').title('リダイレクトはありません').on('click', function(){});
    } else {
     target.css('color:crimson; border-color: green').html('Redirect: <span onclick="googleIt(¥''+ret+'¥')" title="グーグルで検索">' + ret + '</span>');
    }
   });
  }

 一応、これを実現するためのview.php添付しておきますstatディレクトリの既存のやつと置き換えればOKかと思います。前回添付したものの上位版になります。

 今週末にppBlogの最新版配布を予定していますが、これはそのバージョンに組み込み予定です。

 


— posted by martin at 12:24 pm   commentComment [2]  pingTrackBack [0]

HTML5によるファイルアップロードスクリプトの配布

category-icon

 おはようございます、martinです。前々回ぐらいに、HTML5を用いたプログレスバー付きのファイルアップロードのデモを示しました。この手のスクリプトは、プログレスバーの表示にFlashやJavaを用いていることが多いのですが、ファイルサイズが大きくなる傾向になったり、設置がややこしかったりします。

 何件かソース希望のリクエストがあったので、ppBlogからのスピンアウトとして配布しようと思います。配布するやつは、PHPとJavaScript(+CSS)だけでプログレスバーを実現していて、設置も比較的簡単ではないでしょうか。添付ファイルを展開すると以下のファイルが含まれています。

  • index.html(ここにアクセス)
  • fileUpload.php(PHPでのファイルアップロード処理用)
  • oParts.js(プログレスバーのためのJSライブラリ)
  • progressbar.png(プログレスバーの画像)
  • PIX(アップロードした画像を保存するフォルダ)

 基本的には、展開したフォルダを然るべき場所にまるごとアップロードして、index.htmlにアクセスすればOKかなと思います。サーバーによっては、PIXディレクトリのパーミッションの指定が必要かもしれません(707とか)。

 画像を保存するディレクトリは、PIXにしていますが、これは適当に名前を変えても良いでしょう。fileUpload.phpの最初の方で指定出来ます。

$pix_dir = 'PIX/'; // 画像を保存するディレクトリ。パーミッションは707とか。

 うまく動けば、アップロード中は以下のような画面になっているかと思います。

shot

*あくまでサンプルです。最低限の実装なので、セキュリティ関連は、各自でいじって下さい。JavaScriptをいじれば、プログレスバーに加えて、全体の何パーセントが完了みたいなことも出来るでしょう。

添付ファイル: MultipleFileUpload.zipattachedIcon 

     


— posted by martin at 02:29 pm   commentComment [0]  pingTrackBack [1]

HTML5による複数ファイルアップロード

category-icon

 こんばんは、martinです。以前、Flex(Flash)を用いた複数ファイルのアップローダーLink を紹介しましたが、実はHTML5だけで出来るのになぁ、と思っていました。現時点で、IE8を除く主要なブラウザでは軒並み、HTML5のINPUT要素に対するmultiple属性に対応しているので、それによる実装をppBlogに施してみました。複数ファイルを選択可能にするには、input要素にmultipleを指定するだけです。

<input type="file" name="src[]" id="src" multiple />

 とりあえず実装してみただけですが、きちんと動作しました(ここのエントリーLink は画像を複数枚一度にアップロードした)。UIをどうするかで試行錯誤しましたが、プロトタイプにしてはまぁまぁかなと思っています。

shot1
このように一度に複数画像の選択が可能です。

 さて、複数の(画像)ファイルがアップロード出来るようになると、アップロードする枚数に応じて、サーバーにデータを渡す間、じっと待たされるようになります。現状、HTML5のみではぼーっと待つしかありません(-o-) なので、アップロードの進捗状況を示すプログレスバーが欲しくなります。この手のスクリプトはウェブ上にいろいろありますが、どれもFlashを用いたり、Perl(+JavaScript)を用いたりしたものです。出来ればPHP(+JavaScript)のみで完結させたい。

 いろいろ調べてみると、PHPとJavaScriptのみでは、ファイルアップロードに伴なうプログレスバーのギミックを提供するのは無理という記述ばかりです。というのもPHPには、ファイルアップロードの途中経過を知らせる仕組みが備わっていないからです。実は、PHP5.2以上であれば、PECL APC拡張機能を組み込んで可能Link なのですが、サーバー側で PECL APCエクステンションをインストールする必要があり、これはレンタルザーバー等では敷居が高いでしょう。

 なので(Perlはあまり好きになれないという理由もあり)PHPとJavaScriptのみによる実装を考えてみました。まずは、PHPにおける、POST メソッドによるファイルアップロード時の挙動を知る必要があります。マニュアルによれば、基本的に以下の手順を踏みます。
  1. サーバー上に転送される(画像)データは、最初は一時的なディレクトリ(テンポラリディレクトリ)にアップロードされます。この一時的なディレクトリは、だいたい/tmpディレクトリのことが多いです。php.iniで指定可。
  2. 画像データの転送が無事に終わると、move_uploaded_file関数を用いて指定したディレクトリに画像データを移動させます。

 PHPでのネックは、この1番目の進捗状況を知るメソッドが備わっていないことです(なのでこの部分だけはPerlで処理するスクリプトがある)。サーバーサイドで提供しないのであれば、こちらからゲットしに行きましょう。アップロード中のデータは、テンポラリディレクトリに溜まっていくので、そのディレクトリのサイズは徐々に大きくなるはずです。なので、そのディレクトリのサイズを定期的に監視すればOKということになります。この「定期的に監視」という部分にJavaScriptのAjaxを使えば良いわけです。

 ディレクトリのサイズは、以下の記述で取得可能です。
$tmp_dir = '/tmp'; // 取得したいテンポラリディレクトリ

$size = 0; // ディレクトリのサイズ

$d = opendir($tmp_dir);
while($file = readdir ($d)){
 if(is_file($tmp_dir.'/'.$file)){
  $size += filesize($tmp_dir.'/'.$file);
 }
}
closedir($d);
echo($size); // ディレクトリの合計サイズを得る

 なお、上の例では、テンポラリディレクトリは/tmpですが、これを取得したい場合は、ファイルアップロード時に現れる変数の$_FILES['src']['tmp_name']を利用して、

dirname($_FILES['src']['tmp_name']);

で取得可能です。

 あとは、AjaxとPHPで、このディレクトリサイズを返すような記述をして、それをJavaScript側に渡し、プログレスバーっぽく見せればOKとなります。具体的なデモLink を見てみましょう。うまく行けば、転送中のブラウザ画面は下のようなスクリーンショットになります。Firefox3.6.3Safari, Google Chromeの最新版で動くと思います。

progressbar
プログレスバーが表示され、進行状況が一目瞭然。

       


— posted by martin at 01:14 am   commentComment [6]  pingTrackBack [0]

Flexを用いた複数ファイルアップロード

category-icon

 こんばんは、martinです。前回のエントリーで述べていたように、次期バージョン(v1.9.0)では、画像ファイルのアップロードの際に、複数の画像をまとめてアップロードできる仕組みを提供予定です。

 現状では、複数の画像を一度にアップロードするには、FlashかJavaを使うしかありません。JavaもFlashも素人ですが、とっつきやすいのはFlashですし、ファイルアップロードに関しては、色んなサイトでソースコード付きのFlash/Flexのデモサイトがあったので、Flexを用いたインターフェイスを作ってみました。

実際に試すことが出来るデモサイトLink

 実際には、Coding CowboysLink というサイトにあったプログラムをベースに、好みのインターフェイスになるよういじっただけです。

uploadInterface
改良したインターフェイス。日本語化したりとか。

 ローカルのフォルダからは基本的に任意のファイルを選べるのですが、画像ファイル(*.jpg, *.png, *.gif)のみに絞っています。また、Flexの練習もかねて、デモページのFlashではアップロードした画像を見ることが出来るように、右下に画像ギャラリーへのリンクボタンを付けてます。

画像ギャラリーへのリンクLink

 ちなみに、このリンク先の画像ギャラリーは、Flashとは関係なしに、単にPHPでページを生成しています。CSSのみを用いたシンプルなものです。IE向けのハックは使ってませんが、IE6でもそう表示が崩れることはないかなと期待。アップロードされた画像ファイルの内、最新のJPEG画像を5枚表示するようにしてます。

galleryShot
CSSのみでのフォトギャラリー。IE6でも何とか動くかな。

 今後、いじるとすれば、ファイルサイズ上限を指定したりとかですかね。とりあえず。

     


— posted by martin at 04:10 am   commentComment [8]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0074 sec.
prev
2017.11
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30