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