PHP5.4からPHP7へのハードル

PHP5.4からPHP7へのハードル

暫くWeb開発から遠ざかっていたせいか、PHP7なるものが出た事を最近知った。PHP5から何がどう変わったのか定かではないが、使っているレンタルサーバーによればサーバー負荷が低減され2倍以上高速化しているという。またWordpressは勿論、Modxでも既に対応しているらしい。

そこで自作システムで運用しているサイトも含め、WebサーバーをPHP7に切り替えるべくいろいろ試したら・・・・やはりスンナリとは行かなかった。

ローカルサーバーの構築

普段の小変更はリモート(レンタル)サーバーにいきなり流し込んでいるが(;´∀`) 流石にPHP自体がメジャーアップデートしたのにぶっつけ本番では不味いので、久しぶりにローカルサーバーを構築してテストすることにした。

先ずは、FTPソフトでリモートファイルをローカルにダウンロード。これは個人的な事情だが、自宅PCの環境(OSやHDD)がここ数年で何度か新しくなっているので、ローカルにはファイルが殆ど無い。よってリモートからダウンロードするのに、量やサイズが大きすぎてFFFTPが何度も止まってしまった。

次はXAMPPをインストール、これ自体はウイザードに従うだけなので簡単。FileZillaやTomcatは取り敢えず不要なので除外し、Apache(PHP7を含む)とMySQLだけインストールした。

MySQLのユーザー登録

ここからが曲者。先ず、リモートで運用しているphpMyAdminのフォルダを一式DL。ローカルホストでアクセスしたら、何時もリモートサーバで使ってるユーザーでログイン出来ない。よく考えたらこれは当然で、そんなユーザーが真っさらのMySQLに居るはずない。しかし中々それに気づかず、設定ファイルで一生懸命パスワードの設定を弄ってしまった(;´∀`)

そもそも、XAMPPにはデフォルトでphpMyAdminが付いており、コントロールパネルのMySQLの「Admin」ボタンを押すだけでローカルのphpMyAdminに飛んでくれる。そこでrootかなにかでログインし、何時もリモートで使ってるユーザーを新規登録すればよかったのだ。

そこでmysqlというデータベースのUSERテーブルで、rootユーザを複製して名前を何時ものユーザーに変えたらOK・・・と思いきや又してもログイン出来ない!権限を変えてもダメなので、このユーザー(レコード)は一旦削除して、今度は普通にメインメニューから、ユーザー>ユーザーを追加したら上手く行った。USERテーブル以外にも何か書き換わるのかもね。

データのインポート

次にコンテンツであるデータをリモートからローカルに引っ張ってくる。やり方は、リモートのphpMyAdminにログインしてデータをエクスポートし、吐き出されたSQL文をローカルのphpMyAdminでインポートする。

当然DB一全体を一気に移動するのは無理なので、幾つかのテーブルを選んでエクスポートするも、インポート時に容量オーバーでエラーになってしまう。だから更に細切れにしてエクスポート→インポートを繰り返した。

しかしついに単独で容量オーバになるテーブルがあったので、結局本家のFAQに従いphpの設定を変更。具体的にはphp.iniのupload_max_filesizeを2MBから4MBに変更した(post_max_sizeは最初から8MB)。考えたら、最大2Mは小さいよね?因みにリモートの設定は10Mになってた。

文字化けの修正

ようやく独自システムのWebページがローカルで立ち上がったら、お約束の文字化けが発生。

そこで先ず、phpMyAdminに元々あった幾つかのデータベースの文字コードが殆どラテン系だったので、utf_general_ciに変更してみるが改善せず(もちろんApacheもMySQLも立ち上げ直した)。

次にApacheの設定ファイルhttpd.confを見るも、文字コードに関係しそうな行が見つからずひとまずスルー。またPHPの設定を確認するもdefault_charsetはちゃんとUTF-8になっていた。

そこでMySQLの設定ファイルmy.iniの## UTF 8 Settings以下の5行くらいのコメントアウトを全て外してみたら、見事文字化けがなくなった。DBやテーブルの文字コード変更が必要だったかは判らないが、文字化けしたら大体MySQL設定が怪しいということかな。

PHPコードのエラー

ローカル環境の構築で手こずったが、ここからようやく本題のPHP7のテスト。ローカルに設置した自作システムのページをブラウザで表示させると、実は文字化け以前にエラーメッセージだらけだった(;´∀`)

最初のエラーメッセージは、Undefined index: idという内容で、idというのはGETパラメータの1つ。つまりif($_GET["id"]==1){...といったコードになっているのだが、そんなパラメータは存在しないという警告らしい。確かに、このページのURLはidというパラメータはGETしてないが、PHP5.4では何もエラーは出なかった。

そこでif(isset($_GET['id'])){と先ず仮定しておいて、続けて$id=intval($_GET['id']);等と書けばOKだった。つまりPHP5.4では、値を代入していない変数があってもそのまま空欄でスルーしてくれたが、PHP7ではダメらしい。

mysql_query

続くエラーは殆どがmysql_queryの行で発生。最初は解らなかったが、実はこの関数自体がPHP7では削除されてしまったらしい。という事は、データを抽出しているコードは全滅(・_・;) 仕方ないというか良い機会なので、既に他のページでは使い始めていたPDOで統一することにした。

基本的にはmysql_queryの部分を$dbh->query("SQL文")みたいに変更すれば行けそうだが、折角だからデータを列挙する時は、foreach($dbh->query("select...") as $record)とやってコードをシンプルにした。

mysql_connect

上述のページ(サイト)のエラーを全て解消した後、別のサイト(これも独自システム)にアクセスすると、fatal errorが出てその他は何も表示されない。どうもデータベースに接続するところで躓いてるようだ。結局その原因はmysql_connectだった。つまりこの関数もPHP7では使われなくなっていたのだ。

そこでこれもPDOを使って接続するコードに変えたら繋がるようになった。因みに、上述のページは偶々DB接続だけはお試しでPDOを使っていたので繋がったのだ。mysql_queryの部分はそのままだったというわけ。

連想配列の読み出し方

データベースのレコードはphpで一旦連想配列の形で格納するが、それをmydata[name]等と呼び出すとUnknownエラーが出る。正しくはmydata["name"]という風にキーをダブルクォーテーション(又はクォーテーション)で囲む必要があるようだ。

本来これが正しい書き方なのかもしれないが、PHP5.4では何も問題が起きなかった。

まとめ

「PHP5 PHP7」で検索すると本家サイトがヒットするが、ここにはmysql絡みの変更点など書いていない。他の個人サイトでも同様で、もっと高尚な変更点と言うか、僕が書いてるようなコードとは関係無さそうに見えた。しかしそれは最終のphp5からphp7への変更点という意味のようだ。

確かにPHP 5.5.x で推奨されなくなる機能の中にMySQL拡張モジュールが含まれている。しかし、この時点ではあくまで非推奨であってまだ使えている。PHP7で初めて非対応になったのだから、PHP7で「下位互換性の無い機能」の中にMySQL関連を記述すべきだと思うが。

どうもPHPって、割りとルーズな書き方が許容されてたのに後に禁止されたり、関数自体が無くなったり新設されたりしすぎじゃないの?他のプログラム言語でもこんなに頻繁に変わったりするのかなあ?

Share me!Share on Google+Share on FacebookTweet about this on TwitterShare on TumblrPin on Pinterest

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です