ローカルXamppでテストサイトPHP7.4~8.1にしたらエラーになる問題を解消する

PCアプリ・セキュリティ

古いPHP7.4以下を使ったサイトは、PHP8にするとエラーが出て正常に動かなくなって困るので、まずはローカルにXamppとPHP7.4やPHP8などPHPのバージョンごとに数個起動させて古いサイトを修正していくメモです。

バージョンごとのApacheとPHPはポートを変更して同時に起動してポート番号を変えてサイトが正常に動くか試しました。

  • PHP8.0:https://localhost/test(https:443//localhost/test)
  • PHP8.2:https://localhost:444/test
  • PHP7.4:https://localhost:446/test
  • PHP8.1:https://localhost:447/test

4つ起動させてみました。PHP7.4でもエラーになるスクリプトを全て解消しても、PHP8.1になったらよりシビアになってエラーが出るのでローカルで直していく。

  1. XamppでPHP7.4と最新8.2を同時起動
    1. 2つ目のXampp インストール
    2. 空きポートをチェックする
      1. netstatを使う方法
      2. Xampp Control Panelでも使用しているポートをチェック可能
    3. 2個目のXampp Apacheでポートを変更する設定
      1. httpd.conf
      2. httpd-ssl.conf
      3. httpd-xampp.conf
    4. xampp-control.exeを管理者として実行
    5. 上手く行かない場合はApache Serviceをアンインストール
      1. uninstallがうまく行かない時
    6. MySQLは1個目のXamppのを共用で使う
      1. my.ini 変更点(共用の場合は変更しない)
      2. php.ini 変更点
    7. xampp-control.exeを管理者として実行してPort変更
  2. ローカルにWordPressサイトをコピーする時のメモ
    1. WordPressのダウンロード
    2. MySQLのバックアップからphpMyAdminインポート「Incorrect format parameter」エラー
    3. phpMyAdmin タイムアウト
    4. wp_optionsテーブルのドメインを変更
    5. ACPuを使えるようにする
      1. ダウンロード
      2. 設置
      3. php.iniの設定
      4. phpinfo()で確認
  3. Composer インストール・設定
    1. ダウンロード(Windows用)・インストール
      1. Windows用のインストーラ DL
      2. インストールされたか確認
    2. マニュアル インストール(上記でインストールした場合は使わない)
      1. composer.pharを好きなフォルダに移動してcomposer.batファイル作成
    3. パッケージ インストール
      1. 古いパッケージを修正する
  4. PHP8.1でのスクリプト修正メモ
    1. 未定義
      1. 例:$item = ‘<tag>’.$test.'<tag>’;
      2. if文 例:空じゃない場合、if($item !=”)
      3. if文 例:空の場合、if($item ==”)
    2. PHP8.1 型の厳格化
    3. PHP8.1のCORS・クロスドメイン制約問題
      1. WordPress
      2. .httpaccess
  5. jQuery slick導入
    1. ダウンロード
    2. slick.min.jp,slick.cssを保存
    3. WordPressを使う場合
    4. javascript
  6. 【おまけ】MySQL ダンプを文字コードlatin1で保存してしまったのをUTF-8にする

XamppでPHP7.4と最新8.2を同時起動

Xamppを2個インストールして、異なるバージョンのApachのポートを変える。

2つ目のXampp インストール

1つ目のXamppはPHP7.4.27バージョンをインストールした。

2個目、以下から最新をインストールしてみる。

XAMPP Installers and Downloads for Apache Friends
XAMPP is an easy to install Apache distribution containing MariaDB, PHP and Perl.

古いWindowsのバージョンはここ↓

XAMPP - Browse /XAMPP Windows at SourceForge.net
An easy to install Apache distribution containing MySQL, PHP, and Perl

2個目は1個目(c:\xampp)とフォルダが重ならないように違うフォルダにインストールする。

今回は「xampp-windows-x64-8.2.12-0-VS16-installer.exe」ファイルからインストールするのでフォルダ名をxampp8212にした。

空きポートをチェックする

