- 締切済み
PHPのチャットアプリでの受信音について
下記のPHPスクリプトにおいて、左蘭で、氏名とメッセージを入力後、右蘭の メッセージ部分にメッセージが表示されるという仕組みなのですが、自分自身 が書いたメッセージのときにしか音が鳴りません。 本来、他のデバイスで書き込んだ時の受信音が自パソコンで鳴ればいいのですが。 どうすればよいのか教えていただきたいです。 ちなみに、$_SERVER['REMOTE_ADDR'] でIPによる振り分けも行ったのですが、 だめでした。(自パソコンから投稿したときしか音が鳴りませんでした。) ////////////////////////// // ファイルへの書き込み // ////////////////////////// function writeToLogFile($val){ $filename="log.txt"; date_default_timezone_set("Japan"); $date = date('H:i:s'); echo '<audio src="./music/buble.wav" volume="1" autoplay></audio>'; echo '<bgsound src="./music/buble.wav" loop="1" volume="1">'; if($val===1){ // 初回投稿時で、しかも名前とメッセージがある場合(ログファイルが0バイトの場合) $fp = fopen($filename, 'w'); // $log = $_POST['ip_addr']." ".$date." ".$_POST['name']." : ".$_POST['message']; $log = $date." ".$_POST['name']." : ".$_POST['message']; $buf = $log.",\n"; fwrite($fp, $buf); fclose($fp); } elseif($val===2){ // 既に投稿があって、しかも名前とメッセージがある場合(ログファイルのサイズが0バイトでない場合) $fp = fopen($filename, 'a'); $log = $date." ".$_POST['name']." : ".$_POST['message']; $buf = $log.",\n"; fwrite($fp, $buf); fclose($fp); }else{ return; } }
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- agunuz
- ベストアンサー率65% (288/438)
>おっしゃったように、投稿者名を投稿者のデバイスにクッキーで >送るようにしたんですが、自パソコンで音が鳴りません。 誰もそんなことは書いていません。「最終データの日時を入れておく」とは書きましたが、投稿者名のような基本的に(同一デバイスからであれば)変わらない値を保持しても意味がありません。同一デバイスで前回ログ表示したときのログの状態(更新日時)が必要です。ログの内容が(他からのアクセスによって)書き替えられたかどうかが問題ですので。 また、setcookieが呼び出されるのがbody部以降ではどうしようもありません。HTTPレスポンスヘッダで返すものはブラウザに何も返さないうちに実行する必要があります。 http://php.net/manual/ja/function.setcookie.php ---------- 引用ここから ほかのヘッダ情報と同様に、 クッキーは、スクリプトによる他のあらゆる出力よりも前に 送信される必要があります(これはHTTPプロトコルの制約です)。 ---------- 引用ここまで ><meta http-equiv="refresh" content="5;url=chatbody.php?count=<?php echo $_SESSION['cnt'];?>"> このmeta要素では、$_SESSION['cnt']を引き渡していますから、$_SESSION['cnt']に前回のログ行数でも渡しているんでしょうかね。もしそうであれば、それでチェックしてもいいです。ログの行数が前回の値($_GET['cnt'])と違っていれば音を鳴らすhtml要素を追加出力すればいいでしょう。 私はログファイルの更新日時が前回アクセス時のものと違っているかどうかチェックすればいいんじゃないかと思いましたけどね。リロードでどうせ読み込むなら行数でもいいです。 ただ、いずれにしても記述順序が間違ってますね。このmeta要素を書き出す前にチェックを終わらせておいて新しい値をセットしないといけません。実際の受信音用の要素の書き出しはbody以降になるので、チェック結果(音の鳴らす・鳴らさない)は変数に入れておけばいいです。 先に「ログに書き込むデータをPOSTされていたら書き込む」「ログを読み込んで表示用のデータを準備する」「前回のアクセスとログが変更されていないか確認する(ログファイルの更新日時もしくはログ行数でチェック)」「セッション変数に今回アクセスでのログファイルの更新日時(もしくは行数)を保存する」を行ってから、html要素の書き出しを始めてください。 (蛇足) 今現在の行数と$_SESSION['cnt']をチェックすればいいので、meta要素で$_GET['cnt']で渡す必要なんてないと思いますけどね。どういう動作が前提なんですかね。まさかアクセス回数ってわけではないだろうし(意味がなさすぎ)。リロードを確実にさせるためにURLを変えるなら <meta http-equiv="refresh" content="5;url=chatbody.php?<?= md5(microtime()); ?>"> でいい話だし。 なお、提示されたソースはchatbody.phpとは別のものですよね。session_start()すら存在しないので、セッション変数が使えません。$_SESSIONを使うソースになっていません。 http://php.net/manual/ja/function.session-start.php
- agunuz
- ベストアンサー率65% (288/438)
提示されたソースは書き込み時の処理しかありませんので(当然ですが)「自分が書き込んだとき」しか反映されません。 >他のデバイスで書き込んだ時の受信音 他のデバイスで書き込んだとき、どうやってチャットログに反映させているのでしょうか?meta要素とかJavaScriptとかでReloadしているんですかね?もしそうであれば「当該デバイスに対して前回返した内容が変わった」ときにaudio要素やbgsound要素も書き出せばいいと思います。 Cookieに最終データの日時を入れておくのが楽だと思います。
お礼
ご回答、どうも有難うございました。
補足
おっしゃったように、投稿者名を投稿者のデバイスにクッキーで送るようにしたんですが、 自パソコンで音が鳴りません。 全ソースを記述しますので、どうすれば、他デバイスからの投稿で、自パソコンで音が鳴るか教えていただきたいです。 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--<meta http-equiv="refresh" content="5">--> <meta http-equiv="refresh" content="5;url=chatbody.php?count=<?php echo $_SESSION['cnt'];?>"> <title>チャット</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> $(function() { $('html,body').animate({ scrollTop: $('#last').offset().top },'fast'); }); </script> </head> <body text="white" background="./image/mokume2.jpg" onLoad="sound_beep()"> <?php ////////////////////////////// // フォームデータの読み込み // ////////////////////////////// function getPostData(){ $name = $_POST['name']; $message = $_POST['message']; $ip_addr = $_POST['ip_addr']; if(!is_null($name) && !is_null($message)) return 1; else return -1; } ////////////////////////// // ファイルへの書き込み // ////////////////////////// function writeToLogFile($val, $name){ $filename="log.txt"; date_default_timezone_set("Japan"); $date = date('H:i:s'); if($val===1){ // 初回投稿時で、しかも名前とメッセージがある場合(ログファイルが0バイトの場合) $fp = fopen($filename, 'w'); $log = $date." ".$_POST['name']." : ".$_POST['message']; $buf = $log.",\n"; fwrite($fp, $buf); fclose($fp); echo '<audio src="./music/chime.mp3" autoplay></audio>'; }elseif($val===2){ // 既に投稿があって、しかも名前とメッセージがある場合(ログファイルのサイズが0バイトでない場合) // 自パソコンがWEBサーバーから送られてきて食べたクッキーと違う投稿者名だった場合に音鳴らす if($name!==$_COOKIE['name']) echo '<audio src="./music/buble.wav" autoplay></audio>'; $fp = fopen($filename, 'a+'); $buf = fread($fp, filesize($filename)); $date_file = strtok($buf, ","); if($date!==$date_file){ // 時間が、ファイル内の時間と一致してれば何もしない $log = $date." ".$_POST['name']." : ".$_POST['message']; $buf = $log.",\n"; fwrite($fp, $buf); fclose($fp); } }elseif($val===3){ return; } } //////////////////////////////////////// // ファイルのリードと、ログの画面出力 // //////////////////////////////////////// function dispLogFile($val){ $filename="log.txt"; $fp = fopen($filename, 'r'); if($val===1){ // 初回で正常投稿された場合 $buf = fread($fp, 5000); fclose($fp); }elseif($val===2 || $val===3){ // 既存の投稿があって、正常投稿されたまたは何もされなかった場合 $buf = fread($fp, filesize($filename)); fclose($fp); }else{ fclose($fp); return; } $log = strtok($buf, ","); echo '<b>'.$log.'</b><br>'; while(($log=strtok(","))!=FALSE){ echo '<b>'.$log.'</b><br>'; } } ////////////////////////////////////// // ログクリアボタンとアイコンの表示 // ////////////////////////////////////// function dispClearButton(){ $filename="log.txt"; if(filesize($filename)){ echo '<br><br>'; echo '<form name="form1">'; print("<input type=\"button\" name=\"clear\" value=\"メッセージクリア\" onclick=\"location.href='clear_message.php'\">"); echo ' '; echo '<img src="./image/coffee.gif">'; echo '</form>'; } } //////////////////// // メインルーチン // //////////////////// $val = 0; $filename="log.txt"; if(getPostData()===1){ // 名前メッセージ両方入力あって、送信ボタンをクリックするかエンターキー押下 $name = $_POST['name']; setcookie("name", $name); // 投稿デバイスでの投稿者名をクッキーとして、投稿デバイスに送る if(!filesize($filename)){ // 初回投稿時 $val = 1; writeToLogFile($val, $name); dispLogFile($val); dispClearButton(); }else{ // 既に投稿がある場合 $val = 2; writeToLogFile($val, $name); dispLogFile($val); dispClearButton(); } }else{ if(filesize($filename)){ // 既に投稿がある場合(何もしなければ) $val = 3; // writeToLogFile($val); dispLogFile($val); dispClearButton(); }else{ // 初回投稿で何もされなかった場合、何もしない ; } } ?> <div style="height: 90px;"> </div> <div id="last"></div> </body> </html>
お礼
詳しいご回答、どうもありがとうございました。