スタッフブログ

  • カテゴリ PHP の最新配信
  • RSS

PHPでファイルアップロードの上限サイズを引き上げるときに同時に変更する設定項目

Ryuji : PHP 2013/10/7 10:31

Blogger's Avatar

PHPでファイルアップロードサイズの上限値は upload_max_filesizeで設定します。 .htaccessなら下記の様な感じですね。

php_value upload_max_filesize 256M

この数値を変更したときに合わせて見直しておきたい設定項目が2つあります。

memory_limit と post_max_sizeです。

この3つの設定項目の数値はそれぞれ下記のような関係である必要があります。

memory_limit > post_max_size > upload_max_filesize

 ここ、気をつけてないと、upload_max_filesizeは増やしたけど他のサイズが小さくてファイルアップロードがうまくいかないということが発生します。

私がはまったパターンでは、post_max_sizeが小さくて大きなファイルをアップロードしようとすると、$_POSTが空っぽになってしまい、いきなり別ページに飛ばされるなんてことがありました(^^; # 最近のフロントコントローラ方式だとまずこうなりますね

PHP5.4対応とhtmlspecialchars

Ryuji : PHP 2013/10/2 10:49

Blogger's Avatar

数年前はPHP5.3対応のご相談を受けていたのですが、最近はPHP5.4対応のご相談をよく受けるようになりました。

PHP5.4対応の一番の問題として htmlspecialchars関数 の問題があります。この関数はXSS対策に良く用いられる関数なので、Webシステムで利用されないことはまずありえません。

そのhtmlspecialchars関数がPHP5.4以降、文字コードの指定がないとデフォルトで文字コード「UTF-8」だと判断して動作するようになりました。

これが問題になるのはかつてPHPプログラムで文字コード「EUC-JP」をメインに使ってた頃のプログラムです。(UTF-8以外だとダメなのでSJISとかももちろんダメですけどね)

XOOPSもかつてはEUC-JPを使うのが主流でしたので、その頃に構築したサイトはPHP5.4へ移行するとこの問題にぶちあたります。

この問題が発症すると症状として何が起きるかというと文字列の抜け落ちが発生します。XSS対策でサニタイズしている文字列なんかはまるごと抜け落ちるので、たとえば、掲示板とかで枠線とか外観は正常に表示されるのに書き込みメッセージが全く表示されないというような症状になります。

対処法としては、XOOPSなら全般設定で言語を「japanese」から「ja_utf8」へ変更することで回避できます。

他のシステムでも内部エンコードをutf-8にしてあげればほぼ回避できると思います。.htaccessで設定変更できるなら下記の様にします。

php_value mbstring.internal_encoding UTF-8

ちょっとしたプログラムであれば、これだけで問題解決することもあると思います。

# もちろんDBとの接続やファイルの読み書きがある場合は、そのやりとりの文字コード変換をあわせていく必要はありますけどね。

CentOSのPHP5.1をPHP5.2にアップグレードする方法

suin : PHP 2011/2/22 16:03

Blogger's Avatar

CentOSのPHPのデフォルトバージョンは5.1です。なので、PHP5.2にアップデートすることがよくあるので備忘録として手順をまとめておきます。

手順

とりあえずサーバを停止

sudo /etc/init.d/httpd stop
sudo /etc/init.d/mysqld stop

リポジトリを追加する。

sudo vi /etc/yum.repos.d/utterramblings.repo
[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

アップデートをかける。

sudo yum update php -y

実際はここではまりました。ハマった詳細は後述。

リポジトリをOFFにする。enabledを0に書き換えます。

sudo vi /etc/yum.repos.d/utterramblings.repo
[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=0
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

サーバを起動する。

sudo /etc/init.d/httpd start
sudo /etc/init.d/mysqld start

はまったところ

yum update phpで次のようなエラーが出てアップデートできずはまりました。

$ sudo yum update php
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * addons: ftp.yz.yamagata-u.ac.jp
 * base: ftp.yz.yamagata-u.ac.jp
 * extras: ftp.yz.yamagata-u.ac.jp
 * updates: ftp.yz.yamagata-u.ac.jp
Excluding Packages from CentOS-5 - Base
Finished
Setting up Update Process
Resolving Dependencies
--> Running transaction check
--> Processing Dependency: php = 5.1.6-27.el5_5.3 for package: php-devel
---> Package php.x86_64 0:5.2.16-jason.1 set to be updated
--> Processing Dependency: php-common = 5.2.16-jason.1 for package: php
--> Processing Dependency: php-cli = 5.2.16-jason.1 for package: php
--> Running transaction check
---> Package php-cli.x86_64 0:5.2.16-jason.1 set to be updated
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-pdo
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-ldap
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-mbstring
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-gd
--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php-mysql
---> Package php-common.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-devel.x86_64 0:5.2.16-jason.1 set to be updated
--> Running transaction check
---> Package php-gd.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-ldap.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-mbstring.x86_64 0:5.2.16-jason.1 set to be updated
---> Package php-mysql.x86_64 0:5.2.16-jason.1 set to be updated
--> Processing Dependency: libmysqlclient.so.16(libmysqlclient_16)(64bit) for package: php-mysql
--> Processing Dependency: libmysqlclient.so.16()(64bit) for package: php-mysql
---> Package php-pdo.x86_64 0:5.2.16-jason.1 set to be updated
--> Running transaction check
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: perl-DBD-MySQL
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient.so.15()(64bit) for package: libdbi-dbd-mysql
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: perl-DBD-MySQL
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient.so.15(libmysqlclient_15)(64bit) for package: libdbi-dbd-mysql
--> Processing Dependency: libmysqlclient_r.so.15()(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient_r.so.15()(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient_r.so.15()(64bit) for package: MySQL-python
--> Processing Dependency: libmysqlclient_r.so.15(libmysqlclient_15)(64bit) for package: mysql-connector-odbc
--> Processing Dependency: libmysqlclient_r.so.15(libmysqlclient_15)(64bit) for package: mysql-server
--> Processing Dependency: libmysqlclient_r.so.15(libmysqlclient_15)(64bit) for package: MySQL-python
---> Package mysql.x86_64 0:5.1.52-jason.1 set to be updated
--> Running transaction check
---> Package mysql-server.x86_64 0:5.1.52-jason.1 set to be updated
---> Package mysqlclient15.x86_64 0:5.0.91-1.jason.1 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================================================================================================
 Package                                          Arch                                      Version                                             Repository                                         Size
========================================================================================================================================================================================================
Updating:
 php                                              x86_64                                    5.2.16-jason.1                                      utterramblings                                    3.8 M
Installing for dependencies:
 mysqlclient15                                    x86_64                                    5.0.91-1.jason.1                                    utterramblings                                    2.0 M
Updating for dependencies:
 mysql                                            x86_64                                    5.1.52-jason.1                                      utterramblings                                    3.5 M
 mysql-server                                     x86_64                                    5.1.52-jason.1                                      utterramblings                                     13 M
 php-cli                                          x86_64                                    5.2.16-jason.1                                      utterramblings                                    2.6 M
 php-common                                       x86_64                                    5.2.16-jason.1                                      utterramblings                                    522 k
 php-devel                                        x86_64                                    5.2.16-jason.1                                      utterramblings                                    557 k
 php-gd                                           x86_64                                    5.2.16-jason.1                                      utterramblings                                    348 k
 php-ldap                                         x86_64                                    5.2.16-jason.1                                      utterramblings                                     63 k
 php-mbstring                                     x86_64                                    5.2.16-jason.1                                      utterramblings                                    1.4 M
 php-mysql                                        x86_64                                    5.2.16-jason.1                                      utterramblings                                    280 k
 php-pdo                                          x86_64                                    5.2.16-jason.1                                      utterramblings                                    169 k

Transaction Summary
========================================================================================================================================================================================================
Install       1 Package(s)
Upgrade      11 Package(s)

Total size: 28 M
Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test


Transaction Check Error:
  file /etc/my.cnf from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/my_print_defaults.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql_config.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql_find_rows.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysql_waitpid.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqlaccess.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqladmin.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqldump.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/man/man1/mysqlshow.1.gz from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/charsets/Index.xml from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/charsets/cp1250.xml from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/czech/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/danish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/dutch/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/english/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/estonian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/french/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/german/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/greek/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/hungarian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/italian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/japanese/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/korean/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/norwegian-ny/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/norwegian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/polish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/portuguese/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/romanian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/russian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/serbian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/slovak/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/spanish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/swedish/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386
  file /usr/share/mysql/ukrainian/errmsg.sys from install of mysql-5.1.52-jason.1.x86_64 conflicts with file from package mysql-5.0.77-4.el5_5.4.i386

Error Summary
-------------

どうやらこれは、mysql.x86_64とmysql.i386がコンフリクトしているとのことのようです。 mysql.i386を使ってない場合、yum removeしていいとのことでした。

mysqlのどもパッケージは入っているか確認します。

$ yum list installed | grep mysql
libdbi-dbd-mysql.x86_64                   0.8.1a-1.2.2                 installed
mysql.i386                                5.0.77-4.el5_5.4             installed
mysql.x86_64                              5.0.77-4.el5_5.4             installed
mysql-connector-odbc.x86_64               3.51.26r1127-1.el5           installed
mysql-server.x86_64                       5.0.77-4.el5_5.4             installed
php-mysql.x86_64                          5.1.6-27.el5_5.3             installed

.i386なのはmysql.i386だけでした。次に、yum remove(アンインストール)するまえに本当に、使ってないか確認します。

$ mysql --version
mysql  Ver 14.14 Distrib 5.1.52, for redhat-linux-gnu (x86_64) using readline 5.1

i386は使われていなく、x86_64が使われていることが分かりましたので、yum removeします。

$ sudo yum remove mysql.i386
Loaded plugins: fastestmirror
Setting up Remove Process
Resolving Dependencies
--> Running transaction check
---> Package mysql.i386 0:5.0.77-4.el5_5.4 set to be erased
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================================================================================================
 Package                                     Arch                                       Version                                                   Repository                                       Size
========================================================================================================================================================================================================
Removing:
 mysql                                       i386                                       5.0.77-4.el5_5.4                                          installed                                       7.9 M

Transaction Summary
========================================================================================================================================================================================================
Remove        1 Package(s)
Reinstall     0 Package(s)
Downgrade     0 Package(s)

Is this ok [y/N]: y
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Erasing        : mysql                                                                                                                                                                            1/1 

Removed:
  mysql.i386 0:5.0.77-4.el5_5.4    

アンインストールされたようです。

一応、yum list installedでremoveされたか確認します。

$ yum list installed | grep mysql
libdbi-dbd-mysql.x86_64                   0.8.1a-1.2.2                 installed
mysql.i386                                5.0.77-4.el5_5.4             installed
mysql.x86_64                              5.0.77-4.el5_5.4             installed
mysql-connector-odbc.x86_64               3.51.26r1127-1.el5           installed
mysql-server.x86_64                       5.0.77-4.el5_5.4             installed
php-mysql.x86_64                          5.1.6-27.el5_5.3             installed

この後、再度 yum update phpをしたらうまくPHPがアップデートされました。

CentOSにSSH2を入れてみた

suin : PHP 2010/10/4 17:22

Blogger's Avatar

PHPにはSSH2の関数が用意されています。ここでは、CentOSにSSH2を入れる手順を書いておきます。試行錯誤込みで書いてますので、手っ取り早くうまく言ったコマンドだけ知りたい人はこのセクションの最後に飛んでください。

SSH2はPECLの拡張モジュールなので、下記のコマンドを実行すればいいとのこと。

pecl install ssh2-beta

実行してみた。

bash: pecl: command not found

...(-_-;;;

PECLが入ってなかったとは。PECLを入れるために下記のコマンドを実行しました。

yum -y install php-pear

すると、こんどは、Missing Dependencyのエラーが。なんという失敗続き;;

php-devel-5.1.6-27.el5.x86_64 from base has depsolving problems
  --> Missing Dependency: php = 5.1.6-27.el5 is needed by package php-devel-5.1.6-27.el5.x86_64 (base)
Error: Missing Dependency: php = 5.1.6-27.el5 is needed by package php-devel-5.1.6-27.el5.x86_64 (base)
 You could try using --skip-broken to work around the problem
 You could try running: package-cleanup --problems
                        package-cleanup --dupes
                        rpm -Va --nofiles --nodigest
The program package-cleanup is found in the yum-utils package.

稼働中のPHPのバージョンが5.2.14だったので、そのPHPをとってきたリポジトリからyumしました。

yum install --enablerepo=utterramblings php-pear

which peclとコマンドをたたいて、peclが入っているのを確認。

libssh2が必要らしいので、こちらもyumで取ってきます。

yum -y install libssh2
yum -y install libssh2-devel

peclからssh2を入れます。コマンドは、pecl install ssh2を実行。すぐに怒られました。

Failed to download pecl/ssh2 within preferred state "stable", latest release is version 0.11.0, stability "beta", use "channel://pecl.php.net/ssh2-0.11.0" to install
install failed

仕方がないので、下記のコマンドを実行。

 pecl install channel://pecl.php.net/ssh2-0.11.0

ssh2のインストール中にlibssh2の場所を聞かれます。私の場合、/usrではなかったのでパスを指定しました。

libssh2 prefix? [/usr] : /usr/lib64

しかし、これではうまくいかずエラーが出てしまいました。今日は怒られてばかりです(笑)

ERROR: `/tmp/pear/download/ssh2-0.11.0/configure --with-ssh2=/usr/lib' failed

ググったらlibssh2-develも入れないといけないとわかったので、以下のコマンドを実行します。

 yum install libssh2-devel

その後、再度peclコマンドでssh2をインストールします。今度こそうまくいったようなので、php.iniを編集します。

cd /etc/php.d/
 # php.iniを設定しますが、私の環境では.iniを分割していたので、適当にzip.iniをコピーして編集しました。
cp zip.ini ssh2.ini
vim ssh2.in

extension=ssh2.soに書き換えて保存します。あとは、Apacheを再起動して終わりです。

/etc/init.d/httpd restart

結局うまくいったコマンド

# yum install --enablerepo=utterramblings php-pear
 
# yum -y install libssh2
# yum install libssh2-devel
 
# pecl install channel://pecl.php.net/ssh2-0.11.0
 
# cd /etc/php.d/
 ## php.iniを設定しますが、私の環境では.iniを分割していたので、適当にzip.iniをコピーして編集しました。
# cp zip.ini ssh2.ini
# vim ssh2.ini

 	extension=ssh2.soと書き込み

# /etc/init.d/httpd restart

[PHPでサマータイム第2弾] タイムゾーンの識別子を取得してきてセレクトを作ろう

suin : PHP 2010/9/30 22:56

Blogger's Avatar

ユーザがサマータイムかどうか、そしてサマータイムのオフセットをいくつか、といったデータはユーザがどこに住んでいるか分かっている必要があります。PHP5.2では、タイムゾーンとサマータイムを考慮した、タイムゾーン識別子をいくつも用意してくれています。識別子一覧の取得方法は前回のブログで書きました。識別子の大部分は、地域/都市名という書式になっています。

サマータイムを反映するには、内部的にユーザデータとタイムゾーン識別子を紐付けておく必要があるでしょう。そのため、こうしたシステムでユーザに識別子を選んでもらうインターフェイスが必要になります。今回は、タイムゾーン識別子一覧からセレクトボックスを作る方法を説明しようと思います。

前回の記事に引き続き、PHPのDateTimeZoneクラスを継承したRyus_DateTimeZoneクラスを使って、実装してみようと思います。今回、新しく、Ryus_DateTimeZoneに以下のメソッドを追加しました。識別子は、地域・国都市の順にスラッシュで区切られています。このメソッドは、地域と国都市に分解して、多次元配列にして返すものです。PHP5で非推奨になった修飾子とUTCは除外されます。

	public static function getIdentifiersAsArray()
	{
		$identifiers = self::listIdentifiers();

		$result = array();

		foreach ( $identifiers as $identifier )
		{
			if ( $identifier === 'UTC' )
			{
				continue;
			}

			$parts = explode('/', $identifier);
			$area = $parts[0];
			$city1 = $parts[1];

			if ( isset($parts[2]) )
			{
				$city2 = $parts[2];
				$result[$area][$city1.' > '.$city2] = $identifier;
			}
			else
			{
				$result[$area][$city1] = $identifier;
			}
		}

		return $result;
	}

そして、下が上のメソッドを使ったセレクトボックスの生成方法です。地域ごとにoptgroupタグでくくったものが生成されます。

<?php 
require 'Ryus_DateTimeZone.php';
$ret = Ryus_DateTimeZone::getIdentifiersAsArray();
?>
<select name="timezone">
<option value="">--------</option>
<? foreach ( $ret as $area => $cities ) :?>
<optgroup label="<? echo $area ?>">
	<? foreach ( $cities as $city => $identifier ) : ?>
	<option value="<? echo $identifier ?>"><? echo $city ?></option>
	<? endforeach ?>
</optgroup>
<? endforeach ?>
</select>

このリストを生成してみるとわかりますが、optgroupで地域別にくくったと言っても選択肢が多すぎて、決してユーザフレンドリーなインターフェイスとは言えないものになります。どのようにしたら、もうすこし使いやすいセレクトになるか考える必要がありそうです。次回につづく...

今回作成したサンプルのダウンロード:

sample02.zip

[PHPでサマータイム第1弾] PHP5.2で美しくタイムゾーン一覧を取得する

suin : PHP 2010/9/1 18:09

Blogger's Avatar

PHPでは、DateTimeZoneクラスのlistIdentifiers()メソッドでタイムゾーンの一覧が取得できます。しかし、その中には、非推奨になっているタイムゾーンが含まれています。「サポートされるタイムゾーンのリスト:その他」では、以下のような説明がなされています。

警告

ここに挙げられているタイムゾーン (UTC 以外のもの) は使用しないでください。 これらは過去のバージョンとの互換性のためにのみ残されています。

そこで、非推奨になっているタイムゾーンを取り除いた、タイムゾーン一覧をする関数があったほうが便利です。DateTimeZoneクラスを継承したクラスを作り、listIdentifiers()メソッドをオーバライドして、非推奨のタイムゾーンを取り除くようにしてみました。

そうして作ったクラスがRyus_DateTimeZoneです。Ryus_DateTimeZoneとDateTimeZoneのlistIdentifiers()メソッドを比較してみました。

<?php

require 'Ryus_DateTimeZone.php';


$identifiers     = DateTimeZone::listIdentifiers();
$ryusIdentifiers = Ryus_DateTimeZone::listIdentifiers();

?>
<table>
<tr>
<td><pre>
<?php echo implode('<br />', $identifiers) ?>
</pre>
</td>
<td>
<pre>
<?php echo implode('<br />', $ryusIdentifiers) ?>
</pre>
</td>
</tr>
</table>

すると、結果は以下のようになります。Ryus_DateTimeZoneは、不要なタイムゾーンが削られて厳選された一覧が出ているのがわかります。

DateTimeZone::listIdentifiers() Ryus_DateTimeZone::listIdentifiers()
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Ceuta
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/Douala
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Timbuktu
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
America/Argentina/Catamarca
America/Argentina/ComodRivadavia
America/Argentina/Cordoba
America/Argentina/Jujuy
America/Argentina/La_Rioja
America/Argentina/Mendoza
America/Argentina/Rio_Gallegos
America/Argentina/Salta
America/Argentina/San_Juan
America/Argentina/San_Luis
America/Argentina/Tucuman
America/Argentina/Ushuaia
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Barbados
America/Belem
America/Belize
America/Blanc-Sablon
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fort_Wayne
America/Fortaleza
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana/Indianapolis
America/Indiana/Knox
America/Indiana/Marengo
America/Indiana/Petersburg
America/Indiana/Tell_City
America/Indiana/Vevay
America/Indiana/Vincennes
America/Indiana/Winamac
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky/Louisville
America/Kentucky/Monticello
America/Knox_IN
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota/Center
America/North_Dakota/New_Salem
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Porto_Acre
America/Porto_Velho
America/Puerto_Rico
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santa_Isabel
America/Santarem
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife
Antarctica/Casey
Antarctica/Davis
Antarctica/DumontDUrville
Antarctica/Mawson
Antarctica/McMurdo
Antarctica/Palmer
Antarctica/Rothera
Antarctica/South_Pole
Antarctica/Syowa
Antarctica/Vostok
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Ashkhabad
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Colombo
Asia/Dacca
Asia/Damascus
Asia/Dhaka
Asia/Dili
Asia/Dubai
Asia/Dushanbe
Asia/Gaza
Asia/Harbin
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Hovd
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jayapura
Asia/Jerusalem
Asia/Kabul
Asia/Kamchatka
Asia/Karachi
Asia/Kashgar
Asia/Kathmandu
Asia/Katmandu
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Kuwait
Asia/Macao
Asia/Macau
Asia/Magadan
Asia/Makassar
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Oral
Asia/Phnom_Penh
Asia/Pontianak
Asia/Pyongyang
Asia/Qatar
Asia/Qyzylorda
Asia/Rangoon
Asia/Riyadh
Asia/Saigon
Asia/Sakhalin
Asia/Samarkand
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Tel_Aviv
Asia/Thimbu
Asia/Thimphu
Asia/Tokyo
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yekaterinburg
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Canary
Atlantic/Cape_Verde
Atlantic/Faeroe
Atlantic/Faroe
Atlantic/Jan_Mayen
Atlantic/Madeira
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Broken_Hill
Australia/Canberra
Australia/Currie
Australia/Darwin
Australia/Eucla
Australia/Hobart
Australia/LHI
Australia/Lindeman
Australia/Lord_Howe
Australia/Melbourne
Australia/North
Australia/NSW
Australia/Perth
Australia/Queensland
Australia/South
Australia/Sydney
Australia/Tasmania
Australia/Victoria
Australia/West
Australia/Yancowinna
Brazil/Acre
Brazil/DeNoronha
Brazil/East
Brazil/West
Canada/Atlantic
Canada/Central
Canada/East-Saskatchewan
Canada/Eastern
Canada/Mountain
Canada/Newfoundland
Canada/Pacific
Canada/Saskatchewan
Canada/Yukon
CET
Chile/Continental
Chile/EasterIsland
CST6CDT
Cuba
EET
Egypt
Eire
EST
EST5EDT
Etc/GMT
Etc/GMT+0
Etc/GMT+1
Etc/GMT+10
Etc/GMT+11
Etc/GMT+12
Etc/GMT+2
Etc/GMT+3
Etc/GMT+4
Etc/GMT+5
Etc/GMT+6
Etc/GMT+7
Etc/GMT+8
Etc/GMT+9
Etc/GMT-0
Etc/GMT-1
Etc/GMT-10
Etc/GMT-11
Etc/GMT-12
Etc/GMT-13
Etc/GMT-14
Etc/GMT-2
Etc/GMT-3
Etc/GMT-4
Etc/GMT-5
Etc/GMT-6
Etc/GMT-7
Etc/GMT-8
Etc/GMT-9
Etc/GMT0
Etc/Greenwich
Etc/UCT
Etc/Universal
Etc/UTC
Etc/Zulu
Europe/Amsterdam
Europe/Andorra
Europe/Athens
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kaliningrad
Europe/Kiev
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Mariehamn
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Nicosia
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/Samara
Europe/San_Marino
Europe/Sarajevo
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
Factory
GB
GB-Eire
GMT
GMT+0
GMT-0
GMT0
Greenwich
Hongkong
HST
Iceland
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Iran
Israel
Jamaica
Japan
Kwajalein
Libya
MET
Mexico/BajaNorte
Mexico/BajaSur
Mexico/General
MST
MST7MDT
Navajo
NZ
NZ-CHAT
Pacific/Apia
Pacific/Auckland
Pacific/Chatham
Pacific/Easter
Pacific/Efate
Pacific/Enderbury
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Galapagos
Pacific/Gambier
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Johnston
Pacific/Kiritimati
Pacific/Kosrae
Pacific/Kwajalein
Pacific/Majuro
Pacific/Marquesas
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Pago_Pago
Pacific/Palau
Pacific/Pitcairn
Pacific/Ponape
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Samoa
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Truk
Pacific/Wake
Pacific/Wallis
Pacific/Yap
Poland
Portugal
PRC
PST8PDT
ROC
ROK
Singapore
Turkey
UCT
Universal
US/Alaska
US/Aleutian
US/Arizona
US/Central
US/East-Indiana
US/Eastern
US/Hawaii
US/Indiana-Starke
US/Michigan
US/Mountain
US/Pacific
US/Pacific-New
US/Samoa
UTC
W-SU
WET
Zulu
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
Africa/Brazzaville
Africa/Bujumbura
Africa/Cairo
Africa/Casablanca
Africa/Ceuta
Africa/Conakry
Africa/Dakar
Africa/Dar_es_Salaam
Africa/Djibouti
Africa/Douala
Africa/El_Aaiun
Africa/Freetown
Africa/Gaborone
Africa/Harare
Africa/Johannesburg
Africa/Kampala
Africa/Khartoum
Africa/Kigali
Africa/Kinshasa
Africa/Lagos
Africa/Libreville
Africa/Lome
Africa/Luanda
Africa/Lubumbashi
Africa/Lusaka
Africa/Malabo
Africa/Maputo
Africa/Maseru
Africa/Mbabane
Africa/Mogadishu
Africa/Monrovia
Africa/Nairobi
Africa/Ndjamena
Africa/Niamey
Africa/Nouakchott
Africa/Ouagadougou
Africa/Porto-Novo
Africa/Sao_Tome
Africa/Timbuktu
Africa/Tripoli
Africa/Tunis
Africa/Windhoek
America/Adak
America/Anchorage
America/Anguilla
America/Antigua
America/Araguaina
America/Argentina/Buenos_Aires
America/Argentina/Catamarca
America/Argentina/ComodRivadavia
America/Argentina/Cordoba
America/Argentina/Jujuy
America/Argentina/La_Rioja
America/Argentina/Mendoza
America/Argentina/Rio_Gallegos
America/Argentina/Salta
America/Argentina/San_Juan
America/Argentina/San_Luis
America/Argentina/Tucuman
America/Argentina/Ushuaia
America/Aruba
America/Asuncion
America/Atikokan
America/Atka
America/Bahia
America/Barbados
America/Belem
America/Belize
America/Blanc-Sablon
America/Boa_Vista
America/Bogota
America/Boise
America/Buenos_Aires
America/Cambridge_Bay
America/Campo_Grande
America/Cancun
America/Caracas
America/Catamarca
America/Cayenne
America/Cayman
America/Chicago
America/Chihuahua
America/Coral_Harbour
America/Cordoba
America/Costa_Rica
America/Cuiaba
America/Curacao
America/Danmarkshavn
America/Dawson
America/Dawson_Creek
America/Denver
America/Detroit
America/Dominica
America/Edmonton
America/Eirunepe
America/El_Salvador
America/Ensenada
America/Fort_Wayne
America/Fortaleza
America/Glace_Bay
America/Godthab
America/Goose_Bay
America/Grand_Turk
America/Grenada
America/Guadeloupe
America/Guatemala
America/Guayaquil
America/Guyana
America/Halifax
America/Havana
America/Hermosillo
America/Indiana/Indianapolis
America/Indiana/Knox
America/Indiana/Marengo
America/Indiana/Petersburg
America/Indiana/Tell_City
America/Indiana/Vevay
America/Indiana/Vincennes
America/Indiana/Winamac
America/Indianapolis
America/Inuvik
America/Iqaluit
America/Jamaica
America/Jujuy
America/Juneau
America/Kentucky/Louisville
America/Kentucky/Monticello
America/Knox_IN
America/La_Paz
America/Lima
America/Los_Angeles
America/Louisville
America/Maceio
America/Managua
America/Manaus
America/Marigot
America/Martinique
America/Matamoros
America/Mazatlan
America/Mendoza
America/Menominee
America/Merida
America/Mexico_City
America/Miquelon
America/Moncton
America/Monterrey
America/Montevideo
America/Montreal
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
America/North_Dakota/Center
America/North_Dakota/New_Salem
America/Ojinaga
America/Panama
America/Pangnirtung
America/Paramaribo
America/Phoenix
America/Port-au-Prince
America/Port_of_Spain
America/Porto_Acre
America/Porto_Velho
America/Puerto_Rico
America/Rainy_River
America/Rankin_Inlet
America/Recife
America/Regina
America/Resolute
America/Rio_Branco
America/Rosario
America/Santa_Isabel
America/Santarem
America/Santiago
America/Santo_Domingo
America/Sao_Paulo
America/Scoresbysund
America/Shiprock
America/St_Barthelemy
America/St_Johns
America/St_Kitts
America/St_Lucia
America/St_Thomas
America/St_Vincent
America/Swift_Current
America/Tegucigalpa
America/Thule
America/Thunder_Bay
America/Tijuana
America/Toronto
America/Tortola
America/Vancouver
America/Virgin
America/Whitehorse
America/Winnipeg
America/Yakutat
America/Yellowknife
Antarctica/Casey
Antarctica/Davis
Antarctica/DumontDUrville
Antarctica/Mawson
Antarctica/McMurdo
Antarctica/Palmer
Antarctica/Rothera
Antarctica/South_Pole
Antarctica/Syowa
Antarctica/Vostok
Arctic/Longyearbyen
Asia/Aden
Asia/Almaty
Asia/Amman
Asia/Anadyr
Asia/Aqtau
Asia/Aqtobe
Asia/Ashgabat
Asia/Ashkhabad
Asia/Baghdad
Asia/Bahrain
Asia/Baku
Asia/Bangkok
Asia/Beirut
Asia/Bishkek
Asia/Brunei
Asia/Calcutta
Asia/Choibalsan
Asia/Chongqing
Asia/Chungking
Asia/Colombo
Asia/Dacca
Asia/Damascus
Asia/Dhaka
Asia/Dili
Asia/Dubai
Asia/Dushanbe
Asia/Gaza
Asia/Harbin
Asia/Ho_Chi_Minh
Asia/Hong_Kong
Asia/Hovd
Asia/Irkutsk
Asia/Istanbul
Asia/Jakarta
Asia/Jayapura
Asia/Jerusalem
Asia/Kabul
Asia/Kamchatka
Asia/Karachi
Asia/Kashgar
Asia/Kathmandu
Asia/Katmandu
Asia/Kolkata
Asia/Krasnoyarsk
Asia/Kuala_Lumpur
Asia/Kuching
Asia/Kuwait
Asia/Macao
Asia/Macau
Asia/Magadan
Asia/Makassar
Asia/Manila
Asia/Muscat
Asia/Nicosia
Asia/Novokuznetsk
Asia/Novosibirsk
Asia/Omsk
Asia/Oral
Asia/Phnom_Penh
Asia/Pontianak
Asia/Pyongyang
Asia/Qatar
Asia/Qyzylorda
Asia/Rangoon
Asia/Riyadh
Asia/Saigon
Asia/Sakhalin
Asia/Samarkand
Asia/Seoul
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Asia/Tashkent
Asia/Tbilisi
Asia/Tehran
Asia/Tel_Aviv
Asia/Thimbu
Asia/Thimphu
Asia/Tokyo
Asia/Ujung_Pandang
Asia/Ulaanbaatar
Asia/Ulan_Bator
Asia/Urumqi
Asia/Vientiane
Asia/Vladivostok
Asia/Yakutsk
Asia/Yekaterinburg
Asia/Yerevan
Atlantic/Azores
Atlantic/Bermuda
Atlantic/Canary
Atlantic/Cape_Verde
Atlantic/Faeroe
Atlantic/Faroe
Atlantic/Jan_Mayen
Atlantic/Madeira
Atlantic/Reykjavik
Atlantic/South_Georgia
Atlantic/St_Helena
Atlantic/Stanley
Australia/ACT
Australia/Adelaide
Australia/Brisbane
Australia/Broken_Hill
Australia/Canberra
Australia/Currie
Australia/Darwin
Australia/Eucla
Australia/Hobart
Australia/LHI
Australia/Lindeman
Australia/Lord_Howe
Australia/Melbourne
Australia/North
Australia/NSW
Australia/Perth
Australia/Queensland
Australia/South
Australia/Sydney
Australia/Tasmania
Australia/Victoria
Australia/West
Australia/Yancowinna
Europe/Amsterdam
Europe/Andorra
Europe/Athens
Europe/Belfast
Europe/Belgrade
Europe/Berlin
Europe/Bratislava
Europe/Brussels
Europe/Bucharest
Europe/Budapest
Europe/Chisinau
Europe/Copenhagen
Europe/Dublin
Europe/Gibraltar
Europe/Guernsey
Europe/Helsinki
Europe/Isle_of_Man
Europe/Istanbul
Europe/Jersey
Europe/Kaliningrad
Europe/Kiev
Europe/Lisbon
Europe/Ljubljana
Europe/London
Europe/Luxembourg
Europe/Madrid
Europe/Malta
Europe/Mariehamn
Europe/Minsk
Europe/Monaco
Europe/Moscow
Europe/Nicosia
Europe/Oslo
Europe/Paris
Europe/Podgorica
Europe/Prague
Europe/Riga
Europe/Rome
Europe/Samara
Europe/San_Marino
Europe/Sarajevo
Europe/Simferopol
Europe/Skopje
Europe/Sofia
Europe/Stockholm
Europe/Tallinn
Europe/Tirane
Europe/Tiraspol
Europe/Uzhgorod
Europe/Vaduz
Europe/Vatican
Europe/Vienna
Europe/Vilnius
Europe/Volgograd
Europe/Warsaw
Europe/Zagreb
Europe/Zaporozhye
Europe/Zurich
Indian/Antananarivo
Indian/Chagos
Indian/Christmas
Indian/Cocos
Indian/Comoro
Indian/Kerguelen
Indian/Mahe
Indian/Maldives
Indian/Mauritius
Indian/Mayotte
Indian/Reunion
Pacific/Apia
Pacific/Auckland
Pacific/Chatham
Pacific/Easter
Pacific/Efate
Pacific/Enderbury
Pacific/Fakaofo
Pacific/Fiji
Pacific/Funafuti
Pacific/Galapagos
Pacific/Gambier
Pacific/Guadalcanal
Pacific/Guam
Pacific/Honolulu
Pacific/Johnston
Pacific/Kiritimati
Pacific/Kosrae
Pacific/Kwajalein
Pacific/Majuro
Pacific/Marquesas
Pacific/Midway
Pacific/Nauru
Pacific/Niue
Pacific/Norfolk
Pacific/Noumea
Pacific/Pago_Pago
Pacific/Palau
Pacific/Pitcairn
Pacific/Ponape
Pacific/Port_Moresby
Pacific/Rarotonga
Pacific/Saipan
Pacific/Samoa
Pacific/Tahiti
Pacific/Tarawa
Pacific/Tongatapu
Pacific/Truk
Pacific/Wake
Pacific/Wallis
Pacific/Yap
UTC

Ryus_DateTimeZone::listIdentifiers()は、タイムゾーンのバリデーションや、タイムゾーンの選択などに活用できることでしょう。

PHPでマルチバイトの文字数を数える

 : PHP 2008/10/8 21:58

Blogger's Avatar

PHPで文字列の文字数を数える場合,strlen関数を利用して以下のように書きます.
php -r '$re = strlen("テスト"); var_dump($re);'
「テスト」は3文字なので3が返るはずです.しかし,このコードの実行結果は9が返ります. これはstrlenがマルチバイトを考慮していない為です.strlenの場合,文字数というよりはバイト数を表示しています. PHPでマルチバイト文字列をカウントするにはmbstringに含まれるmb_strlen関数を使います.以下はmb_stringを利用した場合のコードです.
php -r '$re = mb_strlen("テスト"); var_dump($re);'
しかし私の環境では,このコードを実行してもやはり9が返ってきました.mb_strlenは与えられた文字列を内部エンコーディングでカウントします.内部エンコーディングはmb_internal_encoding()関数を利用する事で確認できるのですが,結果はISO-8859-1でした.サーバ自体のlangはUTF-8なのであっていません.そこで以下のように書きかえました.
php -r '$re = mb_strlen("テスト", "UTF-8"); var_dump($re);'
これでようやく3という数字がでました.mb_strlenは第二引数を指定する事で任意の文字コードとしてカウントできる為,これを利用する事でマルチバイト文字を正しくカウントできるようになります. 内部エンコーディングを正しく設定しておくのもこうならない為の対策の一つではありますが,それに加えて,mb_strlenを利用する場合は明示的にエンコードを指定しておいたほうが間違いがなくなって良いかもしれません.

if文の条件の書き方

 : PHP 2008/7/30 3:32

Blogger's Avatar

haltです。 皆さんはif文内部に条件を書く時どのように書いていますか? 私の場合、
<?php
$load_error = true;
if ($load_error) {
  exit('error!');
}
とか
if (!in_array($value, array('a','b','c'))) {
  exit("{$value} is not found.");
}
のように、if文の中に変数や関数を直接書いてその結果を判定条件にしています。 が、こういった書き方がすべてだと考えていると必ずハマります。具体的には以下の場合 です。
if (strpos('abc', 'a')) {
  exit('exist!');
}
strposは、第一引数の中に第二引数が存在するか調べ、その文字が見つかった位置を返し ます。見つからなければfalseを返します。 上のプログラムの場合、abcの中にaは含まれているのでifの条件が満たされ、exitでプロ グラムが停止するはずですが実際は停止しません。 い strposが返す文字列位置は0からはじまる為、if文が0をfalseと判い断してしまい、条件>を満たす事ができません。同様のケースとして以下の例があげられます。 http://d.hatena.ne.jp/pirokyun/20080729/1217329949
<?php
$fruit = array('apple', 'orange', 'banana');
if (array_search('apple', $fruit)) {
    return true;
} else {
    return false;
}
?>
array_searchは配列の中から特定の値を含む配列のキーを返す関数なのですが 1番目の配列のキーは0なので0を返し、if文がそれをfalseと判断。結果、配列は値を含ん でいるのに条件分岐の上では含んでいない事になってしまいます。 この問題を避けるには条件の中で変数や関数の結果を直接参照しないで、必ず比較するよ うにする事です。strposの問題やarray_searchの問題は
<?php
if (strpos('abc', 'a') !== false) {
  exit('found!');
}
のようにする事で回避できます。 strposやarray_searchなどphpが用意した関数は覚えてしまったりマニュアルを引いて使>うので慣れればハマる事はありませんが、他人が作った関数などを使う場合は注意したほ うが良いでしょう。

do-whileでエラー遷移を制御する

 : PHP 2008/7/16 2:04

Blogger's Avatar

PHP4の最終リリースもせまり、もうPHP4を触る事はないだろうと思っていたのになぜかPHP4のコードを書いているhaltです。 今日はPHP4でのエラー遷移制御のバッドノウハウ…いやテクニックを紹介します。 通常、エラー発生時にメッセージを貯めていくコードを書くと、以下のような感じになり がちです。
class example1_controller
{
    function post()
    {  
        $comma_count = 3;
        $filename = __FILE__;
        if (file_exists($filename)) {
            if ($filedata = file_get_contents($filename)) {
                $csv_data = array();
                $rows = explode("\n", $filedata);
                array_shift($rows); //先頭行はタイトルなのでイラネ
                if (count($rows) < 1) {
                    $this->error->addError('parse error.');
                } else {
                    foreach ($rows as $row) {
                        $cols = explode(',', $row);
                        if (count($cols) != 4) {
                            $this->error->addError('invalid column count.');
                            break;
                        }
                        $csv_data[] = $cols;
                    }
                }
            } else {
                $this->error->addError('file read failed.');
            }
        } else {
            $this->error->addError('target file not found.');
        }

        // 途中でエラーがあってもここを通したい
        $this->render->setAttribute('error', $this->error);
        $this->render->setTemplate('test.tpl');
    }
}
「エラーがなければ次へ」というifを繰り返して先へ進むこのコードですがネストが深く なってしまいたいへん見辛いコードになっています。 PHP5なら、tryブロックで囲んでエラーが発生したらthrowする事で、ネストする事なしに 処理をとばせるのですが、PHP4にはtry-catch構文がないので仕方なくif文で…となると>>立ちまち汚いコードがうまれてしまいます。 そこで他の人はどうやっているのだろうと検索してみたところ、一回で抜けるようにした do-while文を使ってtryブロックのように囲み、問題が発生した時点でbreakする事によっ て擬似的にtry-catchのような遷移を実現するという方法を知りました。 あきらかにクセがあるので使うタイミングを良く考える必要がありそうですが、具体的に は以下のような感じです。
class example2_controller
{
    function post()
    {
        $comma_count = 3;
        $filename = __FILE__;

        do {
            if (!file_exists($filename)) {
                $this->error->addError('target file not found.');
                break;
            }

            $filedata = file_get_contents($filename);
            if ($filedata === false) {
                $this->error->addError('file read failed.');
                break;
            }

            $csv_data = array();
            $rows = explode("\n", $filedata);

            array_shift($rows); //先頭行はタイトルなのでイラネ
            if (count($rows) < 1) {
                $this->error->addError('parse error.');
                break;
            }

            foreach ($rows as $row) {
                $cols = explode(',', $row);
                if (count($cols) != 4) {
                    $this->error->addError('invalid column count.');
                    break;
                }
                $csv_data[] = $cols;
            }
        } while(0);

        // 途中でエラーがあってもここを通したい
        $this->render->setAttribute('error', $this->error);
        $this->render->setTemplate('test.tpl');
    }
}
do-whileブロック内では、エラー発生時点でbreakを使って処理を抜けている為、if文連>打のようにネストが深くなる事はありません。do-whileテクニックを知っている人が見れ ば非常に見易いでしょう。ただし、ネスト回数の少ないコードでこれを使うと意図が見え づらく、混乱の元になりそうです。 クラスなどを利用して擬似的にExceptionを扱う方法もあるようなのですがこのあたりで>調査を終わりにしたいと思います。こういった方法を使うよりもPHP5を使った方がずっと 幸せになれるからです。

スタッフブログ最新
カテゴリ一覧

〒104-0061 東京都中央区銀座1丁目3番3号 G1ビル7階
お問い合わせ TEL 03-3524-8860

Copyright(c) 2012 RYUS.All Rights Reserved.