2012-06-29 20 views
6

私は何年も "ビーコン"イメージを使って電子メールを追跡しています。イメージをダウンロードできるクライアントでは、電子メールを開いた人の数を追跡するのに効果的です。電子メールで開かれた長さの追跡

クライアントが実際にメールを読むまでの時間を示す "DidTheyReadIt"というサービスが出てきました。私は無料サービスでテストしましたが、実際にメールを開いた時とかなり近いです。

これを追跡する能力がどのように達成されたかは非常に興味がありますが、どのようなソリューションを選択してもサーバー/データベースに負荷がかかり、多くのコミュニティが「停止」、いいえ、いけない "と私はこれを調査し、それを試してみたいと思っても、私はサーバー上でテストを実行し、"地獄いいえ "と言うだけで十分です。私はいくつかのグーグルをしたと私は(睡眠を使用して試験を行った塩基性溶液http://www.re-cycledair.com/tracking-email-open-time-with-php

を有し、この記事を見つけた)ビーコン画像ページ内

<?php 

set_time_limit(300); //1000 seconds 
ignore_user_abort(false); 

$hostname_api = "*"; 
$database_api = "*"; 
$username_api = "*"; 
$password_api = "*"; 

$api = mysql_pconnect($hostname_api, $username_api, $password_api) or  trigger_error(mysql_error(),E_USER_ERROR); 
mysql_select_db($database_api, $api); 

$fileName = "logo.png"; 

$InsertSQL = "INSERT INTO tracker (FileName,Time_Start,Time_End) VALUES ('$fileName',Now(),Now()+1)"; 
mysql_select_db($database_api, $api); 
$Result1 = mysql_query($InsertSQL, $api) or die(mysql_error()); 
$TRID = mysql_insert_id(); 

//Open the file, and send to user. 

$fp = fopen($fileName, "r"); 
header("Content-type: image/png"); 
header('Content-Length: ' . filesize($fileName)); 
readfile($fileName); 

set_time_limit(60); 
$start = time(); 

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

// Update Read Time 

$UpdateSQL = "UPDATE tracker SET Time_End = Now() WHERE TRID = '$TRID'"; 
mysql_select_db($database_api, $api); 
$Result1 = mysql_query($UpdateSQL, $api) or die(mysql_error()); 

time_sleep_until($start + $i + 1); 
} 

?> 

上記コードの問題( 1秒ごとにデータベースを更新する以外に)、スクリプトが実行されると、ユーザーが切断(この場合は別のメールに移動)してもスクリプトは実行され続けます。

"ignore_user_abort(false);"が追加されましたが、メールクライアントへの接続がなく、ヘッダーが既に書き込まれているため、 "ignore_user_abort(false);"発射することができます。私は下の「Haragashi」から最高ポストTrack mass email campaignsと1を見

は言う:

「すべてのバイトが応答をフラッシュした後、あなたは単にバイトで追跡画像のバイトを返す追跡ハンドラを構築することができます。一定の期間のために眠る。

あなたが発生した場合は、ストリームは、クライアントが(知っている別の電子メールを削除または変更)の電子メールを閉じた例外を閉じた。

の例外が発生したときのクライアントが電子メールをどのくらい読むかを知っている」

このような「追跡ハンドラを構築する」とか、ユーザーが切断したときにコードの実行を強制するコードに実装できる解決策を知っている人はいますか?私は、問題はあなたがそう頻繁に、すべてをリダイレクトヘッダを行っていないということだと思います

<?php 
// Time the request 
$time = time(); 

// Ignore user aborts and allow the script 
// to run forever 
ignore_user_abort(true); 
set_time_limit(0); 

// Run a pointless loop that sometime 
// hopefully will make us click away from 
// page or click the "Stop" button. 
while(1) 
{ 
    // Did the connection fail? 
    if(connection_status() != CONNECTION_NORMAL) 
    { 
     break; 
    } 

    // Sleep for 1 seconds 
    sleep(1); 
} 

// Connention is now terminated, so insert the amount of seconds since start 
$duration = time() - $time; 

答えて

1

+0

クライアントは多くのリダイレクトに従っていないので、これは事実上理にかなっているものよりも理論的な答えです。これはOPが引用したものではありません。 – hakre

0

あなたはより多くのこのようなことをしないだろう。それが必要なのは、スクリプトがPHP + Apacheで実行されると、基本的には終了するまでクライアントを無視するからです。 X秒ごとにリダイレクトを強制すると、クライアントがまだ接続されている場合、サーバーは再評価されます。クライアントが接続されていない場合、リダイレクトを強制することはできず、したがって、時間の追跡は停止します。

私はこのようなものをいじったとき、私のコードは次のように見えた:クライアントIDが設定された場合、このコードブロックの上に、私は、データベース内のビーコンを読んで、この試みが記録されます

header("Content-type: image/gif"); 
while(!feof($fp)) { 
    sleep(2); 
    if(isset($_GET['clientID'])) { 
     $redirect = $_SERVER['REQUEST_URI']; 
    } else { 
     $redirect = $_SERVER['REQUEST_URI'] . "&clientID=" . $clientID; 
    } 
    header("Location: $redirect"); 
    exit; 
} 

。サーバーがリダイレクトを強制するたびに、電子メール列の時刻を2秒ずつ増やすのは簡単でした。

+0

上記のコードを送信していただきありがとうございます。私はそれを試して、私が$ duration = $ time() - $ timeの後に置くと、ブラウザ上でstopをクリックすると挿入が行われません。 私はsleep(1)の後にdb insertを挿入しようとしました。それは毎秒更新されますが、私がページを止めればスクリプトは続行します。 – jdublu

+0

ignore user abortがfalseに設定されているため、設定されていないタイムアウトまで停止しません。 –

+1

も毎回バイトを送信します。そうしないと、接続が閉じてもPHPは気付かないでしょう。トラフィックを作成します。 – hakre

関連する問題