Apacheはデフォルトでポート80と、SSLでポート443を使う。2個目のXamppのApacheを80と443ではなく違うポートにするためにまずは空いているポートをチェックする。

netstatを使う方法

netstat -ano

Apache80、SSL443、SMB445は使われているので他を使う。

Xampp Control Panelでも使用しているポートをチェック可能

以下のように表示されます。

今回は2個目のXamppではMySQLは使いませんが、別にMySQLを使う場合も3306とは違うポートにする必要がある。

2個目のXampp Apacheでポートを変更する設定

httpd.conf

C:\xampp8212\apache\conf\httpd.confを編集する。

ポート80を82などに変更。

以下のように変更した。

Listen 82
ServerName localhost:82

httpd-ssl.conf

C:\xampp8212\apache\conf\extra\httpd-ssl.confも変更する。

3箇所変更するところがある。

今回は445はSMBに使われていたので444にした。

Listen 444
<VirtualHost _default_:444>
ServerName www.example.com:444

httpd-xampp.conf

複数のサイトがある場合はhttpd-xampp.confにサイトを追加しておく。

サイトを保存してあるフォルダを指定する。

もともとあるwebalizerの上に追加しておくとサイトが見れるようになる。

xampp-control.exeを管理者として実行

xampp-controlでも設定が必要。管理者として起動する。

右上の「Config」ボタンを押して↓ウィンドウが出るので「Service and Port Settings」を押す。

ここ↓でApacheのポート番号を変更する。

MySQLのタブを選ぶとMySQLのポートも変更できる。

これで、2つのXamppのApacheが起動する。

上手く行かない場合はApache Serviceをアンインストール

上記までの設定でApacheをスタートしても「Attempting to start Apache app…」の状態で起動しない時は、Apacheのパスが違っている場合が多い。

なので、Xampp Control Panelを管理者で起動して↓Apacheの左側緑チェックを押してApache ServiceをアンインストールにYesを押す。

すると↓Apacheの左側が「X」になって、Startボタンを押すと起動した。

Portは82と444になって設定通り動いている。

最近は全てSSLなので「https://localhost:444」でサイトが表示される。

uninstallがうまく行かない時

MySQLも削除しようとしたがエラーになった。Service was NOT (un)installed!とインストールされてない?ようなアラートが出る。

そういう場合はまずはサービスを停止する。左下のスタートメニューを右クリックして「ファイル名を指定して実行」を選択。

「services.msc」を入力する。

MySQL(Apacheもエラーになったら同様に)を見つけて右クリックで「停止」を押す。

この状態でXampp Control Panelに戻って再びMySQL ServiceをUninstallすると「X」になって、Startボタンを押すと起動するようになる。

MySQLの場合もポートが競合する別のエラーになるのでご注意ください。

MySQLは1個目のXamppのを共用で使う

MySQLは1個目のXamppのを共用で使うので変更しない。

MySQLはPHPと違ってバージョンによる違いはあまり無いようです。一応変更方法をメモしておきます。

my.ini 変更点(共用の場合は変更しない)

Xampp Control Panelからmy.ini(MySQLの設定ファイル)を選ぶ。

以下の部分の番号を変更する。

[client]
port=3306
[mysqld]
port=3306

php.ini 変更点

MySQLのポート変更するにはphp.ini(PHPの設定ファイル)も変更する必要がある。

[MySQLi]と[MySQL]セクションの2箇所ある。

[MySQLi]
mysqli.default_port=3306

[MySQL]
mysql.default_port=3306

xampp-control.exeを管理者として実行してPort変更

こちらも最後にXampp Control Panelの右上ConfigボタンからService and Port SettingsでMySQLのポートを変更する。

MySQLは何個も起動する必要がないので、上記は未検証です・・・

ローカルにWordPressサイトをコピーする時のメモ

本番サーバーからローカルにサイトをコピーしてテストとして使う時のエラーなど。

WordPressのダウンロード

WordPress本体はここからダウンロードする。

ダウンロード
Get WordPress Everything you need to set up your site j…

