Tag Archives: PHP

PHPをC++に変換して高速化する「HipHop for PHP」

PHPもC++も使うプログラマーにとっては凄い興味が沸きます。確かにPHPはスクリプト言語という宿命がある限り、キャッシュしようが限界がありますよね。だからといってC++で再コーディングするにも時間的なコストを考えると手段から外される事も多い。

FacebookがPHPをC++に変換し高速化する「HipHop for PHP」を公開したようです | ke-tai.org

http://ke-tai.org/blog/2010/02/05/hiphopphp/

PHPをC++に変換して高速化する「HipHop for PHP」をFacebookが公開 : candycane development blog
 PHPがウェブアプリ作る言語としてオリジナルで便利な関数が揃っている為プログラマーを教育しやすい初心者にも敷居が低いのは良く分かりますが、元々HTMLにSSIの代わりに埋め込んで使うような言語でJavaScriptとの違いはサーバーで動作させるか、クライアントで動作させるかといったものなのに、Smartyのようなテンプレートエンジンやその他多機能なフレームワークなど、折角Apacheモジュールとして高速動作させているのにパフォーマンスに対して本末転倒なライブラリを実装する開発のほうが標準的になっている事がとても嘆かわしいですね。
 そういったPHPを遅くするライブラリどもを全てエクステンションに追い出せるならサーバーコスト(特にCPU周り)の節約に貢献できそうです。あとバッチ処理とか単体で変換できるとバッチ付き抜け防止に役立ちそうですね。(そもそもPHPでバッチ組むなというのもありますがシェルプログラミングスキルがあまり無いのでほんのちょっとでも複雑になると他のスクリプト言語に逃げてしまいます。。。Perl使ってもOKならPHP選ぶ前に使ってます。)
 RubyはPerlの文字化けに苦しんでいた10年前は興味ありましたが未だに手を出してないなぁ。。。Pythonはあまり興味なし。(多分仕事で使うことがなさそうだから)。Javaはどうなんでしょう?アプレットは遊びで作ってましたが、サーブレットはコンパイル済みプログラムをシステムに反映するのにApache、tomcatを再起動なんて仕様がデバッグコストを上げる原因にもなるし、無停止サービスを目指すシステムから見れば「ナンセンス」なのでまずサービス稼動したままリロードできるようにしないと大変ですよね。

 

各言語のtrue/false

これは興味深いです。C言語は単純なので分かりやすいですが、PHPでは微妙に独自ルールがあるなぁ~と思っていたのでこういう表があるとわかりやすいですね。この結果から言えることは「真偽の判定式は面倒でも明示的にtrue/falseに収束するように書くように」ってところかな。今までもPHP等でif($obj)みたいなコードがバグの原因となっていたケースをよく発見していたので、変数が定義済かどうか真偽の二値に収束しているかしっかり書くように勧めたいと思います。

特にPHPは変数宣言を用意してない癖に値の型はC言語以上に細かいので条件に利用するときは面倒なこともあります。0(数値)とfalse(偽)とNULLとEMPTY(空文字列)とUndefined(未定義)のどれがやってくるかわからない場合の判別とか。

各言語におけるtrue/falseまとめ – 床のトルストイ、ゲイとするとのこと
http://d.hatena.ne.jp/mirakui/20090604/truefalse

QRコード生成スクリプト

PC用サイトから携帯サイトに誘導する手段として昔はメール送信が多かったのですが今ではGRコードで読み取ってもらってアクセスという方法も一般化してきました。そこで携帯トップだけではなく毎ページごとやキャンペーンサイトに誘導したいと思ったときQRコードが動的に生成できたらいいなっと探したらこんな記事がありました。

第3回 PHPでQRバーコードを作成する(その1):ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20061110/253264/

簡単過ぎて鼻水でそうになったwこれはとても便利なので機会があるごとに使っていこうと思います。ちなみに動的生成でサーバー負荷が心配になる場合はコマンドで使用してファイル書き出しですね。

