ホームページ >バックエンド開発 >PHPチュートリアル >データベース接続における超常現象について議論するため、経験豊富な専門家を緊急招集します。
SAAS モデルの ERP システムを構築しました。現在の方法では、企業ごとにデータベースを構築しますが、共通の PHP スクリプトを使用します。たとえば、私の SAAS 顧客には 50 社の企業があり、これは MYSQL で 50 の DB を構築したことを意味しますが、データ構造は同じです。この場合、PHP スクリプトは 1 セットしかないため、1 か所を変更することは 50 台のシステムをアップグレードすることに相当し、より便利です。
各企業が最初のページにログインするときに、データベースに接続するための PHP スクリプトに SESSION['db'] を保存します。接続名 DB = SESSION['db'] になります。会社は修正されました そのデータベースを追加、削除、変更し、チェックインします。
今不思議なのはクロスナンバー現象が時折起こることです。たとえば、A 社は最初のページでログインするときに SESSION['DB'] = 'A' を設定し、再度ログインするときに A という名前のデータベース内のユーザー名とパスワードを確認します。データベース内のテーブルを追加、削除、および変更します。しかし、A社がログインして更新すると突然B社のデータになり、その後C社のデータが表示されるということがたまに起こります。この接続では DB が A に固定されているのに、なぜ他のデータベースのデータがエイリアス化されるのか疑問に思いました。
これが私の最初の分析です。スクリプトはすべて同じ、つまり URL もすべて同じであるためです。理論的には、SESSION['db']はページを開くたびに自動的に接続されるので問題ありません。シリアル番号が表示されるので、キャッシュが原因であると思われます。後でインターネットで調べてみると、360 Browser がユーザーのプライバシーとチェーン COOKIE をアップロードしたことが報告されているようで、その時は 360 Browser の動作が原因なのかと疑問に思っていました。
一つ目の対策として、ドメイン名のパンレゾリューションを利用して各社のURLを異なるもの、つまりA社のURLはA.xxx.com、B社のURLはb.xxx.comに変更しましたが、全体的にフレームワークは同じであり、PHP スクリプトも同じです。この場合、360 が COOKIE をサーバー キャッシュにアップロードしたとしても、URL が異なるため、エイリアスは存在しませんよね。しかし、私はまた間違っていたことが分かりました。午後、別の顧客から電話があり、自社のシステムで他社のデータをどうやって見ることができるかについて問い合わせがありました。私は完全に狂っています。
2 回目の分析ですが、mysql_pconnect() 接続が原因なのでしょうか?会社 A がデータベースへの永続的な接続を確立していると考えています。企業 B のログインも mysql_pconnect() です。APACHE は企業 A によって確立された接続を企業 B で使用するために直接使用しますか?そこで、すぐに pconnect を夜間接続に変更しました。しかし、このデータのシリアル番号が商用ソフトウェアに与える影響はそれほど単純ではないと私は感じています。力を入れすぎて、力が及ばないかもしれません。
もう一度、この奇妙な現象がなぜ起こるのか、専門家に分析を手伝ってもらいます。キャッシュの原因を何度も疑ったのですが、キャッシュされたページが表示されても相互に変更できないはずなので、やはりデータベース接続に問題が発生しているのでしょうか?
私の QQ 番号は 13676987、杭州です。専門家とのコミュニケーションを楽しみにしています。
1. SESSION['db'] $_SESSION['db'] ですか?
2. セッション中に dbname を書き込む必要があるのはなぜですか?
各サイトに異なる情報を記録するために設定ファイルを使用してみてはいかがでしょうか。たとえば、各サイトには config.php,
define('DBNAME', 'db1'); があります。
3. セッションは db に保存されていますか?
50 社が PHP スクリプトのセットを共有しています。つまり、config.php は 1 つだけあり、50 社がそれを一緒に使用しています。そのため個別に設定することはできません。でも、あなたが私にインスピレーションを与えてくれたので、config1.php config2.php config3 を作ることができます... このように、50 を作るのは悪くないアイデアではないでしょうか?
これもかなり良い解決策ですが、少しばかげています。笑
これが事実であれば、50 個の仮想ホストは異なるはずです。
Apache の Env モジュールを使用します。使用方法については、以前に書いた記事を参照してください: http://blog.csdn.net/fdipzone/article/details/9388959
仮想ホストで、
<IfModule mod_env.c> SetEnv DBNAME DB1</IfModule>
ヒント: Env を使用して保存されたデータは Web 上でのみ読み取ることができ、php cli モードでは読み取ることができません。特定のニーズに応じて使用します。
データベース接続が長いと、データベース サーバーへの接続は再利用されますが、データベースへの接続は再利用されません
まずは システム内の他社データを参照する方法 から始めましょう:
「初めて」から 対策として, 「ドメイン名の汎解決を使用しています」とユーザー認証が独立していることがわかります。 SSO は現在非常に人気があり、あなたもそれを使用している可能性を排除しません
複数の企業が同じソフトウェアのセット (インターフェースを含む) を変更せずに使用できるため、これらの企業が同じ業界。したがって、A 社の担当者が B 社の担当者のログイン パスワードを知っている可能性は否定できません。マルチタブ ブラウザを使用して、タブ A で A 社にログインし、タブ B で B 社にログインします。タブ A に戻ると、企業 B のデータが表示されます
複数のタブで Cookie が共有されており、A によって設定されたセッション ID が B によって変更されているためです
実際、受信データに対する無条件の信頼が CSRF 攻撃の基盤です
第 2 レベル ドメイン名方式を使用する場合、ドメイン名が異なるため、Cookie は共有されません。しかし、まだシングルサインオンである場合、トラストドメインのせいで状況は変わりません
現在、データベースの機能を信じず、データキャッシュなどを構築することを好む人が多すぎます(リスクを恐れて)データベースを使い果たす、思いやりの精神は称賛に値します)
データ キャッシュは主にクエリ名によって区別され、システム内のデータの所属を区別するのはライブラリ名です。混乱するのは普通のことです
データベース接続が長いと、データベースサーバーへの接続は再利用されますが、データベースへの接続は再利用されません
システム内の他社のデータを確認する方法から始めましょう
: 「最初の回答では、ドメイン名 pan を使用しました」 -analytics」 ご覧のとおり、ユーザー認証は独立しています。 SSO は現在非常に人気があり、あなたもそれを使用している可能性を排除しません 複数の企業が同じソフトウェアのセット (インターフェースを含む) を変更せずに使用できるため、これらの企業が同じ業界。したがって、A社の人がB社の人たちのログインパスワードを知っている可能性は否定できません
マルチタブブラウザを使用し、タブAでA社にログインし、タブBでB社にログインします。タブ A に戻ると、企業 B のデータが表示されます
複数のタブで Cookie が共有されており、A によって設定されたセッション ID が B によって変更されているためです
実際、受信データに対する無条件の信頼が CSRF 攻撃の基盤です
第 2 レベル ドメイン名方式を使用する場合、ドメイン名が異なるため、Cookie は共有されません。しかし、まだシングル サインオンである場合は、信頼ドメインの関係により、状況は変わりません
現在、データベースの機能を信じず、データ キャッシュなどを構築することを好む人が多すぎます。データベースを使い果たすことを恐れ、思いやりの精神は賞賛に値します)
データ キャッシュはほとんどの場合クエリ名で区別されますが、システムではデータの所属を区別するのはライブラリ名です 混乱するのは普通のことです
既知の考えられる問題をすべて排除しても、問題が解決されていない場合
これは、議論する必要がある問題がまだあるということです
ポスターも同じ意味です。 , 彼は、あなたが問題を引き起こす可能性があるとわかっている側面をリストアップして、彼がトラブルシューティングできるようにしてほしいと願っています
それらを解決する方法については、後の話です。問題が見つかりません。どんな解決策も無駄です
問題はキャッシュにあるということですか?毎回データベースに接続していれば問題ないのでしょうか?
データベース接続が長いと、データベース サーバーへの接続は再利用されますが、データベースへの接続は再利用されません
長い接続に問題があるのではないかと今でも疑っています。 「長い接続とは、データベース サーバーに再利用される接続です。」 前提として、この接続のユーザー名とパスワードは同じであり、接続しているすべての企業のユーザー名がわかっているだけです。サーバーは同じですが、データベースにリンクする場合はSESSION[''DB']を使用して区別します。では、この場合、データベースリンクも再利用される確率はあるのでしょうか?特にSESSION['DB']が何らかの不明な理由でクリアされた場合はどうでしょうか?
これは 100% 除外できます。
データベースキャッシュが原因であれば、最初の投稿の分析と同じで、他社のデータであっても改変できないはずです。キャッシュは読み取り専用なので、SELECTに対してはUPDATE DELETEすら効かない。 右?
熱心なご協力ありがとうございました。頑張って調べてみます。とても勉強になった気がします
ヒント: Env を使用して保存されたデータは Web 上でのみ読み取ることができ、php cli モードでは読み取ることができません。特定のニーズに応じて使用してください。
データベースリンクが再利用される確率はありますか?
存在する可能性は全くありません
特に SESSION['DB'] が何らかの不明な理由でクリアされた場合はどうでしょうか?
SESSION['DB'] がクリアされている場合、それは失敗する mysql_select_db('') を実行するのと同じです (データベースが選択されていません)
私が話しているキャッシュは、プロジェクトのキャッシュ関数を指します
それ通常、クエリ結果をキャッシュするために使用されます。頻繁にアクセスする場合はデータベースを読み取らないでください
第 2 レベルのドメイン名を使用する場合は、第 2 レベルのドメイン名をデータベース名にバインドする必要があります
マーク、初心者は学習のために通り過ぎます
これを作るとしたら、顧客用に個別のテーブルを作成し、各データ テーブルとインデックスに顧客 ID フィールドを追加し、管理に便利な顧客を追加するための単純な一般的な背景を作成します~
モデルを作成するとき。フロントデスクのレイヤーは、変数をフィルタリングするために where xxx を渡し、顧客 ID=xxx を一律に追加します~ ただし、このアプローチの欠点についてはよくわかりません
ヒント: Env を使用して保存されたデータは Web 上でのみ読み取ることができます。 php cli モードではありません。特定のニーズに応じて使用してください。
ルート ドメイン名は $_SERVER['HOST'] です。どのリンクを使用する必要がありますか?
試験のその部分を教えてもらえますか?
私の現在のアプローチは、各企業が独自のドメイン名を使用し、プログラムのルートが異なるドメイン名を使用し、異なる構成を取るというものです。
会社 a は http://a.xx.com を使用します
会社 b は http://b を使用します。 .xx.com
現在、多くの企業が一連の情報を発行しており、それぞれの企業が を使用しているということを確認してください。
b 会社は http://b.xx.com を使用します
クロスではありません。現在、多くの企業が一連の情報を公開しており、それを参照してください。
この方法は非常に優れています。もっと早く知っていたら、あなたの方法を使用したでしょう。笑