- Bashを使う
- 一般ユーザに使用させるべきではない名称
- mod_rewriteを使う
- CentOS6 で Apache2.4 + PHP5.4 環境を作る
- PHP5.3.3のセキュリティ
- PHP5.4のセキュリティ
- PHPを5.6にバージョンアップ
- PHPを7.1にバージョンアップ
- PHPを8.2にバージョンアップ
- PHPのバージョンを同居させて使用する
- PHP CS Fixer(コード整形)を使う
- PHPでSSLを強制する
- PHPでURLから「www.」を省略する
- PHPでCookieをサブドメイン間で共有する
- PHPのセッション有効期限を伸ばす
- PHPでPEARを使う
- PHPでPHARを展開する
- PHPでHTTPの疎通確認を行う
- PHPからシェルスクリプトを実行する
- PHPで並列処理を行う
- PHPでComposerを使う
- PHPでファイルロックを使う
- MySQLでトランザクション分離レベルを変更する
- MySQLでロックを行う
- MySQLへの一斉アクセスをテストする
- cronでPHPを定期実行
- ImageMagickを使う
- wkhtmltopdf(PDF作成)を使う
- MeCab(形態素解析)を使う
- Igo(形態素解析)を使う
- OpenCV(画像処理・画像解析・顔認識)を使う
- Sisimai(バウンスメール解析)を使う
Bashを使う
初心者向けシェルスクリプトの基本コマンドの紹介 - Qiita
https://qiita.com/zayarwinttun/items/0dae4cb66d8f4bd2a337
bashで始めるシェルスクリプト基礎の基礎 (1/2):Windowsユーザーに教えるLinuxの常識(8) - @IT
https://www.atmarkit.co.jp/ait/articles/0202/05/news001.html
/usr/bin/envを使って移植性の高いスクリプトを書く方法 | マイナビニュース
https://news.mynavi.jp/article/20180620-650003/
bash の select は令和の時代も役に立つ, その一例 - ようへいの日々精進XP
https://inokara.hateblo.jp/entry/2020/04/18/083329
一般ユーザに使用させるべきではない名称
一般ユーザに払い出すと危険なサブドメインやメールアドレス - ASnoKaze blog
https://asnokaze.hatenablog.com/entry/2022/07/04/000036
levis-members/users.php at master - refirio/levis-members
https://github.com/refirio/levis-members/blob/master/app/models/users.php#L244
mod_rewriteを使う
mod_rewriteが機能しなかったり、「No input file specified.」と表示されて動作しなかった場合の対応。
サーバ環境によっては、少し書き方を変える必要がある。
以下は大抵のサーバで動作する書き方。
チュートリアル | levis: PHP Framework
http://refirio.org/levis/manual/tutorial.html#url
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpeg|jpg|jpe|gif)$
RewriteRule (.*) index.php/$1
</IfModule>
以下はXServerなどで動作させるための書き方。
リライトで「index.php?/$1」とした場合でもPATH_INFOを取得するフォールバックコード - Qiita
https://qiita.com/sounisi5011/items/6681bea157a04acf5a51
SetEnvIf Request_URI ".*" Ngx_Cache_NoCacheMode=off
SetEnvIf Request_URI ".*" Ngx_Cache_StaticMode
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !\.(css|js|png|jpeg|jpg|jpe|gif)$
#RewriteRule (.*) index.php/$1
RewriteRule (.*) index.php?/$1 [QSA,L]
</IfModule>
CentOS6 で Apache2.4 + PHP5.4 環境を作る
■Apache2.4
Install Apache 2.4 on CentOS 6 with yum ← RootLinks Co., Ltd.
https://www.rootlinks.net/2016/10/07/install-apache-2-4-on-centos-6-with-yum/
# cd /etc/yum.repos.d/
# curl -O https://repos.fedorapeople.org/repos/jkaluza/httpd24/epel-httpd24.repo
# yum search httpd24
# yum install httpd24
# /etc/init.d/httpd24-httpd start
# vi /opt/rh/httpd24/root/etc/httpd/conf/httpd.conf
インストールできた。
ServerName www.example.com:80
DocumentRoot "/opt/rh/httpd24/root/var/www/html"
# /etc/init.d/httpd24-httpd restart
# chkconfig httpd24-httpd on
※以下はエラーになった。
yum --enablerepo=centos-sclo-rh -y install httpd24
※以下もエラーになった。
yum install wget
wget https://repos.fedorapeople.org/repos/jkaluza/httpd24/epel-httpd24.repo
yum reinstall --enablerepo=epel-httpd24 httpd24
■PHP5.4
【シンプル】CentOS6にPHP5.4をyumで簡単にインストールする手順田舎に住みたいエンジニアの日記 | 田舎に住みたいエンジニアの日記
http://blog.ybbo.net/2014/01/22/%E3%80%90%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%80%91centos6%E3%81%...
# yum remove php*
# yum clean all
# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# yum install php --enablerepo=remi
# service httpd restart
インストールできた。
PHP5.3.3のセキュリティ
CentOS6では、未だにデフォルトでPHP5.3が入る件について。
RHEL/CentOS 6のPHP5.3.3 は安全か?
http://qiita.com/nanasess/items/4248b2dc63a035c2933e
公式な開発は5.3.29で終了しているが、その後Redhatが5.3.3をベースに5.3.3-46のようにメンテナンスを続けていて。
2020年11月30日までメンテナンスされる…らしい。
よって、セキュリティ的な意味では5.3だからと言ってダメというわけでも無いみたい。
AWSのEC2はPHP5.3.29なので、これには当てはまらないかも?
ただしAmazonLinuxの一部としてメンテナンスされているかも?
いずれにせよ、可能ならPHP5.6へバージョンアップすることを推奨。
PHP5.4のセキュリティ
PHP5は公式にはサポートが終了しているが、Redhatがアップデートを続けている。
CentOS7にバンドルされているPHP5.4.16は、適切にアップデートしていれば2024年6月30日まで安心して使うことができる。
PHPのリリース日とサポート期限 - Qiita
https://qiita.com/bezeklik/items/72d1ff8393f66673e2bc
RHEL/CentOS 7のPHP5.4.16 は安全か? - Qiita
https://qiita.com/nanasess/items/029d96cf6360be867ac8
PHP のサポート期間について(バージョンごとの一覧表あり) - Qiita
https://qiita.com/Web_akira/items/c3e5dbd86ab82affe8fa
PHPを5.6にバージョンアップ
PHP5.3をPHP5.6にする手順。
AWS EC2 で始めるお手軽LAMP環境 APACHE2.4 MYSQL5.5 PHP5.6
http://qiita.com/bboobbaa/items/62761fc219136c37af14
Amazon Linux AMIでPHPを5.3から5.4にアップグレードする方法 with FuelPHP
http://qiita.com/Keech/items/70593f432008dc89c2e8
AWS EC2 Amazon LinuxでphpMyAdminを動かす方法!mysqli|mysql 拡張がありません。って
http://yutaihara.com/archives/240
■インストール済みのバージョンを確認
# httpd -v … Apacheのバージョンを確認。
Server version: Apache/2.2.31 (Unix)
Server built: Jul 19 2016 00:11:31
# php -v … PHPのバージョンを確認。
PHP 5.3.29 (cli) (built: May 12 2015 22:42:19)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
# yum list installed | grep php … PHP関連のモジュールを確認。
php.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-cli.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-common.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-devel.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-gd.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-mbstring.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-mysql.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-pdo.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-pear.noarch 1:1.10.1-1.19.amzn1 @amzn-main
php-process.x86_64 5.3.29-1.8.amzn1 @amzn-main
php-xml.x86_64 5.3.29-1.8.amzn1 @amzn-main
■古いバージョンをアンインストール
# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.20170525 … Apacheの設定ファイルをバックアップ。
# cp /etc/php.ini /etc/php.ini.20170525 … PHPの設定ファイルをバックアップ。
# yum remove httpd-* … Apacheをアンインストール。(PHP5.4以降ではApache2.4とセットで使う…と思っていたが、2.2でも動くみたい。)
# yum remove php … PHPをアンインストール。
# yum remove php*
# yum remove php-*
# yum clean all … 念のためyumのキャッシュを削除。
■インストール
# yum -y install httpd24 … Apache2.4をインストール。
# yum -y install php56 php56-mbstring php56-gd … PHP5.6をインストール。(必要に応じてGDなどもインストール。あらかじめ確認しておくこと。)
# php -v
# vi /etc/php.ini
# service httpd start … httpdを起動。
# chkconfig httpd on … httpdの自動起動を設定。
■MySQLを使っている場合
# yum -y install php56-mysqlnd … php-mysqlをインストール。(「php56-mysql」などはダメだった / EC2以外なら大丈夫かも。)
# service httpd restart … httpdを再起動。
PHPを7.1にバージョンアップ
PHP5.3をPHP7.1にする手順。
Apacheは2.2のまま。
■環境によっては実行
サーバ環境によっては先に以下の作業を行う。
・/etc/yum.conf でアップデート制限を解除。(制限している場合 / 作業が完了したら元に戻す。)
・yum -y update を実行しておく。
・service yum-cron restart を実行しておく。
・サーバ自体を再起動し、PHPの稼働とメールの送信に問題が無いことを確認しておく。
※「yum -y update」をしておかないと、PHP7インストール時に「パッケージ php71w-devel は利用できません amazon linux」と表示されることがあるみたい。
※サーバを再起動しないと、メールが送信されないことがあるみたい。
■古いバージョンをアンインストール
# cp /etc/php.ini /etc/php.ini.20190514 … PHPの設定ファイルをバックアップ。
# yum remove php … PHPをアンインストール。
# yum remove php*
# yum remove php-*
# yum clean all … 念のためyumのキャッシュを削除。
■インストール
# rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm
# yum -y install --enablerepo=webtatic-testing php71w php71w-devel php71w-mbstring php71w-gd php71w-mysql php71w-pdo php71w-xml
# php -v
# vi /etc/php.ini
# service httpd restart
■AmazonLinux2の場合
上のyumではインストール時に以下のエラーになって終了してしまう。
--> 依存性解決を終了しました。
エラー: パッケージ: php71w-common-7.1.29-1.w6.x86_64 (webtatic-testing)
要求: libgmp.so.3()(64bit)
以下のように、Extrasからならインストールできた。
# amazon-linux-extras install php7.1 -y
■新規にインストールする場合
新規にインストールしたときのメモは Web.txt の nginx+PHP7 などを参照。
AWS EC2にApache2.4, PHP7環境を構築するメモ
https://qiita.com/hosoken/items/b60a4c9cc2afcddb8041
PHPを8.2にバージョンアップ
AmazonLinux2で、amazon-linux-extrasを使ってPHP7.4をインストールした環境を想定し、
PHP8.2へのバージョンアップを実際に試したときのメモ。
■検証内容
検証のために、以下のとおりWebサーバをインストールしておく。
# localedef -f UTF-8 -i ja_JP ja_JP
# localectl set-locale LANG=ja_JP.UTF-8
# timedatectl set-timezone Asia/Tokyo
# timedatectl status
# yum -y install httpd
# vi /etc/httpd/conf/httpd.conf
以下でPHP7.4をインストールしておく。
#ServerName www.example.com:80 … コメントを解除。
# systemctl start httpd
# systemctl enable httpd
# amazon-linux-extras install php7.4 -y
# yum -y install php-cli php-common php-devel php-fpm php-mbstring php-mysqlnd php-pdo php-gd php-xml php-zip
# php -v
# systemctl restart php-fpm
# systemctl restart httpd
適当なページを作成して phpinfo() の内容が表示されるようにし、ブラウザからアクセスできることを確認しておく。
ここまでが検証の準備。
ここからがPHPのバージョンアップ作業。
# amazon-linux-extras list | grep php
# yum remove php-*
# php -v
# amazon-linux-extras disable php7.4
# amazon-linux-extras enable php8.2
パッケージ一覧に続いて以下のコマンドが表示されるので、そのまま実行する。
(最低限必須になるものが表示されているのか、あくまでも例として表示されているのか。)
Now you can install:
# yum clean metadata
# yum install php-cli php-pdo php-fpm php-json php-mysqlnd
引き続き、必要な機能をインストールする。
# yum -y install php-cli php-common php-devel php-fpm php-mbstring php-mysqlnd php-pdo php-gd php-xml php-zip
# php -v
Webサーバを再起動。
# systemctl restart php-fpm
# systemctl restart httpd
ブラウザからアクセスして phpinfo() の内容を確認しておく。
■アプリケーションの対応
プログラムの調整やテストについて触れられている。
必要になったら参考にしたい。
PHPバージョンアップけもの道 - Speaker Deck
https://speakerdeck.com/uzulla/phpbaziyonatupukemofalsedao
PHPのバージョンを同居させて使用する
PHP7.0〜7.4を同時に使えるようにしたときのメモ。(使用するPHPは、バーチャルホストごとに.htaccessで指定する。)
今回はRemiのリポジトリを使用するので、あらかじめ追加しておく。
■うまく行かなかった方法
remiリポジトリから以下のように複数のPHPをインストールすると、
# yum -y install --enablerepo=remi-php73 php php-cli php-common php-devel php-fpm
# yum -y install --enablerepo=remi-php74 php php-cli php-common php-devel php-fpm
PHPのバージョンは最後にインストールした7.4になる。
PHPは /etc/php.d にインストールされる。
# php -v
PHP 7.4.24 (cli) (built: Sep 21 2021 11:23:11) ( NTS )
# php74 -v
-bash: php74: command not found
# php73 -v
-bash: php73: command not found
PHPは「php73 -v」や「php74 -v」ではなく、「php -v」で参照できるのみ。
■うまく行った方法
以下を実行すると、新たにPHP7.3とPHP7.4のインストールが始まる。
# yum -y install php73 php73-php-gd php73-php-xml php73-php-mbstring php73-php-mysqlnd
# yum -y install php74 php74-php-gd php74-php-xml php74-php-mbstring php74-php-mysqlnd
それぞれがインストールされる。
# php -v
PHP 7.4.24 (cli) (built: Sep 21 2021 11:23:11) ( NTS )
# php74 -v
PHP 7.4.24 (cli) (built: Sep 21 2021 11:23:11) ( NTS )
# php73 -v
PHP 7.3.31 (cli) (built: Sep 21 2021 10:24:03) ( NTS )
以下を実行すると、新たにPHP7.0とPHP7.1とPHP7.2がインストールされる。
# yum -y install php70 php70-php-gd php70-php-xml php70-php-mbstring php70-php-mysqlnd
# yum -y install php71 php71-php-gd php71-php-xml php71-php-mbstring php71-php-mysqlnd
# yum -y install php72 php72-php-gd php72-php-xml php72-php-mbstring php72-php-mysqlnd
なお、最低限以下の指定だけでインストールできる。(PHP7.2の場合の例。)
# yum -y install php72
Yum で任意のバージョンの PHP をインストールする - Qiita
https://qiita.com/bezeklik/items/74106f3ed528584293c3
上記によると、別バイナリ名として「php70」「php71」などが登録されているらしい。
複数バージョンのPHPを共存できるようにするために提供されているのかもしれない。
これにより、例えば以下のようにインストールすると
# yum -y install --enablerepo=remi-php74 php php-cli php-common php-devel php-fpm
# yum -y install php74 php74-php-gd php74-php-xml php74-php-mbstring php74-php-mysqlnd
# yum -y install php73 php73-php-gd php73-php-xml php73-php-mbstring php73-php-mysqlnd
以下のように参照できる。
$ php -v
PHP 7.4.24 (cli) (built: Sep 21 2021 11:23:11) ( NTS )
$ php74 -v
PHP 7.4.24 (cli) (built: Sep 21 2021 11:23:11) ( NTS )
$ php73 -v
PHP 7.3.31 (cli) (built: Sep 21 2021 10:24:03) ( NTS )
Apacheから参照するには、php-fpmを利用する。
/etc/php-fpm.d/www.conf はそのままデフォルトとし、
listen = 127.0.0.1:9000
pm = dynamic
/etc/opt/remi/php74/php-fpm.d/www.conf は70〜74までそれぞれ設定する。(以下はPHP7.4用の設定。)
listen = 127.0.0.1:9000
pm = dynamic
↓
listen = 127.0.0.1:9074
pm = ondemand
/etc/httpd/conf.d/vhosts.conf などで以下のように指定する。(「FilesMatch」のブロックを追加。この場合はPHP7.2。)
<VirtualHost *:80>
ServerName php.development.local
DocumentRoot /var/www/vhosts/php/html
</VirtualHost>
↓
<VirtualHost *:80>
ServerName php.development.local
DocumentRoot /var/www/vhosts/php/html
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9072"
</FilesMatch>
</VirtualHost>
これで任意のPHPを使用することができる。
■参考
参考になりそうなページ。
Yum で複数バージョンの PHP を共存させる - Qiita
https://qiita.com/bezeklik/items/860ba080bf4c664cd8e9
複数のバージョンの PHP を切り替えて使う - Qiita
https://qiita.com/centipede/items/0a5e2f55ec3f66dc6bd9
PHP5.6、PHP7.0、PHP7.1の混在環境の構築 | agathion アメブロ支店
https://ameblo.jp/amebajes/entry-12322702469.html
PHP CS Fixer(コード整形)を使う
GitHub - FriendsOfPHP/PHP-CS-Fixer: A tool to automatically fix PHP coding standards issues
https://github.com/FriendsOfPHP/PHP-CS-Fixer
からファイルを入手する。具体的には
http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar
からpharファイルを取得し、「php-cs-fixer.phar」に名前を変更して保存する。
インストールはこれで完了。以下のように、バージョンが表示されることを確認する。
$ php php-cs-fixer.phar --version
PHP CS Fixer 2.10.0 Bowling Bear by Fabien Potencier and Dariusz Ruminski (513a376)
変換対象プログラム(テスト)を用意する。
これはPSR-2の「名前空間の宣言直後に空行を入れる」「ブレス({ 〜 })は改行する」という2点に違反している状態。
$ vi test/sample.php
以下のコマンドでコード整形ができる。
<?php
namespace Sample;
class Dummy {
}
$ php php-cs-fixer.phar fix ./test
You are running PHP CS Fixer with xdebug enabled. This has a major impact on runtime performance.
If you need help while solving warnings, ask at https://gitter.im/PHP-CS-Fixer, we will help you!
Loaded config default.
1) test\\sample.php
Fixed all files in 0.449 seconds, 9.750 MB memory used
以下のコマンドで「PSR-2に整形する」と明示できる。(デフォルトでPSR-2なので、この場合は結果は同じ。)
$ php php-cs-fixer.phar --rules=@PSR2 fix ./test
PHP CS Fixerで快適PHPライフ - FLOG SPLASH
http://fivestar.hatenablog.com/entry/2014/12/08/033345
PHP CS Fixer v2 でもっと快適PHPライフ - FLOG SPLASH
http://fivestar.hatenablog.com/entry/2017/03/30/233744
コーディング規約自動調整ツールCodeSniffer2とphp-cs-fixer - Qiita
https://qiita.com/dozo/items/ed4baa58a0131945ad6f
GitHub - FriendsOfPHP/PHP-CS-Fixer: A tool to automatically fix PHP coding standards issues
https://github.com/FriendsOfPHP/PHP-CS-Fixer
PHPでSSLを強制する
if (empty($_SERVER['HTTPS'])) {
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit;
}
.htaccessで行うなら、以下のように記述する。
RewriteEngine On
RewriteCond %{HTTPS} Off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
htaccessでHTTPSにリダイレクトする - Qiita
https://qiita.com/foursue/items/58e74c4a8c946dd49e12
PHPでURLから「www.」を省略する
if ($_SERVER['HTTP_HOST'] == 'www.refirio.net') {
header('Location: https://' . 'refirio.net' . $_SERVER['REQUEST_URI']);
exit;
}
※上記のコードは「refirio.net」を2回書いているので、そのうち改良したい。
PHPでCookieをサブドメイン間で共有する
クッキーをサブドメイン間で共有する - kawama.jp
http://kawama.jp/archives/2006/04/27/post_11.html
PHPのセッション有効期限を伸ばす
プログラム側で期間を伸ばしても、デフォルトでは大元のPHP側で24分(1440秒)に制限されている。
(ただし、24分経ったセッションは古いとみなす「ことがある」という設定なので、数時間保持されることもある模様。
対策に、.htaccess へ以下の設定を追加するといい。
(この場合、保持期間を24時間に伸ばしている。期間はgc_maxlifetimeで変更可能。)
php_value session.gc_divisor 1000
php_value session.gc_maxlifetime 86400
php_value session.gc_probability 1
以下はPHPプログラム内で設定する場合の例。
ini_set('session.gc_divisor', 1000);
ini_set('session.gc_maxlifetime', 86400);
ini_set('session.gc_probability', 1);
以下は php.ini 内で設定する場合の例。
session.gc_divisor = 1000
session.gc_maxlifetime = 86400
session.gc_probability = 1
PHP&CakePHPでセッション保持の時間を設定する - Qiita
https://qiita.com/katsukii/items/cf21e6731fbd87aa23dd
PHPでPEARを使う
set_include_path(get_include_path() . PATH_SEPARATOR . getcwd() . '/PEAR/');
require_once 'HTTP/OAuth/Consumer.php';
.htaccess で設定するなら以下のように設定できる。
php_value include_path '.:/path/to/PEAR/:/path/to/libs/'
Windows環境なら以下のように設定できる。
php_value include_path '.;C:/path/to/PEAR/;C:/path/to/libs/'
PHPでPHARを展開する
PHARファイルの展開
http://curtaincall.weblike.jp/blog/?p=66
<?php
try {
$phar = new Phar('goutte.phar');
$phar->extractTo('./goutte/');
} catch (Exception $e) {
}
PHPでHTTPの疎通確認を行う
実際にHTTPリクエストを送り、「200 OK」が返ってきてコンテンツに特定の文字列が含まれている。
とするのが確実。
<?php
// リクエストを送信
$http_response_header = null;
$context = stream_context_create(array(
'http' => array('ignore_errors' => true)
));
$response = file_get_contents('http://example.com/test/', false, $context);
// ヘッダとボディの両方を調べて、正常なレスポンスかどうかを確認する
if (preg_match('/200 OK/', implode("\n", $http_response_header)) && preg_match('/テスト/', $response)) {
echo 'OK';
} else {
echo 'NG';
}
exit;
存在しないサーバのアドレスを指定した場合、実行結果は以下になる。
Apacheがダウンしている場合も同様みたい。
<pre>Array
(
)
<hr><hr>NG
PHPからシェルスクリプトを実行する
<?php
echo shell_exec('ls -l');
echo `ls -l`;
文字列のエスケープ。
<?php
echo escapeshellarg('test');
外部プログラムの実行
http://so-zou.jp/web-app/tech/programming/php/exec/
PHPで並列処理を行う
以下のプログラムを用意して main.php を実行すると、1.txt 〜 3.txt に同じ時刻が記録される。
つまり前のプログラムの終了を待たずに次のプログラムが実行されている。
「CPUやメモリを消費してもいいから、とにかく処理速度優先にしたい」という場合に使える。
main.php
<?php
echo '[start:' . date('H:i:s') . ']';
//exec('nohup php child.php 1 > /dev/null &');
exec('nohup /usr/bin/php child.php 1 > /dev/null &');
exec('nohup /usr/bin/php child.php 2 > /dev/null &');
exec('nohup /usr/bin/php child.php 3 > /dev/null &');
echo '[end:' . date('H:i:s') . ']';
child.php
<?php
sleep(2);
file_put_contents($argv[1] . '.txt', date('H:i:s'));
[PHP]execでバックグラウンド実行するときの落とし穴に落ちた。 nohup!nohup! - DQNEO起業日記
http://dqn.sakusakutto.jp/2012/08/php_exec_nohup_background.html
PHPで並列処理を作ってみた - Qiita
https://qiita.com/Mizumon/items/1e89b024617afb940881
PHPである処理を行うと、約1時間かかるとします。(この時間は短… - 人力検索はてな
http://q.hatena.ne.jp/1227966968
PHPでComposerを使う
PHPの依存性管理ツール。
依存ライブラリ郡も含めて、まとめてインストールできる。
composer require 使いたいライブラリ
もしくは、composer.json に使いたいライブラリを記述して
composer install
とコマンドを実行するとインストールされる。
自分で一つ一つ依存ライブラリをダウンロードする必要が無い。
ダウンロードしたファイルは vendor フォルダ内に格納される。
PHP開発でComposerを使わないなんてありえない!基礎編 - Qiita
http://qiita.com/niisan-tokyo/items/8cccec88d45f38171c94
Laravel5のプロジェクトをGitで管理する - Qiita
https://qiita.com/zaburo/items/bc448a9fbf2d35194302
php - vendorディレクトリをGit管理下に置かないのは何故? - スタック・オーバーフロー
https://ja.stackoverflow.com/questions/23725/vendor%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%...
CentOS7にComposerをインストールする - Qiita
https://qiita.com/inakadegaebal/items/d370bcb1627fce2b5cd1
Composer を CentOS にインストールする手順 | WEB ARCH LABO
https://weblabo.oscasierra.net/php-composer-centos-install/
PHPパッケージ管理ツール「Composer」の処理の仕組みを見てみよう! (1/4)|CodeZine(コードジン)
https://codezine.jp/article/detail/20455
■インストール
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
# php composer-setup.php
# php -r "unlink('composer-setup.php');"
# php composer.phar
ハッシュの値はバージョンによって異なるため、最新の手順は以下で確認する
https://getcomposer.org/download/
この際、
All settings correct for using Composer
Unable to create Composer home directory "/usr/share/httpd/.config/composer": mkdir(): Permission denied
と表示されるなら、rootで以下を実行しておく。(もしくは apache を所有者とするディレクトリを作成するか。)
# cd /usr/share/httpd
# mkdir .config
# cd .config
# mkdir composer
# chmod 0777 composer
Composerをどこからでも呼び出せるようにする場合、以下も実行する。
# mv composer.phar /usr/local/bin/composer
以下のように、パスも拡張子も無しで呼び出せる。
# composer
■コマンド例
バージョンを表示。(Composerの動作確認。)
$ composer
ライブラリのインストール。(Goutteをインストールする場合。)
$ composer require fabpot/goutte
各ライブラリを最新に更新。(プログラムの動作に影響する可能性があるので慎重に。)
$ composer update
composer.json に書かれたライブラリとバージョンに従って更新。(他環境で更新された場合など。)
$ composer install
以下のようにすると、開発用ツールを除いてインストールされる。(本番環境などでは、この方法でインストールするといい。)
$ composer install --no-dev
インストールに失敗して原因が不明な場合、以下のように composer.lock を退避してから実行すれば成功することがある。(ただし恐らく非推奨。)
$ mv composer.lock composer.20200513.lock
$ composer install --no-dev
「--no-dev」の指定については、以下などが参考になる。
【Laravel】composer require-devの開発、本番での切り分け - Qiita
https://qiita.com/k-kurikuri/items/8e644b3338d8759d64fd
PHP |【パッケージ管理】Composerの使い方 - わくわくBank
https://www.wakuwakubank.com/posts/415-php-composer/
■オートローディング
名前空間に従って自動的にファイルを読み込む。
require_once などで明示的にファイルを読み込む必要がない。
Composerを使うことで簡単に導入できる。
PHPでクラスをspl_autoload_registerを使ってオートロードする - バカンス駆動開発
http://egapool.hatenablog.com/entry/2013/11/17/195045
PHPのオートロード(autoload) - Qiita
http://qiita.com/atwata/items/5ba72d3d881a81227c2a
src/Refirio/Greeting/Hello.php
<?php
class Hello
{
function say()
{
echo 'Hello World!';
}
}
sample.php
<?php
require_once "src/Refirio/Greeting/Hello.php";
$hello = new Hello();
echo $hello->say();
↓オートロードに対応させる。
composer.json
{
"autoload": {
"psr-4": {
"myapp\\": "src/"
}
}
}
$ composer install … composer.json に設定した内容に合わせて vender ディレクトリ内にプログラムが作られる
以下のようにしてオートロードを利用できる。
src/Refirio/Greeting/Hello.php
<?php
namespace myapp\Refirio\Greeting;
class Hello
{
function say()
{
echo 'Hello World!';
}
}
sample.php
<?php
require_once "vendor/autoload.php";
$hello = new myapp\Refirio\Greeting\Hello();
echo $hello->say();
↓名前空間のエイリアスを作成。
<?php
require_once "vendor/autoload.php";
use myapp\Refirio\Greeting\Hello;
//use myapp\Refirio\Greeting\Hello as Hello; // クラスに別名を指定する場合
$hello = new Hello();
echo $hello->say();
■require
新しいパッケージを追加する。
$ composer require fabpot/goutte
vendor 内に諸々のプログラムがインストールされる。
また、composer.json が以下のように変更される。
composer.json
{
"autoload": {
"psr-4": {
"myapp\\": "src/"
}
},
"require": {
"fabpot/goutte": "^4.0"
}
}
goutteが追加されたことを確認。
sample.php
<?php
require_once 'vendor/autoload.php';
$client = new Goutte\Client();
$crawler = $client->request('GET', 'http://refirio.org/');
$tr = $crawler->filter('ul li')->each(function($element){
echo $element->text()."\n";
});
なお、以下のようにインストールできるパッケージがあったとして、
$ composer require xxx/yyy
以下のようにすることでバージョンを指定してインストールできる。
$ composer require xxx/yyy:"4.1.2"
■install
composer.lockに書かれている各ライブラリをインストールする。
$ composer install
vendor 内に諸々のプログラムがインストールされる。
■update
composer.jsonをもとに各ファイルを最新版にアップデートする。
$ composer update
■composer.json の指定
$ COMPOSER=composer-default.json composer install
とすると、composer.json と composer.lock ではなく。
composer-default.json と composer-default.lock をもとにインストールが行われる。
以下、検証した内容。
composer.json と composer.lock のコピーを、それぞれ。
composer-default.json と composer-default.lock として作成する。
つまり goutte をインストールできる状態。
$ composer require monolog/monolog
monologが追加されたことを確認。
sample.php
<?php
require_once 'vendor/autoload.php';
use \Monolog\Logger;
use \Monolog\Handler\StreamHandler;
// ロガー作成
$logger = new Logger('sample');
$logger->pushHandler(new StreamHandler('logs/sample.log', Logger::INFO));
// INFOログ出力
$logger->info('情報ログ');
echo "OK\n";
vendor を削除し、再度以下を実行する。
$ composer install
goutte と monolog がインストールされる。
つまり vendor がなくても composer.json と composer.lock によって環境を再現できた。
vendor を削除し、今度は以下を実行する。
$ COMPOSER=composer-default.json composer install
goutte だけがインストールされる。
monolog はインストールされない。
つまり composer-default.json を指定してインストールできた。
追加で以下を実行する。
$ composer install
monolog が追加インストールされた。
■create-project でプロジェクト作成
$ composer create-project ethna/ethna-project
によって、以下が実行されているみたい。
$ git clone https://github.com/ethna/ethna-project.git
$ cd ethna-project
$ composer install
Composerのcreate-projectが何をやっているのか調べてみた - Qiita
https://qiita.com/DQNEO/items/74f4bb8fe447e4582a97
ただし自作のリポジトリで create-project をしようとすると以下のエラーになった。
また詳細を確認したい。
$ composer create-project https://github.com/refirio/laravel6 test
Creating a "https://github.com/refirio/laravel6" project at "./test"
[UnexpectedValueException]
Could not parse version constraint //github.com/refirio/laravel6: Invalid version string "//github.com/refirio/laravel6"
■補足
vendor フォルダは通常、gitの管理対象外とする。
インストールしたライブラリの情報は composer.json と composer.lock に記録され、
「composer install」を実行すると同じバージョンのライブラリをダウンロードしてくれる。
つまり、他の環境でも同じ状態を再現できる。
ただし運用方法によっては、vendor をgit管理対象にするのも有効(コマンドラインでの操作が難しい開発メンバーが多い、など。)
メリット&デメリットを考える。
XAMPP環境にインストールする手順は XAMPP.txt を参照。
PHPでファイルロックを使う
以下勉強メモ。
PHPでファイル入出力 | refirio.org
http://refirio.org/view/18
PHPでファイル入出力(続き) | refirio.org
http://refirio.org/view/19
ファイル入出力改良版 | refirio.org
http://refirio.org/view/22
ファイルロック解除処理 | refirio.org
http://refirio.org/view/26
Webアプリケーションへの同時アクセス対策メモ | refirio.org
http://refirio.org/view/367
MySQLでトランザクション分離レベルを変更する
トランザクション分離レベルについては、MySQL.txt の「トランザクション」を参照。
MySQLでロックを行う
ロックについては、MySQL.txt の「ロック」を参照。
MySQLへの一斉アクセスをテストする
一斉アクセスのテストについては、MySQL.txt の「一斉アクセスをテストする」を参照。
cronでPHPを定期実行
# vi /etc/crontab
PHPファイルの一行目に「#!PHPへのパス」を設定して、実行権限を与える方法も有効。
以下、PHPプログラム内でパスを設定する方法。
*/5 * * * * webmaster /usr/bin/php /var/www/html/cron/test.php
set_include_path(get_include_path() . PATH_SEPARATOR . '/var/www/html/twitter/' . PATH_SEPARATOR . '/var/www/html/twitter/PEAR/');
require_once 'config.php';
require_once 'HTTP/OAuth/Consumer.php';
ImageMagickを使う
■PHP7.4で検証したときのメモ
Amazon Linux 2 環境で、ImageMagickのインストールを検証。
# localedef -f UTF-8 -i ja_JP ja_JP
# localectl set-locale LANG=ja_JP.UTF-8
# localectl status
# timedatectl set-timezone Asia/Tokyo
# timedatectl status
# yum -y install httpd
# vi /etc/httpd/conf/httpd.conf
ここまで準備。
ここからImageMagickのための手順。
ServerName www.example.com:80
# service httpd start
# chkconfig httpd on
# vi /var/www/html/index.html
test
# amazon-linux-extras install php7.4 -y
# yum -y install php-cli php-common php-devel php-fpm php-gd php-mbstring php-mysqlnd php-pdo php-xml
# service httpd restart
# yum -y groupinstall "Base" "Development tools"
# yum -y install ImageMagick ImageMagick-devel
# yum -y install php-pear
# pecl install imagick
Please provide the prefix of ImageMagick installation [autodetect] : … Enterを入力。
# vi /etc/php.d/test.ini … ファイル名は任意。
これで phpinfo() に「imagick」の項目が表示された。
また、以下のようにしてImageMagickを呼び出せるようになる。
extension = imagick.so
# service php-fpm restart … こちらも再起動が必要だった。
# service httpd restart
<?php
new Imagick();
■PHP7.4で検証したときのメモ(Ansible用の考察)
以下を実行すると、プレフィックスを決めるように求められる。
カラEnterで次に進むが、AnsibleのPlaybookで処理する場合には問題となる。
# pecl install imagick
Please provide the prefix of ImageMagick installation [autodetect] :
以下のようにすれば自動でEnterが入力されるため、問題無く進む。
# yes '' | pecl install imagick
また、imagickがインストールされているか否かの判定はどうするか。
ひとまず /usr/lib64/php/modules/imagick.so が存在するかどうかの判定にした。
まとめると、以下のコードでimagickをインストールするようにした。
- name: check imagick
stat: path=/usr/lib64/php/modules/imagick.so
register: imagick_bin
tags: imagick
- block:
- name: install imagick
shell: yes '' | pecl install imagick
when: not imagick_bin.stat.exists
tags: imagick
■PHP5.4で検証したときのメモ
CentOS6 上のPHPでImageMagickを動かす - Qiita
https://qiita.com/fulcrum/items/5563f3cc2f976c19f86f
PECL ImageMagick(PHP)インストール手順 - Qiita
https://qiita.com/fumiriku/items/3f4f28ac93c9ef303ddf
# yum install ImageMagick
# yum -y install php-pear
# yum install php-devel --enablerepo=remi … PHP5.4用のリポジトリに変更したため。
# which php
# cd /usr/bin
# wget http://pear.php.net/go-pear.phar
# php go-pear.phar
# vi /etc/php.ini
phpinfo() で確認すると「imagick」の項目が追加されていた。
以下のプログラムで画像の作成ができた。
include_path=".:/usr/PEAR"
# pecl install imagick --enablerepo=remi
Can't find PHP headers in /usr/include/php
The php-devel package is required for use of this command.
ERROR: `phpize' failed … エラーになった。
# yum install ImageMagick ImageMagick-devel ImageMagick-perl … これなら大丈夫だった。
# pecl install imagick
# vi /etc/php.ini
[PECL]
extension=imagick.so
# service httpd restart
<?php
$file = 'data/sample.pdf';
$output = 'data/sample.png';
try {
$im = new Imagick($file . '[0]');
$im->setImageFormat('png');
$im->thumbnailImage(2000, 2000, true);
$im->writeImage($output);
} catch (Exception $e) {
exit('NG:' . $e->getMessage());
}
exit('OK');
wkhtmltopdf(PDF作成)を使う
■wkhtmltopdfのインストール(2023年にAmazonLinux2で試したもの)
wkhtmltopdf を CentOS 7 にインストールする方法 - LAOX PowerTech
https://laox.com/ja/9mcv
wkhtmltopdf
https://wkhtmltopdf.org/downloads.html
Release 0.12.6 - wkhtmltopdf/wkhtmltopdf
https://github.com/wkhtmltopdf/wkhtmltopdf/releases/0.12.6/
バージョン「0.12.6」が最終安定板となっている。
「xorg-x11-fonts-75dpi」「xorg-x11-fonts-Type1」は必須のフォントらしい。
# yum install -y libXrender libXext
# yum install -y xorg-x11-fonts-75dpi xorg-x11-fonts-Type1
# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox-0.12.6-1.amazonlinux2....
# rpm -Uvh wkhtmltox-0.12.6-1.amazonlinux2.x86_64.rpm
# /usr/local/bin/wkhtmltopdf -V
wkhtmltopdf 0.12.6 (with patched qt)
追加でフォントをインストール。
# yum install -y ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts
フォントは以下のようになった。
# ll /usr/share/fonts
合計 0
drwxr-xr-x 2 root root 314 11月 30 17:02 dejavu
drwxr-xr-x 2 root root 35 11月 30 17:06 ipa-gothic
drwxr-xr-x 2 root root 35 11月 30 17:06 ipa-mincho
drwxr-xr-x 2 root root 36 11月 30 17:06 ipa-pgothic
drwxr-xr-x 2 root root 36 11月 30 17:06 ipa-pmincho
■wkhtmltopdfのインストール(2020年にCentOS7で試したもの)
PHPでPDFを作成するphpwkhtmltopdfはまだまだ戦える - このすみエンジニアブログ
https://www.konosumi.net/entry/2018/06/22/015223
CentOS7 に wkhtmltopdf をインストールする - Qiita
https://qiita.com/ucan-lab/items/5ba8c8fac4407239f19f
wkhtmltopdfをインストール。
$ sudo su -
# cd
# yum -y install fontconfig libXrender libXext xorg-x11-fonts-Type1 xorg-x11-fonts-75dpi freetype libpng zlib libjpeg-turbo
# wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox-0.12.5-1.centos7.x86_6...
# rpm -Uvh wkhtmltox-0.12.5-1.centos7.x86_64.rpm
# wkhtmltoimage --version
wkhtmltoimage 0.12.5 (with patched qt)
# wkhtmltopdf --version
wkhtmltopdf 0.12.5 (with patched qt)
# rm -f wkhtmltox-0.12.5-1.centos7.x86_64.rpm
wkhtmltopdfを動作確認。(ただし日本語は表示できない。)
# wkhtmltopdf http://www.yahoo.co.jp yahoo.pdf
日本語フォントをインストール。
# fc-list
# wget https://moji.or.jp/wp-content/ipafont/IPAexfont/IPAexfont00301.zip
# unzip IPAexfont00301.zip
# mv IPAexfont00301 /usr/share/fonts
# rm -f IPAexfont00301.zip
# fc-cache -fv
# fc-list
日本語フォント込でwkhtmltopdfを動作確認。
# wkhtmltopdf http://www.yahoo.co.jp yahoo.pdf
■wkhtmltopdfのインストール(2019年にCentOS7で試したもの)
CentOS7 に wkhtmltopdf をインストールする - Qiita
https://qiita.com/ucan-lab/items/5ba8c8fac4407239f19f
wgetでIPAフォントを落とそうとして失敗(returned a non-zero code: 4)した時の対処 - TonamiLog
http://th.hatenablog.jp/entry/2019/03/13/093956
# cd
# yum -y install libXrender libXext
# wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.4/wkhtmltox-0.12.4_linux-generic-a...
# tar Jxfv wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
# cp wkhtmltox/bin/wkhtmltoimage /usr/local/bin/
# cp wkhtmltox/bin/wkhtmltopdf /usr/local/bin/
# wkhtmltoimage --version
wkhtmltoimage 0.12.4 (with patched qt)
# wkhtmltopdf --version
wkhtmltopdf 0.12.4 (with patched qt)
# rm -f wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
# rm -rf wkhtmltox
引き続き日本語フォントの追加。
上記解説からURLが変更になっているので注意。
# fc-list
# wget https://oscdl.ipa.go.jp/IPAexfont/IPAexfont00301.zip
# unzip IPAexfont00301.zip
# mv IPAexfont00301 /usr/share/fonts
# rm -f IPAexfont00301.zip
# fc-cache -fv
# fc-list
■wkhtmltopdfのインストール(2016年にCentOS6で試したもの)
PHPでPDFを作成する時はwkhtmltopdf + snappyで戦え
http://qiita.com/morisuke/items/b9c18dcba99ba6501d6e
上記手順で進めると、インストール時に以下のエラーが発生した。
# rpm -ivh wkhtmltox-0.12.2.1_linux-centos6-amd64.rpm
error: Failed dependencies:
xorg-x11-fonts-Type1 is needed by wkhtmltox-1:0.12.2.1-1.x86_64
xorg-x11-fonts-75dpi is needed by wkhtmltox-1:0.12.2.1-1.x86_64
「フォントが無い」と言われているので、該当するフォントをインストール。
# yum install -y xorg-x11-fonts-Type1
# yum install -y xorg-x11-fonts-75dpi
日本語フォントを使うために、以下も実行。
# wget http://dl.ipafont.ipa.go.jp/IPAexfont/IPAexfont00301.zip
# unzip IPAexfont00301.zip
# mv IPAexfont00301/ /usr/share/fonts
フォントをインストールできたら、改めてwkhtmltopdfのインストールを実行する。
■PHPプログラムから扱う
Snippy(ライブラリを簡単に扱うためのラッパー)をインストールする。Composerは使える前提とする。
composer.json を同一階層に作る。記述は以下のようにする。
{
"require": {
"knplabs/knp-snappy": "dev-master"
}
}
composer.json のある階層で以下を実行してインストール。
$ composer install
もしくは、以下のコマンドで直接インストール。
$ composer require knplabs/knp-snappy
あとは以下の記述で自動的に読み込めば、命令を使うことができる。
require 'vendor/autoload.php';
以下、サンプルプログラム。
<?php
require 'vendor/autoload.php';
$html = <<<EOF
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>サンプル</title>
<style>
body {
padding: 10px 0;
}
</style>
</head>
<body>
<p>サンプル。</p>
</body>
</html>
EOF;
// wkhtmltopdfの位置をコンストラクタに渡す
$pdf = new Knp\Snappy\Pdf('/usr/local/bin/wkhtmltopdf');
// 文字コードUTF-8
$pdf->setOption('encoding', 'utf-8');
// 用紙サイズ
$pdf->setOption('page-size', 'B5');
// 用紙の向き
$pdf->setOption('orientation', 'landscape');
// PDFをブラウザに出力
header('Content-Type: application/pdf');
echo $pdf->getOutputFromHtml($html);
exit;
■他環境からフォントを複製
A環境のフォントをダウンロードし、B環境にアップロードする…という手順で複製できる。
基本的に、/usr/share/fonts に配置するだけで大丈夫そうではある。
LINUX(CentOS)のフォントのあれこれ #Linux - Qiita
https://qiita.com/kenta8813/items/fb0c7c348e0d6b17dd87
フォントキャッシュの更新について、以下で触れられている。
(44) wkhtmltopdfでホームページをPDF化 - Linuxやってみる!
https://www.dogrow.net/linux/blog44/
以下、実際に default と liberation を複製したときの作業メモ。(環境はEC2。)
↓
A環境で以下を実行し、default.zip と liberation.zip をダウンロード。
$ sudo su -
# cp -rp /usr/share/fonts/default /home/ec2-user
# cp -rp /usr/share/fonts/liberation /home/ec2-user
# cd /home/ec2-user
# zip -r default.zip default
# zip -r liberation.zip liberation
B環境に default.zip と liberation.zip をアップロードし、以下を実行。
$ sudo su -
# cd /home/ec2-user
# unzip default.zip
# unzip liberation.zip
# cp -rp default /usr/share/fonts
# cp -rp liberation /usr/share/fonts
B環境のフォントキャッシュをクリア。
# fc-cache -fv
B環境のフォントを確認。
# fc-list
■wkhtmltopdfの乗り換え先
ゼロからはじめるPython(114) HTMLからPDFを作成するツール「wkhtmltopdf」が開発終了・代替ライブラリのxhtml2pdfとWeasyPrintを試してみよう | TECH+(テックプラス)
https://news.mynavi.jp/techplus/article/zeropython-114/
文書配付機能でPDFレンダリングのライブラリを置き換えた話 - SmartHR Tech Blog
https://tech.smarthr.jp/entry/2023/07/03/170509
【Rails】Ferrumを使ってHTMLをPDFへ変換してみた(wicked_pdfからの移行) #Ruby - Qiita
https://qiita.com/aisplay/items/7ed4ec9fd311395f6540
wkhtmltopdfの次どうするか問題 - おもしろwebサービス開発日記
https://blog.willnet.in/entry/2023/02/10/233053
ゼロからはじめるPython 第114回 HTMLからPDFを作成するツール「wkhtmltopdf」が開発終了・代替ライブラリのxhtml2pdfとWeasyPrintを試してみよう:マピオンニュース
https://www.mapion.co.jp/news/column/cobs2737199-1-all/
MeCab(形態素解析)を使う
※定番のライブラリではあるが、UNIX環境でroot権限が必要。
root権限が無い場合、後述の「Igo(形態素解析)を使う」を参照。
yumでMeCabをインストール
http://qiita.com/ikenyal/items/275ca3096002822e8cd6
# rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-1.noarch.rpm
# yum makecache
# yum install mecab mecab-ipadic
# mecab --version
mecab of 0.996
# mecab
すもももももももものうち
すもも 名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも 名詞,一般,*,*,*,*,もも,モモ,モモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも 名詞,一般,*,*,*,*,もも,モモ,モモ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
うち 名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS
Igo(形態素解析)を使う
※MeCabよりも手軽に形態素解析を利用できる。
[PHP]文章を解析して単語ごとに分解する(形態素解析)
http://php-archive.net/php/morphological-analysis/
[PHP]自然言語処理(形態素解析)を利用した簡易全文検索
http://php-archive.net/php/full-text-search1/
■辞書ファイルの入手
https://sourceforge.net/projects/mecab/files/mecab-ipadic/
から
2.7.0-20070801
をダウンロード。(辞書ファイル。)
■本体の入手
https://osdn.jp/projects/igo/releases/
から
igo-0.4.5.jar
をダウンロード。(Igo本体。)
もしくは
igo-0.4.5-src.tar.gz
をダウンロードして
cd igo-0.4.3-src
ant
でコンパイル。(igo-0.4.5.jar が作成される。)
■辞書ファイルのビルド
例えば C:\igo で作業する場合、この場所に igo-0.4.5.jar とmecab-ipadic-2.7.0-20070801 を置く。
ビルドに成功すると、ipadicフォルダが作られる。これが辞書となる。
cd C:\igo
java -Xmx1024m -cp igo-0.4.5.jar net.reduls.igo.bin.BuildDic ipadic mecab-ipadic-2.7.0-20070801 EUC-JP
■PHPプログラムの入手
https://osdn.jp/projects/igo-php/
から
igo-php 0.1.7
をダウンロード。
■サンプルプログラムの作成
<?php
require_once 'igo-php/lib/Igo.php';
$igo = new Igo('./ipadic', 'UTF-8');
$text = 'これはテストです';
$result = $igo->wakati($text);
//$result = $igo->parse($text);
print_r($result);
※ipadicディレクトリ(辞書データ)はバイナリモードでアップロードする。
アスキーモードだと正しく認識されない。
■単語の追加
Java製形態素解析エンジン「Igo」を試してみる
http://www.mwsoft.jp/programming/munou/igo_install.html
MeCabの辞書を利用できるため、データの作成方法はMeCab用と同じ。
mecab-ipadic-2.7.0-20070801 内に User.name.csv を作成し、以下の内容を記述する。
(ファイル名は任意。文字コードはECU。)
ランスロット,1291,1291,500,名詞,固有名詞,人名,名,*,*,ランスロット,ランスロット,ランスロット
マーリン,1291,1291,500,名詞,固有名詞,人名,名,*,*,マーリン,マーリン,マーリン
追加したら、辞書ファイルを再ビルドする。
■はてなキーワードの単語を追加する場合
http://developer.hatena.ne.jp/ja/documents/keyword/misc/catalog
から
http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv
をダウンロード。
mecab-wikipedia-hatena-csv.php で keywordlist_furigana.csv から hatena-list.csv を作成する。
ファイルの文字コードをEUCに変換し、mecab-ipadic-2.7.0-20070801 内に置く。
その後、辞書ファイルを再ビルドする。
PHPのメモリ消費が大きいようなら ini_set('memory_limit', -1); を追加して様子を見る。
■Wikipediaの単語を追加する場合
https://ja.wikipedia.org/wiki/WP:DD
の
https://dumps.wikimedia.org/jawiki/
から
https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-all-titles-in-ns0.gz
をダウンロード。
ファイルを展開して jawiki-latest-all-titles-in-ns0 を入手する。
mecab-wikipedia-hatena-csv.php で jawiki-latest-all-titles-in-ns0 から wikipedia-list.csv を作成する。
ファイルの文字コードをEUCに変換し、mecab-ipadic-2.7.0-20070801 内に置く。
その後、辞書ファイルを再ビルドする。
PHPのメモリ消費が大きいようなら ini_set('memory_limit', -1); を追加して様子を見る。
※無改造の mecab-wikipedia-hatena-csv.php ではてなキーワードとWikipediaの両方を取り込むと、形態素解析の際にメモリ消費が大きすぎた。
mecab-wikipedia-hatena-csv.php を改造して辞書データのサイズを抑え、はてなキーワードのみ取り込むようにした。
また、読み仮名をカタカナで登録するなどの調整も行った。
OpenCV(画像処理・画像解析・顔認識)を使う
■OpenCVのインストール
# git clone https://github.com/jayrambhia/Install-OpenCV
# cd Install-OpenCV
# cd RedHat
# chmod +x *
# ./opencv_latest.sh
2時間くらい?で
OpenCV 3.2.0 ready to be used
と表示された。
■Facedetectのインストール
# yum -y install php-devel … phpizeを使えるようにする。
# git clone https://github.com/infusion/PHP-Facedetect
# cd PHP-Facedetect
# phpize && ./configure && make
# make install
# vi /etc/php.ini
■エラー回避
プログラムからface_detectを呼び出すと、以下のようなエラーが表示された。
extension=facedetect.so … 追加。
# service httpd restart
OpenCV Error: Unspecified error (The node does not represent a user object (unknown type?)) in cvRead,
file /root/Install-OpenCV/RedHat/OpenCV/opencv-3.2.0/modules/core/src/persistence.cpp, line 6628
https://sourceforge.net/projects/opencvlibrary/
からライブラリをダウンロードし、
opencv\sources\data\haarcascades
opencv\sources\data\haarcascades_cuda
を取り出して
haarcascades_cuda/haarcascade_frontalface_alt2.xml
を読み込めば認識できた。
Vagrantで実行する場合、画像ファイルのキャッシュに注意。
<pre><?php
// 顔認識
$facefile = 'images/yukata2.jpg';
$facedb = 'haarcascades_cuda/haarcascade_frontalface_alt2.xml';
$faces = face_detect($facefile, $facedb);
// 顔認識の結果を画像に書き込む
$im = imagecreatefromjpeg($facefile);
$red = imagecolorallocate($im, 255, 0, 0);
foreach ($faces as $i => $face) {
$x = $face["x"];
$y = $face["y"];
$w = $face["w"];
imagerectangle($im, $x, $y, $x + $w, $y + $w, $red);
echo "[$i] (x:$x, y:$y, w:$w)\n";
}
// 画像を出力
imagejpeg($im, "face-out.jpg");
echo "<img src='face-out.jpg'>";
Sisimai(バウンスメール解析)を使う
Sisimai | bounceHammerの後継となるバウンスメール解析ライブラリ
http://libsisimai.org/ja/
Sisimaiを使ったバウンスメールの管理
http://techlife.cookpad.com/entry/2017/05/15/000000
Sisimaiでバウンスメールを解析してみる
http://qiita.com/taku1201/items/0afae3dd90507a688e3e
ニッチな領域に勝機あり!人生をメールサーバに捧げたエンジニアの生存戦略|ハイクラス転職・求人情報サイト AMBI(アンビ)
https://en-ambi.com/itcontents/entry/2017/08/23/110000/
■インストール(失敗)
>gem install sisimai
ERROR: Could not find a valid gem 'sisimai' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3
read server certificate B: certificate verify failed (https://api.rubygems.org/latest_specs.4.8.gz)
インストールできないので、以下を参考に設定を変更。
http://book.scss.jp/code/c2/07.html
>gem source -a http://rubygems.org/
https://rubygems.org is recommended for security over http://rubygems.org/
Do you want to add this insecure source? [yn] y
http://rubygems.org/ added to sources
■インストール
>gem install sisimai
Fetching: oj-2.18.5.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions. This could take a while...
Successfully installed oj-2.18.5
Fetching: sisimai-4.21.0.gem (100%)
Successfully installed sisimai-4.21.0
Parsing documentation for oj-2.18.5
Installing ri documentation for oj-2.18.5
Parsing documentation for sisimai-4.21.0
Installing ri documentation for sisimai-4.21.0
Done installing documentation for oj, sisimai after 7 seconds
2 gems installed
■解析例
#!/ruby/bin/ruby
require 'find'
require 'sisimai'
puts "Content-type: text/html\n\n"
puts '<!DOCTYPE html>'
puts '<html>'
puts '<head>'
puts '<meta charset="utf-8">'
puts '<title>Sisimai</title>'
puts '</head>'
puts '<body>'
puts '<h1>Sisimaiのテスト</h1>'
# バウンス理由 http://libsisimai.org/ja/reason/
# ハードバウンスとは https://sendgrid.kke.co.jp/blog/?p=7837
reasons = {
'hostunknown' => '宛先ホスト名が存在しない(ハードバウンス)',
'userunknown' => '宛先メールアドレスは存在しない(ハードバウンス)',
'filtered' => 'DATAコマンド以降で拒否された',
'hasmoved' => '宛先メールアドレスは移動した(ハードバウンス)',
'rejected' => 'エンベロープFromで拒否された',
'mailboxfull' => 'メールボックスが一杯',
'suspend' => '宛先アカウントは一時的に停止中',
'vacation' => '宛先は現在不在である自動応答メッセージ',
'contenterror' => '不正な形式のヘッダまたはメール',
'exceedlimit' => 'メールサイズが最大値を超過(5.2.3)',
'feedback' => '元メールへの苦情によるバウンス(FBL形式の)',
'mesgtoobig' => 'メールが大き過ぎる(5.3.4)',
'securityerror' => 'ウィルスの検出または認証失敗',
'spamdetected' => 'メールはスパムとして判定された',
'blocked' => 'IPアドレスやホスト名による拒否',
'expired' => '配送時間切れ',
'mailererror' => '宛先ホストでのメールプログラムのエラー',
'networkerror' => 'DNS等ネットワーク関係のエラー',
'norelaying' => 'リレーの拒否',
'notaccept' => '宛先ホストはメールを受けとらない',
'systemerror' => '宛先サーバでのOSレベルのエラー',
'systemfull' => '宛先サーバのディスクが一杯',
'toomanyconn' => '接続制限数を超過した',
'delivered' => '正常に配信された',
'syntaxerror' => 'SMTPの文法エラー',
'onhold' => 'エラー理由の特定は保留',
'undefined' => 'バウンスした理由は特定出来ず',
}
Find.find('set-of-emails/maildir/err/') {|path|
if File.ftype(path) == 'file' then
puts '<h2>' + File.basename(path) + '</h2>'
bounces = Sisimai.make(path)
if bounces.is_a? Array then
puts '<pre>'
bounces.each do |bounce|
if reasons.has_key?(bounce.reason) then
reason = ' … ' + reasons[bounce.reason]
else
reason = ''
end
puts 'from: ' + bounce.addresser.address # shironeko@example.org # From
puts 'to: ' + bounce.recipient.address # kijitora@example.jp # To
puts 'host: ' + bounce.recipient.host # example.jp
puts 'status: ' + bounce.deliverystatus # 5.1.1
puts 'code: ' + bounce.replycode # 550
puts 'reason: ' + bounce.reason + reason # userunknown
end
puts '</pre>'
else
puts '<p>There is no bounce message in the mailbox or Sisimai could not parse</p>'
end
end
}
puts '</body>'
puts '</html>'
exit
■活用例
SisimaiはRubyとPerlに対応している。
もしメインシステムがRubyかPerlなら、上のような仕組みを普通に組み込めばいい。
メインシステムがRubyでもPerlでもないなら、
・Ruby+Sisimaiでバウンスメールを解析し、問題のあったメールアドレスとその詳細(バウンスの理由など)をデータベースに記録する。
・別途PHPでそのデータベースを参照し、メール送信先リストを更新する。
のような仕組みが必要になりそう。
Rubyで直接メール送信先リストを書き換えると、機能追加や仕様変更があったときの対応が大変そう。