10

私はPHP/MySQLに非常に慣れていないので、学習しながら学習しています。私が学んだ新しいことの1つは、特定のユーザー名に対してデータベースに対して確立できる接続の最大数があるということです。Wordpressで最初にWebサイトを構築し始めたとき、私は古いmysql_query()コマンドを使用していました。WordpressはWebサイトにログインするだけでアクティブな接続を維持するため、MySQLデータベースに接続する必要はありませんでした。すべてのMySQLクエリをPDO拡張機能に切り替えることにしたとき、Wordpressのアクティブな接続を利用できなくなり、独自のデータベース接続を開始する必要がありました。これは、スクリプトを実行するすべてのページに含めた個別のPHP構成ファイルで行いました。PHPコードは次のようになります。

try {
    $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
}
catch(PDOException $e) {  
    echo "Select DB Error: " .$e->getMessage(). "</br>";
}

残念ながら、今は常に次のエラーが発生します。

「SQLSTATE[42000][1203]ユーザーにはすでに「max_user_connections」を超えるアクティブな接続があります」

いくつかのオンライン調査に基づいて、私はこれを修正するためにさまざまな異なる方法を試しました。まず、各スクリプトの最後でデータベース接続をnullに設定しようとしました(ただし、これはPHP PDOのデフォルトである必要がありますか?)。null次に、データベースの各クエリの後に各ステートメントハンドルを設定しようとしました(これは絶望的な試みでした)。そして最後に、設定ファイルの次の行を変更して、持続的接続を使用してみました。

$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass, array(PDO::ATTR_PERSISTENT => true));

これはどれも機能していないようですが、それでもまったく同じエラーが発生します。サイトの準備ができたら、無数の異なるデータを入力する1日あたり100〜200人を処理できる必要があります。PDOを使用してWordpressのアクティブな接続を利用する方法を理解できたとしても、それは良いスタートです。私が得ることができるどんな助けにも感謝します。

アップデート:

SHOW FULL PROCESSLISTコードの1つでMySQLクエリとして実行していますが、非常に奇妙な動作をしています。これは私のスクリプトの最初の部分です(SHOW FULL PROCESSLISTクエリは含まれていません):

<?php

include 'config.php';

if(isset($_POST['submit']))
{
//Get Current User Login
global $current_user;
$current_user = wp_get_current_user();
$ulog = $current_user->user_login;
$tablename_cc = "cc_".$ulog;
$tablename_db = "db_".$ulog;
$tablename_misc = "misc_".$ulog;
$tablename_cash = "cash_".$ulog;

try {
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_cc. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), cc_num TEXT(4), cc_amnt DECIMAL(8,2), cc_app TEXT(20), cc_date VARCHAR(10), cc_time VARCHAR(10))");            
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_db. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), db_num TEXT(20), db_amnt DECIMAL(8,2), db_date VARCHAR(10), db_time VARCHAR(10))");        
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_misc. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), misc_item TEXT(1000), misc_amnt DECIMAL(8,2), misc_date VARCHAR(10), misc_time VARCHAR(10))");       
    $DBH->exec("CREATE TABLE IF NOT EXISTS " .$tablename_cash. " (ID bigint(100) NOT NULL AUTO_INCREMENT, PRIMARY KEY(ID), accnt TEXT(20), cash_amnt DECIMAL(8,2), cash_time VARCHAR(10))");
}
catch(PDOException $e) {  
    echo "Create Tables Error: " .$e->getMessage();
}
} ?>

SHOW PROCESS LISTifステートメントの外でクエリを実行しようとすると、アクティブな接続が1つあるという結果が得られます。ただし、 ifステートメントSHOW FULL PROCESSLISTでクエリを実行しようとすると、接続数を超えたというエラーが表示されます。この結果に基づいて、ユーザーがフォームを送信するときに(基本的にデータベースに2回接続しようとすると)、ページの最上部にある私の行が問題を引き起こしている可能性があると考えたので、ifステートメント内に移動しましたが、違いもありませんでした。なぜこれが起こっているのか私は途方に暮れています。include

更新/回答(まだいくつかの質問):

私は自分の問題が何であるかを理解しました。スクリプトの1つが完了すると、別のスクリプトがそれらの請求書を印刷するウィンドウをポップアップするjavascriptコマンドがあります。その2番目のスクリプトも、構成ファイルを使用してデータベースへの接続を試みます。ユーザーが操作しているフォームは動的であるため(必要な数のデータセットを入力できます)、ユーザーが少数のデータを挿入すると、PDOクエリが非常に高速に実行され、競合は発生しません。接続の数。ただし、ユーザーが大量のデータを入力すると、かなり長い時間がかかり、サーバーは接続の最大数に達します。この問題は、サーバー環境の悪さと私の側の非効率的なクエリの組み合わせに本当にあります(まだPHPを学習しています)。この時点で考えられる唯一の解決策は、他のスクリプトに追いつくために、2番目のスクリプトでより長いスリープを設定することです(すでに3秒のスリープを使用しています)が、ある時点で、これには時間がかかりすぎます。もっと良い提案があるかどうかわかりませんか?

4

3 に答える 3

2

データベースに接続できる別のツールを使用している場合は、実際に作成している接続数を確認することができます。ピンチで、phpmyadminこれを行うことができます。

通常、すべてのアクティブなクエリと接続を次のように表示できます。

SHOW PROCESSLIST

PDO 接続ルーチンで間違いを犯した場合、リクエストの期間中ではなく、実行しようとしているクエリごとに接続を作成している可能性があります。また、各リクエストが適切に閉じられていない接続の大きなプールを作成していないことを確認する必要がある場合もあります。おそらく、接続オプションを試す必要があります。

于 2012-08-22T03:36:31.247 に答える
1

include_once('config.php')またはrequire_once('config.php')の代わりにファイル内で使用include 'config.php'すると、データベース接続の重複を避けることができます。

于 2012-08-27T05:33:36.613 に答える
0

必要なものは、PDO「シングルトン」クラスと呼ばれます。次に例を示します。

http://tonylandis.com/php/php5-pdo-singleton-class/

コンストラクターが取る引数が多すぎるため、これは最良の例ではありません。$dsn,.., 引数をコンストラクターにハードコードするだけです。_construct(){...} を使用すると、PDO() を使用する場所ならどこでも new sdb() を使用できます。クラスに対して 1 回を除いて、include または require ステートメントは必要ありません。

$pdo オブジェクトはクラス内に静的変数として格納されるため、常にアクセスできます。

于 2012-09-15T14:14:28.003 に答える