PHP5.4.30 + MySQL5.6.19で文字化けに対応。

ちなみに、PHPからは以下のようにつないでいます。

// PDO接続(PHP 5.3.6以降だとcharsetが使えます
$dsn="mysql:dbname=%s;host=%s;charset=utf8";

文字化けする環境と、/etc/my.cnfに対応したもの

$ cat /etc/redhat-release
CentOS release 6.5 (Final)

$ mysql --version
mysql  Ver 14.14 Distrib 5.6.19, for Linux (x86_64) using  EditLine wrapper

$ php -v
PHP 5.4.30 (cli) (built: Jun 25 2014 15:27:51)

$ yum list installed | grep mysql
mysql-community-client.x86_64        5.6.19-2.el6    @mysql56-community
mysql-community-common.x86_64        5.6.19-2.el6    @mysql56-community
mysql-community-devel.x86_64         5.6.19-2.el6    @mysql56-community
mysql-community-libs.x86_64          5.6.19-2.el6    @mysql56-community
mysql-community-server.x86_64        5.6.19-2.el6    @mysql56-community

$ find / -name libmysql*
/usr/lib64/mysql/libmysqlclient_r.so.18.1.0
/usr/lib64/mysql/libmysqlclient_r.a
/usr/lib64/mysql/libmysqlclient_r.so
/usr/lib64/mysql/libmysqlclient.so.18
/usr/lib64/mysql/libmysqlclient.a
/usr/lib64/mysql/libmysqlclient_r.so.18
/usr/lib64/mysql/libmysqlservices.a
/usr/lib64/mysql/libmysqlclient.so
/usr/lib64/mysql/libmysqlclient.so.18.1.0

$ php -r "phpinfo();" | grep "PDO"
PDO
PDO support => enabled
PDO drivers => mysql, sqlite
PDO Driver for MySQL, client library version => 5.6.19
PDO Driver for SQLite 3.x => enabled

こっちでは

# /etc/my.cnfの文字コード
character-set-server=utf8
skip-character-set-client-handshake #超だいじ

普通に文字化けしない環境の設定情報

$ cat /etc/redhat-release
CentOS release 6.5 (Final)

$ mysql --version
mysql Ver 14.14 Distrib 5.6.12, for Linux (x86_64) using EditLine wrapper

$ php -v
PHP 5.4.29 (cli) (built: Jun 5 2014 16:07:48)

$ yum list installed | grep mysql
mysql-libs.x86_64 5.5.32-1.el6.remi @remi
php-mysql.x86_64 5.4.29-3.el6.remi @remi

$ find / -name libmysql*
/usr/lib64/libmysqlclient_r.so.12
/usr/lib64/libmysqlclient_r.so.18.0.0
/usr/lib64/mysql/libmysqlclient_r.a
/usr/lib64/mysql/libmysqlservices.a
/usr/lib64/mysql/libmysqlclient.so.18
/usr/lib64/mysql/libmysqlclient.a
/usr/lib64/mysql/libmysqlclient.so.18.0.0
/usr/lib64/libmysqlclient.so.16
/usr/lib64/libmysqlclient.so
/usr/lib64/libmysqlclient.so.15.0.0
/usr/lib64/libmysqlclient_r.so.15
/usr/lib64/libmysqlclient_r.so.14
/usr/lib64/libmysqlclient_r.so.14.0.0
/usr/lib64/libmysqlclient_r.so.16.0.0
/usr/lib64/libmysqlclient.so.15
/usr/lib64/libmysqlclient_r.so.18
/usr/lib64/libmysqlclient_r.so
/usr/lib64/libmysqlclient.so.16.0.0
/usr/lib64/libmysqlclient_r.so.16
/usr/lib64/libmysqlclient.so.14.0.0
/usr/lib64/libmysqlclient.so.18
/usr/lib64/libmysqlclient_r.so.15.0.0
/usr/lib64/libmysqlclient.so.14
/usr/lib64/libmysqlclient.so.12.0.0
/usr/lib64/libmysqlclient.so.18.0.0
/usr/lib64/libmysqlclient_r.so.12.0.0
/usr/lib64/libmysqlclient.so.12

$ php -r "phpinfo();" | grep "PDO"
PDO
PDO support => enabled
PDO drivers => mysql, sqlite
PDO Driver for MySQL => enabled
PDO Driver for SQLite 3.x => enabled

PDO Driver for MySQL => enabled…? でも動いているんですよねー…。 ↓ ↓ ↓

# /etc/my.cnfの文字コード
character-set-server = utf8

ちなみに、両方ともMySQL Workbenchやコマンドラインから見るとこうなんだけど
mysql> show variables like "%character%";
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
文字化けするほうをPHP通して出力すると以下のようになってました。
character_set_client | <strong>latin1</strong>
character_set_connection | <strong>latin1</strong>
character_set_database | utf8
character_set_filesystem | binary
character_set_results | <strong>latin1</strong>
character_set_server | utf8
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