MySQLのバックアップからphpMyAdminインポート「Incorrect format parameter」エラー

本番サーバーのMySQLからDBごとバックアップをダウンロードして、

phpMyAdminでローカルにインポートしようとすると「Incorrect format parameter」エラーになった。

バックアップデータが800MBとか大きかったのがエラーの原因、php.iniを以下のように編集する。

post_max_size = 1500M
upload_max_filesize = 1500M

その後、XamppのApacheとMySQLを再起動。

phpMyAdmin タイムアウト

MySQLのインポートSQLが多いとphpMyAdminがタイムアウトするので、phpMyAdminの設定を変更する。

C:\xampp\phpMyAdmin\libraries\config.default.php

300秒になっているのでタイムアウトしちゃう、無制限の「0」にする。

$cfg['ExecTimeLimit'] = 0;

wp_optionsテーブルのドメインを変更

本番サーバーからバックアップしたMySQLテーブルでwp_optionsの「siteurl」,「home」のドメインをローカル用に変更する必要がある。

変更しないと、本番サイトに飛んでしまってローカルサイトは操作不可能になる。

ACPuを使えるようにする

古いキャッシュ保存方法、キャッシュを保存する時に使うAPCUをXampp(Windows)のPHPで使えるようにする設定です。

ダウンロード

ここにhttps://pecl.php.net/アクセスして「APCu」を検索、以下のように出て来るのでWindowsのDLLをダウンロードする。

一番上の5.1.21をダウンロードした。

PECL :: Package :: APCu 5.1.21 for Windows

PHPのバージョン別と、DL項目は4つある。PHP7.4を使っていてXamppはApacheなので、7.4 Thread Safe (TS) x64(PCはAMD Ryzen 7 使ってるので64ビット用)を選ぶ。(7.4 Non Thread Safe (NTS) x64はNginx用)

設置

解凍すると中に以下のようなファイルが入っている。

php_apcu.dllをC:\xampp\php\extの中にコピーする↓

extフォルダには↑他の機能拡張がたくさん入っている。

php.iniの設定

php.iniのextension=の記述がある行あたりに追加する。

extension=php_apcu.dll
apc.enabled=1

最後にApacheを再起動する。

phpinfo()で確認

<?php phpinfo(); ?>をサイトが見れるファイルに保存してブラウザで見る、以下のようにAPCuの項目が追加されていれば成功。

Composer インストール・設定

ComposerはPHPパッケージ依存管理ツール。依存しているツールをまるごとインストールしてくれたりしてかなり便利なツールで、PHP開発するならかなり必須ツール。

ツールは誰か頭の良い方がすでに開発してくれたもので、そのツールを利用しつつ、自分の実現したいサイトやアプリを簡単に構築できるようにしてくれるありがたいものm(_ _)m

ダウンロード(Windows用)・インストール

Composer (getcomposer.org)

Windows用のインストーラ DL

Download、Windows InstallerのComposer-Setup.exeをダウンロードする。

Xamppの中のPHPにインストールする、なにも変えることなくNextを押していく。

インストールされたか確認

XamppのApacheを再起動してXamppのフォルダをクリックして「ターミナルで開く」を選ぶ。

composer -vでcomposerのバージョンはヘルプが表示される。↑

composer -v

マニュアル インストール(上記でインストールした場合は使わない)

他の方法、マニュアルでインストールする場合、今回は使わない。

DownloadページのManual Downloadから↓以下のLatest Stableを押すと「composer.phar」がダウンロードされる。

composer.pharを好きなフォルダに移動してcomposer.batファイル作成

自分の場合ですがサイトのファイルを保存してあるところにcomposerフォルダを作って入れました。例「C:\Users\GO\Dropbox\site\composer」

composer.pharを置いたフォルダ内をクリックして「ターミナルで開く」を選ぶ。

PowerShellかコマンドプロンプトが開いたら以下のコマンドを打つ。

'@php "%~dp0composer.phar" %*' | Out-File -Encoding ASCII composer.bat

フォルダにcomposer.batファイルができました。

composer.batの中身↓このように1行書いてあります。

@php "%~dp0composer.phar" %*

パッケージ インストール

例「C:\Users\GO\Dropbox\site」にパッケージをインストールしてみます。

例としてWebページをスクレイピングするphp-html-parserをインストールしてみます。

composer require paquettg/php-html-parser

Vendorフォルダ(中にツールと依存されているツール郡が保存される)をインストールしたい場所(例:C:\Users\GO\Dropbox\site)フォルダでクリックして「ターミナルで開く」を選ぶで上記を入力する。

C:\Users\GO\Dropbox\siteにVendorフォルダができて、なにやらいろいろなパッケージがダウンロードされた。

古いパッケージを修正する

これでPHPで↓このようなスクリプトを書けばスクレイピングできる。かなり簡単ですね。

require 'vendor/autoload.php';

use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('<div class="all"><p>Hey bro, <a href="google.com">click here</a><br /> :)</p></div>');
$a = $dom->find('a')[0];
echo $a->text; 

ただ・・・php-html-parserの場合は4年くらい更新されていないのでPHP7.0前のmb_eregi_replace()を使っているので、そのままでは使えずエラーになる。ので、php-html-parserのファイルを修正する必要がある。

vendor\paquettg\php-html-parser\src\PHPHtmlParser\DomのCleaner.phpの以下を修正しました。

            //$str = \mb_eregi_replace("<\s*style\s*>(.*?)<\s*/\s*style\s*>", '', $str);
            $str = mb_ereg_replace("<\s*style\s*>(.*?)<\s*/\s*style\s*>", '', $str, 'i');

            //$str = \mb_eregi_replace("(\{\w)(.*?)(\})", '', $str);
            $str = preg_replace("/(\{\w)(.*?)(\})/i", '', $str);

これでphp-html-parserが動くようになった♪ けど今はほとんど使ってない。

PHP8.1でのスクリプト修正メモ

PHP7.4からPHP8にするとエラーがたくさん出てくるので修正していくメモ。

未定義

PHP8前からですが、以下のようなエラーがでてくる。

Notice: Undefined index: test←変数名

変数を定義していないのが原因。最初に$item = ”;などとして変数を定義しておかないといけない。

既存のスクリプトに基本的にisset()とempty()に変えていかないとエラーになる。めんどうな仕様になったなぁ、

例:$item = ‘<tag>’.$test.'<tag>’;

$testが定義されていないと言われたら、なるべくそのままの状態で「(isset($test) ? $test : ”)」を入れて、ある場合はそのまま$test:無い場合は「”(空の状態)」で$testを定義する。

$item = '<tag>'.$test.'<tag>';
  ↓
$item = '<tag>'.(isset($test) ? $test : '').'<tag>';

if文 例:空じゃない場合、if($item !=”)

isset($item)を追加しますが、isset($item)だけだと$item変数が定義されているかどうかをチェックするのみなので、中身が空の場合でも入る。なので$item !=”も必要。

if(isset($item) and $item !='')

if文 例:空の場合、if($item ==”)

空かどうかをチェックするのにはemptyに変えればいいと思う。

if(empty($item))

PHP8.1 型の厳格化

$allcont=($allcont+(int)$xml->SearchResult->TotalResultCount);

で以下のエラーになった。

Fatal error: Uncaught TypeError: Unsupported operand types: string + int

$allcontにもintをつけないといけないようです。↓

$allcont=((int)$allcont+(int)$xml->SearchResult->TotalResultCount);

数式の場合は全ての関数でint、floatを付けないとエラーになるみたい。

PHP8.1のCORS・クロスドメイン制約問題

PHP8.1にすると外部にファイルをとりに行くのを拒否される。fontawesomeを使ったアイコンが表示されなくなった。

ブラウザのエラーを見ると以下のように表示されている。

クロスオリジン要求をブロックしました: 同一生成元ポリシーにより、https://localhost/wp-content/themes/cocoon-master/webfonts/fontawesome/fonts/fontawesome-webfont.woff2?v=4.7.0 にあるリモートリソースの読み込みは拒否されます (理由: CORS ヘッダー ‘Access-Control-Allow-Origin’ が足りない)。ステータスコード: 200

