質問
- セッションデータが断続的に失われるのは、競合状態が原因である可能性がありますか?いいえの場合、何が問題である可能性がありますか?
- 外部の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()
したがって、後でこのスクリプトが再度起動されると、データベースに保存されていた古い値が取得されました。
セッションがデータベースに書き込まれない原因はまだわかりません。