ラベル CentOS の投稿を表示しています。 すべての投稿を表示
ラベル CentOS の投稿を表示しています。 すべての投稿を表示

2024年10月28日月曜日

deprecated: str_replace(): passing null to parameter #2 ($replace) of type array|string is deprecated

大量の str_replace のエラー

CentOS もサポート終了してしまったので、数ある Linux プロジェクトの多くを Ubuntu に変更してます。
当然、CakePHP3 のような古いバージョンで構築されているプロジェクトも移植の対象になります。
とあるプロジェクトを Virtual Machine 上に構築した Ubuntu 22.04 LTE 上で動作させようとして、最初に CakePHP home を表示したら、こんなエラーがたくさん出てきまして。

PHP8.1 あたりで仕様が変わったことによる問題なんですけどね。
CakePHP のソースも変更しなきゃならないの?とビビってしまいました。

動作環境

OS:Ubuntu 22.04.01 LTE
MySQL: MariaDB 15.xxx
PHP 7.4.33
phpMyAdmin: 5.2.1
CakePHP 3.10

ということで。
CakePHP3 を動作させるための環境なので、PHP 7.4 で動かそうとしてるんだけど、Cake の homeページを開こうとするときに、PHP 8.x が動いちゃってる、という状況なんですね。

PHP の動作バージョンを変更する

この方法は、あちこちに書いてありますが、alternatives で定義しておき、バージョンを変更します。
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.3 100
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.4 110
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.0 120

sudo update-alternatives --config php
There are 3 choices for the alternative php (providing /usr/bin/php).

Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/php8.1 130 auto mode
* 1 /usr/bin/php7.4 110 manual mode
2 /usr/bin/php8.1 130 manual mode
3 /usr/bin/php8.2 82 manual mode

Press to keep the current choice[*], or type selection number:
ここで、対象となる PHP をセットしておけばいいわけです。

apache2 の mod を変更する

ちゃんとPHPを7.4に変更したのに、ブラウザで表示させたときのエラーは消えません・・・PHP8 で動いてしまいます
原因は apache2 でした。
# ll mods-enabled/php*
lrwxrwxrwx 1 root root 29 Oct 28 11:06 mods-enabled/php8.1.conf -> ../mods-available/php8.1.conf
lrwxrwxrwx 1 root root 29 Oct 28 11:06 mods-enabled/php8.1.load -> ../mods-available/php8.1.load

# a2dismod php8.1
# a2enmod php7.4
# service apache2 restart

home を開いてみると、無事エラーが消えているのを確認できます。

まとめ

「環境構築」って、なんか、しょっちゅうやってる気がします。
え?コンテナを使えって?w知ってるw

ま、こういった悩みを持ってしまう人も、少なからずいるだろうから、書き留めておきますよっと。
c.f.
https://qiita.com/murakami77/items/a9945f2a8e51ca3791de

2019年1月21日月曜日

Perl uri_unescape で文字化け

実は文字化けにはその後も苦しんでおりまして。
原因となる現象をようやく突き止めましたのでサンプルプログラムを公開しますね。

use Carp::Heavy;
use strict;
use URI::Escape;
use Encode;
use encoding 'utf-8';

my $a1 = '%E8%A9%A6%E9%A8%93';
my $b0 = '試験';
my $b1 = uri_escape_utf8($b0); #内容は '%E8%A9%A6%E9%A8%93'
print("$a1\n");
print("$b1\n");
print("1\n") if($a1 eq $b1);    #当然のごとく1が出力される

my $a2 = uri_unescape($a1);
my $b2 = uri_unescape($b1);
print("1\n") if($a2 eq $b2);    #なぜか 1 が表示されない
print("$b2\n"); #こちらは '試験'
print("$a2\n"); #文字化け
exit;


use encoding 'utf-8' を取ったり use utf8; にしたりすると他所に
大影響が出てしまうため変更できません。

これ。本当にハマりましたよ。
いったい何がどうなっているのかさっぱりわかりませんでした。

※実際には CGI 上のパラメータが文字化けしてました。

上記の謎の動作ですが
$a1= encode_utf8($a1);
を呼び出すことで期待通りの動きをすることがわかりました。

さて、本番環境に対応しようと・・・
my $cgi = new CGI();
my $a2 = $chi->param('a2');
文字化けです。
CGI の sub new で取得するuri_encode されたパラメータに対して事前に
encode_utf8を実行しなければならないのに、POSTリクエストだから標準
入力を変更する術が見つかりません。

