はじめに
こんにちは、SANACHANです。
サーバーサイドのスクリプト言語の代表であるPHP言語。クライアント側(ブラウザ等)に動的なコンテンツを提供するための言語で、様々なWebサイトで使用されています。Wordpressで作成されたWebサイトは全てこのPHPが使用されています。
たくさんのWebサイトで利用されていることもあり、セキュリティの観点から、バージョンアップ時に既存関数が削除される場合があります。
昔作成した家計簿のWebアプリが動作しなくなり、調べてみるとMySQLに関する関数が一新されており、「そんな関数ないよ!」というエラー「HTTP Response 500 (Internal Server Error)」が出ていました。
今回は、PHP5からPHP7のMySQLに関する更新内容と、更新後の対処方法を記載します。
こんな方におすすめ
- PHPとMySQLを使うWebアプリで、急にデータベースに接続できなくなり困っている
- 接続できない原因は分かったけど、良い対処方法が分からない
語句説明
PHPとは
Wikipediaには、以下のように記載されています。
PHP(ピー・エイチ・ピー)は "The PHP Group" によってコミュニティベースで開発[3]されているオープンソースの汎用プログラミング言語およびその公式の処理系であり、特にサーバーサイドで動的なウェブページ作成するための機能を多く備えていることを特徴とする。
MySQLとは
Wikipediaには、以下のように記載されています。
MySQL(まい・えすきゅーえる)は、オープンソースのリレーショナルデータベース管理システム(RDBMS)である。その名前は、共同設立者のMichael Wideniusの娘の名前である「My」と、Structured Query Languageの略称である「SQL」を組み合わせたものである。
PHPとMySQL
PHPはサーバーサイドで実行できるスクリプトのため、サーバーで管理しているデータベース「MySQL」などと組み合わせて使用されます。「PHP+MySQL」を題材とした書籍も多数出版されており、いかにメジャーな使い方であるかが分かるかと思います。
例えば、ユーザーの情報や表示するために必要な情報をデータベースに保存し、アクセスされた時の状態(ユーザー等)やデータベースに蓄積されている内容に応じて動的にHTMLを生成します。
PHP5からPHP7の更新で変わったこと
PHPの公式サイトで変更点が分かります。
なんと、そのページのタイトルは「下位互換性のない変更点」。PHP5系からPHP7系の更新により、下位互換性が損なわれた機能の一覧が掲載されています。
MySQLに関する内容として、公式ページには以下の記載があります。
ext/mysql のすべての関数が削除されました。
その他の MySQL API の選択肢については MySQL API の選択 を参照ください。
MySQLに関する全ての関数が削除されたようです。
mysql_connect など、今まで使用していた関数がPHP7では使用できなくなったということです。
MySQLに関するPHP7で削除された関数
削除された関数の中から、よく利用されている関数を列挙しておきます。
これらを利用しているPHPのコンテンツでは、PHP7に更新の際は動かなくなる可能性があります。
- mysql_connect()
MySQLのデータベースに接続する関数 - mysql_select_db()
接続したMySQLサーバー内のデータベースを選択する関数 - mysql_query()
選択したデータベースに対してSQL文を実行する関数 - mysql_close()
接続したMySQLデータベースから切断する関数
これを見ても分かる通り、mysql_xxxx 関数は「手続き型」の関数であることが分かります。
PHP7で利用可能なMySQLに関する代替え関数
PHP公式ページでは、「MySQL改良版拡張モジュール」を代替え関数として推奨しています。
mysqli というクラスの利用を推奨しているのです。
クラス(オブジェクト型)の利用を推奨しているものの、手続き型の関数(https://www.php.net/manual/ja/ref.mysqli.php)も用意されています。
mysqlからmysqliへの置き換え対処法
置換の手順は、以下の通りです。
- mysqli_xxxx のラッパー関数を用意する
- 従来の mysql_xxxx を使用している箇所でラッパー関数を読込む
それぞれ、詳しく見ていきましょう。
PHP5で動作するMySQLクラス(mysql_connectなど)
大昔に書いて、なお現役のMySQLのクラスを紹介します。PHP5では動作していました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
<?php class MySQL { var $m_con; var $m_host_name; var $m_user_name; var $m_password; function MySQL () { } function ConnectServer ($host, $user, $pass) { $this->m_con = mysql_connect ($host, $user, $pass); if ($this->m_con === false) { die ("Cannot connect mysql server"); } $this->m_host_name = $host; $this->m_user_name = $user; $this->m_password = $pass; } function EscapeString ($str) { $ret = mysql_real_escape_string ($str); if ($ret === false) { die ("Cannot escape string: " . $str); } return $ret; } function SelectDatabase ($db_name) { $ret = mysql_select_db ($db_name, $this->m_con); if ($ret !== true) { die ("Cannot select database: " . $db_name); } return true; } function ExecuteSQL ($sql) { $ret = mysql_query ($sql); if ($ret === false) { die ("Invalid query: " . mysql_error ()); } return $ret; } function GetSQLResultRowsNum ($result) { return mysql_num_rows ($result); } function GetSQLResultByRow ($result) { return mysql_fetch_row ($result); } function GetSQLResultByAssocRow ($result) { return mysql_fetch_assoc ($result); } function GetAllResultByRow ($result) { $ret = array (); while ($row = $this->GetSQLResultByRow ($result)) { array_push ($ret, $row); } return $ret; } function GetAllResultByAssocRow ($result) { $ret = array (); while ($row = $this->GetSQLResultByAssocRow ($result)) { array_push ($ret, $row); } return $ret; } function FreeResult ($result) { mysql_free_result ($result); } function Disconnect () { mysql_close ($this->m_con); } } ?> |
スポンサーリンク
mysqli_xxxx のラッパー関数を用意(mysqli_connectなどをwrap)
これをどのように置き換えるか。悩みに悩んだ末、ラッパーの関数群を用意することにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<?php function mysql_connect($host, $user, $pass) { global $mysqliObj; $mysqliObj = mysqli_connect($host, $user, $pass); return $mysqliObj; } function mysql_select_db($dbname, $con="") { global $mysqliObj; return mysqli_select_db($mysqliObj, $dbname); } function mysql_query($sql) { global $mysqliObj; return mysqli_query($mysqliObj, $sql); } function mysql_real_escape_string($str) { global $mysqliObj; return mysqli_real_escape_string($mysqliObj, $str); } function mysql_num_rows($result) { return mysqli_num_rows($result); } function mysql_result($result, $row, $field) { $result->data_seek($row); $datarow = $result->fetch_array(); return $datarow[$field]; } function mysql_fetch_row($result) { return mysqli_fetch_row($result); } function mysql_fetch_assoc($result) { return mysqli_fetch_assoc($result); } function mysql_free_result($result) { return mysqli_free_result($result); } function mysql_error() { global $mysqliObj; return mysqli_error($mysqliObj); } function mysql_close($mysqliObj) { return mysqli_close($mysqliObj); } ?> |
スポンサーリンク
従来 mysql_xxxx を使用していたところでロードする
以下のように記述しておくと、PHP5とPHP7両方で動作するようになります。
1 2 3 4 5 6 7 8 9 10 11 |
<?php if (!function_exists("mysql_connect")) { require_once('lib_mysqli.inc'); } require_once ('lib_mysql.php'); #実際のコード ?> |
おわりに
いかがでしたでしょうか。
今回、PHP5系からPHP7系へ更新し、PHPが下位互換を保証していないということを痛感しました。
今後の更新でも、既存関数が削除されることになると思いますので、更新の際は慎重に。
以上、「【情報】PHP7でMySQLに関する関数が一新された件」でした。