QRコード CGI & PHP scripts – QRcode generator for perl & php
http://www.swetake.com/qr/qr_cgi.html

swetake.com
http://www.swetake.com/

 

PHPで数式画像が作れるライブラリ

これは綺麗な数式ですね。学生なら使い道あるかな?論文はLaTeXでそれ以外ならWordの数式エディタで作っていましたがウェブ公開用というのは今までなかったかも。多分現状の数式が載っている学校系のサイトはWordの数式エディタで作った数式を画像として出力してアップロードしているのような気がします。使い方もLaTeXで数式書いていた人には難なく使えそうですね。(細かいところは忘れますたが同じような書き方だったような気がします)。これの一番嬉しいことは数式をソースコードで定義できるから左記のWordで画像作ってアップロードみたいな面倒がなくなる事ですね。

PHPで複雑な数学式の画像が作れる「PhpMathPublisher」:phpspot開発日誌
http://phpspot.org/blog/archives/2009/01/phpphpmathpubli.html

PhpMathPublisher
http://www.xm1math.net/phpmathpublisher/

Cookieを使ったSQLインジェクション

最近Cookieを使ったSQLインジェクションが発見されたということでその手法の詳細記事がありました。前置きが長すぎてもっと簡潔にして欲しかったのですが問題点は以下のようになります。

  • メジャーな侵入検知システムはPOST/GETの検査を行うがCookieを見逃していた。
  • スクリプト側でPOST/GET等メソッドを明示的に区別してデータ取得していない。
  • スクリプト側で入力データの検査が出来ていない。

元記事には

ここまで聞くと、「うちのサイトではクッキーにデータベースに関連するような情報は格納していないから関係ない」と、早合点する人もいるかもしれない。それは間違いなので、もう少しお付き合いいただきたい。

なんて書いてるからよくよく読んでみましたがCookie使う以前の問題で仕事でウェブプログラミングしているならその会社のスキルを疑って良いレベルです。PGのスキル不足は常にあると仮定してもレビューせずに素通りかPLが無能。PMが放置主義って言ってる様なもので会社でレベルで恥かいてるぞ。私ならこんな杜撰なコード組む会社に2度目の外注はしない。

まずコードの品質を上げる前に侵入検知システム等に頼るのは気が進まないし費用のムダ。これの方法の恐いのは侵入検知システム自体に穴がある場合だけでなく、サーバー移設等環境が変わった場合にミスが起きやすい。ニュースで「サーバーの設定ミスで情報漏えい」というケースがこれ。

次にデータ取得においてメソッドを区別していないのはCookie以前の問題でGETしか想定していないスクリプトでPOSTで渡されてもスクリプトのみでは同じ問題が起きるので注意すること。昔Perlで外部ライブラリなしでコーディングしているときは非常に面倒だと思いつつもどうやってデータがウェブサーバに送られてくるのか勉強になりました。今時よく利用されるASPやPHPはその辺の面倒な処理を自動的にやってくれて組込関数グローバル変数から読み込めますがRequest系の実装は気持ち悪くて使えない。未だにRequestについてGET/POSTを気にせずどっちでも使えるから便利とか発言するPGを見かけるが変数名が重複したときの対処方法を考えていないのが大半。セキュリティはともかくバグの元になる事を想定できていない。そういう人に限ってデバッガ未経験だったりする。

あとニュース記事には書かれていませんがPHPの場合、Requestでなくても$_POSTや$_GETのみで変数を上書きできるから注意ですね。通常リスト構造のデータを受け取るときは配列型にしたほうが便利ですが、それをせず同じ変数名で並べて送ってくるフォームがありそれにも$_POSTや$_GETは対応できないのでPerlの時のように素の入力データから抽出しています。それと同じ方法で本来の変数を上書きされても発見できない場合がありますので注意です。

