ホームページ バックエンド開発 PHPチュートリアル PHP のセッション ロック、同時実行性、カバレッジの詳細な説明

PHP のセッション ロック、同時実行性、カバレッジの詳細な説明

Mar 22, 2018 am 09:13 AM
php session 詳しい説明

この記事では主に、PHP セッションのロックと同時実行に関する現象について説明します。興味のある方は参考にしていただければ幸いです。

ログインできません
ある日、バグを解決するためにバックエンド システムの 1 つにログインしようとしましたが、アカウントのパスワード確認コードを正確に入力したところ、ログインできませんでした。多くの実験を行った結果、主なエラー メッセージが 2 つあることがわかりました:

  • csrf 検証に失敗しました

  • 検証コード エラー [コードの神に誓って、私が使用した検証コードを入力したことを確認します。半角、順序は一貫していました、いいえ さらに文字を追加]

私たちのシステム私たちのシステムは、ご覧のとおり、Palcon 2.0.8に基づいて開発されています。フォームフィールドでの CSRF 攻撃。キャプチャも有効になっています。

<input type="hidden" 
  name="{{ security.getTokenKey() }}"
  value="{{ security.getToken() }}"/>
<img src="/login/getCaptcha" id="img-captcha"/>
ログイン後にコピー

最初にこれら 2 つのコンポーネントをチェックしたところ、どちらもセッションにデータを保存していることがわかりました。

# phalcon/security.zep
# Security::getToken()
let session = <SessionInterface> dependencyInjector->getShared("session"); 
session->set(this->_tokenValueSessionID, token); 
$this->session->set(&#39;admin_get_captcha_action&#39;, $captcha);
ログイン後にコピー

次に、セッションの実装をチェックしたところ、データが Redis に保存されていることがわかりました。

探して検索 ログインできない問題は何ですか?データの検証に問題があるため、テスト環境の redis マシンにログインし、redis-cli モニターを実行して、ログイン プロセスを実行したところ、出力は次のようになりました。 ):

  • GET sessionId

  • GET sessionId

  • SETEX sessionId 3600 csrf=xxxx

  • SETEX セッション ID 3600 captcha=abcd

次のことがわかります:

1. ここには 2 つのリクエストがあり、1 つはフォームをロードすること、もう 1 つは検証コードを生成することです。
2. 「同時実行」状況が発生します。これらの 2 つのリクエストは、フォームがロードされて表示された後に検証コードを要求する必要があります。つまり、セッション シーケンスは get->set->get->set になります。同時リクエストが行われたように見えますか?
3. 後者の SETEX には csrf コンテンツがありません。つまり、以前のデータが上書きされます。しかし、問題が何であるかは少しわかりました。何が問題なのでしょうか? PHP のセッション データ アクセスから始まる長い話です。

PHP セッション データ アクセス セッション データは文字列にエンコードされ、メモリ [ファイル、データベース、redis、memcache など] に保存されます。セッションを使用するとき、いつメモリにアクセスしますか?データを取得していますか?データはいつメモリに書き込まれますか?

この質問に対する答えは、一部の友人の考えとは異なる場合があります。リクエストでは、PHP は session_start 中に 1 回だけメモリを読み取り、その後、リクエストの終了時に 1 回だけメモリに書き込みます。 session_write_close を呼び出す 時間が来たら、データをメモリにフラッシュして戻し、セッションを閉じます。

そして次の質問が来ます:

1、如果一个会话,同时出现两个读写session请求,没有保证获取1-写入1-获取2-写入2,同时没有cas版本管理机制的情况下,这些并发请求就会彼此读取不到对方的写入,最后写入的会把前面请求写入的session覆盖掉。
2、如果请求是串行的,像登录页面的表单和验证码,也有可能前面的请求已经输出内容了,但是session还没写入,后面的请求就已经发起了。
锁与不锁
解决这种资源的并发一般会通过锁或版本管理来处理。但是版本管理我看不到好的方法。就聊聊锁吧。

其实锁是不大适合,有弊端的。

php的session,默认是用文件存储的,在打开session的时候,会对文件加独占锁,这样,其它请求就无法获取锁了,只能等待直到前面的锁解了。

这样保证了 读取-写入,读取-写入的顺序。

其它存储器,例如mysql,可以借助select for update进行行锁。redis可以通过一个自增键,返回1的获取到锁等来实现。

这个实现的话,对数据流来说很理想,但是,对于目前这种页面大量应用ajax的情况,所有请求排队处理,将大大加大页面展现的耗时,甚至出现请求超时等不可用故障。

没有解决的解决不建议过多使用session,其一次读取一次写入的机制所引发的问题,会造成坑的存在。
在模版渲染前,或请求输出前调用session_write_close

# 立刻回写session,避免session覆盖
$eventManager = $this->view->getEventsManager();
if (!$eventManager) { 
  $eventManager = new Manager();
  $this->view->setEventsManager($eventManager);
}
$eventManager->attach("view:afterRender",function(){
  session_write_close();
});
return $this->view; 
if($login) { 
  # 立刻回写session,避免session读取不到
  $eventManager = $this->dispatcher->getEventsManager();
  if (!$eventManager) {
    $eventManager = new Manager();
    $this->dispatcher->setEventsManager($eventManager);
  }
  $eventManager->attach(&#39;dispatch:afterDispatchLoop&#39;,function(){
    session_write_close();
  });
  return $this->response->setHeader(&#39;Location&#39;, &#39;/&#39;);
}
ログイン後にコピー

相关推荐:

php中session锁防止阻塞请求的实例分析

以上がPHP のセッション ロック、同時実行性、カバレッジの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

CakePHP の日付と時刻 CakePHP の日付と時刻 Sep 10, 2024 pm 05:27 PM

Cakephp4 で日付と時刻を操作するには、利用可能な FrozenTime クラスを利用します。

CakePHP について話し合う CakePHP について話し合う Sep 10, 2024 pm 05:28 PM

CakePHP は、PHP 用のオープンソース フレームワークです。これは、アプリケーションの開発、展開、保守をより簡単にすることを目的としています。 CakePHP は、強力かつ理解しやすい MVC のようなアーキテクチャに基づいています。モデル、ビュー、コントローラー

CakePHP ファイルのアップロード CakePHP ファイルのアップロード Sep 10, 2024 pm 05:27 PM

ファイルのアップロードを行うには、フォーム ヘルパーを使用します。ここではファイルアップロードの例を示します。

CakePHP バリデータの作成 CakePHP バリデータの作成 Sep 10, 2024 pm 05:26 PM

Validator は、コントローラーに次の 2 行を追加することで作成できます。

CakePHP のロギング CakePHP のロギング Sep 10, 2024 pm 05:26 PM

CakePHP へのログインは非常に簡単な作業です。使用する関数は 1 つだけです。 cronjob などのバックグラウンド プロセスのエラー、例外、ユーザー アクティビティ、ユーザーが実行したアクションをログに記録できます。 CakePHP でのデータのログ記録は簡単です。 log()関数が提供されています

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

CakePHP クイックガイド CakePHP クイックガイド Sep 10, 2024 pm 05:27 PM

CakePHP はオープンソースの MVC フレームワークです。これにより、アプリケーションの開発、展開、保守がはるかに簡単になります。 CakePHP には、最も一般的なタスクの過負荷を軽減するためのライブラリが多数あります。

See all articles