じゃあ、ってことで呼び出し側を GET にしましたら、なんの変更も加えず
文字化けしなくなりましたよ。
Perlモジュールのバージョンの影響かと思い、さんざん調査すること3日
こういうのって、あっけなく解決するもんなんですねぇ
あー眠たい。

2018年12月30日日曜日

perl CGI HTML::Template で文字化け

Perl CGI での文字化け問題は何年も前に解決させたはずだったのですが(以前は Perl + Template の場合)
新しい CentOS (サーバに無料で入ってる Ver 6)の環境で、現在動作しているcgiを実行すると文字化けしてしまう現象に悩まされました。

ハマった手順を書いてみますね。

1)httpd.conf の変更
文字化けはこれでなおる!とネット上のあちこちに書いてあります。
# vi /etc/httpd/conf/httpd.conf

AddDefaultCharset off
または
#AddDefaultCharset off コメントアウト。


動作結果:NG
世界中でほとんど解決しているらしいのですが、うまくいきません。

2)php.ini の変更
# vi /etc/php.ini

;default_charset = "UTF-8"

default_charset = ""
に変更


動作結果:NG
そもそも php 使ってませんし。

ここでブラウザ側のレスポンスヘッダを確認してみますと utf-8 となっていました。
んー?なのに文字化け?理解できないぞ・・・

ちなみに、cgi のソースや HTML, CSS, JS, テンプレートファイルなど、すべてのファイルは UTF-8 で記述してます。(改行は LF)
なぜだろう、と、試験を実施することに。


3)簡単なHTMLを用意
[test.html]

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>テストページ</title>
    </head>
    <body>
        UTF-8で記述されたページ
    </body>
</html>


動作結果:なんと、うまく表示されます。

4)cgi だとダメなのかな?
[test.cgi]

#!/usr/bin/perl --
print "Content-Type: text/html; charset=utf-8\n\n";
print "<html><body><div>\n";
print 'クオート文字';
print '<br>';
print "ダブルクオート文字";
print '<br>';
print "<div></body></html>\n";
exit;

クオートとダブルクオートで分けたのは、 perl の動作で文字化けしているのかどうかを確認するためです。

動作結果:なんと、うまく表示されます。

5)HTML::Template が怪しい。
どうやら使用している HTML::Template が怪しいのではないかとあたりを付けて検索したら情報がありました。
HTML::Template 2.98 で UTF問題が解決してる!というのです。
移行先のサーバーの HTML::Template は Ver,2.97 です。
ちなみにうまくいっていた旧サーバーの HTML::Template は Ver,2.94 でした。

Ver 2.98 のソースはここにありました。
https://github.com/mpeters/html-template

CPAN からのインストールしかやったことないので、git からどうやってインストールするのかわからずw
ダウンロードした HTML/Template.pm, HTML/Template/FAQ.pm をそのまま perl5 のファイルに上書きw

文字化けする cgi を動作させてみました。

動作結果:NG
ここまで、大量に時間を食ったにもかかわらず、うまくいかないとは・・・

6)binmode => 'utf8' を記述
既存 cgi の new HTML::Template 構文で、binmode => 'utf8' を追加する、との記述があったので
試してみました。

動作結果:NG
この記述は、上記リンクをたどる際に対応したパッチを当てたソースの場合に有効だったもので、動かないことは予想できていました。

7)utf8 => 1 を記述
HTML/Template のドキュメントを読み、new 構文の utf8 オプションがあることを発見。(旧サーバにはないオプションでした。)

既存 cgi の new HTML::Template 構文で、utf8 => 1 オプションを追加して実行してみました。

my $tmpl = HTML::Template->new(die_on_bad_params => 0, filename => $file, utf8 => 1);

動作結果:おお!!!!ようやく文字化けせずに表示されました!

しかしながら、問題があります。
既存プログラムの cgi ファイルは山のようにあります。
その全部にフラグを追加するのは困難ですよ。
デグレードなんか発生させちゃった日にゃ目も当てられません。
なんとかならないかな・・・

8)HTML::Template を編集。
perl5 の HTML/Template.pm を開いてみると、次のような部分なありました。

my %OPTIONS;
BEGIN {
    %OPTIONS = (
        debug                       => 0,
        ;
        utf8                        => 0,
        ;

ええい、こいつを1にしてしまえ!

        utf8                        => 1,

と変更した後で、既存の cgi に戻して動作

動作結果:OK

文字化けが解消されました!!!

モジュールの挙動が変わるなんて、ほんと困りものです。