最後に入力されたデータを検査していないのは論外、今回のセキュリティホールもPOST/GETを想定した変数だとしてもスクリプト側で検査していれば問題になっていない。メソッドを明示していればCookie経由で上書きしようとした変数はその場でイジェクトできるし、Request受けていてもそのデータを検査できていれば良いのである。とは言っても現実はApacheエラーログを見ずに組む人が多い、サニタイズどころかValidateやisset検査すらせずにエラーログを汚しまくる奴もいる。指摘するとErrorじゃなくてWarningだから大丈夫だろうとか言葉を理解できていない人やErrorじゃ無いんだからサーバー側でログ出力止めろよ!と逆ギレする民度の低いPGも少なからず存在する。そういうのに限ってこれまたPHPはPerlと違ってセッション実装できているから凄いとか内部処理を知らずに自慢(それもPHP作った本人じゃないのに)していたことがあって呆れたこともあります。

以上で愚痴込みのまとめは終わりますが、元記事を見てハッと気付いた脅威が一つありました。
最低限の作業として送られてくるデータは特定して検査するように書いているつもりですが、セッション変数はサーバーに保存されているデータなのでそこまでは強制的に検査していませんでした。(ヒマがあればするけれど他人にまで強制していない)

これの何が原因かというと、一度送られたフォームデータ(特にショッピングカート等)は途中ページでの改ざんを防ぐ為にセッション変数として保持することがありますが、保存したセッション変数からデータを再取得するときに検査をしていない場合がありました。近年はCookieに値セットして使うことが無いので完全な見逃しですが、Cookieを改ざんされた時に$_SESSIONが自動的に汚染されないか確認したことが無かった・・・。これは週明け直ぐにでもチェックしてみます。

他にDBとの入出力に対しての検査も、最初はそこまでする必要あるのかな?と思っていましたが仕事で使う内に必須だと思うようになりました。セキュリティ的には外部と接触する部分で一斉検査すれば大体良いのですが、開発途中でDBのデータがいい加減に入力されているとか仕様外の構成になっていたりするとが多く、というかほぼ100%でデバッグの障害になってたりもします。これでPGとDBエンジニアが鶏が先か卵が先かみたいなケンカもします。そこでスクリプト側としてはDBとの入出力にも開発効率を上げるために検査を入れておいたほうが良いと思います。あとApache管理者の意見として、大量のUndefined indexでログを汚すなというのもあります。

またまた進化したSQLインジェクションの脅威 クッキーを悪用 セキュリティー-最新ニュース:IT-PLUS
http://it.nikkei.co.jp/security/news/index.aspx?n=MMIT2g000028102008&cp=1

PHPにPDOを実装

最近PHPの開発でDB接続にPDOを使用する機会が増えてきました。PDOとはPHP5.1以降に登場したPHP Extensionで従来のmysql等の代わりに使えるライブラリらしいです。ということは従来のmysql関数群は無くても良いということかな?それは余ったサーバでも捜して試してみるかな。またPEAR::DBのようなスクリプトのラッパーではなくネイティブコードなのでパフォーマンスの低下も少ないというメリットもあるそうです。その他既存のデータベース関数と比較すると抽象化しているのでなんたら…とPDOの中身はまだ勉強してませんがw

ソースからのインストール方法は./configureで–with-pdo-mysql=/usr/local/mysqlという風に追加すれば大丈夫のようです。 ググっても–with-pdoは省略されているので無くて大丈夫っぽい。

因みに、既存環境でPDOを追加インストールするのは過去にやってエントリー書いてますのでそちらを参照ください。

PHPにモジュールを追加 (ここでPDOを追加インストールしています)

そういえばmbstringやmysqlもExtensionでしたね。そうすると全くExtensionなしのPHP関数の一覧ってどんなものなんだろう?今後は使う関数がどのライブラリに属しているか気にしたほうがよさげですね。PHPリファレンスもライブラリを調査して明記してくれると大変ありがたい。PHPがdisられているときに関数の銘々規則がめちゃくちゃなんて書かれていましたがExtensionの開発者のクセがそのまま乗っかってるとかそんな気がしてきた…。

