Wonderful! WordPress

画像をクリックした時のログ

この記事は公開または最後に更新されてから3203日が経過しています。情報が古くなっている可能性があるのでご注意下さい。

画像サイトにて画像をクリックして拡大表示で見てくれる人はいるのだろうか。もしクリックしてくれるとしたらどの画像なんだろうか。
などと思いはじめたらとても知りたくなって、なんとかできないものかと考え始めました。

私の鳥画像サイトは珍鳥出現情報などもなく、情報的価値のまったくないサイトなので、そんなサイトにはなかなか人は訪れてはくれないものなのですが、それでもパラパラと間違って立ち寄ってくれる人がいます。
鳥の英名や学名なども掲載しているので外国からのアクセスもそこそこあったりするので、その方々が画像をクリックして見てくれることはあるのだろうかと気にしはじめると知りたくてどうしようもありません。
画像をクリックしたときには、ここの一番はじめの記事画像クリック時のjavascriptに書いた通りjavascriptにて拡大表示の処理をさせているので、javascriptからできればいいのですが、ファイルの書き込みなどはできないはず。

あれやこれやと探しまくり、やっとたどりついたのがAjax
AjaxXMLHttpRrequestを使えば出来そうです。
XMLHttpRrequest以降XHRは主にサーバにデータをリクエストするために使われるが、サーバにデータを送り返すためにも使うことができ、POSTを使って指定したphpファイルにデータを引き渡すことができるということです。しめしめこれは出来そうな気がします。

まずはjavascriptにてXHRで送るデータを作らなければなりません。
データとしては日時、クリックした方のipaddress、どのページの画像かというURLのquery文字列、画像のURLといったところでしょう。
ipaddress、ページのURLのquery文字列はページ読み込み時にphpで取得し、type属性がhidden<input>に入れておいて必要なときにjavascriptから読み出すことにします。

<?php
    $ipadrs = $_SERVER["REMOTE_ADDR"];
    $strquery = $_SERVER["QUERY_STRING"];
    $strquery = $ipadrs . ':' . $strquery;
?>
PHP
CopyExpand

どのページかというURLのquery文字列は$_SERVER["QUERY_STRING"]で得ることができます。
$strqueryをformの[es c=3][/es]のvalueに指定します。

<form name="mainfrm">
	<input type="hidden" name="testword" value="<?php echo $strquery; ?>">
</form>
PHP
CopyExpand

これらを画像のログが欲しいページのテンプレート、index.phpとかsingle.phpとかtag.phpなどのどこかにそれぞれ組み込みます。
'name="mainfrm" formは別のことでも利用するため、実際はもっと複雑な設定になっています。

そしていよいよここの最初の記事、画像クリック時のjavascriptの画像をクリックしたときのjavascriptの関数showpopに処理をくわえます。

function showpop( imageurl ) {
    var tarwid,
        tarhei,
        imgwid,
        imghei,
        numscroll = getScrollPosY(),
        doc = document;
    
    tarwid = getBrowserWidth();
    tarhei = getBrowserHeight();
    
    imghei = tarhei * 0.85;
    if ( imghei > 960 ) {
        imghei = 960;
    }
    imgwid = imghei * 1280 / 960;
  
    var imgstr;
    imgstr = imageurl;

    var ela = doc.getElementById( 'upimage' );
    ela.src = imgstr;
    ela.style.cssText = 'width:' + imgwid + 'px;height:' + imghei + 'px;';

    var elb = doc.getElementById( 'imageframe' );
    elb.style.cssText = 'visibility:visible;top:' + numscroll + 'px;width:' + tarwid + 'px;height:' + tarhei + 'px;';

    var tarip = doc.mainfrm.testword.value;
    var strsend = 'target=' + imgstr + ':' + tarip;
    var url = 'https://~/logimage.php';

    var req = new XMLHttpRequest();
    
    req.open( 'POST', url, true );
    req.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
    // ↓ この下の行があるとエラーがでるようになったので不必要
    // req.setRequestHeader( 'Content-Length', strsend.length );
    req.send( strsend );
}
JavaScript
CopyExpand

追加したのは28~37行目の部分。
28行目でformからデータを取得し、29行目で送信するデータを組み立てています。

送信するデータはPOSTにて送信するわけですが、formから送信する場合は <input>> タグのname属性で指定した文字列で識別できるのと同じように送信後、識別できるようにtarget=のように識別用の文字列を指定します。
30行目はデータを送信する相手のphpファイルを指定しています。フルパスは長いので省略しています。
で、32行目からがいよいよXHRで送信するときの形式となります。

ここで下で紹介してますハイパフォーマンスjavascriptの本で学んだことを実践しているところの説明を。

