CGIをPerlで書いて、MariaDBからデータを抽出して、HTML出力した場合、なぜか文字化けします。
CGIファイルは、UTF-8です。
MariaDBに対して、「show variables like 'char%'」を打つと、下のようになります。
character_set_client : utf8mb4
character_set_connection : utf8mb4
character_set_database : utf8mb4
character_set_filesystem : binary
character_set_results : utf8mb4
character_set_server : utf8mb4
character_set_system : utf8
character_sets_dir : /usr/share/mysql/charsets/
character_set_filesystem 以外、utf8の方がよさそうですが、インターネットのサーバー上にあるため、my.iniファイルが変更する方法がわかりません。
クライアント側の環境:Windows11
サーバー側の環境: Linux
サーバの種類 : MariaDB
サーバのバージョン: 10.5.13-MariaDB-log - MariaDB Server
プロトコル バージョン : 10
ウェブサーバ : Apache
データベースクライアントのバージョン: libmysql - 10.1.48-MariaDB
CGIはHTMLファイルのテンプレートを読み込んで、データを埋め込む形にしています。
エラーとしては、「[sample.cgi:206:warn] Wide character in print at sample.cgi line 206.」とWeb上で表示されています。
206行目は、HTMLタグにデータを埋め込んだ変数をprintしています。
なお、DBのデータだけでなく、data.plファイルをrequireしてsample.cgiの変数に格納してHTML出力していますが、こちらの文字列も文字化けしています。data.plファイルも、UTF-8です。
plファイルの中身は、設定ファイルになっており、web siteの名前とか、site管理者の名前などがハッシュに格納されています。
大体が、「ãÂÂãÂÂã°」という感じで表示されています。
+------+------------+----+----+-------+----------------+
|Field -|Type -------|Null| Key|Default| Extra |
+------+------------+----+----+-------+----------------+
|id |int(6): | NO | PRI| NULL | auto_increment|
+------+------------+----+----+-------+----------------+
|t_bi |datetime | NO | | NULL | |
+------+------------+----+----+-------+----------------+
|ca_no |int(2) | NO | | NULL | |
+------+------------+----+----+-------+----------------+
|title |varchar(400)| NO | | NULL | |
+------+------------+----+----+-------+----------------+
|kizi |text | NO | | NULL | |
+------+------------+----+----+-------+----------------+
|k_bi |datetime |YES | | NULL | |
+------+------------+----+----+-------+----------------+
|iine |int(10) | NO | | 0 | |
+------+------------+----+----+-------+----------------+
|user |varchar(100)| NO | | NULL | |
+------+------------+----+----+-------+----------------+
perl
1use strict; 2use DBI; 3 4require 'data.pl'; 5require 'db.pl'; 6my %out = &out_set; 7my %in = &parse_deco; 8 9my $data_source = $out{"data_source"}; 10my $username = $out{"username"}; 11my $password = $out{"password"}; 12my $user_nm = $in{"user_name"}; 13my $categpry = 1; 14 15# DB接続 16my $dbh = DBI->connect($data_source, $username, $password,{mysql_enable_utf8 => 1}) or die $DBI::errstr; 17 18my $sth = $dbh->prepare(qq{ 19 SELECT * FROM blog WHERE user = '$user_nm' AND ca_no = '$categpry' ORDER BY id DESC LIMIT 1 20}); 21 22$sth->execute; 23my %row; 24my $i = 0; 25while (my $ary_ref = $sth->fetchrow_arrayref){ 26 ($row{"id_$i"},$row{"t_bi_$i"},$row{"ca_no_$i"},$row{"title_$i"},$row{"kizi_$i"},$row{"k_bi_$i"},$row{"iine_$i"},$row{"user_$i"}) = @$ary_ref; 27 $i++; 28} 29$sth->finish; 30 31my $sth2 = $dbh->prepare(qq{ 32 SELECT t_bi FROM blog WHERE user = '$user_nm' AND ca_no = '$categpry' 33}); 34$sth2->execute; 35 36my @tourokubi = (); 37my $t = 0; 38while (my $ary_ref = $sth2->fetchrow_arrayref){ 39 ($tourokubi[$t]) = @$ary_ref; 40 $t++; 41} 42$sth2->finish; 43 44my $sth3; 45my ($yaer,$month); 46my %month; 47foreach(@tourokubi){ 48 $_ =~ /(\d\d\d\d)-(\d\d)-(\d\d)/; 49 $yaer = $1; 50 $month = $2; 51 $sth3 = $dbh->prepare(qq{ 52 SELECT COUNT(*) FROM blog WHERE user = '$user_nm' AND ca_no = '$categpry' AND t_bi LIKE '%$yaer-$month%' 53 }); 54 $sth3->execute; 55 while (my $ary_ref = $sth3->fetchrow_arrayref){ 56 ($month{"$yaer-$month"}) = @$ary_ref; 57 $t++; 58 } 59 $sth3->finish; 60 $sth3 = ""; 61} 62 63 64 65 66# DB切断 67$dbh->disconnect; 68 69# HTML表示 70 71 print <<"TAG"; 72Content-type:text/html 73 74<html> 75<head> 76 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 77 <title>DB test</title> 78</head> 79<body> 80TAG 81 82my $key; 83foreach $key( keys %row){ 84 print qq|$key = $row{"$key"}<br>\n|; 85} 86 87my $key2; 88my $yyyymm; 89foreach $key2( sort keys %month){ 90 $yyyymm = $key2; 91 $yyyymm =~ s/(\d\d\d\d)-(\d\d)/$1年$2月/; 92 print "$yyyymm($month{$key2})<br>\n"; # count 93} 94 95 96 97 print <<"TAG2"; 98</body> 99</html> 100TAG2 101 102exit;

回答2件
あなたの回答
tips
プレビュー