参考:PDOでサクサクDB開発:CodeZine
http://codezine.jp/a/article/aid/433.aspx

参考:PHP 5.1インストール
http://w-d-l.net/memo/vinelinux_ppc/12_php/

UNIX版PHPはexif_read_dataがオプション扱い

phpspotで下記のようなサンプルがあったので現状使い道無いけど、将来ウェブアルバムとか作ることがあったら使うかもしれないので試してみた。

PHPで画像のEXIF情報を読み取るサンプルphpspot開発日誌
http://phpspot.org/blog/archives/2008/04/phpexif.html

結果、関数が組み込まれてなかった。。。GDとかJPEGライブラリ入れているのであると思っていたのが勘違いwググってみたらやはり、–enable-exifをつけてコンパイルしないといけないらしい。

php exif_read_data()が使用できないとは – Yaskey Diary
http://www.yaskey.cside.tv/mapserver/diary/diary.php?mode=main&COM=232

しょうがないので追加モジュールとしてインストールしようとしたら自宅BSDでは

Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF
environment variable is set correctly and then rerun this script.

とエラーが発生。確かにautoconfは今使ってないな。。。昔入れたけど不要になって消した。(元々OSに入ってるはずのm4はm4.orgにしたままだったwww)

下記が以前autoconf入れたときのメモだが、m4は–prefix=/usrで/usr/bin/m4にインストールされるようにしないと後で面倒です。デフォルトだとで/usr/local/bin/m4になってしまう。

autoconf automake libtoolをインストール

これはまた必要になったときにやってみよう。。。ソフトウェアの再利用とか大賛成だけど、どのライブラリを使用しているとか表示義務が欲しいですよね。ソースが見れるからって一々解析するのも面倒。

PHPにモジュールを追加

PHPにモジュールを追加

先日Apacheのモジュールを別途追加したばかりですが、今度はPHPでも同様の事をやってみたのでメモ。

例としてpdoとpdo_mysqlを入れます。
まずはPHPのソースに飛ぶ

# cd /usr/local/src/php-5.2.3/ext/pdo

# ls
CREDITS        config.m4     pdo.php                pdo_sql_parser.lo  pdo_stmt.lo
EXPERIMENTAL   config.w32    pdo_dbh.c              pdo_sql_parser.re  php_pdo.h
Makefile.frag  package2.xml  pdo_dbh.lo             pdo_sqlstate.c     php_pdo_driver.h
README         pdo.c         pdo_sql_parser.c       pdo_sqlstate.lo    php_pdo_int.h
TODO           pdo.lo        pdo_sql_parser.c.orig  pdo_stmt.c         tests

何もしてなければ上記の通り、configureファイルが無いのでphpizeする。

# which phpize
/usr/local/bin/phpize

# phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519

これでconfigureファイルができましたので設計します。

# ./configure –with-pdo

–with-pdoは無くてもできたかも。

# make
# make install
Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20060613/
Installing header files:          /usr/local/include/php/
Installing PDO headers:          /usr/local/include/php/ext/pdo/

以上でpdoのインストールが終わりました。
続いてpdo_mysqlのインストールを行います。

# cd /usr/local/src/php-5.2.3/ext/pdo_mysql
# phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519

今度はmysqlに関連するモジュールのためmysqlがインストールされているディレクトリを指定します。
# ./configure –with-pdo-mysql=/usr/local/mysql/

# make
# make install

最後にphp.iniに下記2行を追加します。

extension=pdo.so
extension=pdo_pgsql.so

php -m コマンドで確認します。

# php -m
[PHP Modules]
ctype
curl
date
dom
ffmpeg
filter
gd
hash
iconv
json
libxml
mbstring
mysql
pcre
PDO
pdo_mysql
pdo_sqlite
posix
Reflection
session
SimpleXML
SPL
SQLite
standard
tokenizer
xml
xmlreader
xmlwriter
zlib

[Zend Modules]

参考:phpize で共有 PECL 拡張モジュールをコンパイルする方法
http://php.plus-server.net/install.pecl.phpize.html

 

