1. ソースをダウンロード [root@server ~]# cd /usr/src/redhat/SOURCES ※PHPダウンロードページの「Complete Source Code」よりソースをダウンロード。 2. 解凍・展開 [root@server SOURCES]# tar -zxvf php-5.2.14.tar.gz 3. specファイルのコピー [root@server SOURCES]# cd ../SPECS [root@server SPECS]# cp ../SOURCES/php-5.2.14/php5.spec.in ./php5.spec 4. specファイルの編集 下記環境・条件にて動作するするよう調整。
---- php5.spec %define version 5.2.14 # バージョン番号が初期値の "@VERSION@" ではうまくいかなかった %define so_version 5 %define release 1 # 適宜値を修正(再ビルドごとに数値を増やす) %define source_root /usr/src/redhat/SOURCES/php-5.2.14 # ソースルートパス Name: php Summary: PHP: Hypertext Preprocessor Group: Development/Languages Version: %{version} Release: %{release} License: The PHP license (see "LICENSE" file included in distribution) # ^"Copyright"は古い書式であることによりビルドエラー。"License"に修正。 Source: https://www.php.net/get/php-%{version}.tar.gz Icon: %{name}-%{version}/php.gif # パス "%{name}-%{version}/" 追記。 URL: http://www.php.net/ Packager: PHP Group <group@php.net> BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildArch: x86_64 # 実際のアーキテクチャに応じた値を記述 %description PHP is an HTML-embedded scripting language. Much of its syntax is borrowed from C, Java and Perl with a couple of unique PHP-specific features thrown in. The goal of the language is to allow web developers to write dynamically generated pages quickly. %prep %setup %build set -x #./buildconf --force # モジュール類を生成? # またはインストール済みモジュール(/usr/lib64/php/modules/
の*.so
)をソースtarballのmodules
に加えておく。 #./configure --prefix=/usr --with-apxs \ # --disable-debug \ # --with-xml=shared \ #↓ 必要要件などに合わせ修正 ./configure --build=x86_64-redhat-linux-gnu \ --host=x86_64-redhat-linux-gnu \ --target=x86_64-redhat-linux-gnu \ --program-prefix= --prefix=/usr \ --exec-prefix=/usr --bindir=/usr/bin \ --sbindir=/usr/sbin --sysconfdir=/etc \ --datadir=/usr/share --includedir=/usr/include \ --libdir=/usr/lib64 --libexecdir=/usr/libexec \ --localstatedir=/var --sharedstatedir=/usr/com \ --mandir=/usr/share/man --infodir=/usr/share/info \ --cache-file=../config.cache --with-libdir=lib64 \ --with-config-file-path=/etc \ --with-config-file-scan-dir=/etc/php.d \ --disable-debug --with-pic --disable-rpath \ --without-pear --with-bz2 --with-curl \ --with-exec-dir=/usr/bin --with-freetype-dir=/usr \ --with-gd \ --with-png-dir=/usr --enable-gd-native-ttf \ --without-gdbm --with-gettext --with-gmp \ --with-iconv --with-jpeg-dir=/usr --with-openssl \ --with-pspell \ --with-pcre-regex=/usr --with-zlib \ --with-layout=GNU --enable-exif --enable-ftp \ --enable-magic-quotes --enable-sockets \ --enable-sysvsem --enable-sysvshm --enable-sysvmsg \ --enable-wddx --with-kerberos --enable-ucd-snmp-hack \ --with-unixODBC=shared,/usr \ --enable-shmop --enable-calendar \ --with-mime-magic=/usr/share/file/magic.mime \ --without-sqlite \ --with-libxml-dir=/usr \ --with-apxs2=/usr/sbin/apxs \ # Apache2系の場合はapxs ではなく apxs2 を指定 --with-mysql \ --disable-dba \ --without-unixODBC \ --enable-pdo \ # pdoを有効化、"=shared" (共有オプション)はつけない方がいいらしい[1] --disable-xmlreader --disable-xmlwriter \ --enable-mbstring #make clean make # デフォルトではcli版とcgi版の両方を生成する手順になっているが、cli版だけを生成する手順に変更。 #mv sapi/cgi/php php.keepme test -f config.cache && rm -f config.cache #cp %{source_root}/sapi/cli/php sapi/cli cp ${RPM_SOURCE_DIR}/%{name}-%{version}/php.gif ${RPM_SOURCE_DIR} #make clean #./configure --enable-cli #make #mv php.keepme sapi/cgi/php # figure out configure options options based on what packages are installed # to override, use the OVERRIDE_OPTIONS environment variable. To add # extra options, use the OPTIONS environment variable. #test rpm -q MySQL-devel >&/dev/null && OPTIONS="$OPTIONS --with-mysql=shared" #test rpm -q solid-devel >&/dev/null && OPTIONS="$OPTIONS --with-solid=shared,/home/solid" #test rpm -q postgresql-devel >&/dev/null && OPTIONS="$OPTIONS --with-pgsql=shared" #test rpm -q expat >&/dev/null && OPTIONS="$OPTIONS --with-xml=shared" #if test "x$OVERRIDE_OPTIONS" = "x"; then # ./configure --prefix=/usr --with-apxs2=$APXS $OPTIONS #else # ./configure $OVERRIDE_OPTIONS #fi %install rm -rf $RPM_BUILD_ROOT mkdir -p ${RPM_BUILD_ROOT} mkdir -p $RPM_BUILD_ROOT%{_libdir}/httpd/modules install -m 0755 libs/libphp5.so $RPM_BUILD_ROOT%{_libdir}/httpd/modules mkdir -p $RPM_BUILD_ROOT%{_bindir} install -m 0755 sapi/cli/php $RPM_BUILD_ROOT%{_bindir} #install -m 0755 sapi/cgi/php $RPM_BUILD_ROOT%{_bindir}/php_cgi mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 install -m 0755 sapi/cli/php.1 $RPM_BUILD_ROOT%{_mandir}/man1 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir} install -m 0755 php.ini-recommended $RPM_BUILD_ROOT%{_sysconfdir}/php.ini mkdir -p $RPM_BUILD_ROOT%{_libdir}/php/modules install -m 0755 modules/*.so $RPM_BUILD_ROOT%{_libdir}/php/modules %files %defattr(-,root,root) %{_libdir} #/etc/httpd/conf %{_bindir}/php* %{_mandir}/man1/php.1* %{_sysconfdir}/php.ini #%{_libdir}/php/extensions/*.so #/usr/lib/debug #/usr/src/debug %doc TODO CODING_STANDARDS CREDITS LICENSE NEWS README* ----
参考文献・サイト
PHPパッケージソース内の README.SELF-CONTAINED-EXTENSIONS
より。
$Id: README.SELF-CONTAINED-EXTENSIONS 100881 2002-10-23 21:35:17Z jon $ ============================================================================= 「自己内包型PHP拡張モジュールの作り方」 PHPソースに入っている拡張モジュールはPHPソースとは独立に配布することができます。 そのような拡張モジュールを作るには、下記2つの事項が必要になります。 - 設定ファイル (config.m4) - モジュールのソースコード では、これらをどのようにして作り、どのようにして一緒にするのかについて以下に記します。 「システムの準備」 作ったモジュールがあらゆるシステムで動作するようにするには、 以下のツールを開発者は用意しておく必要があります。 GNU autoconf GNU automake GNU libtool GNU m4 これらは全て下記サイトから入手することができます。 ftp://ftp.gnu.org/pub/gnu/ 「既存の拡張モジュールを変換する」 自己内包拡張モジュールを作るのがどれだけ簡単かだけを示すために、 埋め込まれた拡張モジュールを自己内包モジュールに変換する手順を以下に示します。 PHPをインストールして以下のコマンドを実行して下さい。 $ mkdir /tmp/newext $ cd /tmp/newext これで空のディレクトリができました。 ではmysql拡張モジュールのファイルをコピーします。 $ cp -rp php-4.0.X/ext/mysql/* . 次の処理でモジュールの作成は終わりです。以下のコマンドを実行して下さい。 $ phpize これでディレクトリ内のファイルを持ち出して使えるようになりました。 拡張モジュールは完全にそれ単独で動作します。 ユーザが拡張モジュールをインストールする方法は要約すると以下の通りです。 $ ./configure \ [--with-php-config=/path/to/php-config] \ [--with-mysql=MYSQL-DIR] $ make install The MySQL module will either use the embedded MySQL client library or the MySQL installation in MYSQL-DIR. 「新しい拡張モジュールの定義」 以下の例において、拡張モジュールの名前は「foobar」であるとします。 これは「foo.c」と「bar.c」という2つのファイルで構成されています。 (任意数のヘッダファイルも含まれますが、これはここではさほど重要なことではありません) また、ここに例示する拡張モジュールはいずれの外部ライブラリも参照しません (これは重要なことです、なぜならユーザは他に何も指定しなくても良いからです)。 「LTLIBRARY_SOURCES」はソースファイル名を指します。 任意数のソースファイル名をつけることができます。 「M4設定ファイルを作る」 m4設定によって追加のチェックを行うことができます。 自己内包拡張モジュールのために、マクロを呼び出す必要はありません。 ------------------------------------------------------------------------------ PHP_ARG_ENABLE(foobar,whether to enable foobar, [ --enable-foobar Enable foobar]) if test "$PHP_FOOBAR" != "no"; then PHP_NEW_EXTENSION(foobar, foo.c bar.c, $ext_shared) fi ------------------------------------------------------------------------------ 「PHP_ARG_ENABLE」は正しい変数を自動的に設定し、 「PHP_NEW_EXTENSION」によってsharedモードで拡張モジュールが使えるようにします。 「PHP_NEW_EXTENSION」の最初の引数は拡張モジュールの名前を記します。 2番目の引数はソースコードファイル名です。 3番目は $ext_shared に値が渡されます。$ext_shared は PHP_ARG_ENABLE/WITH によって PHP_NEW_EXTENSION に設定されるものです。 PHP_ARG_ENABLE または PHP_ARG_WITH を常に使うようにして下さい。 あなたの作ったPHPモジュールを配布する予定がないとしても、 モジュールを簡単にメインのPHPモジュールの体系に組み込むことができるからです。 「ソースファイルの作成」 ext_skel はPHPにおける全モジュールの共通コードを作る時や、 基本的な関数定義や関数に渡す引数の制御を行うCのコードを記述する場合、 非常に助けとなるでしょう。 詳しくは README.EXT_SKEL をご覧下さい。 As for the rest, you are currently alone here. 多くの既存モジュールがあり、開始点として単一のモジュールを使ってそれに独自のコードを付加することを考えます。 「自己内包拡張モジュールを作る」 config.m4 ファイルと ソースファイルを1つのディレクトリに置きます。 そして、phpizeを実行します。 phpizeはphp 4.0をmake installする際にインストールされます。 例えば、php を --prefix=/php というオプションで configure した場合、 以下のファイルを実行することになるでしょう。 $ /php/bin/phpize これは自動的に必要なビルドファイルをコピーし、config.m4からconfigureを作ります。 これで自己内包拡張モジュールができるのです。 「自己内包型拡張モジュールのインストール」 拡張モジュールは以下のコマンドを実行することによってインストールされます。 $ ./configure \ [--with-php-config=/path/to/php-config] $ make install 「ADDING SHARED MODULE SUPPORT TO A MODULE」 利便性のため、自己内包型拡張モジュールは共有モジュールとして ロードできるようになっている必要があります。 では次に「foo」という名前の既存モジュールに共有モジュールサポートを 付加するのかについて説明します。 1. config.m4 の中で、PHP_ARG_WITH/PHP_ARG_ENABLE を使って下さい。 そうすると --with-foo=shared[,..] または --enable-foo=shared[,..] が自動的に使えるようになります。 2. config.m4 の中で、PHP_NEW_EXTENSION(foo,.., $ext_shared) を使って 拡張モジュールの作成を有効化して下さい。 3. 以下の各行をあなたが作ったCのソースファイルに追加して下さい。 #ifdef COMPILE_DL_FOO ZEND_GET_MODULE(foo) #endif
インストール時に設定しなかったオプションの追加を行うには、
php.ini
を編集する(rpm
パッケージを用いてインストールした場合も同様)
→依然mbstring関数が使えない。
yum install php-mbstring
を実行してパッケージをインストールした後、httpd -k restart
でApacheを再起動する。→"additional .ini files parsed"に/etc/php.d/mbstring.ini
が追加された。
その後php.ini
の[mbstring]の項を修正。
php.ini
のmbstring.func_overload
に以下の値を積算して指定する。
関数の種類 | 元の関数 | オーバーロード関数 | 値 |
---|---|---|---|
メール関数 | mb_send_mail | 1 | |
文字列関数 | strlen | mb_strlen | 2 |
strpos | mb_strpos | ||
strrpos | mb_strrpos | ||
substr | mb_substr | ||
strtolower | mb_strtolower | ||
strtoupper | mb_strtoupper | ||
substr_count | mb_substr_count | ||
正規表現関数 | ereg | mb_ereg | 4 |
eregi | mb_eregi | ||
ereg_replace | mb_ereg_replace | ||
eregi_replace | mb_eregi_replace | ||
split | mb_split |
mbstring.func_overload = 0
だと全てオーバーロードしない、mbstring.func_overload = 7
だと全てオーバーロードする、と言った具合になる。
php.ini
のある場所は<?php phpinfo();?>
と記したスクリプトをブラウザで参照すれば記載されている。
参考文献・サイト:
PHPに関する各種設定情報は php.ini
に記述されている。UNIX系OSでは通常 /etc
、Windowsでは C:¥windows
や C:¥winnt
にある。変更を反映するにはWebデーモン(Apacheなど)の再起動が必要。
キー | 値 | 内容 | 例 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
expose_php | On, Off |
サーバにPHPがインストールされているという情報をHTMLヘッダに乗せるかどうかを設定する。Onなら情報を出し、Offなら情報を出さない[1]。出したからと言って直接セキュリティ上の脅威になる訳ではないが攻撃に有用な情報を取得される可能性があるので、情報を出す必要がないなら出力しない方が好ましい。初期状態の php.ini での設定は On のよう。Onにしている時のhtmlヘッダは以下の様になる。Firefoxでのhtmlヘッダ閲覧方法はこちら。
HTTP/1.1 200 OK
Date:Fri,21 May 2010 00:27:38 GMT
Server:Apache/2.2.8 (Unix) PHP/5.2.8
Content-Type:application/xhtml+xml
...
|
expose_php = On | ||||||||||||
error_log = ファイル名 | エラーログ出力先指定 | エラーログ出力先ファイル名を指定する。指定しない場合、Apacheのログにエラー出力される(Webスクリプトの場合[3])。 | error_log = "/var/log/php.log"; | ||||||||||||
error_reporting | 内容参照 |
エラーレベルを示す文字列または値で指定する。ビット演算子(| →OR、& →AND、^ →XOR、~ ・! →NOT)を用いて組み合わせた指定や特定エラーだけを出なくするような指定も可能[2]。
|
error_reporting = E_COMPILE_ERROR|E_ERROR_E_CORE_ERROR |
参考文献・サイト
原則として<?php
と ?>
の間に記したもののみがPHPスクリプトとみなされ、その外に書いたものはPHPスクリプトとはみなされない。
<?php ←ここからPHPスクリプト (PHPスクリプト) ?> ←ここでPHPスクリプト終わり
例外は以下の通り。
//
」〜行末(または?>
)#
」〜行末(または?>
)/*
」〜「*/
」【例】以下の記述は全てコメントアウト //これはコメントです。 #これもコメントです。 /*これも コメント です。*/
<?php ... ?>
)内で一時的にPHPとしての解釈するのを停止することができる。まとまったhtmlコードを出力する場合などに有効。
【書式】 print <<< 終了検知文字列 (非PHPコンテンツ) 終了検知文字列 【例】 print <<< DOC_END <html> <head> <title>ようこそ</title> </head> <body> <p>ここが本文です</p> </body> </html> DOC_END;
なお、print
を変数名に置き換えれば、出力する代わりに変数への値代入を行うこともできる。
【例】"$contents" に代入 $contents = <<< DOC_END <html> <head> <title>ようこそ</title> </head> <body> <p>ここが本文です</p> </body> </html> DOC_END;
ヒアドキュメント内でも変数を参照することができる。
但し、配列変数を参照する時は、変数名を{ }
で囲む必要がある[3]
【例】 $ cat test.php #!/usr/bin/php <?php date_default_timezone_set('Asia/Tokyo'); $today = date('Y年n月j日')."です。"; echo <<< _STR_ 今日は${today}です。 _STR_ ; ?> $ php test.php 今日は2015年1月19日です。
参考文献・サイト:
進数 | 表記 | 例 |
---|---|---|
10 | 普通に表記 | 17, -34 |
2 | 先頭に0b を表記 |
0b1010(=10進数の10)※PHP 5.4.0から利用可能 |
8 | 先頭に0 を表記 |
0123(=10進数の83) |
16 | 先頭に0x を表記 |
0x1A(=10進数の26) |
基数1 | ←関数 | 関数→ | 基数2 |
---|---|---|---|
2 | - | - | 8 |
decbin | bindec | 10 | |
- | - | 16 | |
8 | - | octdec | 10 |
- | - | 16 | |
10 | hexdec | dechex | 16 |
なお、2〜36の間で任意に基数(進数)変換を行うにはbase_convert(数値,元の基数,変換先)
を用いる。11〜36進数ではa〜zの英字が用いられる(a=10,b=11,...,z=35)。
参考文献・サイト:
(ある程度)一意な値を得る方法
コマンド | 備考 |
---|---|
【書式】
uniqid(接頭辞,more_entropy);
【引数】
【戻り値】(文字列)マイクロ秒単位の現在時刻にもとづいた、接頭辞つきの一意な ID。
文字数は、more_entropyがfalseの場合「接頭辞の文字数+13文字」、trueの場合「接頭辞の文字数+23文字」。
|
この関数が生成する値は、暗号として安全ではないため、暗号として使うなら、random_int() か random_bytes() あるいは openssl_random_pseudo_bytes() を使うべき。
【例】 $ php -r "var_dump(uniqid());" string(13) "58a3ae5632cb6" $ php -r "var_dump(uniqid('hoge'));" string(17) "hoge58a3ae6cbd61c" $ php -r "var_dump(uniqid('',true));" string(23) "58a3ae9cdb0765.65361913" $ php -r "var_dump(uniqid('hoge',true));" string(27) "hoge58a3aecd179a67.37155812" |
【引数】
【戻り値】(整数)最小値以上、最大値以下の範囲で、暗号化されたランダムな整数値。
|
この関数が使えるのはPHP 7.0以降。
【例】 $ php -r "var_dump(random_int(0,100));" int(88)但し、PHP 5.2〜5.6で使えるものが別途つくられているとのこと。 |
【書式1】
rand();
【引数2】※書式1のように両方省略するか、書式2のように両方指定するかのどちらか
【戻り値1】(整数)0以上getrandmax以下の疑似乱数。
【戻り値2】(整数)最小値以上、最大値以下の疑似乱数。
|
この関数が生成する値は、暗号として安全ではないため、暗号として使うなら、random_int() か random_bytes() あるいは openssl_random_pseudo_bytes() を使うべき。
【例】 $ php -r "var_dump(rand());" int(226590108) $ php -r "var_dump(rand(5,10));" int(7) |
【書式】
random_bytes(長さ);
【引数】
【戻り値】(文字列)指定されたバイト数の、暗号化された安全なランダムバイナリ値。
|
この関数が使えるのはPHP 7.0以降。
【例】 $ php -r "var_dump(bin2hex(random_bytes(16)));" string(32) "1dfb64415098d17f8d15cbe56907cad4"但し、PHP 5.2〜5.6で使えるものが別途つくられているとのこと。 |
【書式】
getmypid();
【引数】なし
【戻り値】(整数)現在のPHPプロセスのIDを返す。エラーの場合は false を返す。
|
プロセスIDはある瞬間においては一意かもしれないが、時間差を空けて同じプロセスIDが再利用される可能性があるので、この関数が返す値だけを一意なIDとして使うべきではない。上に記す他の関数が返す値をつなげるなどした方がよい。
【例】 $ php -r "var_dump(getmypid());" int(28410) $ php -r "var_dump(getmypid().'_'.uniqid(rand().'_',true));" string(40) "29104_1734255497_58a3bac85eae22.08791633" |
演算子の種類 | 名前 | 記述例 | 内容 |
---|---|---|---|
代数演算子 | 正負逆転 | -$a | 値の符合を逆にする |
加算 | $a + $b | $a と $bの合計 | |
減算 | $a - $b | $a と $bの差 | |
乗算 | $a * $b | $a と $bの積 | |
除算 | $a / $b | $a を $bで割ったの商* | |
剰余 | $a % $b | $a を $bで割った余り。fmod関数でも同様の処理が可能。 | |
演算代入 | $a += $b | $a の値に $b を加えた値を $a に代入$a = $a + $b と同じ |
|
加算子/減算子 | 前置加算子 | ++$a | $a に 1 を加えて$aを返す |
後置加算子 | $a++ | $aを返してから$a に 1 を加える | |
前置減算子 | --$a | $a から 1 を引いて$aを返す | |
後置減算子 | $a-- | $aを返した後$a から 1 を引く | |
文字列演算子 | 結合演算子 | $a . $b | $a と $b を結合した文字列 |
結合代入演算子 | $a .= $b | $a に $b を追記 |
比較演算子については以下の通り。
演算子 | 判定 | 例 | 備考 | |
---|---|---|---|---|
値 | 型 | |||
$a == $b |
等しい | 不問 |
|
整数値を文字列と比較する際、文字列は数値に変換される。 |
$a === $b |
等しい | 等しい |
|
|
$a != $b
|
等しくない | 不問 |
|
== の否定。 |
$a !== $b
|
値が等しくない、または型が違う |
|
=== の否定。 |
|
$a < $b
|
$a は $b より小さい | 不問 | 1 < "02" → true | |
$a > $b
|
$a は $b より大きい | 不問 | 3 > "02" → true | |
$a <= $b
|
$a は $b 以下 | 不問 | 1 <= "02" → true | |
$a >= $b
|
$a は $b 以上 | 不問 | 3 >= "02" → true |
書式 | 内容 | 例 |
---|---|---|
array_sum(配列変数) |
配列変数の各要素の和を返す | |
array_product(配列変数) |
配列変数の各要素の積を返す |
演算子 | 内容 |
---|---|
$a & $b |
ビット積。両変数とも1になっているビットのみ1とした値を返す。 |
$a | $b |
ビット和。どちらかまたは両方が1になっているビットを1とした値を返す。 |
$a ^ $b |
ビット排他的論理和。どちらか一方が1になっているビットを1とした値を返す。 |
~ $a |
ビット否定。ビットを反転させた値を返す。 |
$a << $b |
ビット左シフト。$a のビットを $b ビット左にシフトする(=2$b倍する) |
$a >> $b |
ビット右シフト。$a のビットを $b ビット右にシフトする(=1/2$b倍する) |
$ cat test.php <?php $val1 = 0xa; $val2 = 0x9; echo "論理積(両方のビットがONならON)\n"; echo $val1.sprintf('(%04b_2)',$val1).' & '.$val2.sprintf('(%04b_2)',$val2).' = '.sprintf('%2d',$val1 & $val2).sprintf('(%04b_2)',$val1 & $val2)."\n"; echo "論理和(少なくともどちらか一方のビットがONならON)\n"; echo $val1.sprintf('(%04b_2)',$val1).' | '.$val2.sprintf('(%04b_2)',$val2).' = '.sprintf('%2d',$val1 | $val2).sprintf('(%04b_2)',$val1 | $val2)."\n"; echo "排他的論理和(一方がONでもう一方がOFFならON、論理和−論理積)\n"; echo $val1.sprintf('(%04b_2)',$val1).' ^ '.$val2.sprintf('(%04b_2)',$val2).' = '.sprintf('%2d',$val1 ^ $val2).sprintf('(%04b_2)',$val1 ^ $val2)."\n"; echo "否定(ビット反転)\n"; echo '~ '.$val1.sprintf('(%04b_2)',$val1).' = '.sprintf('%2d',~ $val1).sprintf('(%b_2)',~ $val1)."\n"; echo "ビット左シフト\n"; echo $val1.sprintf('(%04b_2)',$val1).' << 2'.sprintf('(%04b_2)',2).' = '.sprintf('%2d',$val1 << 2).sprintf('(%b_2)',$val1 << 2)."\n"; echo "ビット右シフト\n"; echo $val1.sprintf('(%04b_2)',$val1).' >> 2'.sprintf('(%04b_2)',2).' = '.sprintf('%2d',$val1 >> 2).sprintf('(%04b_2)',$val1 >> 2)."\n"; ?> $ php test.php 論理積(両方のビットがONならON) 10(1010_2) & 9(1001_2) = 8(1000_2) 論理和(少なくともどちらか一方のビットがONならON) 10(1010_2) | 9(1001_2) = 11(1011_2) 排他的論理和(一方がONでもう一方がOFFならON、論理和−論理積) 10(1010_2) ^ 9(1001_2) = 3(0011_2) 否定(ビット反転) ~ 10(1010_2) = -11(1111111111111111111111111111111111111111111111111111111111110101_2) ビット左シフト 10(1010_2) << 2(0010_2) = 40(101000_2) ビット右シフト 10(1010_2) >> 2(0010_2) = 2(0010_2)
参考文献・サイト:
max
、min
は最大、最小の値を返す。引数には1個の配列または1個以上の変数を指定する。
文字種 | 扱い |
---|---|
数値を含む | 数値 |
文字列のみ | 文字コードが一番大きい(maxの場合)/小さい(minの場合)文字列 |
関数 | 書式 | 処理内容 |
---|---|---|
round | round(数値,丸める桁数,中間値の扱い); |
四捨五入により指定桁に丸めた値を返す |
ceil | ceil(数値); |
数値を越える整数の中で最も小さい整数を返す(小数点以下切り上げ) |
floor | floor(数値); |
数値を超えない最大の整数を返す(小数点以下切り捨て) |
値 | 内容 | 例 |
---|---|---|
PHP_ROUND_HALF_UP | 丁度中間の値は切り上げる (指定がない場合の既定の動作) |
echo round(1.5, 0, PHP_ROUND_HALF_UP);
|
PHP_ROUND_HALF_DOWN | 丁度中間の値は切り捨てる |
echo round(1.5, 0, PHP_ROUND_HALF_DOWN);
|
PHP_ROUND_HALF_EVEN | 偶数側に丸める |
echo round(1.5, 0, PHP_ROUND_HALF_EVEN); echo round(2.5, 0, PHP_ROUND_HALF_EVEN); |
PHP_ROUND_HALF_ODD | 奇数側に丸める |
echo round(1.5, 0, PHP_ROUND_HALF_ODD); echo round(2.5, 0, PHP_ROUND_HALF_ODD); |
fmod
は指定した数で割り算した時の余り(剰余)を返す。
【書式】 fmod(被除数,除数); 【戻り値】 剰余
「被除数 = 除数 × 商 + 余り」の関係になる。
%演算子を使った場合と同じ? 以下の例を見る限り、同じに見える。
$ cat test.php <?php echo "10 % 3 (10÷3の余り)= ".(10 % 3)."\n"; echo "fmod(10,3) (10÷3の余り)= ".fmod(10,3)."\n"; ?> $ php test.php 10 % 3 (10÷3の余り)= 1 fmod(10,3) (10÷3の余り)= 1
log10
は底を10とする対数を返す。その他の底を使う時はlog
を用いる
【書式】 log10(真数); log(真数,底); 【引数】 真数:浮動小数点数(float) [logのみ]底:浮動小数点数(float) 指定がない場合の既定値はネピア数(e、自然対数の底) 【戻り値】 [log10] 10を底とする真数の対数:浮動小数点数(float) [log] 指定した底と真数に対する対数:浮動小数点数(float)
rand
は乱数を生成して返す。引数を指定しない場合は0からgetrandmax
の間の擬似乱数(整数)を、指定した場合はその範囲内の擬似乱数(整数)を返す。いずれも範囲には端点を含む。
【書式】 rand(); rand(最小値(整数),最大値(整数));
なお、rand
よりも生成速度などに優れたmt_rand
関数もある。使い方は同じ。引数を指定しない場合の最大値はmt_getrandmax
で取得できる。
【書式】 mt_rand(); mt_rand(最小値(整数),最大値(整数));
uniqid
はマイクロ秒単位の現在時刻にもとづいた、指定した接頭辞つきの一意な文字列を返す。戻り値の文字数は more_entropy が false の場合は(接頭辞+13 文字)、true の場合は(接頭辞+23 文字)。
【書式】 uniqid(接頭辞,more_entropy);
echo
などによる出力の出力先は、通常の場合標準出力(端末、ブラウザなど)となるが、ob_start
を使うと一時的に出力先を内部バッファに変更できる。バッファの内容は ob_get_contents
で文字列変数などに取り込むことができる。ob_end_flush
はバッファの内容を出力し、ob_end_clean
はバッファの内容を消去する。
ob_get_length
は出力バッファの内容の長さをバイト単位で返す。
ob_start
は出力のバッファリングを開始する。バッファリングを開始すると、ヘッダを除くスクリプトからの出力内容が内部バッファに蓄積される。
【書式】 ob_start(); 【戻り値】 成功→true 失敗→false
コマンド | 戻り値 | バッファリング | バッファ内容 | 標準出力への送信 |
---|---|---|---|---|
ob_get_contents() |
バッファの内容※1 | 継続 | 保持 | × |
ob_flush() |
なし | 継続 | 消去 | ○ |
ob_clean() |
なし | 継続 | 破棄 | × |
ob_get_flush() |
バッファの内容※1 | 終了 | 消去 | ○ |
ob_get_clean() |
バッファの内容※1 | 終了 | 破棄 | × |
ob_end_flush() |
成功→true、失敗→false | 終了 | 消去 | ○ |
ob_end_clean() |
成功→true、失敗→false | 終了 | 破棄 | × |
【書式】 ob_get_contents(); 【戻り値】 出力のバッファリングが有効になっている時→出力バッファの内容 出力のバッファリングが有効になっていない時→false
【例】 <?php ob_start(); #- 出力バッファリング開始 $log = 'hoge.log'; #- 出力先ファイル名定義 $handle = fopen($log,'w'); #- 出力先ファイルを開く if ($handle) { echo "The log file was opened successfully.\n"; } else { echo "The log file couldn't be opened.\n"; } fwrite($handle,ob_get_contents()); #- バッファ内容をファイルに書き込む fclose($handle); #- ファイルを閉じる ?>
参考文献・サイト:
改行は\n
(UNIX系 LF),\n\r
(DOS系 LF+CR),\r
(Mac系 CR)。
echo
やprint
は文字列をそのまま出力する。どちらも引数を括弧でかこまなくてよい。
【書式】 echo 出力内容,出力内容,... print 出力内容 【戻り値】 echo→なし print→常に1
括弧はあってもなくてもOK
【例】 $ cat test.php <?php echo ("Hello World from echo with parentheses.\n"); print ("Hello World from print with parentheses.\n"); echo "Hello World from echo without parentheses.\n"; print "Hello World from print without parentheses.\n"; ?> $ php test.php Hello World from echo with parentheses. Hello World from print with parentheses. Hello World from echo without parentheses. Hello World from print without parentheses.
ダブルクォート(")で囲むと、中に記述した変数名や特殊文字(改行¥nなど)は解釈した結果に置換して出力される。シングルクォート(アポストロフィ、')で囲むと、解釈は行われない。
【例】 $ cat test.php <?php $keyword = 'Hello World'; echo "$keyword from echo\n surrounded by double quote.\n"; print "$keyword from print\n surrounded by double quote.\n"; echo '$keyword from echo\n surrounded by single quote.\n'."\n"; print '$keyword from print\n surrounded by single quote.\n'."\n"; ?> $ php test.php Hello World from echo surrounded by double quote. Hello World from print surrounded by double quote. $keyword from echo\n surrounded by single quote.\n $keyword from print\n surrounded by single quote.\n
複数行に渡って引数を記すこともできます。
【例】 $ cat test.php <?php echo "echoの引数は複数行に渡って 書くことができます\n"; print "printの引数も複数行に渡って 書くこともできます\n"; ?> $ php test.php echoの引数は複数行に渡って 書くことができます printの引数も複数行に渡って 書くこともできます
echo 文中に数値の計算式を記すときは全体を括弧で囲んでおく。
<?php
$x = 100;
$y = 120;
echo $x . " - " . $y . " = " . ($x -$y) . "\n";
echo $x . " - " . $y . " = " . $x -$y . "\n";
?>
【処理結果】
100 - 120 = -20
-20
printf
は整形文字列を出力し、その長さを返す。
sprintf
は整形文字列を出力し、その整形済み文字列を返す。
【書式】 (s)printf(書式指定,文字列1,文字列2...) 【例】 $num = 5; $location = 'tree'; $format = 'There are %d monkeys in the %s'; ←"%d"は整数10進数、"%s"は文字列 printf($format, $num, $location); ←There are 5 monkeys in the tree $format2 = 'The %2$s contains %1$d monkeys'; ←"%"+数値で何番目の引数を割り当てるかを指定できる (指定が無ければ登場順) printf($format2, $num, $location); ←The tree contains 5 monkeys
書式設定にはそのままの文字が表示される通常の文字列と、それぞれ特定の変換を行う変換指定子を0個以上組み合わせて指定する。変換指定子(群)の先頭はパーセント記号(%
)で始まる。
指定子種別 | 指定子 | 内容 | 例 |
---|---|---|---|
符合指定子 | %+ |
数値に対して±の符合をつける。これがないと負値のみ符合がつく。 |
echo sprintf('%+d','12345'); → +12345 echo sprintf('%+d','-12345'); → -12345 echo sprintf('%d','12345'); → 12345 echo sprintf('%d','-12345'); → -12345 |
パディング指定子 | %埋める文字 |
表示幅指定子で指定した幅より文字列が短かった場合、指定幅になるまで埋める文字で埋める。埋める文字は空白文字または0はそのまま記し、それ以外の文字は前にシングルクォート(")を記す。 |
echo sprintf('% 10s','12345'); → 12345 echo sprintf('%010s','hoge'); → 000000hoge echo sprintf('%'#10s','hoge'); → ######hoge |
アライメント指定子 | %- |
これを指定すると左寄せで出力される。指定しない場合は右寄せ。 |
echo sprintf('[%-10s]','hoge123'); → [hoge123 ] echo sprintf('[%10s]','hoge123'); → [ hoge123] |
表示幅指定子 | %自然数 |
最低何桁(何文字幅)で表示するかを指定する。 | |
精度指定子 | %.自然数 |
浮動小数点に対して数値を何桁まで表示するかを指定する。文字列の場合はこの文字数を超えた分が切り捨てられる。 |
echo sprintf('%.2f','123.4567'); → 123.45 echo sprintf('%.5f','123.4567'); → 123.45670 echo sprintf('%.5f','hogehoge'); → hogeh |
型指定子 | % |
パーセント記号そのもの | |
%b |
整数値に対応する2進数 |
echo sprintf('%b','55'); → 110111 ※10進数55を2進数に直すと "110111" |
|
%c |
整数値に対応するASCIIコードを持つ文字列 |
echo sprintf('%c','55'); → 7 ※キャラクターコード55の文字は "7" |
|
%d |
整数値に対応する10進数 |
echo sprintf('%d','55'); → 55 |
|
%e |
指数形式 |
echo sprintf('%e','55'); → 5.50000e+1 |
|
%u |
符合無し10進数。負数の場合2の補数(ビット反転して+1)に当たる正の10進数 |
echo sprintf('%e','-55'); → 4294967241 |
|
%f |
倍精度浮動小数点数 |
【例】小数点以下3桁表示 echo sprintf('%.3f','55'); → 55.000 【例】8文字固定長右揃え echo sprintf('% 8s',sprintf('%.3f','55')); → 55.000 |
|
%F |
単精度浮動小数点数(PHP 4.3.10、5.0.3以降) | ||
%o |
整数として扱い8進数にして返す | ||
%s |
文字列 |
【例】通常、幅10文字右詰め、幅10文字左詰め $ php -r "echo sprintf('[%s]','hoge').\"\n\";" [hoge] $ php -r "echo sprintf('[%10s]','hoge').\"\n\";" [ hoge] $ php -r "echo sprintf('[%-10s]','hoge').\"\n\";" [hoge ] |
|
%x |
16進数(小文字) | ||
%X |
16進数(大文字) |
str_repeat
は文字列を指定回数繰り返した文字列を返す。
【書式と戻り値】 str_repeat(文字列,回数); →文字列を指定回数繰り返した文字列(文字列 string 型)
文字列を整形して出力する。配列変数の内容を表示する場合などに便利。
var_dump
は、変数に関する情報を出力する。戻り値はなし。
==== test.php === <?php $a = array(1, 2, array("a", "b", "c")); $b = 1.23; $c = true; $d = "abc"; var_dump($a); var_dump($b); var_dump($c); var_dump($d); ?> ================= shell> ./test.php array(3) { [0]=> int(1) [1]=> int(2) [2]=> array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" } } float(1.23) bool(true) string(3) "abc"
var_dumpの出力を変数に代入するには、出力バッファリングを使う[17]。
【例】 <?php ob_start(); # 出力バッファリング開始 var_dump($var); # 変数varの内容をダンプ $output = ob_get_contents(); # バッファ内容を変数に代入 ob_end_clean(); # バッファ内容を破棄してバッファリング終了 ?>
標準入力からの文字入力を取得したい場合、fgetsを使うとよい。ファイル名には「STDIN」を指定する。ファイルオープン処理は不要。
strlen
は指定した文字列の長さをバイト単位で返す。マルチバイト文字は2以上にカウントされる。マルチバイト関数のオーバーロード設定で文字列関数が有効になっている場合はマルチバイト文字対応のmb_strlen
で読み替えられる。その場合は、マルチバイト文字についても1文字とカウントされる。
【書式】 strlen(文字列) mb_strlen(文字列,エンコーディング)
substr_count
は指定文字列の出現回数を返す。
【書式】 substr_count(検査対象文字列,副文字列,検査開始位置,検査文字数); 【戻り値】 整数
【例】 $ php -r 'echo substr_count("hogehogehoge","hogehoge")."\n";' 1
【例】 $ php -r 'echo substr_count("abcdefg-abcedfg","abc")."\n";' 2 $ php -r 'echo substr_count("abcdefg-abcedfg","abc",0,3)."\n";' 1 $ php -r 'echo substr_count("abcdefg-abcedfg","abc",1,3)."\n";' 0 $ php -r 'echo substr_count("abcdefg-abcedfg","abc",8,3)."\n";' 1 $ php -r 'echo substr_count("abcdefg-abcedfg","abc",9,3)."\n";' 0 $ php -r 'echo substr_count("abcdefg-abcedfg","abc",8,8)."\n";' # 長さが1文字オーバーしている Warning: substr_count(): Length value 8 exceeds string length in Command line code on line 1
参考文献・サイト:
strpos
は文字列が別の文字列中で見つかれば「最初に出現する位置を示す整数」(先頭が0番)を返し、見つからなければfalseを返す。単純文字列検索に使える。なお、文字列が見つからないことを検知する際、"===" 演算子を使う(またはその否定形"!==")。"==" 演算子だと型が論理値型(boolean)ではないがfalseを意味する 0 なども検知されてしまう(最初の文字にヒットした場合は0が返る)。
【書式】 strpos(検索対象文字列,検索内容,開始位置) 【戻り値】 文字列が見つかった場合:見つかった位置(文字列の最初が0文字目) 見つからなかった場合:false
strpos
は任意長の文字列を検索できるのに対し、指定文字列の先頭文字だけを取り出して検索したい場合はstrrpos
を用いる。マルチバイト関数オーバーロードが有効な場合はマルチバイト対応可能なmb_strpos
が自動的に適用される。
preg_match
はPerl互換正規表現構文による文字列検索を行う。指定パターンを検出した時点で検索を終了して 1 を返す。検出しなければ 0、何らかのエラーがあれば False を返す。マッチ回数を取得したいならpreg_match_all
を用いる(戻り値はヒット回数またはFalse)。正規表現については正規表現も参照のこと。マルチバイト文字にも対応した検索についてはmb_ereg
参照のこと。
【書式と戻り値】 preg_match(検索パターン,検索対象文字列,結果格納配列,フラグ,検索開始位置) 検出した場合→1(整数 (int) 型) 検出しなかった場合→0(整数 (int) 型) エラー発生→false(論理 (boolean) 型) preg_match_all(検索パターン,検索対象文字列,結果格納配列,フラグ,検索開始位置) 検出した場合→検出した個数(整数 (int) 型) 検出しなかった場合→0(整数 (int) 型) エラー発生→false(論理 (boolean) 型)
"/^[abc]/"
)。なお、ereg系関数の場合はスラッシュ不要。
preg_match
の場合、結果格納配列を指定すると指定した名前の配列変数に検索結果が格納される。結果格納配列[0] にはパターン全体に一致した文字列が、結果格納配列[1] 以降にはキャプチャ用サブパターン(検索パターン中に(...)で指定したパターングループ)に一致した文字列が代入される。
preg_match_all
の場合、結果格納配列を指定するとフラグの指定に応じた内容が指定した名前の配列変数に検索結果が格納される。格納内容はフラグの項目参照。
preg_match
の場合、フラグに指定できる値は "PREG_OFFSET_CAPTURE
" のみ。このフラグを指定すると、戻り値は一致回数(0か1)に加え、パターンが見つかった位置のオフセット値(先頭を0としてバイト単位で数えた値、UTF-8の場合平仮名、カタカナ、漢字などは3バイト、半角英数字記号は1バイトとしてカウント)も含む配列となる。また結果格納配列にもこのオフセット値が追加される。
preg_match_all
の場合、フラグに指定できる値とそれぞれの場合に結果格納配列へ格納される値は以下の通り。指定しない場合の既定値は "PREG_PATTERN_ORDER"。値による指定も可能[18]。
値 | 結果格納配列[0]への格納値 | 結果格納配列[1]への格納値 | |
---|---|---|---|
PREG_PATTERN_ORDER |
1 | パターン全体に一致した文字列の配列、[0][0]が最初に一致した値、[0][1]が2番目に一致した値。 | 最初のサブパターンに一致した文字列の配列、[1][0]が最初に一致した値、[1][1]が2番目に一致した値。 |
PREG_SET_ORDER |
2 | 最初に検索パターンに一致した値の配列。[0][0]が全体、[0][1]以降がサブパターン。 | 2番目に検索パターンに一致した値の配列。[1][0]が全体、[1][1]以降がサブパターン。 |
PREG_OFFSET_CAPTURE |
256 | 結果格納パターンは既定値の"PREG_PATTERN_ORDER"と同じ。 このフラグを指定すると、戻り値は一致回数(0か1)に加え、パターンが見つかった位置のオフセット値(先頭を0としてバイト単位で数えた値、UTF-8の場合平仮名、カタカナ、漢字などは3バイト、半角英数字記号は1バイトとしてカウント)も含む配列となる。また結果格納配列にもこのオフセット値が追加される。 |
パターンの後に任意で以下の修飾子を指定することができる(例:/pattern/i、大文字小文字を区別しない)。参照:PHP: 正規表現パターンに使用可能な修飾子 - Manual
修飾子 | 内容 |
---|---|
i | 大文字小文字を区別せずマッチする |
m | 通常、文字列は単一行として扱われるため、行頭指定(^)や行末指定($)は文字列の最初や最後にしかマッチしないが、この修飾子を指定すると文字列の最初・最後に加えて各改行の直後・直前にもマッチするようになる。 |
s | 通常、任意の1文字を意味するドット(.)は改行にはマッチしないが、この修飾子を指定すると改行にもマッチするようになる。 |
【例1】preg_match→パターンに一致する文字列が1つ見つかったら終わり $a = 'カロテノイドとその産物が働いているところをPDBに登録されたいくつかの構造で見ることができる。多くのβ-カロテン分子が、光合成で光を捕らえるのに用いられる大きな光化学系で見られる。上図左に示した例はシアノバクテリアから得られた[[mom:022|光化学系I]](PDBエントリー [[PDB:1jb0]])である。端には橙色で示したいくつかのβ-カロテン分子が見える。レチナールはβ-カロテンの半分の大きさで、上図右に示した[[mom:027|ロドプシン]](rhodopsin、PDBエントリー [[PDB:1f88]])のような光感覚蛋白質で見られる。ピンク色で示したレチナールは蛋白質の内側奥深くに埋まっており、そこでリジン(lysine)アミノ酸が付加されている。'; preg_match('/\[\[mom:(.+?)\|(.+?)\]\]/',$a,$match); print_r($match); 【実行結果】 Array ( [0] => [[mom:022|光化学系I]] [1] => 022 [2] => 光化学系I ) 【例2】preg_match + PREG_OFFSET_CAPTUREフラグ preg_match('/\[\[mom:(.+?)\|(.+?)\]\]/',$a,$match,PREG_OFFSET_CAPTURE); print_r($match); 【実行結果】 Array ( [0] => Array ( [0] => [[mom:022|光化学系I]] [1] => 330 ) [1] => Array ( [0] => 022 [1] => 336 ) [2] => Array ( [0] => 光化学系I [1] => 340 ) ) 【例3】preg_match_all→見つかってもその後の文字列から検索続行、最後まで preg_match_all('/\[\[mom:(.+?)\|(.+?)\]\]/',$a,$match,PREG_PATTERN_ORDER); print_r($match); このフラグは既定値と同じなのでなくても動作は同じ↑ 【実行結果】 Array ( [0] => Array ( [0] => [[mom:022|光化学系I]] [1] => [[mom:027|ロドプシン]] ) [1] => Array ( [0] => 022 [1] => 027 ) [2] => Array ( [0] => 光化学系I [1] => ロドプシン ) ) 【例4】preg_match_all、フラグPREG_SET_ORDER preg_match_all('/\[\[mom:(.+?)\|(.+?)\]\]/',$a,$match,PREG_SET_ORDER); print_r($match); 【実行結果】 Array ( [0] => Array ( [0] => [[mom:022|光化学系I]] [1] => 022 [2] => 光化学系I ) [1] => Array ( [0] => [[mom:027|ロドプシン]] [1] => 027 [2] => ロドプシン ) ) 【例5】preg_match_all、フラグ PREG_OFFSET_CAPTURE preg_match_all('/\[\[mom:(.+?)\|(.+?)\]\]/',$a,$match,PREG_OFFSET_CAPTURE); print_r($match); ↑既定のフラグ PREG_PATTERN_ORDER の内容に加え、見つかった場所をオクテット(バイト)値で示す値が追加される。 【実行結果】 Array ( [0] => Array ( [0] => Array ( [0] => [[mom:022|光化学系I]] [1] => 330 ) [1] => Array ( [0] => [[mom:027|ロドプシン]] [1] => 563 ) ) [1] => Array ( [0] => Array ( [0] => 022 [1] => 336 ) [1] => Array ( [0] => 027 [1] => 569 ) ) [2] => Array ( [0] => Array ( [0] => 光化学系I [1] => 340 ) [1] => Array ( [0] => ロドプシン [1] => 573 ) ) )
マルチバイト文字に対応した正規表現検索を行うにはmb_ereg
を用いる(preg_match
と似ているが、こちらはマルチバイト文字に対応していない)。マッチした部分文字列が不要ならmb_ereg_match
を使ってもよい。
【書式】 mb_ereg(検索パターン,検索対象文字列,結果格納変数) mb_ereg_match(検索パターン,検索対象文字列)
.*
(任意の文字0回以上)を付加しておく。
mb_ereg
は検索パターンにヒットした場合、結果格納変数を指定していなければ1を、指定していればヒットした部分のバイト数を返す。それ以外の場合はfalseを返す。
mb_ereg_match
は検索パターンにヒットすればtrue、ヒットしなければfalseを返す。
cat test.php
<?php
$str = 'ふらいぱん';
echo $str." →「ぱん」で検索 ... ";
if (mb_ereg_match('ぱん',$str)) {
echo "Hit!\n";
} else {
echo "Not Hit!\n";
}
echo $str." →「.*ぱん」で検索 ... ";
if (mb_ereg_match('.*ぱん',$str)) {
echo "Hit!\n";
} else {
echo "Not Hit!\n";
}
?>
php test.php
ふらいぱん →「ぱん」で検索 ... Not Hit!
ふらいぱん →「.*ぱん」で検索 ... Hit!
preg_match_all
のマルチバイト文字対応版に当たる、複数回のヒットに対応した関数は用意されていないが、mb_ereg_search_init
(検索条件初期設定を行う)とmb_ereg_search_regs
(実際の検索を行う)を使って相応の関数を定義できる。但し以下の点に注意。
/ ... /
のようにスラッシュではさむが、mb_ereg系関数ではパターンをスラッシュで囲んではいけない。function mb_ereg_match_all($pattern,$subject) { #- マルチバイト文字列検索設定(失敗したらfalseを返して終了) if (!mb_ereg_search_init($subject,$pattern)) { return false; } else { #- 結果格納配列変数初期値セット(空配列) $matches = array(); #- 見つからなくなるまで検索を繰り返す while ($match = mb_ereg_search_regs()) { $matches[] = $match; } return $matches; } }
使用例
$ cat test.php <?php $str = '我々と最も近縁な[哺乳類 ほにゅうるい]のミオグロビンは我々のものとかなり似ているが、[爬虫類 はちゅうるい]や魚類になると分化からより長い時間が経っており違いはより大きくなっている。'; preg_match_all('/[^\[]?[\[]([^\[]+?) +?([^\[]+?)[\]][^\]]?/',$str,$match); $match2 = mb_ereg_match_all('[^\[]?[\[]([^\[]+?) +?([^\[]+?)[\]][^\]]?',$str); echo "Search Items (preg_match_all):\n"; echo var_dump($match); echo "Search Items (mb_ereg_match_all):\n"; echo var_dump($match2); ?> $ php test.php Search Items (preg_match_all): array(3) { [0]=> array(2) { [0]=> string(32) "�[哺乳類 ほにゅうるい]�" [1]=> string(32) "�[爬虫類 はちゅうるい]�" } [1]=> array(2) { [0]=> string(9) "哺乳類" [1]=> string(9) "爬虫類" } [2]=> array(2) { [0]=> string(18) "ほにゅうるい" [1]=> string(18) "はちゅうるい" } } Search Items (mb_ereg_match_all): array(2) { [0]=> array(3) { [0]=> string(36) "な[哺乳類 ほにゅうるい]の" [1]=> string(9) "哺乳類" [2]=> string(18) "ほにゅうるい" } [1]=> array(3) { [0]=> string(36) "、[爬虫類 はちゅうるい]や" [1]=> string(9) "爬虫類" [2]=> string(18) "はちゅうるい" } }
参考文献・サイト
preg_grep
は、配列の要素のうち、指定した正規表現パターンにマッチするものを要素とする配列を返す。
【書式】 preg_grep(正規表現パターン,配列,フラグ) 【戻り値】 [配列]指定した正規表現パターンにマッチするものを要素とする配列。配列キーは配列のまま。
【例】 $ cat test.php <?php $array = array('tiger','leopard','snow leopard','lion','mountain lion','mavericks','yosemite'); echo "【元配列】"; print_r($array); echo "【leopardを含む】"; print_r(preg_grep('/leopard/',$array)); ?> $ php test.php 【元配列】Array ( [0] => tiger [1] => leopard [2] => snow leopard [3] => lion [4] => mountain lion [5] => mavericks [6] => yosemite ) 【leopardを含む】Array ( [1] => leopard [2] => snow leopard )
str_replace
は、検索対象の中で見つかった検索内容を全て置換内容と置き換えて返す。正規表現を使わない単純な文字列置換。
【書式】 str_replace(検索内容,置換内容,検索対象,置換数格納先) 【戻り値】 置換後の文字列または配列。
↑文字列の検索置換変換などに戻る
strtr
は、文字の変換や部分文字列置換を行う。
【書式】文字単位での置換 strtr(置換対象文字列,置換対象文字群,置換後文字群); 【戻り値】 変換後の文字列
置換対象文字列の中で、置換対象文字群のn文字目が見つかると置換後文字群のn文字目の文字と置換された値が返る。置換対象文字群と置換後文字群の文字列長が同じでなかった場合、長い方の前部、短い方と同じ長さ分だけ用いられ、それより後の部分は無視される。
【書式】文字列単位での置換 strtr(置換対象文字列,置換対応群); 【戻り値】 変換後の文字列 但し、置換対応群の中に空文字のキーがあるとfalseを返す。
置換対応群には、検索文字列をキー、置換後文字列を値した要素群を指定する。複数のキーに一致する場合、より長いキーの方が優先される。
【例】 $ cat test.php <?php $str = "abccbadef"; echo $str."\n"; echo strtr($str,"abc","123")."\n"; echo strtr($str,"abc","12345")."\n"; echo strtr($str,"abcde","123")."\n"; echo strtr($str,array("abc"=>"123","ab"=>"xxx")); ?> $ php test.php abccbadef 123321def # a→1、b→2、c→3 の置換 123321def # 置換後文字の4,5は無視 123321def # 置換前文字のd,eは無視 123cbadef # abc→123 の置換、ab→xxxの置換はabcより短く優先度下なので適用されない
preg_replace
は、Perl互換正規表現構文による文字列置換を行う。正規表現については正規表現も参照のこと。
【書式】 preg_replace(検索パターン,置換パターン,検索置換対象,置換上限回数,置換数格納先); 【戻り値】 検索置換対象が文字列→文字列 検索置換対象が配列→配列 文字列または配列の各要素の扱い 検索パターンにマッチした→置換後の値 検索パターンにマッチしない→検索置換対象そのまま エラーがあった場合→NULL
'/(検索パターン)/(修飾子)'
)で記述する。
戻り値は、置換後の文字列または配列。マッチしなかった場合は元の$subject
がそのまま返される。エラーが発生した場合はNULL
が返される。
検索パターンの修飾子は以下の通り。
修飾子 | 意味 |
---|---|
g | マッチしたものを全件拾う |
i | 大文字と小文字を区別しない |
m | 文字列を複数行として扱う(この指定があると行末指定は実際の行末) |
o | 変数展開を1回行う |
s | 文字列を単一行として扱う(この指定があると行末指定時に改行文字を無視) |
x | 拡張正規表現を使う |
【例1】 <script> $string = '$pname はでんぶんを加水分解する酵素の1つです。'; $pattern = '/¥$pname/'; $replacement ='アミラーゼ'; echo preg_replace($pattern,$replacement,$string); <結果> アミラーゼ はでんぶんを加水分解する酵素の1つです。 【例2】 <script> $string = '右図上部に示したのはノイラミニダーゼ([[PDB:1nn2]])で、4つの同じサブユニットが四角く並んでいる。' $pattern = '/¥¥[¥[(PDB):([0-9a-z]{4})¥]¥]/'; $replacement = '$1エントリー:<a href="http://pdbjs8.pdbj.org/xPSSS/xPSSSSearch?search_type=pdbid_search&query=$2">$2</a>' echo preg_replace($pattern,$replacement,$string); <結果> 右図上部に示したのはノイラミニダーゼ(PDBエントリー:<a href="http://pdbjs8.pdbj.org/xPSSS/xPSSSSearch?search_type=pdbid_search&query=1nn2">1nn2</a>)で、4つの同じサブユニットが四角く並んでいる。
マルチバイト文字に対応した正規表現検索を行うにはmb_ereg_replace
を用いる。大文字小文字の区別をしない場合はmb_eregi_replace
(mb_ereg_replace
で i オプションをつけたのと同じ)。使用するエンコードは内部エンコーディングまたはmb_regex_encoding
で指定したもの。
【書式】 mb_ereg_replace(検索パターン,置換パターン,置換対象文字列,オプション);
オプション
.
」(任意の1文字)に含まれるようになる)置換に成功した場合は置換後の文字列を、エラー発生時はfalseを返す。
【例】
<?php
echo "<html>\n<body>\n";
$a = "あいうえお.jpg あいうえお.png あかさたな.jpg";
echo "<p>\$a は「" . $a . "」です。</p>\n";
echo "<p>「あ」で始まり、「.jpg」で終わる場合、「あ」を「か」に置換します。</p>\n";
echo "<p>結果は「" . mb_ereg_replace('あ([^ ]+?\.jpg)','か\1',$a) . "」です。</p>\n";
echo "</body>\n</html>\n";
?>
※パターンについて
[^ ]: 空白( )以外
+?\.jpg: 1文字以上最短マッチ(最初の .jpg でヒット範囲は停止)
【出力結果】
$a は「あいうえお.jpg あいうえお.png あかさたな.jpg」です。
「あ」で始まり、「.jpg」で終わる場合、「あ」を「か」に置換します。
結果は「かいうえお.jpg あいうえお.png かかさたな.jpg」です。
trim
は指定文字列の先頭末尾にある指定文字を削除した文字列を返す。またltrim
は先頭だけを対象に、rtrim
は末尾だけを対象にして指定文字を削除し、削除済みの文字列を返す。削除対象とする文字の指定がない場合の既定値は空白文字(NULL、タブ、改行などを含む、詳細は下記参照)。
【書式】 trim(文字列,削除対象文字); ltrim(文字列,削除対象文字); rtrim(文字列,削除対象文字); 【戻り値】 指定文字削除済み文字列
substr
は、文字列の一部を返す。位置指定はバイト単位で行うため、マルチバイト文字についてはバイト数を考慮してカウントし指定する必要がある。マルチバイト関数のオーバーロード設定で文字列関数のオーバーロードを有効にしている場合は、mb_substr
と読み替えられる。その場合は文字種にかかわらず1文字としてカウントされる。
【書式】 substr(処理対象文字列, 開始位置, 長さ) mb_substr(処理対象文字列, 開始位置, 長さ) 【例1】 $rest = substr("abcdef", 0, 3); → "abc" を返す(正数は先頭からのカウント、先頭文字が0番目) $rest = substr("abcdef", 3); → "def" を返す(第2引数がない場合は最後まで) $rest = substr("abcdef", -1); → "f" を返す(負数は末尾からのカウント、最後の文字が-1番目) $rest = substr("abcdef", -2); → "ef" を返す $rest = substr("abcdef", -3, 1); → "d" を返す $rest = substr("abcdef", 0, -1); → "abcde" を返す $rest = substr("abcdef", 2, -1); → "cde" を返す $rest = substr("abcdef", 4, -4); → "" を返す $rest = substr("abcdef", -3, -1); → "de" を返す 【例2】UPDATE datatable SET name="jiro",species="shiba",sex="male" WHERE name="taro" を生成 $datalist = array('name'=>'jiro,'species'=>'shiba','sex'=>'male'); $qstr = 'UPDATE datatable SET '; foreach($datalist as $key=>$value) { $qstr = $qstr . $key . '="' . $value . '",'; } $qstr = substr($qstr,0,-1) . ' WHERE name="' . 'taro' . '"'; ↑最後の1文字(カンマ)を除去してから WHERE...を追加している 【例3】@より前の部分を取り出す <?php $address = "user@mail.hoge.com"; $local = substr($address,0,strpos($address,'@')); ↑0番目(先頭文字)からn文字取り出す n='@'の場所、先頭を0として数えているのでn文字取り出すと丁度@の直前文字までになる strposコマンドも参照のこと echo $local; ?> user
以下の通りいくつか文字列を分割する関数がある。詳細は各節を参照のこと。
関数 | 分割基準 | 戻り値 |
---|---|---|
explode(区切り文字列,対象文字列,最大要素数)
|
指定文字列 | 配列 |
preg_split(パターン,対象文字列,最大要素数,フラグ)
|
正規表現 | |
str_split(対象文字列,分割部最大長)
|
文字数 | |
wordwrap(対象文字列,文字数,分割文字列,cut)
|
文字数 | 文字列 |
explode
は文字列を指定した文字列で分割し、各部分文字列を要素とする配列を返す。
$ php -r "print_r(explode(',','Shiga,Kyoto,Osaka,Hyogo,Nara,Wakayama'));" Array ( [0] => Shiga [1] => Kyoto [2] => Osaka [3] => Hyogo [4] => Nara [5] => Wakayama )
explode
は文字列を指定した文字列で分割し、各部分文字列を要素とする配列を返す。最大要素数に正の値を指定した場合、返される配列の要素数はこの指定値以内となり、部分文字列の個数がこの値を越えた場合は最後の要素に対象文字列の残り全てが格納される。負の値が指定された場合は、最後の"-要素数"個の要素を除く全てが返される。0を指定すると1を指定したものとみなされる(=全てが1個の要素に格納される)。このパラメータを省略した場合は、全ての要素が返される。
区切り文字列が空("")の場合、戻り値はfalse。 区切り文字列が対象文字列に含まれず、要素数が負である場合は対象文字列全体を含む要素を1つ持った配列を返す。
preg_split
はパターンで指定した正規表現にマッチした文字列で対象文字列を分割し、各部分文字列を要素に持つ配列を返す。
最大要素数として自然数を指定すると、分割要素数は最大でも指定した個数となり、残った文字列は最後の要素に含められる。最大要素数に0または-1を指定すると「制限なし」を指定したものとして扱われる(既定値は-1)。
フラグには次のフラグを組み合わせたものを指定する。ビット論理和演算子「|」で指定を組み合わせることもできる。
$ php -r "var_dump(preg_split('/,/','alpha,,gamma,delta'));" array(4) { [0]=> string(5) "alpha" [1]=> string(0) "" ←PREG_SPLIT_NO_EMPTYオプションを付けるとこれは除外される [2]=> string(5) "gamma" [3]=> string(5) "delta" } $ php -r "var_dump(preg_split('/,/','alpha,,gamma,delta',-1,PREG_SPLIT_NO_EMPTY));" array(3) { [0]=> string(5) "alpha" [1]=> string(5) "gamma" [2]=> string(5) "delta" }
$ php -r "print_r(preg_split('/(\(.+?\)),/', 'midosuji(red),tanimachi(perple),yotsubashi(blue),chuo(green),sennichimae(pink),sakaisuji(brown),nagahori-tsurumiryokuchi(lime green),imazatosuji(orange),', -1,PREG_SPLIT_NO_EMPTY));" # "\(.+?\)" で ?(最短マッチ指定)を付けないと最長パターン「(red),...(orange)」にマッチ # 対象文字列最後にあるコンマの後の空文字はPREG_SPLIT_NO_EMPTYオプションで除外 Array ( [0] => midosuji [1] => tanimachi [2] => yotsubashi [3] => chuo [4] => sennichimae [5] => sakaisuji [6] => nagahori-tsurumiryokuchi [7] => imazatosuji ) $ php -r "print_r(preg_split('/(\(.+?\)),/', 'midosuji(red),tanimachi(perple),yotsubashi(blue),chuo(green),sennichimae(pink),sakaisuji(brown),nagahori-tsurumiryokuchi(lime green),imazatosuji(orange),', -1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE));" # サブパターン「\(.+?\)」(括弧で囲まれた文字列)もキャプチャー Array ( [0] => midosuji [1] => (red) [2] => tanimachi [3] => (perple) [4] => yotsubashi [5] => (blue) [6] => chuo [7] => (green) [8] => sennichimae [9] => (pink) [10] => sakaisuji [11] => (brown) [12] => nagahori-tsurumiryokuchi [13] => (lime green) [14] => imazatosuji [15] => (orange) )
$ php -r "print_r(preg_split('/ /','hypertext language programming'));" Array ( [0] => hypertext [1] => language [2] => programming ) $ php -r "print_r(preg_split('/ /','hypertext language programming',-1,PREG_SPLIT_OFFSET_CAPTURE));" Array ( [0] => Array ( [0] => hypertext [1] => 0 ) [1] => Array ( [0] => language [1] => 10 ) [2] => Array ( [0] => programming [1] => 19 ) )
str_split
は指定文字数ごとに文字列を分割してそれぞれを配列要素に格納する。最後の要素は指定文字数に満たない場合がある。分割部最大長の既定値は1。
【例】3文字ずつに分ける
<?php
$array = str_split("abcdefghij",3);
?>
Array
(
[0] => abc
[1] => def
[2] => ghi
[3] => j
)
wordwrap
は指定文字数ごとに分割文字列を挿入する。cut に true をセットすると、指定幅より長い単語でも強制的に分割される。文字数の既定値は75、分割文字列の既定値は改行(LF、\n
)。
【例】40文字ごとに改行を入れる。 $ php -r 'echo wordwrap("This is a pen. That is a pencire erasers. Those are three pairs of scissors.",40)."\n";' This is a pen. That is a pencil. These are erasers. Those are three pairs of scissors. 【例】長い単語を強制改行 $ php -r 'echo wordwrap("abcdefghijklmnopqrstuvwxyz",10,"\n")."\n";' abcdefghijklmnopqrstuvwxyz $ php -r 'echo wordwrap("abcdefghijklmnopqrstuvwxyz",10,"\n",true)."\n";' abcdefghij klmnopqrst uvwxyz
関数 | 内容 |
---|---|
strtolower(文字列) |
文字列を全て小文字にする |
strtoupper(文字列) |
文字列を全て大文字にする |
lcfirst(文字列) |
先頭文字がアルファベットなら小文字に変換する(他は変更しない) |
ucfirst(文字列) |
先頭文字がアルファベットなら大文字に変換する(他は変更しない) |
ucwords(文字列) |
文字がアルファベットの場合、各単語の先頭文字を大文字にする。 ここで言う単語は空白文字(スペース、LF、CR、LF+CR、水平tab、垂直tab)の直後にあるあらゆる文字列を指す。 |
「アルファベット」の範囲はロケール情報に依存する(既定ではウムラウトがついた文字などは含まれない)。
【例1】 $str = "This is a pen.\n"; echo $str; $str = strtoupper($str); echo $str; $str = strtolower($str); echo $str; $str = ucfirst($str); echo $str; $str = ucwords($str); echo $str; 【結果】 This is a pen. THIS IS A PEN. this is a pen. This is a pen. This Is A Pen.
htmlspecialchars
は、そのままhtmlソースコード上に記述すればhtmlのコードとして認識され意図しない出力となってしまう文字群にエスケープ処理を施し、文字そのもの(実体参照)が表示されるように変換する。逆に元に戻すのがhtmlspecialchars_decode
。
【書式】 htmlspecialchars(文字列,フラグ,文字セット,double_encode) 【戻り値】 変換後の文字列 但し、文字列中に
オプション
ENT_COMPAT | ENT_HTML401
(不等号、アンパサンド、ダブルクォートを変換、コードを HTML 4.01 として処理)。
フラグ名 | ビット値 | 説明 |
---|---|---|
ENT_COMPAT | 2 | ダブルクオートは変換しますがシングルクオートは変換しません。 |
ENT_QUOTES | 3 | シングルクオートとダブルクオートを共に変換します。 |
ENT_NOQUOTES | 0 | シングルクオートとダブルクオートは共に変換されません。 |
ENT_IGNORE | 4 | 無効な符号単位シーケンスを含む文字列を渡したときに、 空の文字列を返すのではなく無効な部分を切り捨てるようになります。 これは過去との互換性のために残されているものです。 セキュリティの問題が発生する可能性があるので、使わないようにしましょう。 |
ENT_SUBSTITUTE | 8 | 無効な符号単位シーケンスを含む文字列を渡したときに、 空の文字列を返すのではなく Unicode の置換文字に置き換えます。 UTF-8 の場合は U+FFFD、それ以外の場合は FFFD; となります。 |
ENT_DISALLOWED | 128 | 指定した文書型において無効な符号単位シーケンスを含む文字列を渡したときに、 Unicode の置換文字に置き換えます。 UTF-8 の場合は U+FFFD、それ以外の場合は FFFD; となります。 |
ENT_HTML401 | 0 | コードを HTML 4.01 として処理します。 |
ENT_XML1 | 16 | コードを XML 1 として処理します。 |
ENT_XHTML | 32 | コードを XHTML として処理します。 |
ENT_HTML5 | (16|32) | コードを HTML 5 として処理します。 |
文字列に含まれる &(アンパサンド)、'(シングルクォート)、"(ダブルクォート)、<、>(不等号)をエスケープする。
対象文字列 | エスケープ処理後文字列 | 第2引数 | ||
---|---|---|---|---|
なし | ENT_NOQUOTES | ENT_QUOTES | ||
& | & | ○ | ○ | ○ |
' | ' | × | × | ○ |
" | " | ○ | × | ○ |
< | < | ○ | ○ | ○ |
> | > | ○ | ○ | ○ |
配列の各要素に対してhtmlエスケープを行いたい場合はforeachを併用する。
【出展】PHP Manual: htmlspecialchars <?php function htmlspecialchars_deep($mixed, $quote_style = ENT_QUOTES, $charset = 'UTF-8') { if (is_array($mixed)) { foreach($mixed as $key => $value) { $mixed[$key] = htmlspecialchars_deep($value, $quote_style, $charset); } } elseif (is_string($mixed)) { $mixed = htmlspecialchars(htmlspecialchars_decode($mixed, $quote_style), $quote_style, $charset); } return $mixed; } ?> $mixed: 配列または文字列(必須) $quote_style: 引用符の扱い(任意、無指定時の既定値は引用符も全てエスケープ) $charset: 文字コード(任意、無指定時の既定値はUTF-8)
元の文字列に戻す、htmlspecialchars
とは逆の操作を行うコマンドがhtmlspecialchars_decode
。引数指定はhtmlspecialchars
と同じ。
urlencode
は、文字列をURLで許可されている形式に変換(エンコーディング)する。具体的には-_. を除くすべての非英数文字が % 記号 (%)に続く2桁の16進数で、空白は + 記号(+)に置換される。rawurlencode
も同様だが、除外対象にチルダ (~) が加わり(PHP 5.3.0以降)、空白は他の非英数文字と同様に % + 2桁の16進数(%20)に置き換えられる点が異なる。
PHP 5.3.0以降におけるrawurlencode
の動作はRFC 3986で規定されたエンコーディング方法、PHP 5.3.0より前のバージョンではRFC 1738の規定に基づきチルダ (~) もエンコードされていた。
urlencode
とrawurlencode
の違いを以下にまとめた。
文字 | urlencode | rawurlencode | 備考 |
---|---|---|---|
|
+ |
%20 |
空白 |
~ |
%7E |
~ |
チルダ |
【例】PHP 5.3.0以降の場合 $ cat test.php <?php $array = array(' -_.~','!"#$%&\'()*+,/', ':;<=>?@', '[\]^`{|}', '¥'); foreach ($array as $val) { echo $val."\n"; echo " urlencode : ".urlencode($val)."\n"; echo " rawurlencode: ".rawurlencode($val)."\n"; } ?> $ php test.php -_.~ urlencode : +-_.%7E rawurlencode: %20-_.~ !"#$%&'()*+,/ urlencode : %21%22%23%24%25%26%27%28%29%2A%2B%2C%2F rawurlencode: %21%22%23%24%25%26%27%28%29%2A%2B%2C%2F :;<=>?@ urlencode : %3A%3B%3C%3D%3E%3F%40 rawurlencode: %3A%3B%3C%3D%3E%3F%40 [\]^`{|} urlencode : %5B%5C%5D%5E%60%7B%7C%7D rawurlencode: %5B%5C%5D%5E%60%7B%7C%7D ¥ urlencode : %C2%A5 rawurlencode: %C2%A5
逆の変換を行うのが、urldecode
とrawurldecode
。
MySQLに送るクエリ文(mysql_query、mysqli_queryで指定するクエリ文)を、安全な形式に変換するにはmysql_real_escape_string
(旧式MySQLコマンド)、mysqli_real_escape_string
(改良型MySQLiコマンド)を用いる。このコマンドは、具体的には以下の各文字列の直前にバックスラッシュを付加してエスケープ処理を行う。
元の値 | 処理後の値 | 処理内容 | 値の内容 |
---|---|---|---|
\x00 |
'\x00' |
シングルクォートで囲む | NULコード(ASCII 0x00、ヌル) |
\n |
'\n' |
LFコード(ASCII 0x0A、Line Feed(改行、UNIX改行コード) | |
\r |
'\r' |
CRコード(ASCII 0x0D、Carriage Return(復帰、Mac改行コード) | |
\x1a |
'\x1a' |
SUBコード(ASCII 0x1A、Substitute(置換)) | |
\ |
\\ |
先頭にバックスラッシュを付加 | |
' |
\' |
||
" |
\" |
※オンラインマニュアル本文では上記全てに対して、「先頭にバックスラッシュ付加」の処理を行うと記載されているが、下部のユーザコメントによると上記の通り一部はクォート処理になるとのこと。
【MySQL】 mysql_real_escape_string(文字列,接続ハンドル) 【MySQLi オブジェクト指向型】 mysqli::real_escape_string(文字列) 【MySQLi 手続き型】 mysqli_real_escape_string(接続ハンドル,文字列) 【戻り値】 エスケープ済みの文字列
サーバレベル、またはmysqli_set_charset
コマンドで文字セット(文字コード)をあらかじめ指定しておく必要あり。
参考文献・サイト:
crypt
は指定した文字列のハッシュを返す。
マルチバイト関数を利用するには、mbstring関数を有効にする必要がある。インストール後の設定参照。
mb_convert_encoding
は指定の文字列の文字エンコーディングを変換した値を返す。
【書式】 mb_convert_encoding(文字列,変換後文字エンコーディング名,変換前文字エンコーディング) 【例】Shift JISに変換 $str = mb_convert_encoding($str, "SJIS");
mb_language
は、現在の言語設定情報の取得や変更を行う。この設定に基づきメール送信のエンコーディングが決定される。
【書式1】現在の言語設定情報の取得
mb_language
→戻り値は言語名(言語設定が事前に行われている場合)または false
【書式2】現在の言語設定情報を変更
mb_language(エンコーディング指定文字列)
→戻り値はtrue(指定が有効な値であった場合)またはfalse
エンコーディング指定文字列に使用できる文字列は以下のいずれか。各値を設定した場合のメール送信のエンコーディングも合わせて記す
エンコーディング指定文字列 | メール送信エンコーディング |
---|---|
Japanese | ISO-2022-JP/Base64 |
ja | |
English | ISO-8859-1/quoted printable |
en | |
English | UTF-8/Base64 |
mb_internal_encoding
は内部文字エンコーディング情報の取得や変更を行う。
【書式1】現在の内部文字エンコーディング情報の取得
mb_internal_encoding
→戻り値は現在の内部エンコーディング名
【書式2】現在の内部文字エンコーディング情報の変更
mb_language(エンコーディング指定文字列)
→戻り値はtrue(設定に成功した場合)またはfalse(設定に失敗した場合)
エンコーディング指定文字列に指定できる文字は次に挙げるものなど。大文字小文字は区別しない?
参考文献・サイト:
chr
は指定コード(10進数で表記したキャラクターコード)に対する文字を、ord
は、指定文字列の最初の文字に対するキャラクターコードを返す。
【書式】 chr(キャラクターコード) ord(文字列)
マルチバイト文字をord
関数で処理した場合、1文字目の先頭1バイトだけのコードが返る。
【例】 echo dechex(ord('あ')); UTF-8の場合「あ」の文字コードは「e38182」 e3 $ php -r "echo 'aaa'.chr(8).'bbb';" キャラクターコード08はBS(BackSpace、後退)、1文字戻る aabbb $ php -r "echo 'aaa'.chr(10).'bbb';" キャラクターコード10(16進数で0A)はLF(LineFeed、改行) aaa bbb $ php -r "echo 'aaa'.chr(11).'bbb';" キャラクターコード11(16進数で0B)はVT(Vertical Tabulation、垂直タブ) aaa bbb $ php -r "echo 'aaa'.chr(12).'bbb';" キャラクターコード12(16進数で0C)はFF(Form Feed、改ページ)だがVTと見た目は同じ? aaa bbb $ php -r "echo 'aaa'.chr(13).'bbb';" キャラクターコード13(16進数で0D)はCR(Carriage Return、復帰) bbb $ php -r "echo 'aaaaa'.chr(13).'bbb'.chr(10);" 復帰しても上書きする文字列の方が短ければ元の文字列が残る bbbaa
マルチバイト文字のコード全体を得るにはmb_convert_encoding
関数で1バイトずつのASCII文字に変換し、それぞれの文字コードを得てつなげる以下のようなユーザ定義関数を用意する。
function uniord($u) { $k = mb_convert_encoding($u, 'UCS-2LE', 'UTF-8'); $k1 = ord(substr($k, 0, 1)); $k2 = ord(substr($k, 1, 1)); return $k2 * 256 + $k1; } 【出展】PHP Manual: ord の "v0rbiz at yahoo dot com" 氏によるコメント。
上記関数を使った例。
echo dechex(uniord('あ')); 3042 「あ」のUnicode(UTF-16)は16進数で「3042」(2進数で 0011|0000|0100|0010)。 (※UTF-8は、判別符合を付加し 1110|0011| 10|0000|01 1000|0010 (16進数で e38182)) ASCII文字のキャラクターコードでは、30→"0"、42→"B" なので、 「あ」をUCS-2LE(LEは下位ビットが先に来る)に変換すると"B0"。 $k1="0x42"(10進数で66), $k2="0x30"(10進数で48)となり、 戻り値は48×256+66=12354(dechexで16進数に変換すると3042)。
date
は、
【書式】 date(書式指定,UNIXタイム値)
書式指定には定義済み定数または書式文字列を指定する。UNIXタイム値(1970年1月1日 00:00:00 GMTからの積算秒数)を指定しない場合の既定値は現在時刻(=time()
の戻り値)。
値 | 相当する書式 | 例 | 備考 |
---|---|---|---|
DATE_RSS |
D, d M Y H:i:s |
Mon, 15 Aug 2005 15:52:01 +0000 |
RSS書式 |
種類 | 書式文字 | 内容 | 戻り値の例 |
---|---|---|---|
年 | Y |
西暦を4桁表示 | 1999 , 2009 |
y |
西暦の下2桁を表示 | 99 , 09 |
|
L |
閏年かどうか | 閏年→1 、非閏年→0 |
|
月 | n |
月の数字表記。先頭の0は表記しない。 | 1 〜12 |
m |
月を常に2桁の数字で表記。 | 01 〜12 |
|
t |
指定月の日数。 | 28 〜31 |
|
F |
月名をフルスペルで表記。 | January 〜December |
|
M |
月名を3文字形式で表記。 | Jan 〜Dec |
|
週 | W |
月曜日に始まる年単位の週番号(ISO-8601形式) | 年の42週目→42 |
日 | j |
日の数字表記。先頭の0は表記しない。 | 1 〜31 |
d |
日を常に2桁の数字で表記。 | 01 〜31 |
|
S |
英語の序数を示す接尾辞2文字。j と併用可能。 |
st , nd , rd , th のいずれか |
|
z |
年通算日。1/1が0。 | 0 〜365 |
|
曜日 | N |
曜日の数値表記(ISO-8601 形式) | 1 (月曜日)〜7 (日曜日) |
w |
曜日の数値表記 | 0 (日曜日)〜6 (土曜日) |
|
l |
曜日のフルスペル表記 | Sunday 〜Saturday |
|
D |
曜日の3文字表記 | Sun 〜Sat |
|
午前午後 | a |
午前午後を小文字2文字表記 | am , pm |
A |
午前午後を大文字2文字表記 | AM , PM |
|
時 | g |
時を12時間単位で表記、1桁時は10の位の0を付けない。 | 1 〜12 |
G |
時を24時間単位で表記、1桁時は10の位の0を付けない。 | 0 〜23 |
|
h |
時を12時間単位で2桁表記、1桁時は10の位の0を付ける。 | 01 〜12 |
|
H |
時を24時間単位で2桁表記、1桁時は10の位の0を付ける。 | 00 〜23 |
|
分 | i |
分を常に2桁の数値で表記。 | 00 〜59 |
秒 | s |
秒を常に2桁の数値で表記。 | 00 〜59 |
タイムゾーン | O |
グリニッジ標準時(GMT)との時差 | 例:+0900 |
P |
グリニッジ標準時(GMT)との時差、時と分の間にコロンあり(PHP 5.1.3以降) | 例:+09:00 |
|
T |
タイムゾーン名略称 | 例:JST |
|
e |
タイムゾーン名(PHP 5.1.0 で追加) | 例:Asia/Tokyo |
|
総合 | c |
ISO 8601 形式の日付(PHP5以降、'Y-m-d\TH:i:sP' 相当) | 例:2004-09-28T13:53:21+09:00 |
r |
RFC 2822 形式の日付('D, d M Y H:i:s O' 相当) | 例:Mon, 28 Sep 2009 13:53:21 +0900 |
|
U |
Unixタイム(1970年1月1日0時0分0秒からの積算秒数) | 例:1254171201 |
【例】 # UNIXタイム0=1970年1月1日 0:00:00(UTC) $ php -r 'echo date("Y/m/d H:i:s O(T)",0)."\n";' 1970/01/01 09:00:00 +0900(JST) # 現在時刻 $ php -r 'echo date("Y/m/d H:i:s O(T)")."\n";' 2013/08/27 15:31:19 +0900(JST)
mktime
は、指定日時に対応するUNIXタイムスタンプ(1970年1月1日 00:00:00からの積算秒数)を返す。引数は後ろから順に省略可能で、省略された値はローカルの日付時刻値に従った現在の値にセットされる。引数が不正であった場合は false が返る(PHP 5.1以降の場合、それより前は -1)。PHP 5.1以降で全ての引数を省略すると E_STRICT notice を返すようになったので、現在時刻のUNIXタイムスタンプを得るにはtime
を使うこと。
【書式】 mktime(時,分,秒,月,日,年) →整数(UNIXタイムスタンプ)または false(PHP 5.1以降、それより前は-1)
date('H')
の戻り値)だが、PHP 5.1以降では全ての引数を省略することはできない。
date('i')
の戻り値)。
date('s')
の戻り値)。
date('n')
の戻り値)。
date('j')
の戻り値)。
date('Y')
の戻り値)。
【例】現在から72時間前 $ cat test.php #!/usr/bin/php <?php date_default_timezone_set('Asia/Tokyo'); # PHP 5.1以降、既定時間帯の設定は必須(php.iniに設定していない場合) echo date('Y/m/d H:i:s',mktime(date('H')-72)); echo " (UNIX epoch: ".mktime(date('H')-72).")\n"; ?> $ php ./test.php 2011/05/10 13:04:39 (UNIX epoch: 1305000279) 【例】前月の年月 $ php -r "date_default_timezone_set('Asia/Tokyo');echo 'Today is '.date('Y/m/d').\"\n\";" Today is 2011/08/01 $ php -r "date_default_timezone_set('Asia/Tokyo');echo 'The last month is '.date('Y/m',mktime(0,0,0,date('m')-1)).\"\n\";" The last month is 2011/07
date_default_timezone_set
は、日付/時刻関数で 使用されるタイムゾーンの既定値を設定する。PHP初期設定ファイルのdate.timezone
に設定しても同じ(記述例:date.timezone = 'Asia/Tokyo'
)。PHP 5.1.0 以降、タイムゾーンを 正しく設定せずに日付/時刻関数をコールすると E_NOTICE が発生し、システムの設定や TZ 環境変数を 使用すると E_WARNING エラーが発生するようになっている。
【書式】 date_default_timezone_set(タイムゾーン識別子); 【戻り値】 正しいタイムゾーン識別子→true 正しくないタイムゾーン識別子→false 【例】 date_default_timezone_set('Asia/Tokyo'); # 既定タイムゾーンの設定がないと、警告が出る $ cat test.php #!/usr/bin/php <?php $today = date('Y年n月j日'); echo <<< _STR_ 今日は${today}です。 _STR_ ; ?> $ php test.php Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for 'JST/9.0/no DST' instead in /Library/Webserver/Documents/kw1/jv/test/test.php on line 3 今日は2015年1月19日です。 # 既定タイムゾーンの設定を追加すると、警告が出なくなった $ cat test2.php #!/usr/bin/php <?php date_default_timezone_set('Asia/Tokyo'); $today = date('Y年n月j日'); echo <<< _STR_ 今日は${today}です。 _STR_ ; ?> $ php test2.php 今日は2015年1月19日です。
strtotime
は英語の書式で書かれた日付をUnixタイムスタンプ(1970 年 1 月 1 日 00:00:00 UTC からの経過秒数)に変換する。
【書式】 strtotime(文字列,起点となる時刻); 【引数】 文字列:[文字列]日付や時刻を含む文字列 起点となる時刻:[整数]戻り値を計算する際、起点となる時刻のUNIXタイムスタンプ。 指定がなかった場合の既定値は現在時刻(timeの戻り値) 【戻り値】 成功→[整数]タイムスタンプ 失敗→false 【例】 $ cat test.php <?php $strlist = array("now","10 September 2000","+1 day","+1 week","+1 week 2 days 4 hours 2 seconds", "next Thursday","last Monday","2018/02/01","03/02/01","2018-02-01"); foreach ($strlist as $str) { echo date('Y-m-d H:i:s O(T)',strtotime($str)).' ('.strtotime($str).')'.' <- '.$str."\n"; } ?> $ php test.php 2018-02-21 15:01:40 +0900(JST) (1519192900) <- now 2000-09-10 00:00:00 +0900(JST) (968511600) <- 10 September 2000 2018-02-22 15:01:40 +0900(JST) (1519279300) <- +1 day 2018-02-28 15:01:40 +0900(JST) (1519797700) <- +1 week 2018-03-02 19:01:42 +0900(JST) (1519984902) <- +1 week 2 days 4 hours 2 seconds 2018-02-22 00:00:00 +0900(JST) (1519225200) <- next Thursday 2018-02-19 00:00:00 +0900(JST) (1518966000) <- last Monday 2018-02-01 00:00:00 +0900(JST) (1517410800) <- 2018/02/01 2001-03-02 00:00:00 +0900(JST) (983458800) <- 03/02/01 2018-02-01 00:00:00 +0900(JST) (1517410800) <- 2018-02-01
日付の表記には注意が必要。スラッシュ区切りはアメリカ風の m/d/y 、ダッシュ (-) あるいはドット (.) で区切られている場合はヨーロッパ風の d-m-y であるとみなす。年を二桁で表して区切り文字がダッシュ (-) である場合は、 y-m-d であるとみなす。
このような曖昧さを避けるためにも、ISO 8601 形式 (YYYY-MM-DD) を使うか、可能であれば DateTime::createFromFormat() を使うことが推奨される。
書式列のリンク先はPHP Manualの各ページ。
書式 | Trueパターン |
---|---|
ctype_digit(文字列)
|
文字列が全て数字だった場合。 ※「数値」は文字列ではないのでFalseが返る。数値もtrueを返して欲しい場合は is_numeric を用いる。
|
is_numeric(変数)
|
変数が数値または全て数字で構成される文字列であった場合('1a'など英字を含む16進数表記も'0x1a'と記して16進数である宣言を行えばtrueになる)。 |
is_int(変数)
|
変数が整数であった場合。 |
is_float(変数)
|
変数が浮動小数点型(float)であった場合。 |
is_bool(変数)
|
変数が真偽値型(boolean)であった場合。 |
is_null(変数)
|
変数がNULLであった場合。 |
is_string(変数)
|
変数が文字列であった場合。 |
is_array(変数)
|
変数が配列であった場合。 |
is_object(変数)
|
変数がオブジェクトであった場合。 |
is_resource(変数)
|
変数がリソース型であった場合。リソース型はオープンされたファイル、データベース接続、イメージキャンバスエリアのような特殊なハンドルを保持する変数型。 |
式 | 判定 | 備考 |
---|---|---|
$src = array(1,0,0,0,1,0,0,0,1,0,0,0); $dest = array(1,0,0,0,1,0,0,0,1,0,0,0); $src == $dest; |
true | 配列同士の比較も可能 |
array() == NULL; | true | 空配列とNULL |
array() === NULL; | false | 空配列は型判定まで含むとNULLとは一致しない |
前に"(型)
" と記すことで型を宣言(型キャスト)できる。
$a = 100; // $a は整数 $b = (string) $a; // $b は文字列
利用できる型キャストは以下の通り。
型キャスト記述 | |
---|---|
(int), (integer) |
整数 |
(bool), (boolean) |
論理値 |
(float), (double), (real) |
float(浮動小数点)値 |
(string) |
文字列 |
(array) |
配列 |
(object) |
オブジェクト |
(unset) |
NULL(PHP5) |
intval
は、指定された文字列を整数に変換する。
【書式】 intval(変数名,基数);
戻り値は以下の通り。
引数、状況 | 戻り値 |
---|---|
変換成功 | (指定基数の整数値) |
変換失敗 | 0 |
空の配列 | |
空のオブジェクト | |
空ではない配列 | 1 |
空ではないオブジェクト | |
文字列 | 先頭(左側)に1つ以上の数字があればその数字群が示す数値、そうでなければ0 |
論理値 | false は 0、true は 1 |
英字を含む引数に指定した場合、「数値または.」+「e/E」+「数値または.」の形式なら数値とみなされる。基数に10より大きい値を指定した場合で、該当値に当たる文字があれば数値とみなされる(例:16進数のA~F)。それ以外の英字は0となる。
【例】 intval(42); → 42 intval(4.2); → 4 intval('42'); → 42 intval('+42'); → 42 intval(042); → 42 intval('042'); → 42 intval('42',8); → 34、8進数の"42"が10進数の整数値に変換される intval('0x1f'); → 0、英字を含むと原則として0になる intval('0x1f',16); → 31、基数を指定するとa〜fも数字文字列とみなされる intval('1f',16); → 31、基数16を指定すれば"0x"を前に付けなくても16進数とみなされる intval('01f',16); → 31、頭に空桁があっても同じ
なお、intval
は出力形式を指定できないので、出力形式を指定したい場合はsprintf
を用いる。
バイナリ値を16進数値に変換するにはbin2hex
を用いる。
逆16進数値をバイナリ値に変換するにはhex2bin
を用いる。
for
は指定回数繰り返し処理を行うのに使える。
【書式】 for (式1;式2;式3) { 文 }
式1は繰り返し処理全体の開始時、無条件に実行される。 式2は各回繰り返し処理開始時に評価され、結果がTrueなら文が実行される。Falseなら繰り返し処理は終了する。 式3は各回繰り返し処理後、無条件に実行される。
【例】 for ($i = 1; $i <= 10; $i++) { echo $i . " "; } 【結果】 1 2 3 4 5 6 7 8 9 10
まず最初に「$i = 1
」($i に 1 を代入する)が実行されて繰り返し処理が開始される。
「$i <= 10
」($i は 10 以下)の評価結果はTrueなので「$i . " "
」($i と空白を出力)が実行される。その後「$i++
」($i に 1 を足す)が実行されて次のループに進む。10回ループが実行され $i が 11 になった時、$i <= 10
がFalseになるので繰り返し処理は終了する。
foreach
は配列の全要素に対して処理を行う。
【書式】 foreach (配列変数 as 一時変数名) foreach (配列変数 as 一時変数キー名=>一時変数名) 【例】 $a = array(1,2,3); foreach ($a as $item) { echo $item * 2 . ","; } 2,4,6 foreach ($a as $key=>$item) { $b[$key] = $item * 2; } print_r($b); Array ( [0] => 2 [1] => 4 [2] => 6 )
while
は最初に条件判定を行い条件を満たしている間処理を繰り返す。do-while
は最低1回は処理を行ってから条件判定を行う。
【書式】 while (条件) { 処理 } do { 処理 } while (条件); 【例】 $i = 1; while ($i <= 10) { ←$iが10以下である間は繰り返す echo $i++ . " "; ←$iを表示してから1を加える(→演算参照) } 1 2 3 4 5 6 7 8 9 10 $i=10の処理→次は$i=11なので処理されず終了 do { echo $i++ . " "; } while ($i <= 10); ←$iが10以下である間は繰り返す 11 まず処理実行→その後判定→$i=12>10なので条件に合わず終了
break
は for, foreach, while, do-while, switch 構造の実行を終了する。引数を省略すると直近のループ構造のみを出る(つまり既定値は1)。
【書式】
break ループ構造を抜ける段数
参考文献・サイト:
PHP の定義済み変数のうち「スーパーグローバル」は、スクリプト全体を通して全てのスコープで使用可能。関数やメソッドの内部からアクセスする際にも global $variable; などの宣言は不要。スーパーグローバルには以下のものがある。
現在の設定値はコマンドラインで直接コードを実行(→参照:直接コマンドライン上にコードを記述する)して確認できる(但し、スクリプト上でないと確認できない項目もある)
shell> php -r 'print_r($_SERVER);' Array ( [HOSTNAME] => www.hoge.com [TERM] => xterm-color [SHELL] => /bin/bash ... )
下記の例は、
/var/www/html/index.php
http://www.hoge.com/foo/index.php
http://www.hoge.com/foo/index.php?p=123&q=abc
$_SERVERの各キーと対応する値の内容、例を以下に示す。
変数 | 例 | 内容 |
---|---|---|
$_SERVER['SERVER_PROTOCOL'] | HTTP/1.1 | プロトコル名、バージョン |
$_SERVER['SERVER_SOFTWARE'] | Apache/2.2.3 (Red Hat) | ウェブサーバのソフトウェア名、バージョン |
$_SERVER['REQUEST_METHOD'] | GET | リクエストメソッド名(GET,HEAD,POST,PUTなど) |
$_SERVER['SERVER_NAME'] | www.hoge.com | サーバのホスト名 |
$_SERVER['HOSTNAME'] | www.hoge.com | サーバのホスト名 |
$_SERVER['SERVER_ADDR'] | 1.2.3.4 | サーバのIPアドレス |
$_SERVER['PHP_SELF'] | /foo/test.php | リモート絶対パス+ファイル名 |
$_SERVER['SCRIPT_NAME'] | /foo/test.php |
PHP_SELFとは常に同じ?
REQUEST_URIとは以下の場合に値が異なる。
|
$_SERVER['REQUEST_URI'] | /foo/test.php?p=123&q=abc | アクセスURIの絶対パス+ファイル名+クエリ文字列。URI末尾にある#以降の文字列(id属性値で表示するページ内の位置を指定する)は含まれない。 |
$_SERVER['QUERY_STRING'] | p=123&q=abc | クエリ文字列(ファイル名の後に記す?より後の文字列) |
$_SERVER['DOCUMENT_ROOT'] | /var/www/html | ドキュメントルートのローカル絶対パス |
$_SERVER['SCRIPT_FILENAME'] | /var/www/html/foo/test.php | ローカル絶対パス+ファイル名 |
__FILE__ | /var/www/html/foo/test.php | $_SERVER['SCRIPT_FILENAME']と同じ |
$_SERVER['HTTP_USER_AGENT'] | Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; ja-JP-mac; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 | リクエストにUser-Agent:ヘッダがあればその内容 |
$_SERVER['HTTP_ACCEPT_LANGUAGE'] |
ja ja,en-us;q=0.8,en;q=0.7,zh-cn;q=0.5,zh-tw;q=0.3,ru;q=0.2 |
リクエストにAccept-Language:ヘッダがあればその内容。クライアントブラウザに複数の言語が設定されている場合、適当に比重を示す値が合わせてセットされウェブサーバに送られるよう。 |
$_SERVER['REMOTE_PORT'] | 56789 | アクセス元側の通信ポート番号 |
$_SERVER['SERVER_PORT'] | 80 | ウェブサーバ側の通信ポート番号 |
$_SERVER['HTTP_REFERER'] | http://example.com/ | リンクをたどってページにやってきた場合、リンク元のURL情報があればその値を返す |
$_SERVER['HTTPS'] | on | 使用プロトコルがHTTPSであった場合、空ではない値(on)が返される。 |
スクリプトファイル名だけを取り出すにはbasename
関数を用いる。
スクリプトをコマンドラインから実行する場合に関わる定義済み変数($argv
、$argc
)についてはコマンドラインからの実行 - 引数の指定と参照を参照のこと。
それぞれ、GETメソッド、POSTメソッドで送られたキーと値のセットが配列として格納される。
フォームで送信されたファイルに関する情報が格納される。詳細はファイルのアップロードに関する情報参照を参照のこと。
unset
は変数の割り当てを解除する。
【書式】 unset(変数名,変数名...) 【例】 $ cat test.php <?php $array = array(1=>'Hydrogen',2=>'Helium',3=>'Lithium',4=>'Beryllium',5=>'Boron',6=>'Carbon'); var_dump($array); unset($array[1]); var_dump($array); ?> $ php test.php array(6) { [1]=> string(8) "Hydrogen" [2]=> string(6) "Helium" [3]=> string(7) "Lithium" [4]=> string(9) "Beryllium" [5]=> string(5) "Boron" [6]=> string(6) "Carbon" } array(5) { [2]=> string(6) "Helium" [3]=> string(7) "Lithium" [4]=> string(9) "Beryllium" [5]=> string(5) "Boron" [6]=> string(6) "Carbon" }
isset
は変数の設定状況を判定する。「セットされ、NULLではない」ならtrue、そうでないならfalseを返す。複数の変数を指定した場合、前から順に判定してfalseとなる変数があった時点でfalseを返し、最後まで全てtrueならtrueを返す。
【書式】 isset(変数名,変数名...)
empty
は変数が空であるかを調べる。変数が存在しないか、またはfalseと判定される値がセットされている場合に空とみなされる(変数が存在しなくてもエラーにはならない)。「 !isset($var) || $var == false
」の判定をやっているのと同じ。
【書式】
empty(変数);
【戻り値】
空と判定(変数が存在しない場合も含む)→true
空ではない(変数が存在し、かつその値が空と判定されるような値ではない)→false
空と判定される値は以下のとおり。
""
(空文字列)"0"
(文字列の0)参考文献・サイト:
$配列変数名[キー値]
の形でキー毎に個別に代入するか、またはarray
を使って一度に指定する。
【例1】arrayを使って複数の要素を一度に定義 $a = array('abc','def','123'); foreach ($a as $tmp) { print "$tmp¥n"; } 【結果1】 abc def 123 【例2】配列内の個別要素を定義するには、変数名[キー値]を用いる。値は非負整数または文字列。 $b[0] = "ghi"; $b[3] = "def"; $b[] = "xyz"; キー値を省略すると既存最大キー値(3)+1が自動的に採用される print "$b[0]¥n"; print "$b[3]¥n"; print "$b[4]¥n¥n"; print_r $b; 【結果2】 ghi def xyz Array ( [0] => ghi [3] => def [4] => xyz ) 【例3】連想配列(キー値が数値ではない配列)の設定 $c = array('apple' => 'red', 'banana' => 'yellow', 'chocolate' => 'brown'); print_r $c; Array ( [apple] => red [banana] => yellow [chocolate] => brown )
関数 | 処理位置 | 追加/削除 | 戻り値 | 備考 |
---|---|---|---|---|
array_unshift(配列,追加値,追加値...) |
先頭 | 追加 | 処理後の要素数 | 配列の数字添字は0から振り直し、文字キーはそのまま。 |
array_shift(配列) |
先頭 | 削除 | 配列が空ではない→取り出した値 配列が空または配列ではない→NULL |
配列の数字添字は0から振り直し、文字キーはそのまま。 第1引数が空の配列または配列ではない場合、NULLを返す。 |
array_push(配列,追加値,追加値...) |
末尾 | 追加 | 処理後の要素数 | $配列変数名[]=値 を繰り返すのと同じ。 |
array_pop(配列) |
末尾 | 削除 | 配列が空ではない→取り出した値 配列が空または配列ではない→NULL |
第1引数が空の配列または配列ではない場合、NULLを返す。 |
特定の要素を削除するのはunset
。配列添字ふり直しはarray_values
(配列から全ての値を取り出し、数値添字をつけた配列を返す)。
【書式】 unset(変数名, 変数名...); array_values(配列);
$a = array (2 => 'two', 3 => 'three'); print_r($a); Array ( [2] => two [3] => three ) array_push(4 => 'four', 5 => 'five'); ←最後に要素追加 print_r($a); Array ( [2] => two [3] => three [4] => four [5] => five ) $a[] = 'six'; ※要素を1個だけ追加するなら、この方が軽い print_r($a); Array ( [2] => two [3] => three [4] => four [5] => five [6] => six ) array_pop($a) ←最後に要素を1個削除 print_r($a); Array ( [2] => two [3] => three [4] => four [5] => five ) array_unshift($a,'zero','one') ←先頭に要素追加し、添字番号ふり直し(文字列キーの要素はそのまま) print_r($a); Array ( [0] => zero [1] => one [2] => two [3] => three [4] => four [5] => five ) array_shift($a) ←先頭から1個要素削除し、添字番号ふり直し(文字列キーの要素はそのまま) print_r($a); Array ( [0] => one [1] => two [2] => three [3] => four [4] => five ) unset($a[3]) ←指定の要素を削除(添字はそのまま) print_r($a); Array ( [0] => one [1] => two [2] => three [4] => five ) ※unsetは配列用の関数ではなく、変数一般を削除する関数 $a = array_values($a) ←添字番号割り振り直し print_r($a); Array ( [0] => one [1] => two [2] => three [3] => five )
配列の内部ポインタを扱う関数群を以下に記す。
関数 | ポインタ移動先 | 戻り値 |
---|---|---|
reset(配列) |
先頭 |
配列が空→false(論理値)
配列が空ではない→最初の要素の値
|
end(配列) |
末尾 |
配列が空→false(論理値)
配列が空ではない→最後の要素の値
|
next(配列) |
ひとつ次 |
次の要素がない→false(論理値)
次の要素あり→次の要素の値
|
prev(配列) |
ひとつ前 |
前の要素がない→false(論理値)
前の要素あり→前の要素の値
|
current(配列) |
移動せず |
ポインタ箇所が最終要素の次、または配列が空→false(論理値)
それ以外→現在のポインタがある箇所の要素の値
|
key(配列) |
移動せず |
ポインタ箇所が最終要素の次、または配列が空→false(論理値)
それ以外→現在のポインタがある箇所の要素のキー
|
値だけではなく、キーと値のセットを取り出すのに使える、each
という関数(配列から現在のポインタ位置のキー・値ペアを返して、ポインタを進める)があったがこの関数はPHP7.2.0で非推奨となりPHP8.0.0で削除されたので利用は非推奨。
【書式】
each(配列);
【戻り値】
ポインタ位置が配列の最後より後→false
not→以下の配列
Array {
(
[0]=>キー
[1]=>値
[key]=>キー
[value]=>値
)
}
配列内の要素数を数えるにはcount
関数を用いる。
【書式】 count(配列,カウントモード) 【戻り値】 数えられるオブジェクト→要素数(整数) 数えられないオブジェクト→1(整数) NULL→0(整数) 未セット→0(整数)※isset関数を併用すると、NULLなのか未セットなのかは区別可能
カウントモードに0またはCOUNT_NORMALを指定した場合は最上階層要素だけ数える。1またはCOUNT_RECURSIVEを指定した場合は、全階層の要素数を数える。
【例】 <?php $a = array('a','b','c'); $b = array(array('a','b','c'), array('1','2','3')); echo '$a: ' . count($a); . "¥n"; echo '$b: ' . count($a); . "¥n"; echo '$b(all): ' . count($a,COUNT_RECURSIVE); . "¥n"; ?> 【出力】 $a: 3 $b: 2 $b(all): 8
なお、第1引数にテキストファイル名を指定した場合、テキストファイルの行数を返す。
【書式】
count(テキストファイル名)
in_array
は配列要素中に指定した値があるかどうか調べる。あればtrue、それ以外はfalseを返す。
【書式】 in_array(探索値,配列,strict) 【戻り値】真偽値(bool) 探索値が配列要素中にあった:true 探索値が配列要素中になかった:false
array_key_exists
は配列中に指定したキーがあるかどうか調べる。あればtrue、なければfalseを返す。
【書式】 array_key_exists(探索値,配列) 【戻り値】真偽値(bool) キーが見つかった:true キーが見つからない:false
isset
はnull値を持つ配列キーは返さないが、このarray_key_exists
はtrueを返す。
array_key_exists
は最初のレベルのキーだけを探索する。多次元配列の第2階層以降にあるキーは探索対象外。
array_search
はin_array
と似ているが、戻り値が「最初に見つかった値のキー」である点が異なる。見つからない場合 false を返すのは同じ。
【書式】 array_search(探索値,配列,strict) 【戻り値】整数(int)、文字列(string)またはfalse 値が見つかった:要素のキー 値が見つからない:false
全てのマッチした値に対するキーを得るには、array_keys
関数で 検索値オプションを指定する。
array_keys
を用いる(配列キーを配列で得られる)。
【書式】 array_keys(配列,検索値,型判定);
===
)が行われる。falseを指定すると型判定までは行わない通常の比較(==
)が行われる。指定がない場合の既定値は false。
【例】
$airports = array('KIX'=>'関西国際空港',
'ITM'=>'伊丹空港',
'UKB'=>'神戸空港',
'SHM'=>'南紀白浜空港',
'TKG'=>'コウノトリ但馬空港');
$cords = array_keys($airports);
print_r($cords);
<出力結果>
Array
(
[0] => KIX
[1] => ITM
[2] => UKB
[3] => SHM
[4] => TKG
)
array_rand
は配列から一つ以上の要素をランダムに取り出し、取り出した要素キーを返す。取り出す要素の数が1つである場合はそのキー値、複数ある場合は各キー値を要素とする配列を返す。配列の中にある要素数より多くの要素を取り出そうとすると E_WARNING レベルのエラーが発生し、NULL を返す。
【書式】 array_rand(配列,取り出す要素数); 【戻り値】 取り出す要素が1つ→文字列:そのキー値 取り出す要素が複数→配列:各キー値を要素とする配列 配列の中にある要素数より多くの要素を取り出そうとした時→NULL
【例】 $ cat test.php <?php $array = array(1=>'Hydrogen',2=>'Helium',3=>'Lithium',4=>'Beryllium',5=>'Boron',6=>'Carbon'); echo '1つ取り出し:'; var_dump($array[array_rand($array)]); echo '2つ取り出し:'; foreach (array_rand($array,2) as $key) { var_dump($array[$key]); } ?> $ php test.php 1つ取り出し:string(9) "Beryllium" 2つ取り出し:string(8) "Hydrogen" string(6) "Carbon"
array_flip
はキーを値を入れ替えた配列を返す。キーが整数型(integer)または文字列型(string)である必要があり、そうでないキーを持つキーと値の組については入れ替えずそのままになる? またある値が複数出現した場合、最後に出現した値がキーとして採用され、その他の値は失われる。戻り値はキーと値の反転に成功した場合はその配列、失敗した場合はNULL。
array_flip(配列);
関数名 | 並べ替えの基準 | キーと値の関係 | 並べ替え順 |
---|---|---|---|
sort(配列,ソート型フラグ) | 値 | 維持しない | 昇順 |
rsort(配列,ソート型フラグ) | 降順 | ||
usort(配列,比較関数) | ユーザ定義 | ||
asort(配列,ソート型フラグ) | 維持する | 昇順 | |
arsort(配列,ソート型フラグ) | 降順 | ||
uasort(配列,比較関数) | ユーザ定義 | ||
ksort(配列,ソート型フラグ) | キー | 維持する | 昇順 |
krsort(配列,ソート型フラグ) | 降順 | ||
uksort(配列,比較関数) | ユーザ定義 | ||
shuffle(配列) | 値 | 維持しない | ランダム |
戻り値はいずれも並べ替えに成功した場合はtrue、失敗した場合はfalse。
function comp($a,$b) { if ($aが前と判定される条件) { return -1; } else if ($bが前と判定される条件) { return 1; } else { # $a,$b 同点の場合 return 0; } }
なお、これらの並べ替え関数はマルチバイト文字には有効ではない(文字単位ではなくバイト単位で判断されるよう)。 対応策として、uniord(引数文字に対応する文字コードを返す関数ordのマルチバイト対応版)をユーザ定義関数として定義しておき、比較関数として以下のような関数を定義する(以下の例において長音記号は無視して判定している)。
function mbcmp($a,$b) { #= エンコーディング設定 $encode = 'UTF-8'; #== 短い方の文字の長さを取得し、短い方が前と仮判定 #- $a の方が短い場合 if (strlen($a) < strlen($b)) { $len = strlen($a); $cmp = -1; #- $a の方が長い場合 } else if (strlen($a) > strlen($b)) { $len = strlen($b); $cmp = 1; #- 同じ長さ→$aが前とする } else { $len = strlen($a); $cmp = 0; } #== 変数定義 $i = 0; #- チェック位置(最初の文字が0) $dash = array('a'=>0, 'b'=>0); #- 長音記号数 $flg = true; #- チェック継続フラグ(falseになると判定終了) #== チェック while ($flg !== false) { #- 前の長音記号チェック(長音記号なら$dash['a']に1加算) if (mb_substr($a,$i+$dash['a'],1,$encode) == "ー") { $dash['a']++; } #- 後の長音記号チェック(長音記号なら$dash['b']に1加算) if (mb_substr($b,$i+$dash['b'],1,$encode) == "ー") { $dash['b']++; } #- i-1文字目(長音記号はカウントせず)が同じ if (mb_substr($a,$i+$dash['a'],1,$encode) == mb_substr($b,$i+$dash['b'],1,$encode)) { #- チェック位置を次に $i++; #- 短い方の最後まで到達(短い方=長い方の前部)→短い方が前 if ((($cmp <= 0) and ($i+$dash['a'] >= $len)) or (($cmp > 0) and ($i+$dash['b'] >= $len))) { $flg = false; } #- i-1文字目が違う } else { #- $a の($i-1)文字目の文字コード $code_a = uniord(mb_substr($a,$i+$dash['a'],1,$encode)); #- $b の($i-1)文字目の文字コード $code_b = uniord(mb_substr($b,$i+$dash['b'],1,$encode)); #- $a の文字コードの方が小さい場合→$aが前 if ($code_a < $code_b) { $cmp = -1; #- $b の文字コードの方が小さい場合→$bが前 } else if ($code_a > $code_b) { $cmp = 1; } $flg = false; } } return $cmp; }
array_values
は配列から全ての値を取り出し、数値をキーとする配列を返す。
【書式】
array_values(配列);
【例】
<?php
$a = array (1 => 'one',
'二' => 'two',
3 => 'three',
'четыре' => 'four');
$b = array_values(配列);
print_r($a);
print_r($b);
?>
「実行結果」
Array
(
[1] => one
[二] => two
[3] => three
[четыре] => four
)
Array
(
[0] => one
[1] => two
[2] => three
[3] => four
)
array_unique
は、配列の各要素の値をチェックし、重複した値を取り除いた配列を返す。同じキーを持つ配列要素が存在した場合、先に登場した方が残され、後に登場する方が捨てられる。型の扱いは既定では全て文字列に変換して比較される(後述のソートフラグオプション参照)。
【書式】 array_unique(配列,ソートフラグ); 【戻り値】 (配列)処理済の配列
値 | 比較式 | 内容 |
---|---|---|
SORT_REGULAR | $変数1 === $変数2 |
そのままのデータ型で型も含めて比較。但し文字と数値が表記上同じなら型が違っても同じとみなされるよう。 |
SORT_NUMERIC | (float) $変数1 === (float) $変数2 |
数値として比較 |
SORT_STRING | (string) $変数1 === (string) $変数2 |
文字列として比較(これが既定値) |
SORT_LOCALE_STRING | (string) $変数1 === (string) $変数2 |
現在のロケール(地域設定)に基づき文字列として比較 |
【例】 <?php $input = array("a" => "green", "red", "b" => "green", "blue", "red"); $result = array_unique($input); print_r($input); print_r($result); ?> ↓結果 Array ( [a] => green [0] => red [b] => green # キー"a"に同じ値があるので除去対象 [1] => blue [2] => red # キー"0"に同じ値があるので除去対象 ) Array ( [a] => green [0] => red [1] => blue ) 【例】 <?php $input = array(4, "4", "3", 4, 3, "3","3.0"); var_dump($input); var_dump(array_unique($result,SORT_STRING)); var_dump(array_unique($result,SORT_REGULAR)); var_dump(array_unique($result,SORT_NUMERIC)); ?> ↓結果 array(6) { [0]=> int(4) [1]=> string(1) "4" # 型は違うが文字として比較すると[0]に一致→除外対象 [2]=> string(1) "3" [3]=> int(4) # [0]に一致→除去対象 [4]=> int(3) # 型は違うが文字として比較すると[2]に一致→除去対象 [5]=> string(1) "3" # [2]に一致→除去対象 [6]=> string(3) "3.0" # 数値としては[2]に一致、文字としては不一致→REGULAR,NUMERICは除去対象 } # 元の型は保持されている array(2) { [0]=> int(4) [2]=> string(1) "3" }
複数階層の配列の場合、
<?php $a = array('A'=>array('0036','0037','0036','0038'), 'B'=>array('0012','0013','0012','0014')); print_r($a); print_r(array_unique($a,SORT_STRING)); echo $a['A']."\n"; echo $a['B']."\n"; print_r(array_unique($a,SORT_REGULAR)); #- 下位階層の各値の重複を取り除くには各下位階層にarray_uniqueを適用 foreach ($a as $key=>$subarray) { $a[$key] = array_unique($subarray); } ?> #- 元の配列 Array ( [A] => Array ( [0] => 0036 [1] => 0037 [2] => 0036 [3] => 0038 ) [B] => Array ( [0] => 0012 [1] => 0013 [2] => 0012 [3] => 0014 ) ) #- 文字列として比較して処理した結果(既定の動作もこれ) Array ( [A] => Array ( [0] => 0036 [1] => 0037 [2] => 0036 [3] => 0038 ) ) # どちらも"Array"という文字列として判断され一致するので、後者は除去される a['A']: Array a['B']: Array # 型そのままだとそれぞれの配列内容は異なるので除去対象なし Array ( [A] => Array ( [0] => 0036 [1] => 0037 [2] => 0036 [3] => 0038 ) [B] => Array ( [0] => 0012 [1] => 0013 [2] => 0012 [3] => 0014 ) ) # 各下位階層内で重複除去するにはループ処理により可能 Array ( [A] => Array ( [0] => 0036 [1] => 0037 [3] => 0038 ) [B] => Array ( [0] => 0012 [1] => 0013 [3] => 0014 ) )
コマンド類 | 文字列キー要素 | 数値キー要素 |
---|---|---|
array_merge |
同一のキーを持つ要素があった場合、後の配列の値で上書き。 | キー値を0から割り振り直して、前の配列の要素、後の配列要素の順で全て追加。 |
加算演算子(+) | 同一のキーを持つ要素があった場合、前の配列の値をそのまま残す。 | 前の配列にないキー値の要素のみ追加。前の配列にあるキー値の要素は前の配列の要素のまま。 |
array_merge
は指定した1つ以上の配列に含まれる全要素を1つの配列に格納して返す。
文字列をキーにもつ要素(連想配列要素)で同じキーを持つ要素が存在した場合、後に登場した値で上書きされる。数字をキーに持つ要素の場合、登場順に0からの通しの連番が振り直される。
【書式】 array_merge(配列,配列...); 配列 + 配列 + 配列...; 【例】 $array1 = array("color" => "red", 2, 4); $array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4); $result_merge = array_merge($array1, $array2); $result_add = $array1 + $array2; echo '$array1:'; print_r($array1); echo '$array2:'; print_r($array2); echo '$result_merge:'; print_r($result_merge); echo '$result_add:'; print_r($result_add); 【結果】 $array1:Array ( [color] => red [0] => 2 [1] => 4 ) $array2:Array ( [0] => a [1] => b [color] => green [shape] => trapezoid [2] => 4 ) $result_merge:Array ( [color] => green ←後の配列($array2)がセットされている [0] => 2 [1] => 4 [2] => a [3] => b [shape] => trapezoid [4] => 4 ) $result_add:Array ( [color] => red ←前の配列($array1)がセットされている [0] => 2 [1] => 4 [shape] => trapezoid [2] => 4 ←後の配列($array2)にしかないキー要素のみ追加 )
キー値が同一であっても両方とりこみたいなら、foreach
を使って別の配列に各要素を格納していけばよい(但し、キーと値の関係は崩れる)。
【例】 $array1 = array("color" => "red", 2, 4); $array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4); foreach ($array1 as $val) { $result[] = $val; ←キーを指定しない場合、最大数字キーの次の番号が自動で設定される } foreach ($array2 as $val) { $result[] = $val; } print_r($result); 【結果】 Array ( [0] => red [1] => 2 [2] => 4 [3] => a [4] => b [5] => green [6] => trapezoid [7] => 4 )
array_intersect
は複数配列に共通する要素を返す。戻り値となる配列のキーは比較元配列のキーが維持される。
array_intersect(比較元配列,比較対象配列,比較対象配列)
switch
は単一の変数の値によって処理を分岐させるのに用いることができる。なお、swtich
、case
で行われる比較は緩やかな比較(データ型が一致しているかどうかまでは見ない)となる。
case
で指定する条件にマッチした場合、break
に出会うまでの内容が処理される。default
はどのcase
にもマッチしなかった場合に適用される。
switch(変数名) { case 値1; 式1; break; case 値2; 式2; break; … case 値n; 式n; break; default; 式(n+1); break; }
評価の対象となる変数を変数名で指定し、その後case
節で条件を記述する。if...else if...
文と異なるのは、break
を記さないと、switch
文の最後まで処理されてしまう点。逆にそれを利用して複数の条件を束ねることができる(式1とその後のbreak
を記さないと、値1または値2の場合に式2が処理される。
switch($obj) { case "Nara"; case "Osaka"; case "Kyoto"; case "Hyogo"; case "Shiga"; case "Wakayama"; echo "It's in the Kinki region."; break; case "Kagawa"; case "Tokushima"; case "Ehime"; case "Kochi"; echo "It's in the Shikoku region."; break; default; echo "It's neither in the Kinki region nor in the Shikoku region."; break; }
fgets
(Enter入力または指定文字数まで)、fgetc
(1文字)を用いる。いずれもファイルリソースには"STDIN"を指定する。
【例1】 echo "IDを入力して下さい(8文字以内)"; fgets(STDIN,8); 【例2】 echo "これでよろしいですか(y/n)?"; fgetc(STDIN);
参考文献・サイト:
exit
はメッセージを出力して、現在のスクリプト処理を終了する。die
も働きは同じ。戻り値はなし。
【書式】メッセージを出力して終了する
exit(文字列);
【例】
exit("エラーが発生しました!");
引数に整数を指定した場合は、エラーコードを設定して終了する。指定できる値は0〜254の整数。0はプログラムを正常終了させるのに用いる。値の指定がない場合の既定値は0。
【書式】エラーコードを設定して終了する
exit(整数)
【例】正常終了
exit;
exit();
exit(0);
MySQLデータベースを操作するための関数。PHP3以降で利用可能。MySQL 4.1.3以前のMySQLを扱うことを意図した手続き型インタフェースを提供する。この拡張モジュールは PHP 5.5.0 で非推奨になり、PHP 7.0.0で削除された1-2-2-1。PHP5以降ではMySQL改良版拡張モジュール「MySQLi」またはPHP Data ObjectのMySQL関数(PDO_MySQL)を使うことが推奨される。また、使用するMySQLのバージョンが4.1.3以降である場合もMySQLiの使用を強く推奨する。MySQL APIに関する概要も参照のこと。
mail
コマンドによってメールを送信することができる。なお、メールに関するマルチバイト関数をオーバーロードする設定を行っていると、mb_send_mail
関数に読み替えて実行される。
【書式】 mail(宛先,件名,本文,追加ヘッダ,追加オプション) mb_send_mail(宛先,件名,本文,追加ヘッダ,追加オプション) 【戻り値】 メール送信に成功→true メール送信に失敗→false
< ... >
)で囲んでその前に別名を記す。複数のアドレスを併記する場合はコンマ(,
)で区切る。
user@example.com user@example.com, anotheruser@example.com User <user@example.com> User <user@example.com>, Another User <anotheruser@example.com>なお、名前部分に日本語を使っている場合、
mb_encode_mimeheader
を使ってmimeエンコード処理を行わないと受信されたメールの宛先名前部分が文字化けしてしまう。追加ヘッダ中のFrom, Cc, Bccについても同様。
【例】宛先をmimeエンコードする <?php $to = mb_encode_mimeheader('くいだおれ太郎'); $to .= sprintf(' <%s>',taro@kuidaore.com); ... mail($to,$subject,$body,$addheader); ?>
\n
)で各行の長さは70文字以下にすること(参照:wordwrap
コマンド)。
Windows環境の場合、ピリオドから始まる行は無視されるが、これを防ぐには、行頭のピリオドをピリオド 2 つに置換すればよい(例:$body = str_replace("\n.","\n..",$body);
)。
送信元(From)、カーボンコピー(Cc)、ブラインドカーボンコピー(Bcc)の挿入に用いる。複数のヘッダを追加する際はCRLF(\r\n
)で区切る。Fromは必須だが、php.ini
で既定値を指定していれば省略可能。
またここに記す文字列はmb_encode_mimeheader
を使って文字エンコーディング変換を行い、適正な言語設定を行わないと文字化けすることがある(mb_language
、mb_internal_encoding
参照)11、16。
【例】 <?php $from = "white@yagisan.net"; ←送信者アドレス $fromname = "しろやぎ"; ←送信者名 $to = "black@yagisan.net"; ←宛先アドレス $toname = "くろやぎ"; ←宛先人名 $subject = "こんにちわ"; ←件名 $body = <<< DOC_END こんにちは、お元気ですか。 またメールします。 DOC_END; $addheader = "From: " . mb_encode_mimeheader($fromname); $addheader .= "<" . $from . ">\r\n"; mb_language("ja"); mb_internal_encoding("UTF-8"); mb_send_mail($to,$subject,$body,$addheader); ?>
なお、Unicodeメールを送るには以下の2行を追加ヘッダに記述する必要あり12。
Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit
あるいはこう?22
Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: BASE64
それと、メールエンベロープにもfromアドレスを設定した方がいいみたい(迷惑メールとみなされるのを抑制するため)。そのためにはmail(mb_send_mail)の第5引数に「-f [fromアドレス]
」を指定しておく22
メールアドレス全体でASCII文字256文字以下。
@
の前)以下のASCII文字が使用可能。文字数は最大64文字(プロバイダやメールソフトの制約のため実際使えるのはこれより少ない場合がある)。
! # $ % & ' * + - / = ? ^ _ ` { | } ~
(実際はこのうちの一部のみを許可するの制限を加えた実装が多い).
(ピリオド、先頭と末尾以外で使用可能。2個以上連続してはいけない。)" "
で囲んだquoted-stringの形式であれば以下のASCII文字も使用可能
# ( ) < > [ ] : ; @ ,
.
(ピリオド、quoted-string内での制限はなし)@
の後)次のいずれかが使用可能。文字数は最大255文字。
-
)、但し先頭は英数字)をピリオド(.
)でつないだもの(完全修飾ドメイン名、FQDN)[ ]
"でくくったIPアドレス例
mail.hoge-fuga.com
[192.168.0.100]
<?php $addresses = "user1@mail.hoge-fuga.com, user2@mail.foofoo.net"; #- エラーコードとメッセージの定義 $errmsg = array(0 => 'メールアドレスに使えない文字が含まれています(使用できるのは半角英数字記号です)。', 1 => 'メールアドレスの文字数が多すぎます。256文字以下にして下さい。', 2 => '@がないか、または2個以上あります。@は1つのメールアドレスにつき1個にして下さい。', 3 => '@の前(ローカル部)の文字が多すぎます。@の前は64文字以下にして下さい。', 4 => '@の前(ローカル部)に使用できない文字が含まれています。使用できる文字は半角英数字と!#$%&'*+-/=?^_`{|}~.のいずれかです。', 5 => '@の前(ローカル部)の先頭末尾にピリオドは使用できません。', 6 => '@の前(ローカル部)に連続したピリオドは使用できません。', 7 => '@の後(ドメイン部)の文字が多すぎます。@の後は255文字以下にして下さい。', 8 => '@の後(ドメイン部)に使用できない文字が含まれています。使用できる文字は半角英数字とハイフン、ピリオド(-.)のいずれかです。', 9 => '@の後(ドメイン部)の先頭に使用できる文字は半角英数字のみです(先頭にはハイフンやピリオドは使えません。)'); #- チェックフラグ初期値 $check = true; #- 空白類(タブ、リターン、改行、NUL、垂直タブも含む)を除去 $addresses = preg_replace_all('/[ \t\n\r\0\x0B]/','',$address); #- ASCII英数字記号以外があればチェックfalse if (preg_match('/[^\x21-\x7e]/',$addresses) != false) { $check = false; $errcode = 0; } else { #- メールアドレスをコンマで分割して配列に格納 $address_array = implode(",",$addresses); #- 各メールアドレスをチェック foreach ($address_array as $address) { #- 文字数が256文字を越えていたらチェックfalse if (strlen($address) > 256) { $check = false; $errcode = 1; #- @が1個でなかったらチェックfalse } else if (preg_match_all('/@/',$address) !== 1) { $check = false; $errcode = 2; } else { $local = substr($address,0,strpos($address,'@')); #- ローカル部が64文字を越えていたらチェックfalse if (strlen($local) > 64) { $check = false; $errcode = 3; #- ローカル部に許容される文字以外があればチェックfalse } else if (preg_match("/[^0-9A-Za-z!#$%&'*+\-/=?^_`{|}~.]/",$local) != false) { $check = false; $errcode = 4; #- ローカル部先頭末尾にピリオドがあればチェックfalse } else if (preg_match('/(^\.|\.$)/',$local) != false) { $check = false; $errcode = 5; #- ローカル部に連続するピリオドがあればチェックfalse } else if (preg_match('/\.\./',$local) != false) { $check = false; $errcode = 6; } $domain = substr($address,(strpos($address,'@')+1)); #- ドメイン部が255文字を越えていたらチェックfalse if (strlen($local) > 255) { $check = false; $errcode = 7; #- ドメイン部に許容される文字以外があればチェックfalse } else if (preg_match('/^[^0-9A-Za-z\-.]/',$local) != false) { $check = false; $errcode = 8; #- ドメイン部の先頭が英数字でなればチェックfalse } else if (preg_match('/^[0-9A-Za-z]/',$local) == false) { $check = false; $errcode = 9; } } } if ($check === false) { echo "Error was found!\n" . $errmsg[$errcode] . "\n"; } else { echo "Address checking OK!\n"; } } ?>
メールフォームでsubmit→送られてきたメールに記載されたURLをクリック→送信実行、というメールアドレスが有効なものであるかを確認してから送信するメールシステムの作り方について。参考サイト2で紹介されている会員登録システムとは異なり、1回限り有効であればよいものを作る。
カラム名 | データ型 | 内容 |
---|---|---|
confirm_code | varchar(64) | 確認コード |
received_date | date | 送信リクエスト受信日時 |
from_name | varchar(192) | 送信者名(64文字以内) |
from_address | varchar(256) | 送信者メールアドレス(256文字以内) |
subject | varchar(192) | 件名(64文字以内) |
body | text | 本文 |
mysql> CREATE TABLE mail_queue (confirm_code VARCHAR(32),received_date DATE,from_name VARCHAR(192),from_address VARCHAR(256),subject VARCHAR(192),body TEXT);
fopen
は指定したファイルを開いてアクセス可能な状態にする。戻り値はファイルアクセスの際に指定するファイルポインタ(ファイルポインタリソース、オープンに失敗した場合は false)。gzopen
の場合はgzip圧縮ファイルでも扱える(圧縮解凍操作を意識しなくてもアクセスできる)。
【書式】 fopen(ファイル名,アクセスモード) gzopen(ファイル名,アクセスモード) 【戻り値】 正常にオープン→ファイルポインタリソース not→false
引数
"スキーム://..." の形式である場合はURLとみなし、そのプロトコルのハンドラ(ラッパー)を探す。そのプロトコルに対するラッパーが登録されていなければスクリプトに潜在的な問題があることを示す NOTICE を発行したうえで、ファイル名を通常のローカルファイルとみなして開くことを試みる。
ファイルがローカルファイルを示していると判断されると、そのファイルへのストリームを開く。
ファイル名が登録されているプロトコルを示していると判断され、かつそのプロトコルがネットワーク URL として登録されていれば、 PHP は allow_url_fopen が有効となっているかどうかチェックする。 もしこれがオフになっていると、PHP は warning を発行し fopen は失敗する。
指定可能な値は以下の通り。
モード | 読み | 書き | ファイルポインタ | ファイル既存 | ファイル未存 | 備考 |
---|---|---|---|---|---|---|
'r' |
○ | × | 先頭 | ○ | エラー | |
'r+' |
○ | ○ | 先頭 | ○ | エラー | |
'w' |
× | ○ | 先頭 | 消去 | 新規作成 | |
'w+' |
○ | ○ | 先頭 | 消去 | 新規作成 | |
'a' |
× | ○ | 末尾 | 追記 | 新規作成 | |
'a+' |
○ | ○ | 末尾 | 追記 | 新規作成 | |
'x' |
× | ○ | 先頭 | エラー | ○ | |
'x+' |
○ | ○ | 先頭 | エラー | ○ |
戻り値
ファイルオープン成功→ファイルポインタリソース(リソース (resource) 型)fgets/gzgetsによるファイル内容の取得などで用いる。
ファイルオープン失敗→false(論理 (boolean) 型)
fclose
はファイルを閉じる。fopen
でファイルを開いた時に戻り値として得られるファイルポインタを引数に指定。gzopen
で開いた場合はgzclose
で閉じる。
【書式】 fclose(ファイルポインタ) gzclose(ファイルポインタ)
標準出力から読み込むにはファイルポインタとしてSTDINを指定する。これはファイルオープン・クローズのの手続きを踏む必要はない(fopen、fcloseの手続きを踏まなくてもfgetsで1行取得可能)[2]。
feof
はファイルポインタがファイルの終端に達しているかを返す。終端、エラーの場合true、その他の場合はfalseを返す。gzeof
はgzopen
で開いたファイルを扱う以外は同じ。
【書式】 feof(ファイルポインタ) gzeof(gzファイルポインタ) 【戻り値】 ファイルポインタがEOFではない位置を指す→false ファイルポインタが EOF に達している→true エラー発生(ソケットタイムアウトを含む)→true
ファイルポインタにはfopenなどで開いたファイルのポインタを指定する。無効なファイルポインタ(無効なファイルを開こうとすると、fopenはfalseを返す)を渡すと、いつまでもEOFに達せず(feofの戻り値がtrueにならず)無限ループに陥ることがあるので注意。 ファイルポインタがfalseでない場合のみファイル読み込みを行うようなエラー回避の条件分岐を設ける方が安全。
opendir
はディレクトリを開く。戻り値は処理に成功するとファイル名取得アクセスの際指定するディレクトリハンドル、失敗するとfalse。
closedir
はディレクトリを閉じる。引数にはopendir
で開いた時の戻り値として得られるディレクトリハンドル。
【書式】 opendir(パス) closedir(ディレクトリハンドル)
readdir
は、opendir
で開いたディレクトリ内のアイテム(ファイルやディレクトリなど)の情報を1つ読む。成功すればファイル名を、失敗すればfalseを返す。戻り値にはfalseとして評価される0や""が来る可能性があるため、失敗(=これ以上読むべきものがないなど)を検知するには型まで識別する"==="演算子や"!=="演算子を用いること。
【書式】 readdir(ディレクトリハンドル) 【例】ユーザホームディレクトリの一覧を標準出力へ出力 if ($dir_handle = opendir("~")) { # 代入した結果を条件にしている(代入なので等号は一つ) while (($file = readdir($dir_handle)) !== false) { echo $file . "\n"; } } 【例】ユーザホームディレクトリの一覧を標準出力へ出力(. と .. を除く) if ($dir_handle = opendir("~")) { while (($file = readdir($dir_handle)) !== false) { if (($file != ".") and ($file != "..")) { echo $file . "\n"; } } }
file_exists
はファイルまたはディレクトリが存在するかを調べる。ファイルが存在すればtrue、存在しなければfalseを返す。
【書式】
file_exists(ファイル名)
ファイル等の属性を判定する関数を以下に示す。
【書式】 is_file(文字列) is_dir(文字列) is_link(文字列) 【戻り値】文字列に指定したファイル等が is_file:通常ファイル→true、それ以外→false is_dir:ディレクトリ→true、それ以外→false is_link:シンボリックリンク→true、それ以外→false
mkdir
はディレクトリを作成する。ディレクトリ作成に成功すれば true、失敗すれば false を返す。ディレクトリを削除するのはrmdir
。
【書式】 mkdir(パス名,モード,recursive,コンテキスト); 【戻り値】データ型:論理値(boolean) 処理に成功→true 処理に失敗→false
filesize
は指定ファイルのファイルサイズ(単位はバイト)を返す。エラーの場合は false を返すか、または E_WARNING レベルのエラーを発生させる。
【書式】
filesize(ファイル名)
引数
戻り値
【例】 $ php -r 'echo filesize("test.txt")."\n";' 1234
mime_content_type
はファイルの MIME Content-type を返す。取得に失敗した場合は false を返し、E_WARNING レベルのエラーを発生させる。
【書式】
mime_content_type(ファイル名)
引数
戻り値
【例】 $ php -r 'echo file_mime_type("test.txt")."\n";' test/plain
fgets
はfopen
で開いたファイルのポインタ位置から1行分を取得して返す。戻り値には末尾の改行文字も含む。gzgets
はgzopen
で開いたファイルを扱うこと以外は同等。
【書式】
fgets(ファイルポインタ,読み込み長);
gzgets(ファイルポインタ,読み込み長);
【戻り値】
ファイルポインタがファイルの末端ではない→ファイルポインタで指定したファイルポインタから最大読み込み長-1 バイトを読み出して得られた文字列(gzgets
の場合は解凍後の文字列)
ファイルポインタがファイルの末端→false
エラー→false
ファイルポインタにはfopen
やfsockopen
で正常にオープンされ、まだclose
されていないファイルポインタを指定する(gzgets
の場合はgzopen
)。読み込み長を指定した場合、指定値-1バイトを読み出すか、または改行、ファイルの終端(EOF)を検出した時点で読み込みを終了する。指定がない場合は改行またはファイルの終端を検出するまで読み続ける。戻り値は正常に内容を取得できればその読み込んだ文字列、エラーがあればfalse。
【例1】単にファイルを読んで1行ずつ出力
<?php
$handle = fopen('hoge.txt','r');
#-- ファイルopenに成功した場合
if ($handle) {
while (!feof($handle)) {
echo fgets($handle);
}
#-- ファイルopenに失敗した場合
} else {
echo "hoge.txt は開けませんでした。\n";
}
?>
※上記の内容なら、fread
を使うなどした方が簡単
【例2】ファイルの各行を読み込んで 「行頭が#」または「#の前に空白文字しかない」行を除いて出力
<?php
$handle = fopen('hoge.txt','r');
#-- ファイルopenに成功した場合
if ($handle) {
#-- 最初の1行を読み込み($lineの初期値定義も兼ねて)
$line = fgets($handle);
#-- ファイルの最終行まで処理を繰り返し
#-- 行コンテンツチェックも入れないと、最後の1行が処理されずループが終わる
while ((!feof($handle)) or ($line !== false)) {
#-- 「行頭が#」または「#の前に空白文字しかない」行を除いて出力
if (preg_match('/^\s*#/',$line) == false) {
echo $line;
}
#-- 次の1行を読み込み
$line = fgets($handle);
}
#-- ファイルopenに失敗した場合
} else {
echo "hoge.txt は開けませんでした。\n";
}
?>
標準入力から1行ずつ読み込む例:
$ cat test.php <?php while (($line = fgets(STDIN)) !== false) { echo 'あなたは「'.trim($line)."」と入力しましたね\n"; } ?> $ php test.php - hoge あなたは「hoge」と入力しましたね foo あなたは「foo」と入力しましたね (Ctrl-D) $
csvファイルを1行読み込む際はfgetcsvを使うと便利
ただし、この関数はロケール設定を考慮するため、設定とは異なる文字コードで書かれたCSVファイルを読み込むと値が文字化けする可能性がある。これに対処する方法として、ストリームフィルタをつくる方法がある21。あるいはmb_convert_encodingコマンドを使って読み込んだ文字列を変換する、あらかじめエディタで文字コードを変換したファイルを入力ファイルとして用いる、という方法が考えられる。
【書式】 fgetcsv(ファイルポインタ,読み込み長,フィールド分割文字,フィールド囲み文字,エスケープ文字); 【戻り値】 指定されたファイルポインタが有効でファイルポインタがファイルの末端ではない→読み込んだフィールドの内容を含む数値添字配列 ※空行であった場合、nullフィールドを1つだけ含む配列を返す ファイルポインタがファイルの終端、その他エラー→false 指定されたファイルポインタが無効→null
関数 | ファイル指定 | 読み込み開始位置 | 戻り値 | テキスト | バイナリ | 備考 |
---|---|---|---|---|---|---|
fread |
ファイルポインタ | ポインタ位置 | 値 | ○ | ○ | ポインタ位置以降残り全部を出力する時、画像などのバイナリファイルを扱う時に有効。 |
file 、gzfile |
ファイル名 | 先頭 | 配列 | ○ | × | 巨大なファイルを指定するとメモリ不足でエラーになることがある。 |
readfile 、readgzfile |
ファイル名 | 先頭 | (解凍後の)データバイト数 | ○ | × | ファイルを読み込み、解凍し、標準出力に書き込む。 |
file_get_contents |
ファイル名 | 指定可能 | 値 | ○ | × | テキストデータを全て出力するのに有用。 |
fread
は指定したファイルポインタが指すファイルポインタ(ファイル上で処理を行う位置)から以下の条件に適合するまで読み込みを行う。正常に読み込めた場合はその文字列を、何らかのエラーがあった場合はfalseを返す。
【書式】 fread(ファイルポインタ,整数); 【例】ファイル全体を出力 <?php $handle = fopen('test.txt','r'); # 読み取り専用モードでファイルを開く echo fread($handle,filesize('test.txt')); # ファイル全体を出力 fclose($handle); # ファイルを閉じる ?>
fread
は画像ファイルなどのバイナリファイルでも扱うことができる。但し、その場合はバイナリモードでファイルを開く必要がある(fopen
のモードパラメータに'b'を指定)。
fread
はファイル全体を「1つの値」として返すが、file
はファイル全体を読み込んで改行文字で区切り、「各行を要素に格納した配列」を返す。gzfile
は対象がgzip圧縮されたファイルであること以外は同じ。
【書式】 file(ファイル名, フラグ); 【戻り値】 正常取得→ファイルの改行を区切りとした各行を要素とする配列('FILE_IGNORE_NEW_LINES'フラグの指定がない場合は各行末尾の改行記号はついたまま) 取得に失敗→false
FILE_USE_INCLUDE_PATH
…ファイル検索場所にinclude_path
を含めるFILE_IGNORE_NEW_LINES
…各配列要素の末尾に改行文字を含めないFILE_SKIP_EMPTY_LINES
…空行を読み飛ばすFILE_TEXT
…値をUTF-8のテキストで保存。FILE_BINARY
との同時指定は不可。FILE_BINARY
…値をバイナリデータ(そのままの値)で保存。FILE_TEXT
との同時指定は不可。
readfile
はgzfile
とほぼ同等だが、戻り値が得た内容の配列ではなくデータバイト数。得た内容は標準出力に出力される。readgzfile
についても同様。gzip圧縮されたファイルでも扱える。gzfile
との違いは、戻り値が得た内容の配列ではなく解凍後のデータバイト数。得た内容は標準出力に出力される。
【書式】 readfile(ファイル名,use_include_path,コンテキスト); readgzfile(ファイル名,use_include_path); 【戻り値】 読み込みに成功→[整数](解凍後の)データバイト数 読み込みに失敗→false
(readfileの場合)[真偽値]include_pathにあるファイルも検索したい場合 true を指定する。指定がない場合の既定値は false。
(readgzfileの場合)[整数]include_pathにあるファイルも検索したい場合 1 を指定する。指定がない場合の既定値は 0。
file_get_contents
は指定したテキストファイルの中身を全て返す。バイナリファイルを扱うことがないのであればfread
より効率的。
【書式】 file_get_contents(ファイル名またはURL,フラグ,コンテキストリソース,読み込み開始位置,読み込み長); 【戻り値】 読み込みに成功→読み込んだ文字列 読み込みに失敗→false
file
参照(FILE_IGNORE_NEW_LINES, FILE_SKIP_EMPTY_LINES
を除く)。
stream_context_create
で作成したコンテキストリソース。これを使えば、httpフォームでPOSTした結果を得たりすることができる。独自のコンテキストを使用する必要がない場合は、このパラメータに NULL を指定する。
[test.php] #!/usr/bin/php <?php ?> $ chmod +x test.php $ ./test.php →POSTした結果がファイルで得られる
【例】 $ cat test.php #!/usr/bin/php <?php # POST先URLセット $url = 'http://service.pdbj.org/mine/sql'; # POSTパラメータセット $params['q'] = <<< SQL_DOC SELECT e.id, e.pdbx_description FROM xmldoc d JOIN entity e ON d.docid=e.docid WHERE pdbid='1q48' SQL_DOC; $params['format'] = 'csv'; # リクエストコンテンツ作成 $data = http_build_query($params); # リクエストヘッダセット $header = array("Content-Type: application/x-www-form-urlencoded", "Content-Length: ".strlen($data)); # POSTするstreamを構築 $options = array('http'=>array('method'=>'POST', 'header'=>implode("\r\n",$header), 'content'=>$data)); # リクエストをPOST $result = file_get_contents($url, NULL, stream_context_create($options)); # リクエスト結果を出力 echo $result; ?> $ php test.php id,pdbx_description 1,NifU-like protein
なお、リクエストヘッダがなくても一応動作するが、Content-typeが指定されていないのでapplication/x-www-form-urlencodedであると推定し処理しましたというNoticeが出る[2]。
stream_context_create
は、httpフォームのGET/POSTリクエスト送信などのコンテキストを作成し、そのリソースを返す。これをfile_get_contents
などで指定してリクエスト結果を得るのに用いることができる。
【書式】 stream_context_create(オプション,パラメータ); 【戻り値】 ストリームコンテキストリソース
method 文字列 | 文字列にはGET、POSTなどのメソッド名を指定する |
---|
【例】 #!/usr/bin/php <?php ?>
fwrite
はfopen
で開いたファイルリソースのファイルポインタがある位置に書き込みを行う。fputs
でも同じ。
gzopen
で開いたgzファイルのファイルリソースに対してはgzwrite
(gzputs
)を用いる。
【書式】 fwrite(ファイルポインタ,書き込む文字列,バイト数); gzwrite(ファイルポインタ,書き込む文字列,バイト数); 【戻り値】 書き込み成功→書き込んだバイト数(gzwriteの場合、解凍後のサイズ) 失敗→false
fopen
でファイルを開いて得たファイルポインタ。
basename
関数で、パス文字列からファイル名部分を取り出す。オプションで拡張子部分も除去可能。
dirname
関数で、ディレクトリ名を返す。ディレクトリ区切り文字が見つからない場合はカレントディレクトリを示すドット(.)を、それ以外の場合はファイル名とその直前のスラッシュを除いた文字列が返る。
いずれも、Windows環境ではスラッシュ(/)およびバックスラッシュ(\)の両方が、その他の環境ではスラッシュ(/)のみがディレクトリの区切り文字とみなされる。
【書式】 basename(パス文字列,拡張子) dirname(パス文字列) 【例】 $path = "/var/www/html/index.php"; echo basename($path); →index.php echo basename($path,".php"); →index echo dirname($path); →/var/www/html
ファイル名やディレクトリ名の情報を一括して配列変数で受け取るには、pathinfo
関数を用いる。
【書式】 pathinfo(パス文字列,オプション) 【例】 $path = "/var/www/html/index.php"; print_r(pathinfo($path)); Array ( [dirname] => /var/www/html [basename] => index.php [extension] => .php [filename] => index )
realpath
関数では、指定したパスのシンボリックリンクを展開し、「/./」「/../」「/」などの参照をすべて解決することにより、元のファイルに対する絶対パスを返す。ファイルが存在しないなど情報が取得できなかった場合はFALSEを返す。
【書式】 realpath(パス文字列) 【例】 shell> pwd /var/www/html/ shell> ls -l ./jv.jar lrwxrwxrwx 1 hoge hoge 37 1月 1日 12:00 ./jv.jar -> /usr/local/share/jV_3_6_5/jv3_6_5.jar $path = "./jv.jar"; echo realpath($path); /usr/local/share/jV_3_6_5/jv3_6_5.jar
関数 | 戻り値 |
---|---|
fileatime |
最終アクセス日時 |
filectime |
inode変更日時 |
filemtime |
最終更新日時 |
【書式】 fileatime(ファイルパス・ファイル名) filectime(ファイルパス・ファイル名) filemtime(ファイルパス・ファイル名)
正常に情報が取得できた場合はUNIXタイムスタンプ形式の時刻情報が、そうでない場合はfalseが返る。
【例】最終更新日から生成した拡張子を持つバックアップファイルを作成する <?php $srcdir = '/path/to/srcdir'; $dstdir = '/path/to/backupdir'; $dhandle = opendir($srcdir); if ($dhandle) { while (($file = readdir($dhandle)) !== false) { echo 'cp -a '.$srcdir.'/'.$file.' '.$dstdir.'/'.$file.'.bak_'.date('Ymd',filemtime($srcdir.'/'.$file))."\n"; exec('cp -a '.$srcdir.'/'.$file.' '.$dstdir.'/'.$file.'.bak_'.date('Ymd',filemtime($srcdir.'/'.$file))); echo 'ls -ltr '.$srcdir.'/'.$file.' '.$dstdir.'/'.$file.'.bak_*'."\n"; echo shell_exec('ls -ltr '.$srcdir.'/'.$file.' '.$dstdir.'/'.$file.'.bak_*'); } } ?>
rewind
はfopen
で正常に開かれたファイルのファイルポインタ(参照するファイル上の位置)をファイルの先頭に戻す。処理に成功した場合はtrueを、失敗した場合はfalseを返す。gzopenで開いたファイルの場合は、gzrewind
を使う。
【書式】 rewind(ファイルポインタ); gzrewind(ファイルポインタ); 【例】 $ cat test.php <?php $handle = fopen('test.txt','w+'); # 読み書き可能モードでファイルを開く fwrite($handle, '祇園精舎の金の声'); # 先頭から書き込み fwrite($handle, ' 諸業無情の響き有り'); # 末尾に追記 rewind($handle); # ファイルポインタを先頭に戻す fwrite($handle, '祇園精舎の鐘の声'); # 先頭から上書き rewind($handle); # 再びファイルポインタを先頭に戻す echo fread($handle,filesize('test.txt'))."\n"; # ファイル全体を出力→fread参照 fclose($handle); # ファイルを閉じる ?> $ php test.php 祇園精舎の鐘の声 諸業無情の響き有り # 「金」が「鐘」に書き換わっている
fseek
はfopen
で正常に開かれたファイルのファイルポインタ(参照するファイル上の位置)を任意の位置に移動する。
【書式】 fseek(ファイルポインタ,オフセット,whence); 【戻り値】 ポインタ移動に成功→0 ポインタ移動に失敗→-1
オプション
fopen
で得られるファイルポインタ。ポインタをファイルの終端に移動させるには fseek(ファイルポインタ,0,SEEK_END)
。ただし、この状態でfeofを使いファイル終端に達したかを判定してもfalseになる。ここで更に1行読めば判定結果はtrueになる。
copy
はファイルをコピーする。
【書式】 copy(コピー元,コピー先) 【戻り値】 コピーに成功すればtrue、失敗すればfalse
ファイルの最終更新日を保持してコピーする(UNIXのcpコマンドに -a または -p オプションをつけて実行した場合に相当する操作を行う)場合、このcopyコマンドでコピーした後、touchコマンドでコピー元ファイルのタイムスタンプをコピー先ファイルに書き込めばよい
【例】 $ cat test.php <?php $orgfile = "hoge.txt"; $bakfile1 = "hoge.txt.bak1"; $bakfile2 = "hoge.txt.bak2"; copy($orgfile,$bakfile1); copy($orgfile,$bakfile2); touch($bakfile1,filemtime($orgfile)); ?> $ touch hoge.txt $ ls -l --time-style long-iso total 0 -rw-rw-rw- 1 oresama oresama 0 2019-09-20 15:28 hoge.txt -rw-rw-rw- 1 oresama oresama 180 2019-09-20 15:38 test.php $ touch test.php $ ls -l --time-style long-iso total 0 -rw-rw-rw- 1 oresama oresama 0 2019-09-20 15:28 hoge.txt -rw-rw-rw- 1 oresama oresama 0 2019-09-20 15:28 hoge.txt.bak1 -rw-rw-rw- 1 oresama oresama 0 2019-09-20 15:40 hoge.txt.bak2 -rw-rw-rw- 1 oresama oresama 180 2019-09-20 15:38 test.php
touch
はファイルのタイムスタンプ(最終アクセス時刻と最終更新時刻)を変更する。引数の指定値に関わらずアクセス時刻は常に更新されることに注意。ファイルが存在しない場合はファイルが生成される。
【書式】 touch(ファイル名,最終更新時刻,最終アクセス時刻) 【戻り値】 設定に成功すればtrue、失敗すればfalse
rename
はファイルの移動(場所のパス変更)や、ファイル名の変更を行う。新しいファイル名として指定したファイルが既に存在していた場合は暗黙のままに上書きされる(可能であれば)。
【書式】 rename(既存ファイル名,新しいファイル名);
処理に成功した場合は true が、失敗した場合は false が返る。
【例】 $ echo `date "+%Y-%m-%d %H:%M:%S"` > test.txt $ echo `date "+%Y-%m-%d %H:%M:%S"` > test2.txt $ cat test.txt test2.txt 2011-09-14 12:33:16 2011-09-14 12:33:19 $ php -r "rename('test.txt','test2.txt');" $ cat test.txt test2.txt cat: test.txt: No such file or directory 2011-09-14 12:33:16
symlink
はシンボリックリンクファイルを作成する。
【書式】 symlink(リンク元既存ファイルパス,リンク先ファイルパス); 【戻り値】 (真偽値)作成に成功→true、失敗→false
readlink
はシンボリックリンクファイルに対し、そのリンク元ファイルのファイル名を返す。
【書式】
readlink(ファイルパス);
【戻り値】
(文字列)シンボリックリンク元ファイルのパス
unlink
はファイルを削除する。なおPHPにdelete
という関数は存在しない。
【書式】
unlink(ファイル名);
削除に成功すればtrue、失敗すればfalseが返る。
rmdir
はディレクトリを削除する。ディレクトリ削除に成功すれば true、失敗すれば false を返す。
【書式】 rmdir(パス名,コンテキスト); 【戻り値】データ型:論理値(boolean) 処理に成功→true 処理に失敗→false
chmod
は指定したモードにファイルのアクセスモードを変更する。
chown
はファイルの所有者を、chgrp
はファイルのグループを変更する。ファイルの所有者はスーパーユーザのみ変更可能。ファイルのグループは一般ユーザの場合chgrp
を実行するユーザの所属するグループにのみ変更可能。スーパーユーザは任意のグループに変更可能。
【書式】 chmod(ファイル名,モード); chown(ファイル名,ユーザ名またはユーザID,); chgrp(ファイル名,グループ名またはグループ番号); 【戻り値】 変更に成功→TRUE 変更に失敗→FALSE
【例】755(rwxr-xr-x)の権限を設定 chmod('/somedir/somefile', 755); # 誤り 10進数の755は8進数の1363の意味になる chmod('/somedir/somefile', 'rwxr-xr-x'); # 誤り 文字列による指定は受け付けない chmod('/somedir/somefile', 0755); # 正しい
md5_file
は指定したファイルのMD5ハッシュ値を計算する。文字列のMD5ハッシュ値を計算する場合はmd5
を用いる。
【書式】 md5_file(ファイル名,raw_output); 【戻り値】 計算成功:ダイジェスト計算結果 計算失敗:false
コマンド | 対象の指定 | ファイルの扱い |
---|---|---|
gzread |
圧縮ファイルポインタ | ポインタ位置から指定長分の文字列を返す |
readgzfile |
圧縮ファイル名 | 読み込み解凍した内容全てを標準出力に出力する(戻り値は出力したバイト数) |
gzfile |
圧縮ファイル名 | 読み込み解凍した内容全てを、各行を要素に持つ配列で返す |
gzread(ファイルポインタリソース,読み込むバイト数); readgzfile(ファイル名,include_pathを検索対象に含めるかどうかのフラグ); gzfile(ファイル名,include_pathを検索対象に含めるかどうかのフラグ);
gzopen
で得たファイルポインタリソースを指定する。
include_path
にあるファイルも検索対象となる。既定値は0(含めない)。
ファイルポインタリソースが指すポインタ位置から、最大読み込むバイト数に指定したバイト数だけ読み込んで返す。指定バイト数に達する前にファイルの終端(EOF)に達した時も読み込みを終了して読み込んだ値を返す。
readgzfile
は読み込みに成功すればデータのバイト数を、失敗すればfalseを返す。
gzfile
は読み込んだファイルの各行を要素に持つ配列を返す。
gzwrite
はgzip圧縮ファイルへの書き込みを行う。ファイルは gzopen
で得たgzip圧縮ファイルポインタで指定。戻り値は解凍状態での書き込んだバイト数。
gzwrite(ファイルポインタ,書き込む文字列,書き込む長さ);
exec
は、外部コマンドを実行する。戻り値はコマンド出力の最終行。実行されたコマンドの全出力を得るには、出力を受領する変数を第2引数に指定する(出力の各行を要素とする配列が代入される)。shell_exec
も似ているが、戻り値が全てのコマンド出力である点が異なる。
system
は戻り値がコマンド出力の最終行である点は同じだが、PHPをサーバモジュールとして実行している場合、system
を呼び出すと、コマンド出力を出力した後、自動的にウェブサーバの出力バッファの内容を出力して消去される。
passthru
も外部コマンドを実行するが、出力を整形することなくそのまま表示する。コマンドからの出力がバイナリデータで、ブラウザへ直接返す必要がある場合に用いることができる。
【書式と戻り値】 exec(コマンド, 出力受領変数, コマンド戻り値格納変数); →コマンド出力最終行 shell_exec(コマンド); →コマンド出力全体 passthru(コマンド,コマンド戻り値格納変数); →なし system(コマンド,コマンド戻り値格納変数); →コマンド出力最終行(失敗時はfalse)
【例】hoge.txtの行数を得る(→wc=行数とファイル名を返す、gawk=テキスト切り出し) [test.php] <?php $linenum = exec("wc -l hoge.txt | gawk '{print $1}'"); echo "行数は ".$linenum." です。\n"; ?> $ wc -l hoge.txt 150 hoge.txt $ wc -l hoge.txt | gawk '{print $1}' 150 $ php ./test.php 行数は 150 です。 【例】ファイルリストを得る(execを利用した場合) [test.php] <?php echo exec("ls",$output); print_r($output); ?> $ ls 2zuo.pdb1 mom072_rel_ja.html~ mom116_1.jmol 2zv4.pdb1 mom073_ja.html mom116_1.pdb 2zv5.pdb1 mom073_rel_ja.html mom116_2.jmol Jmol.js mom073_rel_ja.html~ mom116_2.pdb biolgen.php mom074_ja.html mom116_ja.html biolgen.php~ mom074_rel_ja.html mom116_jmol_1_ja.html biolgen_pdbml.php~ mom074_rel_ja.html~ mom117_1.jmol carbonext.php mom075_ja.html mom117_1.pdb carbonext.php~ mom075_rel_ja.html mom117_ja.html $ php ./test.php mom117_ja.html # コマンドの戻り値は最終行 Array # 出力受領変数の各要素に出力の各行が格納される ( [0] => 2zuo.pdb1 [1] => mom072_rel_ja.html~ [2] => mom116_1.jmol [3] => 2zv4.pdb1 [4] => mom073_ja.html [5] => mom116_1.pdb [6] => 2zv5.pdb1 [7] => mom073_rel_ja.html [8] => mom116_2.jmol [9] => Jmol.js [10] => mom073_rel_ja.html~ [11] => mom116_2.pdb [12] => biolgen.php [13] => mom074_ja.html [14] => mom116_ja.html [15] => biolgen.php~ [16] => mom074_rel_ja.html [17] => mom116_jmol_1_ja.html [18] => biolgen_pdbml.php~ [19] => mom074_rel_ja.html~ [20] => mom117_1.jmol [21] => carbonext.php [22] => mom075_ja.html [23] => mom117_1.pdb [24] => carbonext.php~ [25] => mom075_rel_ja.html [26] => mom117_ja.html ) 【例】ファイルリストを得る(shell_execを利用した場合) [test.php] <?php echo exec("ls",$output); print_r($output); ?> $ php ./test.php 2zuo.pdb1 # コマンドの戻り値は全ての出力 mom072_rel_ja.html~ mom116_1.jmol 2zv4.pdb1 mom073_ja.html mom116_1.pdb 2zv5.pdb1 mom073_rel_ja.html mom116_2.jmol Jmol.js mom073_rel_ja.html~ mom116_2.pdb biolgen.php mom074_ja.html mom116_ja.html biolgen.php~ mom074_rel_ja.html mom116_jmol_1_ja.html biolgen_pdbml.php~ mom074_rel_ja.html~ mom117_1.jmol carbonext.php mom075_ja.html mom117_1.pdb carbonext.php~ mom075_rel_ja.html mom117_ja.html
なお、エラー出力も受領したい場合はエラーも標準出力に出力するよう指示する必要がある。
$ php -r '$lastline = exec("qstat 12345");echo "The last line of the command output is following:\n".$lastline."\n";' qstat: Unknown Job Id 12345.server ← エラー出力で出力された内容 The last line of the command output is following: ← コマンド(標準)出力最終行は空 $ php -r '$lastline = exec("qstat 12345 2>&1");echo "The last line of the command output is following:\n".$lastline."\n";' The last line of the command output is following: qstat: Unknown Job Id 12345.server ← エラー出力を標準出力にリダイレクトしたのでエラーがこちらに出ている
eval
は、指定した文字列をPHPコードして評価する。
ユーザ定義関数の定義書式は以下の通り。
function 関数名 (引数名,引数名...) { (処理内容) }
戻り値を返したい場合はreturn
を用いる。
function 関数名 (引数名,引数名...) { (処理内容) return 変数名など }
引数は、通常の指定では「値渡し」となり関数内での操作は関数外に影響しないが、「参照渡し」にすると関数外の値を操作できる。「参照渡し」を利用する場合、「参照渡し」としたい引数名の前にアンパサンド(&
)をつけて関数定義する。複数の値を返したい場合などに便利(複数の値を配列に格納すれば、値渡しでも対応は可能)。
function 関数名 (&引数名,&引数名...) { (処理内容) }
既定値を指定するには引数名の後に「 = 値
」を記す。なお、既定値を指定しない変数を先に記すこと。既定値のある引数は、関数を呼び出す際指定を省略できる。既定値は定数のみ指定できる(変数は指定できない)。
function 関数名 (引数名 = 既定値,&引数名 = 既定値...) { (処理内容) }
参考文献・サイト
【書式】 call_user_func (関数名, パラメータ1, ...)
【例】 <ソース> function hoge () { echo "hogehoge"; } echo "foo¥n"; call_user_func("hoge"); <実行結果> foo hogehoge
実はcall_user_func
を使わなくても、定義済み関数と同様に呼び出せる。
【例】 <ソース> function hoge () { echo "hogehoge"; } echo "foo¥n"; hoge();
また、複数の引数を返したい場合は、参照渡しを使うと便利。
【コード】
<?php
function double_val($val) {
$val = $val * 2;
}
function double_ref(&$val) {
$val = $val * 2;
}
$i = 10;
echo "値渡しの場合、" . $i . " は ";
double_val($i);
echo $i . " のままです。<br />";
echo "参照渡しの場合、" . $i . " は ";
double_ref($i);
echo $i . " になります。<br />";
?>
【結果】
値渡しの場合、10 は 10 のままです。
参照渡しの場合、10 は 20 になります。
呼び出す関数を動的に指定するには、あらかじめ変数に関数名をセットしておき、${変数名}(引数)
のように指定する3。
【例】(現実的な例ではないが...) $funcname = "func_" . date("M"); #- date("M") は アルファベット3文字の月名略称を返す ${$funcname}(); #- 4月なら "func_Apr"が呼び出される
参考文献・サイト:
return
が、関数内で呼び出されるとその関数の実行を即座に停止し、引数を関数の戻り値として返す。グローバルスコープ(スクリプトのメイン部分)で呼び出されると、実行中のスクリプトが終了する。なお return
は関数ではなく言語構造であるため引数を括弧で囲む必要はない(囲むと囲まれた値や変数を評価したものを戻り値として扱う)。
return 戻り値
include
文は、外部スクリプトファイルを読み込んで評価する。他のファイルに記述した関数を取り込んで利用することができる。ファイル名のみの場合は、include_path
に設定されたパスを探し、相対パスまたは絶対パスを指定した場合はその指定パスを探しに行く。require
も同等だが、読み込みに失敗した際、E_ERROR
レベルの致命的エラーを発生してスクリプト処理を停止する点が異なる(include
は警告(E_WARNING
)を発するがスクリプト処理は継続される)。
[common.php](読み込まれるファイル) <?php ←読み込まれるファイルにもPHP開始タグは必要 $subway = array( '1'=>array('name'=>'御堂筋','length'=>'24.5','color'=>'red'), '2'=>array('name'=>'谷町','length'=>'28.3','color'=>'purple'), '3'=>array('name'=>'四つ橋','length'=>'11.8','color'=>'blue'), '4'=>array('name'=>'中央','length'=>'17.9','color'=>'green'), '5'=>array('name'=>'千日前','length'=>'13.1','color'=>'pink'), '6'=>array('name'=>'堺筋','length'=>'8.1','color'=>'brown'), '7'=>array('name'=>'長堀鶴見緑地','length'=>'15.0','color'=>'lightgreen'), '8'=>array('name'=>'今里筋','length'=>'11.9','color'=>'orange')); ?> [index.php] <?php include 'common.php'; ←外部ファイルの指定 echo "<ul>\n"; foreach ($subway as $val) { echo "<li>" . $val['name'] . "線(" . $val['length'] . "km, color " . $val['color'] . ")</li>\n"; } echo "</ul>\n"; 【出力】 <ul> <li>御堂筋線(24.5km, color red)</li> <li>谷町線(28.3km, color purple)</li> <li>四つ橋線(11.8km, color blue)</li> <li>中央線(17.9km, color green)</li> <li>千日前線(17.9km, color pink)</li> <li>堺筋線(8.1km, color brown)</li> <li>長堀鶴見緑地線(13.1km, color lightgreen)</li> <li>今里筋線(11.9km, color orange)</li> </ul>
読み込む際、PHPモードが一時解除されるので、PHPスクリプトを記述するのであれば、読み込む先のファイルにPHP開始終了タグ(<?php ... ?>
)が必要。
関数内で呼び出すと、関数内だけで有効。
ファイルにリモートサーバのPHPスクリプトURLを指定した場合、リモートサーバで処理された結果が、読み込まれる。
参考文献・サイト:
exit
はスクリプト処理を終了する。戻り値はなし。die
も機能は同じ。
【書式】 exit(文字列); exit(整数);
【例】 <?php $link = mysql_connect('localhost'.'hoge') or exit("MySQLサーバに接続できません。"); ?>
gethostname
はローカルのマシンに設定されている標準的なホスト名を返す。PHP 5.3.0より使用可能。
【書式】 gethostname(); 【戻り値】 成功→得られたホスト名 失敗→false
gethostbyname
は指定したインターネットホストの IPv4 アドレスを返す。
【書式】 gethostbyname(ホスト名); 【戻り値】 成功→IPv4アドレス(文字列型) 失敗→指定したホスト名をそのまま文字列で返す
ftp_connect
は指定したサーバへのFTP接続を開く。実際にやりとりするにはftp_login
コマンドでログインする必要がある。
【書式】 ftp_connect(FTPサーバ,ポート番号,タイムアウト時間);
戻り値は、接続に成功した場合はその接続のリンクID(FTPストリーム)、そうでない場合はfalse。
ftp_login
は指定したFTPストリームにログインする。
【書式】 ftp_login(接続ID,ユーザ名,パスワード);
ログインに成功した場合はtrueを返す。失敗した場合はfalseを返した上でPHPの警告が発生する。
ftp_pwd
はFTPサーバ上でのカレントディレクトリを表示する。
【書式】
ftp_pwd(接続ID);
カレントディレクトリの取得に成功した場合はそのディレクトリ名を、失敗した場合はfalseを返す。
ftp_chdir
はFTPサーバ上でのカレントディレクトリを移動する。
【書式】 ftp_chdir(接続ID,移動先ディレクトリ);
ディレクトリ変更に成功した場合はtrueを返す。失敗した場合はfalseを返した上でPHPの警告が発生する。
コマンド | 保存先ファイル指定 | 同期モード |
---|---|---|
ftp_get |
引数指定 | 同期(ブロッキング) |
ftp_fget |
ファイルポインタ | 同期(ブロッキング) |
ftp_nb_get |
引数指定 | 非同期(非ブロッキング) |
ftp_nb_fget |
ファイルポインタ | 非同期(非ブロッキング) |
ブロッキングの場合、ダウンロードに成功した場合の戻り値はtrue、失敗した場合の戻り値はfalse。 非ブロッキングの場合、「FTP_FAILED」(失敗)、「FTP_FINISHED」(完了)、「FTP_MOREDATA」(途中)のいずれかが返る。
非ブロッキング(非同期モード)の場合、ダウンロード中でも別の処理が実行可能。他の処理を行うと一時停止するが、ftp_nb_continue
コマンドにて再開できる。
【書式】 ftp_get(接続ID,保存先ファイル名,取得元ファイル名,モード,ダウンロード開始位置); ftp_fget(接続ID,ファイルポインタ,取得元ファイル名,モード,ダウンロード開始位置); ftp_nb_get(接続ID,保存先ファイル名,取得元ファイル名,モード,ダウンロード開始位置); ftp_nb_fget(接続ID,ファイルポインタ,取得元ファイル名,モード,ダウンロード開始位置);
ftp_connect
で得た接続ID。
fopen
で得たファイルポインタリソース。
0
)。
ftp_mdtm
は指定ファイルの最終更新日を返す。
【書式】 ftp_mdtm(接続ID,ファイル名);
情報取得に成功した場合はUNIXタイムスタンプを、エラー時には -1 を返す。
ftp_size
は指定ファイルのサイズを返す。
【書式】 ftp_size(接続ID,ファイル名);
情報取得に成功した場合はファイルサイズを、エラー時には -1 を返す。
ftp_nlist
は指定ディレクトリのファイル一覧を配列で返す。
【書式】 ftp_nlist(接続ID,ディレクトリ名、引数); 【戻り値】 情報取得に成功 → ファイル一覧の配列 情報取得に失敗 → false
"-la /subdir"
)。
XMLファイルを扱うには、--enable-libxmlオプション付きでインストールし、libxml拡張モジュールを有効にしておく必要あり。但し、デフォルトで有効になっているとのこと[3]。RHEL5/CentOS5ではデフォルトでは入っていない? php-xml RPMパッケージを追加インストールする必要があった。
上記の通り、利用できる環境を用意した上で、DOMDocumentクラス
のインスタンス(オブジェクト)を定義する。
DOMNodeを拡張して、DOMDocument(XML文書)、DOMAttr(属性ノード)、DOMElement(要素ノード)が作られる。DOMNodeの配列がDOMNodeList。
DOMノードは文書オブジェクトモデル(Document Object Model、DOM)全体を通して基本となるデータ型(クラス)[xml2]。DOM文書(DOMDocument)、DOM要素(DOMElement)、DOM属性(DOMAttr)などはDOMノードの拡張で定義される。
書式 | 戻り値の型 | 拡張型での利用 | 内容 | ||
---|---|---|---|---|---|
DOM文書 | DOM要素 | DOM属性 | |||
DOMノード->nodeName | 文字列 | ○ | ○ | ○ | ノードのタグ名を返す。 |
DOMノード->nodeValue | 文字列 | ○ | ○ | ○ | ノードの値を返す。 |
DOMノード->parentNode | DOMノード | ○ | ○ | ○ | 親ノードを返す。 |
DOMノード->childNodes | DOMノードリスト | ○ | ○ | ○ | 子ノード群を含むノードリストを返す。 |
DOM文書->formatOutput | 論理値(true/false) | ○ |
字下げや空白を考慮して整形した出力を行うかどうか。trueなら行い、falseなら行わない。
【例】整形を行うよう設定する $xml = new DOMDocument('1.0','utf-8'); $xml->formatOutput = true; |
書式 | 戻り値の型 | 拡張型での利用 | 内容 | ||
---|---|---|---|---|---|
DOM文書 | DOM要素 | DOM属性 | |||
追加先DOMノード->appendChild(追加するDOMノード) | DOMノード | ○ | ○ | ○ | 子ノードを追加し、追加済みのノードを返す。 |
DOMノード->replaceChild(新DOMノード,旧DOMノード) | DOMノード | ○ | ○ | ○ | 子ノードを置き換え、置き換え前のノードを返す。 |
DOMノード->removeChild(削除するDOMノード) | DOMノード | ○ | ○ | ○ | 指定した子ノードを削除し、削除したノードを返す。 |
DOM文書->createElement(要素名,要素値) | DOM要素 | ○ | DOM文書で指定したDOM文書に所属するDOM要素オブジェクトを作成する。実際追加するには appendChild を使う。 | ||
DOM文書->createAttribute(属性名) | DOM属性 | ○ | DOM文書で指定したDOM文書に所属するDOM属性オブジェクトを作成する。実際追加するには appendChild を使い、属性値を設定するには createTextNode でテキストノードを作成し、appendChild でDOM属性ノードに子要素を追加する。操作としてはDOM要素に setAttribute メソッドを使って設定した方が簡単。 | ||
DOM要素->setAttribute(属性名,属性値) | DOM属性 | ○ | DOM要素で指定したDOM要素に属性名、属性値で指定したキーと値を持つ属性を設定する。属性名で指定したキーが存在しない場合は新たな属性が作成される。 | ||
DOM文書->createTextNode(文字列) | DOMテキストノード | ○ | DOM文書で指定したDOM文書に所属するDOMテキストノードオブジェクトを作成する。実際追加するには appendChild を使う。要素値や属性値の設定に利用できる。 | ||
DOM文書->getElementById(ID属性値) | DOM要素 | ○ | 指定したID属性値を持つ要素ノードを返す。 | ||
DOM文書->getElementByTagName(タグ名) | DOMノードリスト | ○ | 指定したタグ名を持つノード(要素、属性)のリストを返す。 | ||
DOM要素->getAttribute(属性名) | 文字列 | ○ | 指定した属性名の属性値を文字列で返す。 |
【書式】 DOMDocument(バージョン,エンコーディング);
<?xml version="バージョン">
」が作成するオブジェクトの先頭に付加される。
<?xml encoding="エンコーディング">
」が作成するオブジェクトの先頭に付加される。
【例】test.php <?php $xml = new DOMDocument('1.0','utf-8'); echo $xml->saveXML(); ?> 【実行結果】 $ chmod +x test.php $ php test.php <?xml version="1.0" encoding="utf-8"?>
DOMDocument::load
は、あらかじめ作成したDOMDocumentオブジェクトに指定したXMLファイルを読み込む。文字列からXMLを読み込むにはDOMDocument::loadXML
を使う。
HTML文字列を読み込むにはDOMDocument::loadHTML、HTMLファイルを読み込むにはDOMDocument::loadHTMLFileを使う。
【書式】 DOMDocumentオブジェクト->load(ファイル名,オプション); DOMDocumentオブジェクト->loadXML(変数,オプション); DOMDocumentオブジェクト->loadHTMLFile(ファイル名,オプション); DOMDocumentオブジェクト->loadXML(変数,オプション);
【例】 <?php $xml = new DOMDocument(); $xml->load("hoge.xml"); $xml_src = <<< XML_END <?xml version="1.0" encoding="utf-8" ?> <stations> <line name="御堂筋"> <station id="11">江坂</station> <station id="12">東三国</station> <station id="13">新大阪</station> <station id="14">中津</station> <station id="15">梅田</station> </line> <line name="谷町"> <station id="11">大日</station> <station id="12">守口</station> <station id="13">太子橋今市</station> <station id="14">千林大宮</station> <station id="15">関目高殿</station> </line> </stations> XML_END; $xml2 = new DOMDocument(); $xml2->loadXML($xml_src); ?>
DOMDocument::save
は、DOM 表現からXMLドキュメントを作成しファイルに出力する。
DOMDocument::saveXML
は、DOM 表現からXMLドキュメントを作成し文字列に出力する。
【書式】 DOMDocumentオブジェクト->save(ファイル名,オプション); 【戻り値】 【書式】 DOMDocumentオブジェクト->saveXML(ノード,オプション); 【戻り値】 エラーなし→XML エラーあり→false
【例】 <?php $xml = new DOMDocument(); $xml->save("hoge.xml"); ?>
DOMDocument::getElementsByTagName
は、DOMDocumentオブジェクトから指定したタグ名を持つ要素全てを抽出したDOMNodeListオブジェクトを返す。各ノードを取り出すにはDOMNodeList::item
を使う。
【書式】指定したタグ名を持つ要素を全て含むノードリストを得る DOMDocumentオブジェクト->getElementsByTagName(タグ名); 【書式】指定したタグ名を持つ要素で、指定番目に登場したノードを得る DOMDocumentオブジェクト->getElementsByTagName(タグ名)->item(位置番号); 【書式】指定したタグ名を持つ要素で、指定番目に登場したノード(要素)の値を得る DOMDocumentオブジェクト->getElementsByTagName(タグ名)->item(位置番号)->nodeValue;
位置番号は登場順に0からの連番が割り振られる。
【例】 --- test.php <?php $pdbml = new DOMDocument(); $pdbml->load("148l-noatom.xml"); $descriptions = $pdbml->getElementsByTagName('pdbx_description'); foreach ($descriptions as $key => $val) { echo "[$key] -> " . $val->nodeValue . "\n"; } ?> --- 148l-noatom.xml <?xml version="1.0" encoding="UTF-8" ?> ... <PDBx:datablock datablockName="148L" xmlns:PDBx="http://pdbml.pdb.org/schema/pdbx-v32.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pdbml.pdb.org/schema/pdbx-v32.xsd pdbx-v32.xsd"> ... <PDBx:entityCategory> <PDBx:entity id="1"> ... <!-- 1個目の pdbx_description 目の要素 --> <PDBx:pdbx_description>T4 LYSOZYME</PDBx:pdbx_description> ... </PDBx:entity> <PDBx:entity id="2"> ... <!-- 2個目の pdbx_description 目の要素 --> <PDBx:pdbx_description>SUBSTRATE CLEAVED FROM CELL WALL OF ESCHERICHIA COLI</PDBx:pdbx_description> ... </PDBx:entity> <PDBx:entity id="3"> ... <!-- 3個目の pdbx_description 目の要素 --> <PDBx:pdbx_description>SUGAR (2-MER)</PDBx:pdbx_description> ... </PDBx:entity> <PDBx:entity id="4"> ... <!-- 4個目の pdbx_description 目の要素 --> <PDBx:pdbx_description>BETA-MERCAPTOETHANOL</PDBx:pdbx_description> ... </PDBx:entity> <PDBx:entity id="5"> ... <!-- 5個目の pdbx_description 目の要素 --> <PDBx:pdbx_description>water</PDBx:pdbx_description> ... </PDBx:entity> </PDBx:entityCategory> ... </PDBx:datablock> ------ $ php test.php [0] -> T4 LYSOZYME [1] -> SUBSTRATE CLEAVED FROM CELL WALL OF ESCHERICHIA COLI [2] -> SUGAR (2-MER) [3] -> BETA-MERCAPTOETHANOL [4] -> water
なぜか数値のnodeValueは echo で出力はできるが、変数への代入ができなかった。
=== 読み込むXML(一部)
...
<PDBx:pdbx_struct_oper_listCategory>
<PDBx:pdbx_struct_oper_list id="P">
<PDBx:matrix11>0.30901699</PDBx:matrix11>
...
</PDBx:pdbx_struct_oper_list>
<PDBx:pdbx_struct_oper_list id="X0">
<PDBx:matrix11>1.00000000</PDBx:matrix11>
...
</PDBx:pdbx_struct_oper_list>
...
</PDBx:pdbx_struct_oper_listCategory>
...
=== PHPコード
#-- DOMインスタンス宣言
$pdbml_noatom = new DOMDocument();
#-- noatomのPDBMLを読み込む
$pdbml_noatom->load("~/1sva-noatom.xml");
#-- タグ名 pdbx_struct_oper_list の要素を全て取得
$nodelist = $pdbml_noatom->getElementsByTagName('pdbx_struct_oper_list');
#== 行列取得
foreach ($nodelist as $node) {
$val = sprintf('%.8f',$node->getElementsByTagName('matrix11')->item(0)->nodeValue);
/* 下記記述では値が代入されなかった
$val = $node->getElementsByTagName('matrix11')->item(0)->nodeValue;
但し、echo はOK
echo $node->getElementsByTagName('matrix11')->item(0)->nodeValue . "\n";
*/
echo sprintf('%2d',$node->getAttribute('id')) . ": " . $val . "\n";
}
↓
1: 0.30901699
2: 1.00000000
...
DOMDocument::getElementsById
は、DOMDocumentオブジェクトから指定したIDを持つ要素を持つDOMElementオブジェクトを返す。
実際この関数を使用するには下記いずれかの方法でIDを参照できる状態にしておく必要がある。
【書式】 DOMDocumentオブジェクト->getElementsById(ID値);
書式 | 戻り値 |
---|---|
ノード->nodeName; |
ノード(要素)名 |
ノード->nodeValue; |
ノード(要素)の値 |
ノード->childNodes; |
全ての子要素を含むノードリスト(子がなければ空のノードリストを返す) |
ノード->textContent; |
指定したノードおよび子ノードのテキスト |
【XML例】sample.xml <?xml version="1.0" encoding="utf-8" ?> <stations> <line name="御堂筋"> <station id="11">江坂</station> <station id="12">東三国</station> <station id="13">新大阪</station> <station id="14">中津</station> <station id="15">梅田</station> </line> <line name="谷町"> <station id="11">大日</station> <station id="12">守口</station> <station id="13">太子橋今市</station> <station id="14">千林大宮</station> <station id="15">関目高殿</station> </line> </stations> 【PHPスクリプト】 #!/usr/bin/php <?php #- XMLオブジェクトを作成 $xml = new DOMDocument('1.0','utf-8'); #- XMLを読み込む $xml->load('sample.xml'); #- line要素を全て含むノードリストを得る $nodes_line = $xml->getElementsByTagName('line'); ... ?>
getAttributeNode
を使って要素から属性ノードを生成することができる。属性値はnodeValue
を使って属性ノードの値を参照しても得られるが、属性値のみが必要なのであれば、属性値を返すgetAttribute
を使う方が便利。
【属性値を得る】 DOMElement->getAttribute(属性名); DOMElement->getAttributeNode(属性名)->nodeValue; 【属性ノードを得る】 DOMElement->getAttributeNode(属性名);
DOMDocument::createElement
は、新たなDOM要素を作成する。実際DOM文書内へ追加するには、DOMNode::appendChild
などで挿入操作を行う必要がある。
DOMNode::appendChild
は子要素群の最後に要素を追加する。
【書式】 (要素の作成)戻り値:DOM要素 DOMDocument->createElement(要素名,要素値); (要素の挿入)戻り値:DOMノード(DOM要素を含む) 子要素が追加されるDOMノード->appendChild(追加するDOMノード);
DOMElement->nodeValue
で値を設定することもできる。
【例】 [test.php] <?php #- 新たなDOM文書オブジェクトを作成する $dom = new DOMDocument('1.0','utf-8'); #- DOM要素オブジェクトを作成する $element = $dom->createElement('root','This is the root element'); #- DOM要素オブジェクトを $dom の最後に追加する $dom->appendChild($element); #- $dom の内容を標準出力(画面)に出力 echo $dom->saveXML(); ?> $ php ./test.php <?xml version="1.0" encoding="utf-8"?> <root>This is the root element.</root>
DOMNode::removeChild
は指定した子要素を削除する。
【書式】 DOMDocument->removeChild(削除するノード); 【戻り値】 削除に成功→削除したノード
DOMNode::replaceChild
は、子ノードの置き換えを行う。
【書式】 DOMノード->replaceChild(新ノード,旧ノード);
新ノードが既に子ノードとして存在した場合は重ねて追加することはしない。 置き換えに成功すると、旧ノードが返される。
【例】 [test.php] <?php #- 新たなDOM文書オブジェクトを作成する $dom = new DOMDocument('1.0','utf-8'); #- DOM要素オブジェクトを作成する $element = $dom->createElement('root','This is the root element'); $element2 = $dom->createElement('root2','This is the other root element'); #- DOM要素オブジェクトを $dom の最後に追加する $dom->appendChild($element); #- $dom の内容を標準出力(画面)に出力 echo $dom->saveXML(); #- $elementの内容を$element2に置換 $dom->replaceChild($element2,$element); #- $dom の内容を標準出力(画面)に出力 echo $dom->saveXML(); ?> $ php ./test.php <?xml version="1.0" encoding="utf-8"?> <root>This is the root element.</root> <?xml version="1.0" encoding="utf-8"?> <root2>This is the other root element.</root2>
属性を追加する方法は以下の通り。
(1)DOMElement::setAttribute を使う。 DOM要素ノード->setAttribute(属性名,属性値); ※属性名で指定したキーを持つ属性が既に存在した場合は属性値のみが更新される。 (2)DOMDocument::createAttribute、DOMDocument::createTextNode、DOMNode::appendChild を使う。 DOM属性ノード = DOM文書ノード->createAttribute(属性名 # 属性ノード作成 DOM要素ノード->appendChild(DOM属性ノード); # 属性ノードを要素ノードに追加 DOMテキストノード = DOM文書ノード->createTextNode(属性値); # テキストノードを作成 DOM属性ノード->appendChild(DOMテキストノード); # テキストノードを属性ノードに追加 ※DOM属性ノードの属性値が空ではなかった場合、後に追記される。置換する場合は replaceChild を使う。 DOM属性->replaceChild(新DOMテキストノード,旧DOMテキストノード); (3)DOMAttrオブジェクトの新規作成、DOMElement::setAttributeNode を使う。 DOM属性ノード = new DOMAttr(属性名,属性値); # 属性ノードを新規作成 DOM要素->setAttributeNode(DOM属性ノード); # 属性ノードを要素ノードに追加 【例】 [test.php] <?php $dom = new DOMDocument('1.0','utf-8'); #- 新規DOM文書作成 $element = $dom->createElement('root','This is the root element.'); #- DOM文書に属する要素作成 $dom->appendChild($element); #- 要素をDOM文書に追加 #- 方法(1)で追加 $element->setAttribute('attr1','setAttribute'); #- 要素ノードに属性追加 #- 方法(2)で追加 $node_attr = $dom->createAttribute('attr2'); #- DOM文書に属する属性ノードを作成 $element->appendChild($node_attr); #- 属性ノードを追加 $text_attr = $dom->createTextNode('createAttribute'); #- DOM文書に属するテキストノードを作成 $node_attr->appendChild($text_attr); #- テキストノードを属性ノードに追加 #- 方法(3)で追加 $node_attr = new DOMAttr('attr3','setAttributeNode'); #- 新規属性ノードを作成 $element->setAttributeNode($node_attr); #- 属性ノードを要素ノードに追加 #- 結果確認 echo $dom->saveXML(); #- XML文書全体を保存し標準出力へ出力 #- 方法(1)で更新 $element->setAttribute('attr1','setAttribute2'); #- 要素ノードに属性追加 #- 方法(2)で更新 $node_attr = $dom->createAttribute('attr2'); #- DOM文書に属する属性ノードを再作成 $element->appendChild($node_attr); #- 属性ノードを再追加 $text_attr = $dom->createTextNode('createAttribute2'); #- DOM文書に属するテキストノードを作成 $node_attr->appendChild($text_attr); #- テキストノードを属性ノードに追加 #- 方法(3)で更新 $node_attr = new DOMAttr('attr3','setAttributeNode2'); #- 新規属性ノードを作成 $element->setAttributeNode($node_attr); #- 属性ノードを要素ノードに追加 echo $dom->saveXML($element); #- $element要素のみ保存し標準出力へ出力 ?> $ php ./test.php <?xml version="1.0" encoding="utf-8"?> <root attr1="setAttribute" attr2="createAttribute" attr3="setAttributeNode">This is the root element.</root> <root attr1="setAttribute2" attr2="createAttribute2" attr3="setAttributeNode2">This is the root element.</root>
属性値を更新する方法は以下の通り。
(4)DOMElement::setAttribute を使う。 DOM要素ノード->setAttribute(属性名,属性値); ※新規に属性を追加する手順と同じ。属性名で指定したキーを持つ属性が既に存在した場合は属性値のみが更新される。 (5)DOMDocument::createAttribute、DOMDocument::createTextNode、DOMNode::replaceChild を使う。 DOM属性ノード = DOM文書ノード->createAttribute(属性名 # 属性ノード作成(作成済みならこの手順は不要) DOM要素ノード->appendChild(DOM属性ノード); # 属性ノードを要素ノードに追加(作成済みならこの手順は不要) 新DOMテキストノード = DOM文書ノード->createTextNode(属性値); # テキストノードを作成 DOM属性->replaceChild(新DOMテキストノード,旧DOMテキストノード); ※appendChildを使うと既存の属性値の後に値が追記されてしまう。 (6)DOMAttrオブジェクトの新規作成、DOMElement::setAttributeNode を使う。 DOM属性ノード = new DOMAttr(属性名,属性値); # 属性ノードを新規作成 DOM要素->setAttributeNode(DOM属性ノード); # 属性ノードを要素ノードに追加 ※新規に属性を追加する手順と同じ。属性名で指定したキーを持つ属性が既に存在した場合は属性値のみが更新される。
属性を削除する方法は以下の通り。
(7)DOMElement::removeAttribute を使う。 DOM要素->removeAttribute(属性名); ※(1)〜(3)どの方法で作った属性に対しても使える。 (8)DOMElement::removeAttributeNode を使う。 DOM要素->removeAttributeNode(属性ノード); ※(2)では appendChild を使ったので、removeChild でも削除できる気がするがなぜかうまくいかない。 ※方法(1)で作った属性の場合、一旦属性ノードを作成する必要があるので、(7)で削除する方が簡単。 DOM属性ノード = DOM要素->createAttributeNode(属性名);
事例
[test.php] <?php $dom = new DOMDocument('1.0','utf-8'); #- 新規DOM文書作成 $element = $dom->createElement('root','This is the root element.'); #- DOM文書に属する要素作成 $dom->appendChild($element); #- 要素をDOM文書に追加 #- 方法(1)で追加 $element->setAttribute('attr1','setAttribute'); #- 要素ノードに属性追加 #- 方法(2)で追加 $node_attr = $dom->createAttribute('attr2'); #- DOM文書に属する属性ノードを作成 $element->appendChild($node_attr); #- 属性ノードを追加 $text_attr = $dom->createTextNode('createAttribute'); #- DOM文書に属するテキストノードを作成 $node_attr->appendChild($text_attr); #- テキストノードを属性ノードに追加 #- 方法(3)で追加 $node_attr = new DOMAttr('attr3','setAttributeNode'); #- 新規属性ノードを作成 $element->setAttributeNode($node_attr); #- 属性ノードを要素ノードに追加 #- 追加結果確認 echo "== 追加結果 ==\n"; echo $dom->saveXML(); #- XML文書全体を保存し標準出力へ出力 #- 方法(4)で更新 $element->setAttribute('attr1','setAttribute2'); #- 要素ノードに属性追加 #- 方法(5)で更新 $text_attr2 = $dom->createTextNode('createAttribute2'); #- DOM文書に属するテキストノードを作成 $node_attr->replaceChild($text_attr2,$text_attr); #- 属性ノードの子要素であるテキストノードを置換 #- 方法(6)で更新 $node_attr = new DOMAttr('attr3','setAttributeNode2'); #- 新規属性ノードを作成 $element->setAttributeNode($node_attr); #- 属性ノードを要素ノードに追加 #- 更新結果確認 echo "== 更新結果 ==\n"; echo $dom->saveXML(); #- 方法(7)で削除 $element->removeAttribute('attr1'); #- 要素ノードから属性削除 #- 方法(7)による属性削除結果確認 echo "== 方法(7)による属性削除結果 ==\n"; echo $dom->saveXML(); #- 方法(8)で削除 $element->removeAttributeNode($node_attr2); #- 要素ノードから属性ノード削除 #- 方法(8)による属性削除結果確認 echo "== 方法(8)による属性削除結果 ==\n"; echo $dom->saveXML(); ?> $ php ./test.php == 追加結果 == <?xml version="1.0" encoding="utf-8"?> <root attr1="setAttribute" attr2="createAttribute" attr3="setAttributeNode">This is the root element.</root> == 更新結果 == <?xml version="1.0" encoding="utf-8"?> <root attr1="setAttribute2" attr2="createAttribute2" attr3="setAttributeNode2">This is the root element.</root> == 方法(7)による属性削除結果 == <?xml version="1.0" encoding="utf-8"?> <root attr2="createAttribute2" attr3="setAttributeNode2">This is the root element.</root> == 方法(8)による属性削除結果 == <?xml version="1.0" encoding="utf-8"?> <root attr3="setAttributeNode2">This is the root element.</root>
「XPath」を使ってXML文書に対する問い合わせを行う場合、XML文書に対するXPathオブジェクトを作成した上で、XPathによる問い合わせを実行する。
DOMXPath::__construct
)
【書式】
new DOMXPath(XMLオブジェクト);
【例】
$xpath = new DOMXPath($xml);
DOMXPath::query
)【書式】 XPathオブジェクト->query(XPath問い合わせ文,基準ノード,基準ノード自動登録);
【例】 $xmlnodes = $xpath->query('/datablock/citationCategory/citation[@id = "primary"]');
HTTP通信について
fopenのファイル名にURLを指定する方法や、cURLを使う方法がある。
HEADリクエストを発行し、返ってきた応答のhttp headerを確認すれば応答のcodeが分かる。これもページ内容を取得する場合と同等の方法が使える。
【fopenを使う方法】 $ cat test.php <php
header
は生のHTTPヘッダを生成する。この関数を呼び出すタイミングは、あらゆる出力の前である必要がある。HTTP/1.1 の仕様詳細についてはこちら。
【書式】 header(ヘッダ文字列,置換フラグ,httpレスポンスコード); 【戻り値】 なし
送信する HTTP ステータスコードを示すには、HTTP/
で始まる文字列を指定する(例:HTTP/1.1 404 Not Found
)。
例:
<?php
header("HTTP/1.1 404 Not Found");
...
?>
→apache のアクセスログでは
xxx.xxx.xxx.xxx - - [27/Jan/2012:10:00:00 +0900] "GET /index.php HTTP/1.1" 404 12345 - ...
のようになる。
リダイレクトをかけるには「Location:リダイレクト先URL」を指定する19
例: <?php header("Location: https://hoge.org/"); exit; ?>
[3]
http_build_query
は与えられた連想配列 (もしくは添字配列) から URL エンコードされたクエリ文字列を生成する。
【書式】 http_build_query(クエリデータ,数値プレフィックス [, string $numeric_prefix [, string $arg_separator [, int $enc_type = PHP_QUERY_RFC1738 ]]] ) 【戻り値】 (文字列型)URL エンコードされた文字列
【例】 $ cat test.php <?php $array = array('H'=>'Hydrogen','O'=>'Oxygen','1'=>'One','CO2'=>'Carbon Dioxide'); print_r($array); echo http_build_query($array,'No','&')."\n"; echo http_build_query($array,'No','&',PHP_QUERY_RFC1738)."\n"; echo http_build_query($array,'No','&',PHP_QUERY_RFC3986); ?> $ php test.php Array ( [H] => Hydrogen [O] => Oxygen [1] => One [CO2] => Carbon Dioxide ) H=Hydrogen&O=Oxygen&No1=One&CO2=Carbon+Dioxide H=Hydrogen&O=Oxygen&No1=One&CO2=Carbon+Dioxide H=Hydrogen&O=Oxygen&No1=One&CO2=Carbon%20Dioxide
htmlのフォームで送信されたデータの参照方法について。
書式 | 内容 |
---|---|
$_GET |
GETメソッドで送信されたデータの配列。キーはフォーム内要素のname属性値、値はキーに対応する値。 |
$_POST |
POSTメソッドで送信されたデータの配列。キーはフォーム内要素のname属性値、値はキーに対応する値。 |
POSTメソッドを用いてファイルをサーバにアップロードする仕組みを構築する際、以下の点に注意が必要。
<input name="MAX_FILE_SIZE"/>
でアップロード可能なファイルサイズの上限を規定できるが、この値はPHP設定ファイル(UNIX系OSの場合、既定では/etc/php.ini
)中の「upload_max_filesize」の指定値を超えることはできない(既定は2M(B)、値は整数または K(キロ), M(メガ), G(ギガ)のいずれか一つを直後に記した整数)。
【設定例】100MBのファイルまでアップロードできるようにする [/etc/php.ini] upload_max_filesize = 2M ↓ upload_max_filesize = 100M
/etc/php.ini
)の「post_max_size」の指定値を超えることはできない(既定は8M(B))。upload_max_filesize 以上の値に設定しておく。
【設定例】250MBのデータまでPOSTできるようにする [/etc/php.ini] post_max_size = 8M ↓ post_max_size = 250M
/etc/php.ini
)の「max_execution_time」で設定されている(既定値は30(秒))が、この時間が短すぎるとアップロードが終わる前にタイムアウトしてしまう。
/etc/php.ini
)の「max_execution_time」で設定されている(既定値は60(秒))が、この時間が短すぎるとアップロードが終わる前にタイムアウトしてしまう。
【例】
<form enctype="multipart/form-data"
method="post"
action="nantoka.php">
...
フォームで送られてきたファイルデータや情報は $_FILES
スーパーグローバル変数(スクリプト全体で全てのスコープにおいて使用できる変数)に格納される(PHP 4.1.0以降)。第1キーはフォーム内要素のname属性値。第2キーの内容および対応する値は以下の通り。
第2キー | 内容 |
---|---|
name |
ウェブクライアント側での元のファイル名 |
type |
ウェブクライアント(ブラウザ)が通知してきたファイルのMIMEタイプ |
size |
アップロードされたファイルのバイト単位のファイルサイズ |
tmp_name |
アップロードされたファイルのサーバ上での一時ファイル名 |
error |
ファイルアップロードに関するエラーコード(PHP 4.2.0以降)。正常であれば 0。 |
アップロードされたファイルはサーバ既定の一時ディレクトリに保存される。このファイルを移動させるにはmove_uploaded_file
関数を用いる。
【書式】 move_uploaded_file(アップロードファイル名,移動後のファイル名); 【戻り値】 成功→true PHPでアップロードされた有効なファイルではない→false PHPでアップロードされた有効なファイルだが、移動に失敗した場合→false(あわせて警告が出力される)
$_FILES[キー]['tmp_file']
変数を参照するのが便利。なお、同名のファイルが既に存在した場合は上書きされる。
【例】 <form enctype="multipart/form-data" action="PHPスクリプトのURL" method="POST"> <!-- MAX_FILE_SIZE は、必ず "file" input フィールドより前に置く --> <input type="hidden" name="MAX_FILE_SIZE" value="30000" /> <!-- input 要素の name 属性の値が、$_FILES 配列の第1キーになる --> このファイルをアップロード: <input name="userfile" type="file" /> <input type="submit" value="ファイルを送信" /> </form>
一時ファイルがHTTP POSTでアップロードされたものであるかどうかを調べるにはis_uploaded_file
を用いる。
【書式】
is_uploaded_file(ファイル名);
【戻り値】
HTTP POSTによりアップロードされたファイル→true
そうでない場合→false
セッション管理を使って、あるページを通ってこないと目的のページに到達できないようにすることができる(例:利用許諾に同意しないとダウンロードページを表示できないようにする)。
【例】 session_start(); if (empty($_SESSION['urlachecked'])) { $_SESSION['urlachecked'] = true; echo '<p>ようおこし</p>'."\n"; echo '<a href="'.$_SERVER['SCRIPT_NAME'].'">次はこちらへどうぞ</a>'."\n"; } else if ($_SESSION['urlachecked']) { echo '<p>よくぞここまできた! あっぱれじゃ!</p>'."\n"; } session_write_close();
phpversion
は現在動作中の PHP パーサあるいは拡張モジュールのバージョンを表す文字列を返す。サブモジュールを指定しない場合は、PHPパーサ本体のバージョンを返す。指定した場合、そのサブモジュールが有効でバージョン情報があればその情報を、そうでなければ false を返す。
【書式】 phpversion(サブモジュール名); 【例】 echo phpversion(); #→ 5.1.6
PHP 5.3からは gethostname
でホスト名が取得できる。
[gethostname53.php] <?php echo gethostname(); ?> $ hostname myserver $ php gethostname53.php myserver
PHP 5.3より前(PHP 4.0.2以降、およびPHP 5)では php_uname
でホスト名が取得できる。
【書式】
php_uname(モード)
モード
[gethostname.php] <?php echo php_uname('n'); ?> $ hostname myserver $ php gethostname.php myserver
php -i
コマンドでPHPの各種設定情報をみることができる。php -r "echo phpinfo();"
と同じ。
getimagesizeコマンドにより画像の縦横ピクセル数などの情報が得られる。この関数で得られる情報をHTMLのimgタグやHTTPのcotent typeとして利用することができる。
なお、この関数は適切な画像ファイルかどうかの判定は行わない。仮に画像ファイルでなくても関数処理は成功するかもしれないが、返る値には意味のない値が含まれる可能性がある。画像ファイルかどうかを判定するにはFileinfo拡張モジュールを使うのがよいとのこと。
【書式】 getimagesize(ファイル名); 【引数】 ファイル名:文字列 情報を取得したいファイルのファイル名。 【戻り値】 成功:最大7つの要素を持つ配列、失敗:FALSE(指定したファイルにアクセスできない、読み込み時にエラーが発生したなど) key: 値 0: 画像の幅(ピクセル数) 1: 画像の高さ(ピクセル数) 2: IMAGETYPE_XXX constants 定数のひとつで、 画像の形式を表す値。 3: imgタグで直接利用できる文字列(例:width="200" height="283") bits: 個々の色のビット数。アニメーションGIFなど画像の形式によっては正しい値を表示できないことがあることに注意。 mime: 画像のMIMEタイプ。この情報は画像とともに正しい HTTP Content-type ヘッダを転送するために使える。 channels: RGB画像は3、CMYK画像の場合は4。アニメーションGIFなど画像の形式によっては正しい値を表示できないことがあることに注意。 【例】 $ php -r "print_r(getimagesize('hoge.png'));" Array ( [0] => 1819 [1] => 2573 [2] => 3 [3] => width="1819" height="2573" [bits] => 8 [mime] => image/png )
PHPスクリプトをコマンドラインから実行するには、(1)php コマンドの引数としてPHPスクリプトファイルを指定する (2) phpスクリプトファイルを実行可能にして実行する (3)php -r 'phpスクリプト'の形で直接phpコードを記述、という方法がある。
【例】sample.phpを実行する(UNIX系OSの場合) shell> ls -l sample.php -rwxrwxr-- 1 user user 1234 11 30 09:00 sample.php ←実行権限(x)があればOK(但し、現在のユーザに権限があること) ↑この場合、ユーザuserまたはグループuserに属するユーザのみ実行権限あり ↓権限を追加する必要がある場合は shell> chmod +x sample.php ↓実行するにはファイル名を指定するだけでOK shell> ./sample.php
ちょっとした処理の確認ならコマンドラインで直接書いた方が便利かも。
【書式】 php -r 'PHPコード' 【例】 shell> php -r 'echo "hogehoge";' hogehoge
コマンドライン引数を指定し、スクリプト内で参照するには$argv
(php.ini
でregister_argc_argv
の値をTRUE
に設定している場合に利用可能、そうでない場合でも$_SERVER['argv']
で参照可能)は各引数を要素に持つ配列、$argc
($_SERVER['argc']
)は$argv
の配列要素数を持つ。$argv[0]
はスクリプトファイル名(入力元が標準入力または-r
オプションを使ってコマンドライン上に直接コードを指定した場合は-
)が格納される。
shell> cat test.php
#!/usr/bin/php
<?php
var_dump($argv);
var_dump($argc);
?>
shell> php test.php hoge fuga
array(3) {
[0]=>
string(10) "./test.php"
[1]=>
string(4) "hoge"
[2]=>
string(4) "fuga"
}
int(3)
※実行権限を与えてあれば以下のようにスクリプトファイルを実行しても同じ
shell> ./test.php hoge fuga
入力元が標準入力の場合、または-r
オプションを使って直接コードを記述した場合
shell> php -r 'var_dump($argv);'
array(1) {
[0]=>
string(1) "-"
}
shell> php -r 'var_dump($argv);' hoge fuga
array(3) {
[0]=>
string(1) "-"
[1]=>
string(4) "hoge"
[2]=>
string(4) "fuga"
}
引数の先頭文字が - の場合、PHPの実行オプションと解釈されるため意図しない実行結果となりうる。それを防ぐには引数群の前に引数リストセパレータ -- を置く必要がある
"-h"オプションが指定されたと解釈され、ヘルプが表示されてしまう shell> php -r 'var_dump($argv);' -h Usage: php [options] [-f] <file> [--] [args...] php [options] -r <code> [--] [args...] php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...] php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...] php [options] -- [args...] php [options] -a -a Run interactively ... "--"以降は引数と解釈される shell> php -r 'var_dump($argv);' -- -h array(2) { [0]=> string(1) "-" [1]=> string(2) "-h" }
引数に「`cat -`
」を指定すればよい。
$ which php /usr/bin/php $ cat test.php <?php echo var_dump($argv); ?> $ php 2513.php `cat -` hoge (Ctrl+D) array(2) { [0]=> string(8) "2513.php" [1]=> string(4) "hoge" }
複数のhtmlファイル(header.html
、main.html
、footer.html
)を連結して表示させる例(linked.php
)。
header.html
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <title>test>/title> </head> <body> <h1>test</h1>
main.html
<ul> <li>東京</li> <li>新横浜</li> <li>小田原</li> <li>熱海</li> <li>三島</li> <li>新富士</li> <li>静岡</li> <li>掛川</li> <li>浜松</li> <li>豊橋</li> <li>三河安城</li> <li>名古屋</li> <li>岐阜羽島</li> <li>米原</li> <li>京都</li> <li>新大阪</li> </ul>
footer.html
<div> Thank you for taking the Nozomi superexpress bound for Shin-Osaka. </div>
linked.php
<?php echo file_get_contents('header.html'); echo file_get_contents('main.html'); echo file_get_contents('footer.html'); ?>
結果:
【例】http://www.hoge.com/index.php?y=2009&m=Jul $getstr = "?"; $keys = array_keys($_GET); foreach ($keys as $key) { $getstr .= $key . "=" . $_GET[$key]; } $getstr = substr($getstr,0, -5); ←最後のアンパサンドを削除 echo $_SERVER['SERVER_NAME']; ← www.hoge.com echo $_SERVER['PHP_SELF']; ← index.php echo $getstr; ← ?y=2009&m=Jul
IFの前の行の最後のセミコロンが抜けているか、コメントアウト記号の#の前に空けていく空白に全角空白が使われている。
Parse error: syntax error, unexpected T_IF in (ローカルパス)on line (行番号)
前項同様か。
PHP5.4.19のRPMパッケージをビルドしようとしたが、以下のエラーによりビルド失敗。
make: *** [ext/pdo_sqlite/pdo_sqlite.lo] Error 1 make: *** [ext/pdo_sqlite/sqlite_driver.lo] Error 1 make: *** [ext/pdo_sqlite/sqlite_statement.lo] Error 1
エラーの出始め部分を見ると、「pdo/php_pdo.h、pdo/php_pdo_driver.h というファイルがない」というメッセージ。元のコンテンツのバックアップを取ってから、該当ファイル「php-5.4.19/ext/pdo_sqlite/{pdo_sqlite.c,sqlite_driver.c,sqlite_statement.c}」に以下の変更を適用。
[root@server ~]# cd /usr/src/redhat/SOURCES [root@server SOURCES]# mv php-5.4.19 php-5.4.19_orig [root@server SOURCES]# vim php-5.4.19/ext/pdo_sqlite/pdo_sqlite.c # 以下の修正を適用、sqlite_driver.c、sqlite_statement.cも同様 #include "pdo/php_pdo.h" #include "pdo/php_pdo_driver.h" ↓ #include "ext/pdo/php_pdo.h" #include "ext/pdo/php_pdo_driver.h"
パッチファイルを作成[3]。そのパッチを適用するようSPECファイルを修正。これでbuildできた。
[root@server SOURCES]# diff -ru php-5.4.19_orig php-5.4.19 >php-5.4.19-1.patch [root@server SOURCES]# cat php-5.4.19-1.patch ←こちらにUploadしています(但し拡張子は.txtに変更) diff -ru php-5.4.19/ext/pdo_sqlite/pdo_sqlite.c php-5.4.19p/ext/pdo_sqlite/pdo_sqlite.c --- php-5.4.19/ext/pdo_sqlite/pdo_sqlite.c 2013-08-20 13:42:41.000000000 +0900 +++ php-5.4.19p/ext/pdo_sqlite/pdo_sqlite.c 2013-08-29 10:59:02.000000000 +0900 @@ -25,8 +25,8 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" -#include "pdo/php_pdo.h" -#include "pdo/php_pdo_driver.h" +#include "ext/pdo/php_pdo.h" +#include "ext/pdo/php_pdo_driver.h" #include "php_pdo_sqlite.h" #include "php_pdo_sqlite_int.h" #include "zend_exceptions.h" diff -ru php-5.4.19/ext/pdo_sqlite/sqlite_driver.c php-5.4.19p/ext/pdo_sqlite/sqlite_driver.c --- php-5.4.19/ext/pdo_sqlite/sqlite_driver.c 2013-08-20 13:42:41.000000000 +0900 +++ php-5.4.19p/ext/pdo_sqlite/sqlite_driver.c 2013-08-29 11:08:16.000000000 +0900 @@ -25,8 +25,8 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" -#include "pdo/php_pdo.h" -#include "pdo/php_pdo_driver.h" +#include "ext/pdo/php_pdo.h" +#include "ext/pdo/php_pdo_driver.h" #include "php_pdo_sqlite.h" #include "php_pdo_sqlite_int.h" #include "zend_exceptions.h" diff -ru php-5.4.19/ext/pdo_sqlite/sqlite_statement.c php-5.4.19p/ext/pdo_sqlite/sqlite_statement.c --- php-5.4.19/ext/pdo_sqlite/sqlite_statement.c 2013-08-20 13:42:41.000000000 +0900 +++ php-5.4.19p/ext/pdo_sqlite/sqlite_statement.c 2013-08-29 11:19:57.000000000 +0900 @@ -25,8 +25,8 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" -#include "pdo/php_pdo.h" -#include "pdo/php_pdo_driver.h" +#include "ext/pdo/php_pdo.h" +#include "ext/pdo/php_pdo_driver.h" #include "php_pdo_sqlite.h" #include "php_pdo_sqlite_int.h" [root@server SOURCES]# vim ../SPECS/php.spec # 以下の修正を適用 ... URL: http://www.php.net/ Packager: PHP Group <group@php.net> Patch0: php-5.4.19-1.patch ←追記 ... %prep rm -rf ${RPM_BUILD_ROOT} mkdir -p ${RPM_BUILD_ROOT} %setup %patch0 -p1 ←追記 %build ./configure ...
PHP(7.1.0)の既定設定では、PHPコードの開始タグ <?php
の省略形 <?
が有効になっている。このままだと静的なxhtmlファイルの冒頭に記述される <?xml version="1.0"?>
などがphp開始タグとして認識されてしまい、phpコードエラーを起こしてしまう。これを防ぐにはPHP設定ファイル(/etc/php.ini
など)に以下の記述を行って省略タグを無効にする[4]。
short_open_tag = Off
MySQLについてはこちらも参照のこと
1回作れば良い。これはわざわざPHPを介さず直接コマンドラインでやってしまうのが簡単。
shell> mysql -umysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 34 Server version: 5.0.67 MySQL Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> create database test2;
【例】 $link = mysql_connect('localhost', 'mysql') ←MySQLに接続 === 接続に成功した場合 === if ($link !== false) { $db_selected = mysql_select_db('データベース名,$link); データベース選択 === データベース選択に成功した場合 === if($db_selected !== false) { $count_resource = mysql_query("SELECT COUNT(*) from テーブル名"); レコード数を数えるクエリ文を送信 $count = mysql_fetch_array($count_resource); 結果を配列として取得 } === データベース選択に成功した場合おわり === mysql_close($link); MySQL接続を切断 } === 接続に成功した場合おわり === echo "レコード数は " . $count[0] . " です。"; $countの1つ目(0番目)の要素を参照 【結果例】 レコード数は 100 です。
参考文献・サイト: