PHP を使用してデータベースに接続する場合、この記事では、データベース スキーマの設計、データベース アクセス、データベースを使用するビジネス ロジック コードなど、PHP アプリケーションで発生する一般的なデータベースの問題とその解決策について説明します。データベースの使用方法が 1 つだけ正しかった場合。 PHP データベースの設計、データベース アクセス、データベース ベースの PHP ビジネス ロジック コードを作成するにはさまざまな方法がありますが、通常はエラーが発生します。この記事では、データベース設計およびデータベースにアクセスする PHP コードで発生する 5 つの一般的な問題と、それらが発生した場合の修正方法について説明します。
PHP データベースの問題 1: MySQL を直接使用する
よくある問題は、古い PHP コードが mysql_ 関数を使用してデータベースに直接アクセスすることです。リスト 1 は、データベースに直接アクセスする方法を示しています。
リスト 1. Access/get.php
<ol class="dp-xml"> <li class="alt"><span><span><?php </span></span></li> <li class=""><span>function get_user_id( $name ) </span></li> <li class="alt"><span>{ </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">db</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">mysql_connect</font></span><span>( 'localhost', 'root', 'password' ); </span> </li> <li class="alt"><span>mysql_select_db( 'users' ); </span></li> <li class=""><span> </span></li> <li class="alt"> <span>$</span><span class="attribute"><font color="#ff0000">res</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">mysql_query</font></span><span>( "SELECT id FROM users WHERE </span><span class="attribute"><font color="#ff0000">login</font></span><span>=</span><span class="attribute-value"><font color="#0000ff">'".$name."'</font></span><span>" ); </span> </li> <li class=""> <span>while( $</span><span class="attribute"><font color="#ff0000">row</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">mysql_fetch_array</font></span><span>( $res ) ) { $</span><span class="attribute"><font color="#ff0000">id</font></span><span> = $row[0]; } </span> </li> <li class="alt"><span> </span></li> <li class=""><span>return $id; </span></li> <li class="alt"><span>} </span></li> <li class=""><span> </span></li> <li class="alt"><span>var_dump( get_user_id( 'jack' ) ); </span></li> <li class=""><span>?> </span></li> </ol>
リスト 2. Access/get_good.php
<ol class="dp-xml"> <li class="alt"><span><span><?php </span></span></li> <li class=""><span>require_once("DB.php"); </span></li> <li class="alt"><span>function get_user_id( $name ) </span></li> <li class=""><span>{ </span></li> <li class="alt"> <span>$</span><span class="attribute"><font color="#ff0000">dsn</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">'mysql://root:password@localhost/users'</font></span><span>; </span> </li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">db</font></span><span> =& DB::Connect( $dsn, array() ); </span> </li> <li class="alt"><span>if (PEAR::isError($db)) { die($db->getMessage()); } </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">res</font></span><span> = $db->query( 'SELECT id FROM users WHERE </span><span class="attribute"><font color="#ff0000">login</font></span><span>=?',array( $name ) ); </span> </li> <li class="alt"> <span>$</span><span class="attribute"><font color="#ff0000">id</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">null</font></span><span>; </span> </li> <li class=""> <span>while( $res->fetchInto( $row ) ) { $</span><span class="attribute"><font color="#ff0000">id</font></span><span> = $row[0]; } </span> </li> <li class="alt"><span>return $id; </span></li> <li class=""><span>} </span></li> <li class="alt"><span>var_dump( get_user_id( 'jack' ) ); </span></li> <li class=""><span>?> </span></li> </ol>
$dsn のデータベース接続文字列を除き、MySQL の直接使用がすべて削除されていることに注意してください。さらに、SQL では ? 演算子を介して $name 変数を使用します。次に、クエリ データは、query() メソッドの最後で配列を通じて送信されます。
PHP データベースの問題 2: 自動インクリメント機能を使用していない
最新のデータベースと同様に、MySQL にはレコードごとに自動インクリメントの一意の識別子を作成する機能があります。さらに、最初に SELECT ステートメントを実行して最大の ID を検索し、次にその ID を 1 ずつインクリメントして、新しいレコードを検索するコードが引き続き表示されます。リスト 3 は、悪いパターンの例を示しています。
リスト 3. Badid.sql
<ol class="dp-xml"> <li class="alt"><span><span>DROP TABLE IF EXISTS users; </span></span></li> <li class=""><span>CREATE TABLE users ( </span></li> <li class="alt"><span>id MEDIUMINT, </span></li> <li class=""><span>login TEXT, </span></li> <li class="alt"><span>password TEXT </span></li> <li class=""><span>); </span></li> <li class="alt"><span>INSERT INTO users VALUES ( 1, 'jack', 'pass' ); </span></li> <li class=""><span>INSERT INTO users VALUES ( 2, 'joan', 'pass' ); </span></li> <li class="alt"><span>INSERT INTO users VALUES ( 1, 'jane', 'pass' ); </span></li> </ol>
ここの id フィールドは単に整数として指定されています。したがって、一意である必要がありますが、CREATE ステートメントに続くいくつかの INSERT ステートメントに示されているように、任意の値を追加できます。リスト 4 は、このタイプのパターンにユーザーを追加するための PHP コードを示しています。
リスト 4. Add_user.php
<ol class="dp-xml"> <li class="alt"><span><span><?php </span></span></li> <li class=""><span>require_once("DB.php"); </span></li> <li class="alt"><span> </span></li> <li class=""><span>function add_user( $name, $pass ) </span></li> <li class="alt"><span>{ </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">rows</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">array</font></span><span>(); </span> </li> <li class="alt"><span> </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">dsn</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">'mysql://root:password@localhost/bad_badid'</font></span><span>; </span> </li> <li class="alt"> <span>$</span><span class="attribute"><font color="#ff0000">db</font></span><span> =& DB::Connect( $dsn, array() ); </span> </li> <li class=""><span>if (PEAR::isError($db)) { die($db->getMessage()); } </span></li> <li class="alt"><span> </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">res</font></span><span> = $db->query( "SELECT max(id) FROM users" ); </span> </li> <li class="alt"> <span>$</span><span class="attribute"><font color="#ff0000">id</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">null</font></span><span>; </span> </li> <li class=""> <span>while( $res->fetchInto( $row ) ) { $</span><span class="attribute"><font color="#ff0000">id</font></span><span> = $row[0]; } </span> </li> <li class="alt"><span> </span></li> <li class=""><span>$id += 1; </span></li> <li class="alt"><span> </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">sth</font></span><span> = $db->prepare( "INSERT INTO users VALUES(?,?,?)" ); </span> </li> <li class="alt"><span>$db->execute( $sth, array( $id, $name, $pass ) ); </span></li> <li class=""><span> </span></li> <li class="alt"><span>return $id; </span></li> <li class=""><span>} </span></li> <li class="alt"><span> </span></li> <li class=""> <span>$</span><span class="attribute"><font color="#ff0000">id</font></span><span> = </span><span class="attribute-value"><font color="#0000ff">add_user</font></span><span>( 'jerry', 'pass' ); </span> </li> <li class="alt"><span> </span></li> <li class=""><span>var_dump( $id ); </span></li> <li class="alt"><span>?> </span></li> </ol>
add_user.php のコードは、最初にクエリを実行して id の最大値を見つけます。次に、ファイルは、ID 値を 1 増やして INSERT ステートメントを実行します。このコードは、負荷の高いサーバーでは競合状態で失敗します。さらに、それは非効率でもあります。では、代替手段は何でしょうか? MySQL の自動インクリメント機能を使用して、挿入ごとに一意の ID を自動的に作成します。