最近PHPがフルボッコのようです

PHPが非難される流れは去年の後半あたりから把握してますが、PHP5以降は言語として特に非難される程のものもないような気がします。PHP本体のセキュリティホールとかは別ですが…。ただPHPプログラマーが訳も分からないまま叩かれているような気がしてちょっとかわいそう。

私も何故かここ3年程仕事で一番多く使った言語がダントツPHPで次がC++そしてPerlといった感じ。PHPが選ばれたのはクライアントや上流の決定による物ですが、理由は単純明快で「書くコード量が少なく開発効率が良いから」「誰にでも割り振れてアサインが楽だから」ということです。当然工数も費用も削減できて良いように思えますが正直コンピュータの動作や通信については理解の妨げになっているので学習者や初心者にはオススメしたくない言語です。あとVBでリストラになってPHP再チャレンジの人も同様です。

簡単であることと基礎的なものは別次元の内容なので学習の際にはこの部分を混同して欲しくない。PHP言語はウェブプログラミングする際に便利な組み込み関数や定義が容易されていて初心者でもすぐにある程度ちゃんとしたものが作れてしまう。だがそこにウェブプログラミングとしての基礎を学ぶことが出来ない。GETやPOSTをPHP言語上でどのように取得するか覚えても、HTTPプロトコル上でどのような形式で送信されていてプログラム内で切り抜き処理をしているかなんてPHPだけでは想像もつかないだろう。PerlやC言語であればそのへんも全部自分で考えて処理しなければならないので勉強になる。

数学に例えれば微分の公式覚えて、微分が出来るようになったけど微分の理論を全然理解してないと似ている。(というのが高校生時代の私…orz)

ゲーム制作スキルとなれば物理や数学の基礎からプログラミングの応用まで勉強すべき事があるのですが、RPGツクールやオーサリングツールだと簡単に作れてしまうみたいな。

だからPHPだけしかやってないと他の言語で同じ事を達成するにはコンピュータ理論や通信の基礎的な学習が必要だし、プログラミングに対しての理解の深さに差が出てきます。仕事で初めてプログラミングに触れてそれがPHPだった言う人も最近は多いのでこの機会にぜひPerlや他の言語にも挑戦してみてください。

最近は確かに学生時代までに趣味または専門授業でコンピュータ理論を勉強したことがなくこの業界にプログラマーとして就職している人も増えてきたので非難する前に勉強するチャンスをあげたほうが良いなと思いました。

DBD-mysqlのインストール

昨日のMT4BETAのインストールですっかりPerlにMySQLコネクタをインストールし忘れていたので今度BETA4を入れる前までに用意します。

# mv DBD-mysql-4.005.tar.gz /usr/local/src/
# cd /usr/local/src
# tar zxf DBD-mysql-4.005.tar.gz
# cd DBD-mysql-4.005

ここまではいつも通りの前準備

まずPerlコマンドを利用してMakefileを作成します。
# perl Makefile.PL

Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 76.

Cannot find the file ‘mysql_config’! Your execution PATH doesn’t seem
not contain the path to mysql_config. Resorting to guessed values!
Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 466.
Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 466.
Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 466.
Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 466.
Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 466.
Can’t exec “mysql_config”: No such file or directory at Makefile.PL line 466.
Failed to determine directory of mysql.h. Use

perl Makefile.PL –cflags=-I<dir>

to set this directory. For details see the INSTALL.html file,
section “C Compiler flags” or type

perl Makefile.PL –help

…う、mysql_configへパスを通してなかったorz。

# find / -name mysql_config
/usr/local/src/mysql-5.0.18/scripts/mysql_config
/usr/local/mysql/bin/mysql_config

.cshrcを確認
set path=(/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin $HOME/bin)

以上より一時的に/usr/local/mysql/binをPATHに追加

set path=(/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin $HOME/bin /usr/local/mysql/bin)

後はmakeとmake installで完了です。
# make
# make install