9

質問

  • セッションデータが断続的に失われるのは、競合状態が原因である可能性がありますか?いいえの場合、何が問題である可能性がありますか?
  • 外部のphpスクリプトからjoomlaセッション変数を読み書きするときに競合状態を防ぐにはどうすればよいですか?

詳細

使っています

  • Joomla 2.5
  • PHP 5.4.3
  • apache 2.2.22
  • mysql 5.5.24
  • ローカルホスト上のwampserver2。
  • 私のスクリプトはJoomlaの外部にあります。
  • (cometchatバージョン3.0.1)

このスクリプトは、非同期ajaxリクエストを使用して、joomla変数を複数回取得および設定しています。セッションに保存しているデータは配列です。断続的に一部の配列データが失われます。ユーザーがログインしてスクリプトを使用すると、より一貫して発生するようです。

正直なところ、何が問題なのかはよくわかりませんが、コードが競合状態になっていると思い始めています。Joomlaがセッション情報を書き終える前に読み込もうとしているか、設定されていない可能性があると思います。失われる情報はランダムに選択されているようで、データの損失は断続的に発生します。

スクリプト1

スクリプト1は、非同期ajaxリクエストを使用してJoomlaセッション変数を取得/設定しています。これは複数回呼び出されます。設計上、ajax応答が成功するまで、スクリプト1を再度呼び出すことはできません。

$.ajax(
            {   cache:false,
                url: 'script2.php',
                data: { 'change': change},              
                dataType: 'json',               
                success: function(data) 
                {
                    //do something
                }
            });

これは、スクリプト2でJoomlaにアクセスしてセッションデータを取得/設定するために使用しているコードの大まかなアイデアです。

スクリプト2

<?php
//some code omitted for brevity

$app = &JFactory::getApplication('site');/
$app->initialise();                     

$nottimedout=false;
$session = JFactory::getSession();
$jquizstart = date( 'Y-m-d H:i:s', time() );    //<<-- time of access       
$nottimedout = $session->has('jtimedout');

if ($nottimedout==true)
{
    $jqid = $session->get('jqid');                //<<-- get array from session
    if (isset($_GET['change'])) 
    { 
        $qnumber=$_GET['change'];   
        $firephp->log($qnumber, 'qnumber');
        $jqid[$qnumber][3]=$jquizstart;     //<<--  add time of access to array
        $firephp->log($jqid[$qnumber][3], '$jqid[$qnumber][3]');
        $session->set('jqid', $jqid);       //<<-- store array in Joomla with updated data
    } 
    else
    {
        $firephp->log('CHANGE NOT SET');
    }

    echo json_encode(
                      array("nottimedout" => $nottimedout) 
                    );                  
}
else 
{
    //Do something  
}
?>

競合状態のテスト

データが上書きされる可能性があると思ったので、以下のコードを使用して簡単なテストを行いました。セッション配列を更新するたびに、更新されたデータのみを使用して新しいセッション変数を作成します。

$qnum[$qnumber]=$jquizstart;
$session->set('var'.$qnumber, $qnum);

別のスクリプトでは、Webサイトの更新が完了したときに、個々のセッションが設定されているかどうかを確認しました。

//Test for race condition in Joomla session

        for ($counter=0; $counter<=$totalnumber-1; $counter++)
        {
            $racecondition=$session->get('var'.$counter);               
            $firephp->log($racecondition, 'var'.$counter.'=');
        }

テストの結果

jqidから欠落している配列情報は、対応する個々のセッション(更新されたデータのみを含むセッション)からも欠落しているため、データが上書きされる問題ではないようです。ただし、これが競合状態を悪化させるかどうかはわかりません。

何が起こっていると思うか、そしてこれを修正する方法についての提案は大歓迎です。

編集

Joomlaの競合状態を防ぐ方法に関する一般的な回答も歓迎します。ありがとう

EDIT2

php5.4とJoomlaの問題ではないかと思い始めています。一緒にうまく機能しないと聞きました。php5.3からアップデートする前に、この問題が発生したことを思い出せません。私は間違っているかもしれません。

EDIT3