ローカルのPHP8.1では以下の3つの方法を試した。

WordPress

子テーマのfunctions.phpに入れる。

add_action('send_headers', 'cors_http_header');
function cors_http_header(){
    header("Access-Control-Allow-Origin: *");
}

もしくは以下をindex.php?かwp-config.phpあたりに追加すると良さそうですが、未解決。

header('Access-Control-Allow-Origin: *');

.httpaccess

Header set Access-Control-Allow-Origin *

Apacheを再起動してもなぜかうまくいかない。と思ったら、.httpaccessの設定を放置しておいたらいつのまにか解決してた。

jQuery slick導入

Javascript jQueryベースの、HTMLにスライダーやスライドショーを表示させるプラグイン。

自分もサイトを作る時にたまに使っているので導入方法をメモしておきます。

ダウンロード

slick - the last carousel you'll ever need
slick is a responsive carousel jQuery plugin that supports multiple breakpoints, CSS3 transitions, touch events/swiping ...

このページにたくさんのスライダーサンプルがあります。

get it nowをクリックすると下のほうにスクロールしてダウンロードボタンを押す。

slick.min.jp,slick.cssを保存

slickフォルダの中にslick.min.jp,slick.cssを入れて自作プラグインに保存しました。

他に↓ファイルがたくさんありますが、特に使わない場合は必要ないので、使うスライダーに合わせてファイルを移動しましょう。

WordPressを使う場合

自作プラグインなどののトップファイルに以下を入れる。

	wp_enqueue_style( 'style-slick', plugins_url('slick/slick.css', __FILE__),false);
	wp_enqueue_script('slickjs', plugins_url('slick/slick.min.js', __FILE__),false );

javascript

Slickはいろいろとできますが、基本的なのは↓以下のようにスライドするだけのスクリプトを使っています。

window.onload = function(){
	jQuery(function() {
		jQuery("#news-loading").fadeOut();
		jQuery("#news-body").fadeIn();
	});
}
jQuery(function() {
	var news = jQuery('.news-slick').slick({
		arrows: false,
		dots: true,
		autoplay: true,
		speed: 400,
		autoplaySpeed: 12000,
		pauseOnHover: true,
		pauseOnDotsHover: true,
	});
});

【おまけ】MySQL ダンプを文字コードlatin1で保存してしまったのをUTF-8にする

2002年頃に運用していたサイトのMySQLデータベースをドジって文字コードをlatin1で保存してしまってEUC-JPで運用していたので文字化け、10年以上放置していましたが、読めるようにして再びphpMyAdminiでインポートしてみました。

以下のPythonスクリプトで文字化け治りました。

# coding: utf-8
import re

def convert_encoding(data, encodings=['utf-8', 'euc_jp', 'shift_jis', 'iso2022_jp']):
    corrected_data = ""
    for item in data:
        # 文字化けが疑われる文字列を特定
        if re.search(r'[^\x00-\x7F]', item):
            corrected_item = None
            for encoding in encodings:
                try:
                    # 各エンコーディングでデコードを試みる
                    corrected_item = item.encode('latin1').decode(encoding)
                    break
                except UnicodeDecodeError:
                    continue
            corrected_item = corrected_item if corrected_item is not None else item
        else:
            corrected_item = item
        corrected_data += corrected_item
    return corrected_data

# 文字化けしているデータが含まれるファイルを読み込む
with open('mysql_old.dump', 'r', encoding='utf-8') as f:
    garbled_data = f.read()

# 文字化けを解消
corrected_data = convert_encoding(garbled_data)

# ファイルに保存
with open('mysql_enco.txt', 'w', encoding='utf-8') as f:
    f.write(corrected_data)

ただ、完璧ではなくところどころカンマが多くなってしまったり一部文字化け解消できていないところがあって、そのあたりは手動で修正した。

サイトをローカルでテストするためのメモでした。

また小技などありましたら追記しておきます。

コメント