//化けた文字をmb_detect_encodingしたもの
index.php#37string(8) "SJIS-win"

インストールしたときにシステムのタイムゾーンUTCだったのとかが関係あるのだろうか。
(途中から/usr/share/zoneinfo/Japanや、/usr/share/zoneinfo/Asia/Tokyoに変更したりした)

やれやれだぜ。

windows8.1にvagrantでCentOS6.4+php4+mysql4を作った

目的

Windows8.1(あえて64bitと明記)でvagrantでテストサーバを立てる。
都合上、php4/mysql4/apache2で構成。

用意するもの

vagrant 1.3.5(最新)
VirtualBox 4.2
現在4.3が最新ですが、Windows系64bitではVirtualBox Host-Only Ethernet Adapterがインストールできず積みます。(積みました)
ソースはここ→ https://github.com/mitchellh/vagrant/issues/2392
お好みのboxファイル
今回は http://www.vagrantbox.es から CentOS 6.4のminimalなものを探して、
https://github.com/2creatives/vagrant-centos/releases/tag/v0.1.0 構成のものを拝借。
Windows Powershell
これはお好み。コピペとサイズ変更が可能なDOS窓がほしかったんや。

やること

VirtualBoxをインストール

ダブルクリックのみ

vagrantをインストール

ダブルクリックしてインストール→再起動後、vagrant upまで。

> vagrant add box CentOS6_4 https://github.com/2creatives/vagrant-centos/releases/download/v0.1.0/centos64-x86_64-20131030.box

> mkdir CentOS6_4_php4_mysql4
> vagrant init

CentOS6_4_php4_mysql4/Vagrantfileを開いて

#書き換え
config.vm.box = &quot;base&quot;

↓ ↓

config.vm.box = &quot;CentOS_6_4&quot;

#以下は追記

config.vm.boot_timeout=60

保存したら

> vagrant up

結構待つ。

起動したら、以下の作業はすべてbox内。

> vagrant ssh

httpdほかインストール

sudo基本なので省略。

$ yum -y install httpd-devel bzip2-devel openssl-devel libjpeg-devel libpng-devel gmp-devel ncurses-devel flex gcc make

mysql4のインストール

sudo基本なので省略。

#php5用のmysql-libsが入っていて邪魔なので削除
$ yum remove mysql-libs

#perl-DBIがなくてインストールできないので先に入れる
$ yum install perl-DBI

#mysql4を入れる(チョイスはなんとなく)
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-server-4.0.24-0.x86_64.rpm
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-client-4.0.24-0.x86_64.rpm
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-devel-4.0.24-0.x86_64.rpm
$ wget ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-share-4.0.24-0.x86_64.rpm

#順番に実行する
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-server-4.0.24-0.x86_64.rpm
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-client-4.0.24-0.x86_64.rpm
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-devel-4.0.24-0.x86_64.rpm
$ rpm -ivh ftp://ftp.pbone.net/mirror/mirror.cheetaweb.com/MySQL/4.0/MySQL-share-4.0.24-0.x86_64.rpm

順番に実行する。

すんなり入る。

設定ファイルはfindして、所定の位置にコピーする

$ sudo find / -name &quot;*my*cnf&quot;
$ sudo cp /usr/share/mysql/my-medium.cnf /etc/my.cnf

文字コードの設定など。

php4のインストール