私は機知に富んでいます。php5.3.10を使用して別のサーバーにWebサイトをインストールしました。ログインしていないユーザーとして10回以上試しました。データの損失はありませんでした。その後、Joomlaにログインすると、ページにアクセスするたびにデータが失われました。Joomlaセッションを使用する必要がなければ!GRRRrrrrr

EDIT4

今必死になって、ただ何かをしようとしています。JRequestは機能しませんでしたが、とにかく使用する必要があります。

ログインすると問題が発生する頻度が高いので、ユーザーがゲストの場合よりもセッションに保存されているコンテンツの方が多いためだと思いました。Jqidは大きな配列なので、常に更新するのではなく、いくつかの小さな配列を作成し、必要に応じてそれぞれを更新してみました。全く効果がありませんでした。繰り返しますが、とにかくこれを行う必要があります。

EDIT5B

その場しのぎの解決策を見つけようとしているときに、セッションが正常に更新されたかどうかをテストしようとしました(これは、セッションを更新したのと同じスクリプトで実行されました)。

これが私がjstartをチェックするために使用したコードです。

//jstart updated
$session->close('jstart');
$try_again_session = JFactory::getSession();
$newjstart=$try_again_session->get('jstart');
$firephp->log($newjstart[$qnumber], 'confirm_jstart_set=');

私が見つけた興味深い点は、jstartにはチェック中に更新された情報が含まれていましたが、完了時にそれが欠落していたことです。それが何を意味するのかはよくわかりませんがJFactory::getSession()、変数として扱った場合、変数はこのスクリプト(ローカル変数のようなものですか?)に対してのみ更新されJFactory::getSession()、何らかの理由でデータベース値が書き込まれなかったと思います。データベース。JFactory::getSession()したがって、後でこのスクリプトが再度起動されると、データベースに保存されていた古い値が取得されました。

セッションがデータベースに書き込まれない原因はまだわかりません。

4

2 に答える 2

3

問題の解決策は見つかりませんでしたが、回避策を見つけました。良いものではありませんが、機能します。セッション変数が更新されるたびに、バックアップとして情報をCookieに保存します。スクリプトの後半で、不足している情報がないかどうかを確認し、必要に応じてCookieから更新します。

私はこのようにしたくないのですが、選択の余地がないようです。

于 2012-11-04T06:59:57.953 に答える
2

最後に、私は解決策を見つけたようです!

たまたまapache_error.log(wamp / logs / apache_error.log)のエラーログを確認しました。

PHP Warning:  session_start(): Cannot send session cache limiter - headers already sent (output started at Z:\\libraries\\joomla\\session\\session.php:96) in Z:\\libraries\\joomla\\session\\session.php on line 532, referer: http://localhost/cq
PHP Warning:  Cannot modify header information - headers already sent by (output started at Z:\\libraries\\joomla\\session\\session.php:96) in Z:\\cometchat\\cometchatcss.php on line 68, referer: http://localhost/cq
PHP Warning:  session_destroy(): Session object destruction failed in Z:\\libraries\\joomla\\session\\session.php on line 96, referer: http://localhost/cq

cometchatをオフにしてサーバーを再起動した後、断続的なセッションデータの損失が停止したように見えることがわかりました。変更後、apache_error.logの下に表示されるエラーはなくなりました。

問題は断続的であるため、100%解決したかどうかはわかりませんが、これを解決策として記述したことは十分に確信しています。使っていた

cometchatバージョン3.0.1

私はそれをテストし続けるつもりです。解決策がうまくいかない場合は、cometchatの更新バージョンを試し、結果を投稿します。

更新:それはcometchatに関連しているようです。最新バージョン4.6.0をインストールしましたが、セッションが失われます。スクリプトを含むページでcometchatを除外することで、これを回避できます。

役立つ情報: 他の誰かがJoomlaセッションで苦労していることに気付いた場合に備えて-このWebサイトは非常に便利ですhttp://tutsforu.com/joomla-module-tutorial/8-joomla-tutorial/75-using-session-in-joomla .html

具体的には

$session->getId();
$session->get('session.counter');
$session->isNew();
$session->getName();
$session->getState();
$session->getExpire();
于 2012-12-28T01:03:26.243 に答える