まず、7行目の var doc = docment; の件で、これは簡単に解釈するとグローバルオブジェクトであるdocumentへの参照は手間がかかりパフォーマンスに関してよろしくないということです。そこで、この関数内のローカル変数docに格納し、以後はグローバル変数の代わりにローカル変数を使うことで、パフォーマンスへの影響を緩和することができるという事です。javascriptにおいてはグローバル変数を使うことは負荷が大きいのでなるべく使用を控え、高速なローカル変数を使うことで、グローバル変数に何度もアクセスするような大きな関数ではパフォーマンスの改善につながるという事です。

そして21から26行目は、要素の再描画と再配置はコストの高い作業であり、これらの処理が行われる回数を減らすことが、アプリケーションの反応性を高める方法として効果的であるということで、すべての変更を一度に適用して、DOMの変更をそれぞれ1回だけにするというものです。

最後に送信されたデータを受け取ってログファイルに記録するlogimage.phpの作成となります。
logimage.phpはこのようにしてみました。

<?php
	$cdt = date( 'Y/m/d H:i:s' );
	$filnam = './***/imglooklog.php';
	if ( isset( $_POST['target'] ) ) {
		$targetstr = $_POST['target'];
		$targetstr = str_replace( 'https://strix.main.jp/wp-content/uploads/', '', $targetstr );
		list( $imgurl, $ipadrs, $pageid ) = explode( ':', $targetstr );
		$hname = gethostbyaddr( $ipadrs );
		
		if ( $ipadrs !== '***.***.***.***' ) {
			$fp = fopen( $filnam, 'a+b' );
			flock( $fp, LOCK_EX );
			
			fputs( $fp, "$cdt  [$ipadrs]  [$hname]  [$pageid]  $imgurl\n" );
					
			fclose( $fp );
		}
	} else {
			$fp = fopen( $filnam, 'a+b' );
			flock( $fp,LOCK_EX );
			
			fputs( $fp, "$cdt data none\n" );
					
			fclose( $fp );
	}
?>
PHP
CopyExpand

6行目は送信されてきたデータに含まれる画像のURLはフルパスとなっていますが、知りたいのは画像が属するディレクトリとファイル名だけでよいので、https://以下必要のない部分をとっています。あとログファイルに記録するデータ量をなるべく少なくしたいということもあります。
10行目は自分がクリックしたときはログなど残す必要などないので、自分のアドレスの時は処理しないようにします。
11行目はログを記録するファイルをこのlogimage.phpがある場所からの相対パスにて指定しています。セキュリティのために拡張子はphpにしていますがただのテキストファイルです。表示は省略しています。
19から26行目は送信されてくるデータ$_POST["target"]にデータがセットされていなかった場合の処理を一応つけてみましたが必要ないと思います。

実際にこれにより記録されたログデータはこのようになります。

2012/05/02 19:13:38  [127.0.0.1]  [localhost]  [page_id=48]  2011/12/1107170043.jpg
PHP
CopyExpand

これで一応は目的が達成されました。
何の画像を見てくれたのかというのを知るのには、ログ閲覧プログラムを作って、画像のフルパスはわかっているのでリンクを作って表示させればいいかと思います。
当分の間はこの状態で使用していましたが、ログがたまってくるといちいち画像を表示させて確認するのも面倒になってきたので、画像の鳥の名称を送信データの中に含めて、画像が何の鳥かすぐわかるように改良しています。

今回のXMLHttpRrequestに関してはこの本で見つけて参考にしました。
グローバルオブジェクトのdocumentの扱い方やDOMによる再描画と再配置による問題、正規表現の最適化など、XHR以外にも学ぶことのとても多い良い本です。O'REILLYにしては200ページ強の薄目の本です。

Leave a Reply!

JavaScript is necessary to send a comment.
You can edit and delete your comment if you input a edit key.
Edit key is necessary for attesting you when you edit and delete it.
The tag of HTML cannot be used in comment.
When you comment for the first time, it is displayed after the approval of the administrator.
Because I cannot speak English so much, it takes time to answer.
Required fields are marked *.

※Please enter more than 5 characters only alphabets.
※Edit or delete are possible for 2000 days after approval.

*

♠Simplistic Comment User Editable v4.0

♠When visitors leave comments on the site this site collect the data shown in the comments form, and also the visitor’s IP address and browser user agent string to help spam detection.
♠This site does not use cookie when visitors leave comments and commenter edit comment.
♠This site uses Akismet to reduce spam. Learn how your comment data is processed.

Comments feed

Trackback URL : https://strix.main.jp/wp-trackback.php?p=16175

Sanbanse Funabashi
2010.10.24 sunrise

Top

スクロールさせるか画像をクリックすると元に戻ります。