sudo基本なの(ry

configure直前まではこちらのサイト通り。

CentOS6でphp4とphp5を共存させる
(openssl.soの流れも行う)

configreオプションは

$ ./configure
 --prefix=/usr/local/php4
 --with-apxs2=/usr/sbin/apxs
 --with-mysql
 --with-gd
 --with-jpeg-dir=/usr
 --with-png-dir=/usr
 --with-zlib
 --with-bz2
 --with-openssl
 --with-gettext
 --with-gmp
 --with-iconv
 --with-ncurses
 --enable-exif
 --enable-gd-native-ttf
 --enable-memory-limit
 --enable-mbstring
 --enable-mbstr-enc-trans
 --enable-bcmath
 --enable-trans-sid
 --enable-sysvsem
 --enable-sysvshm

–enable-mbregex(これが原因でmakeコケる、たぶん使わない)と–with-sqlite(今回は使わない)を削除した。

※なお、makeまで進んでコケたときは、configre再実行前に

$ make distclean

する。

$ make

$ make install

ここから先も、前述のサイトの通りhttpd.confの書き換え、AddHandlerも行う。

php.iniの設定も忘れずに。

そのあとは

vagrant sshを抜けて、CentOS6_4_php4_mysql4/Vagrantfileを開いて

#行頭の#をとる
config.vm.network :private_network, ip: "192.168.33.10"

保存したらコンソールに戻って

> vagrant reload

httpd、mysqlの起動設定とかもろもろやって、動作確認が取れたら

> vagrant package

で、もう二度とこの面倒くさいことをせずとも、同じ環境がpackage.boxから復帰できるようになります。

めでたしめでたし。

余談

phpからmysqlに接続するときに/tmp/mysql.sock関連のエラーが出たら、mysql起動しているかどうか確認して、起きているならmy.cnfの

socket = /var/lib/mysql/mysql.sock
socket = /tmp/mysql.sock

とする。

「Client does not support authentication protocol」エラーが出たら、
こちらを参考に http://d.hatena.ne.jp/psquare/20061207/p1 なんか腑に落ちないけどテスト環境だからまあいいかな処理を施す。

ffmpegで動画を切り分けるときのSQL(駄)

MySQLで

select abs(TIME_TO_SEC(timediff('00:00:00', @time1:='00:13:03')));

とやると時間差を秒でとれる。(マイナス値になるので、absで絶対値になおしている)

というわけで

SET @comPrefix:='ffmpeg.exe -i %1 -vcodec copy -acodec copy ';
SET @filePrefix:=' "%~n1_';
SET @fileSuffix:='.mp4"';
select
 CONCAT(@comPrefix,'-t ',
 @point:=abs(TIME_TO_SEC(timediff('00:00:00', @time:='00:13:03'))),@filePrefix,replace(@time,':','_'),@fileSuffix) as command;
select
 CONCAT(@comPrefix,'-ss ',
 @total:=@point,
 ' -t ',
 @point:=abs(TIME_TO_SEC(timediff(@time, @time:='00:29:51'))),@filePrefix,replace(@time,':','_'),@fileSuffix) as command;
select
 CONCAT(@comPrefix,'-ss ',
 @total:=(@total + @point),
 ' -t ',
 @point:=abs(TIME_TO_SEC(timediff(@time, @time:='00:45:20'))),@filePrefix,replace(@time,':','_'),@fileSuffix) as command;
select
 CONCAT(@comPrefix,'-ss ',
 @total:=(@total + @point),
 ' -t ',
 @point:=abs(TIME_TO_SEC(timediff(@time, @time:='00:57:19'))),@filePrefix,replace(@time,':','_'),@fileSuffix) as command;

キュー時間をいくつか書けば下記のような結果に。

ffmpeg.exe -i %1 -vcodec copy -acodec copy -t 783 "%~n1_00_13_03.mp4"
ffmpeg.exe -i %1 -vcodec copy -acodec copy -ss 783 -t 1008 "%~n1_00_29_51.mp4"
ffmpeg.exe -i %1 -vcodec copy -acodec copy -ss 1791 -t 929 "%~n1_00_45_20.mp4"
ffmpeg.exe -i %1 -vcodec copy -acodec copy -ss 2720 -t 719 "%~n1_00_57_19.mp4"

これやってから、-ssと-tにHH:mm:ssが使える事を知りました。
はっはっは…。

…ははっ…。

なんでJSじゃなくてSQLなのっていうツッコミはなしです。

だってそのときMySQL Workbenchが起動してたから。

load data infile で Excelで作ったCSVを読み込むとき

散々既出だと思うのだけど、普段コマンドラインからいじることも無いため、データベースのデフォルトとカラムの文字コードが合ってりゃ勝手にやってくれると思っていた…。

ExcelのCSVファイルを読み込むテンプレ

--
-- 文字コードをsjisに
--

set character_set_database='sjis';

--
-- 区切り文字「,」囲み文字「(なし)」
--

LOAD DATA INFILE "CSVファイル名" INTO TABLE テーブル名
 FIELDS TERMINATED BY ',' ENCLOSED BY '';

大量にCSVがあるときなどには、phpMyAdminからやるよりちょっぱやです。

24時間を超える日付の計算

プルダウンから時間を選ばせて、DATE型やDATETIME型に入れたいときなど。

プルダウン用テーブル time_list

timeID     timelabel
1     1900-01-00 00:00:00
2     1900-01-00 00:30:00
3     1900-01-00 01:00:00
4     1900-01-00 01:30:00
5     1900-01-00 02:00:00
(中略)
10 1900-01-01 00:00:00
11 1900-01-01 00:30:00
12 1900-01-01 01:00:00

timelabelカラムがDATETIME型なのがポイント。

で、以下のSQLを実行します。

SELECT DATE_ADD(‘2011-02-13′,interval date_format(timelabel,’%d %H:%i’) DAY_MINUTE) FROM time_list;

結果↓

2011-02-13 00:00:00
2011-02-13 00:30:00
2011-02-13 01:00:00
2011-02-13 01:30:00
2011-02-13 02:00:00
(中略)
2011-02-14 00:00:00
2011-02-14 00:30:00
2011-02-14 01:00:00