Strasznie dużo czasu zmarnowałem usiłując zmienić kodowanie w bazie MySQL na UTF i dopasować skrypty Perla do tej zmiany.
Przestawienie MySQLa na UTF-8 jest proste:
mysql -u www -p --default-character-set=utf8 CREATE database kpma CHARACTER SET utf8 COLLATE utf8_bin;
Baza kpma
(użytkownika www
) będzie
kodowana w UTF-8. Można też określić domyślne kodowanie
wszystkich baz
w pliku konfiguracji MySQLa, tj. w pliku /etc/mysql/my.cnf
(Debian):
[mysqld] ... default-character-set = utf8
Trochę diagnostyki:
use kpma; show variables like 'char%'; show table status; select tytul from Utwor; ## jest OK -- na konsoli widać poprawne różne znaki diakrytyczne
Prawdziwa męka to było zmuszenie Perla do poprawnego traktowania danych UTF.
Trzy kluczowe dla poprawnego przetwarzania UTF sprawy to:
1) klauzula binmod
(patrz poniżej);
2) klauzula use utf8
(jeżeli skrypt zawiera napisy kodowane w UTF);
3) wpisy mysql_enable_utf8
/SET NAMES utf8
dotyczące MySQLa.
Szkielet skryptu Perla wygląda następująco:
#!/usr/bin/perl -w # -*- coding: utf-8 -*- -- # use strict; use utf8; ## skrypt zawiera napisy kodowane UTF use CGI qw(:standard); use DBI; binmode(STDOUT, ":utf8"); ## bez tego problemy z UTF my $dbname = 'kpma'; ## Nazwa bazy my $dbuser = 'www'; ## Nazwa użytkownika MySQL my $dbpasswd = '??????'; ## Hasło dla $dbuser my $dsn = "dbi:mysql:$dbname:localhost:3306"; my $dbh = DBI->connect($dsn, "$dbuser", "$dbpasswd", { ChopBlanks => 1 }); $dbh->{'mysql_enable_utf8'} = 1; $dbh->do('SET NAMES utf8'); my $SQL = "SELECT tytul FROM Utwor WHERE id_kompozytor1 = 59 ORDER BY rok "; ##my $SQL = "SELECT nazwisko FROM Kompozytor "; my $sth = $dbh->prepare($SQL); $sth ->execute(); while ( my @piece = $sth->fetchrow_array() ) { print ">> @piece\n"; } $dbh->disconnect || warn "Nie mogę zamknąć bazy $dbname\n";
Jeżeli skrypt korzysta (pobiera dane)
z param()
to koniecznie należy
zastosować funkcję decode_utf8
:
use Encode; ## param() trzeba dekodować if (param()) {# -- Wypełniono formularz -- ## http://ahinea.com/en/tech/perl-unicode-struggle.html my $who = Encode::decode_utf8(param("kto"));
Działa nawet z dość starym Perlem:
$perl --version This is perl, v5.10.0 built for arm-linux-gnueabi-thread-multi Copyright 1987-2007, Larry Wall
Ponieważ główny system plików powinien być jak najmniejszy, z uwagi
na szczupłość miejsca w pamięci FLASH przenoszę na kartę SD bazy mysql
oraz główny katalog dokumentów Apacza.
Procedura nie jest skomplikowana (por. How to change the MySQL data default directory):
service mysql stop cp -R -p /var/lib/mysql /media/sd/data/ ## zmiana pliku konfiguracyjnego: vim /etc/mysql/my.cnf
W pliku zmieniam:
#datadir = /var/lib/mysql datadir = /media/sd/data/mysql
Piszą, że trzeba dokonfigurować apparmor
(niepotrzebne, bo w wersji Ubuntu na Sheevaplug, nie ma
działającego apparmora
,
co można sprawdzić wpisując np. service apparmor restart
):
## u mnie apparmor nie działa ale plik jest: vim /etc/apparmor.d/usr.sbin.mysqld
Gdyby wszakże ktoś uruchomił apparmor
, to należy zmienić var/lib/
na
/media/sd/data
. Podobne zmiany należy zaaplikować do zawartości pliku
/etc/apparmor.d/abstractions/mysql
Zrestartować mysql
.
Teraz dla sprawdzenia, że wsio działa
uruchomiłem mysql
:
mysql -u root -p
dodałem użytkownika tomek
:
-- tomek ma status superużytkownika -- CREATE USER 'tomek'@'localhost' IDENTIFIED BY 'hasło'; GRANT ALL ON *.* TO 'tomek'@'localhost'; FLUSH PRIVILEGES;
Załadowałem przykładową bazę:
mysql -u <user> -p < r-sklep.sql
Działa...
Domyślnym katalogiem dla dokumentów WWW serwera Apache
w Ubuntu jest /var/www/
. Zaczynam od skopiowania
tego katalogu w inne miejsce:
cp -R -p /var/www /media/sd/data/
Kopiuję także stosowny plik konfiguracyjny:
cp /etc/apache2/sites-available/default /etc/apache2/sites-available/jupiter
Teraz trzeba zmienić plik jupiter
:
vim /etc/apache2/sites-available/jupiter
Należy zmienić (w dwóch miejscach)
/var/www/
na /media/sd/data/wwww/
.
Teraz należy zmodyfikować ustawienia systemowe uruchamiając:
a2dissite default a2ensite jupiter ## restart serwera service apache2 restart
Działa...