AJAX経由でリクエストを受け入れ、いくつかのデータ操作を行い、いくつかのデータを返すアクションを持つコントローラーがあります。
_function publicDirectoryAjaxSearch(){
// Check the form token
JSession::checkToken('get') or die('Invalid Token');
// Don't show PHP errors in raw output
ini_set('display_errors', 'Off');
// Sort out the session status
$session = JFactory::getSession();
$session->set('getOrganisationsStatus', 'Searching...');
// Get orgs
$response = $this->doPublicDirectorySearch();
// Get the document object.
$document = JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding('application/json');
// Change the suggested filename.
JResponse::setHeader('Content-Disposition','attachment;filename="result.json"');
echo json_encode($response);
}
_
このメソッドには時間がかかる場合があるため、JSessionを使用してステータス変数getOrganisationStatus
を保存しています。これは、AJAXを介して定期的に確認でき、$this->doPublicDirectorySearch()
メソッドが取得されました...
_function doPublicDirectorySearch(){
...
while($running)
$session->set('getOrganisationsStatus', 'Fetched '.$handled."/".$totalResults." results.");
...
}
_
ただし、いくつか問題があります。 Joomlaグローバル構成セッションハンドラーをDatabaseに設定した場合、getOrganisationsStatus
セッション変数は常に1つのデータ要求を「遅れ」ているように見えます。たとえば(この例の準備では、既存のすべてのセッションをクリアしました):
publicDirectoryAjaxSearch
publicDirectorySearchStatus
$this->doPublicDirectorySearch()
がデータを処理するときにセッション値が変化するpublicDirectorySearchStatus
へのステータス呼び出し。返されたセッション変数は空です(このステップはこの間隔で繰り返されます)publicDirectoryAjaxSearch
データリクエストが完了しました。メソッドがJSONオブジェクトを返すpublicDirectorySearchStatus
。に対して行われた最終ステータスコール。返されたデータ(セッション変数)は、データリクエストメソッドで設定された正しいテキストを表示するようになりました。Joomlaグローバル設定をNoneをセッションハンドラー(つまり、PHPの組み込みファイルベースハンドラー)として使用するように設定すると、スクリプトは(- PHPはセッションファイルをロックします スクリプトがアクセスすると、AJAX呼び出しは、セッション変数を更新するメソッドが終了するまで待機する必要があります。 )。
どこがいけないの?どうやって..
すべてのページリクエストが同じユーザーセッションを共有します。したがって、同じセッションで非同期に複数のページを呼び出すと、競合状態を見つけることができます。 http://en.wikipedia.org/wiki/Race_condition
PHPはマルチスレッドではないため、これらのケースを回避するためのロックメカニズムはありません。
最良の解決策は、この状態を回避することです。メインループを再編成し、コントロールをAjax側に移動します。このようにして、ブラウザは初期化、内部ループを次のように呼び出します必要に応じて何度も、そしてファイナライズ。