PHPを3日くらい使って思ったこととか

これまで全く接点のなかったPHPを使う機会があったので、はじめて触れたときの記録として思ったこととかを勝手に書いてみます。
PHPをちゃんと勉強した訳じゃないので間違ってたり、単なる偏見だったりするかもしれませんが、お許しを。
何か変なこと言ってたら容赦なく突っ込んでもらえると嬉しいです。
こういうのってほんとに初めてのときにしか感じることができなかったりすることだと思うので貴重かな、と思い記してみる次第。

概要

今回いじることになったのは、本番環境でPHP 4.4.0で動いてるちっちゃいアプリでした。フレームワークとか特に使ってません。テンプレートエンジンはSmartyです。Smartyは聞いたことあります。

で、機能拡張するにあたりまずは開発環境を構築します。開発環境で簡単に使えるPHPのバージョンが、一番近いもので4.4.4だったのでこれを使うことにしました。まー、マイナーバージョンの違いなんで問題ないだろうと。

コンパイルオプションを確認する

で、PHPといったらコンパイルオプションが云々というのは聞いたことがあったので、仕様書に書かれているオプションと、開発環境にインストールされているPHPコンパイルオプションを比較することから始めました。差分は仕様書に書かれているオプションがいくつか多い次第。

  • --enable-mbstr-enc-trans
    • enable-mbstr-enc-trans : mbstring 変換エンジンを使用した、HTTP 入力の文字エンコーディング変換を有効にします。この機能が有効の場合、 HTTP 入力文字エンコーディングは、自動的にmbstring.internal_encoding に変換されます。

注意: PHP 4.3.0 以降、このオプション --enable-mbstr-enc-trans は廃止され、実行時の設定mbstring.encoding_translation に変更となります。HTTP 入力文字エンコーディング変換は、 このオプションをOn に設定した場合のみ 有効となります (デフォルトは Offです)。
http://manual.xwd.jp/ref.mbstring.html

ふむふむ。

  • --enable-jstring

4.0.6から--enable-mbstringになったという噂。

PHP4.0.6‚ւ̃AƒbƒvƒOƒŒ[ƒhƒƒ‚

  • --enable-track-vars
    • enable-track-vars

PHP 3: デフォルトで GET/POST/Cookie トラック変数を有効にします
PHP 4: PHP 4で利用できないオプションです。PHP 4.0.2現在 track_varsは常にオンです。

http://itbtech.itboost.co.jp/man/php_man/install.configure.html

  • --enable-versioning

--enable-versioning

要求されるシンボルのみをエクスポートします。 詳細な情報は INSTALL を参照ください。

PHP: Configure オプション - Manual

よくわかりません。

cl.pocari.org - PHP 4 の --enable-versioning はトラブルの元か?
[PHP] --enable-versioningを止めるの巻 - Blog::koyhoge::Tech

どうやらPHP3と4を共存させる時に使うらしい。

  • --enable-trans-sid

--enable-trans-sid

透過的なセッション ID の伝播を有効にします。PHP 4.1.2 以前でのみ 有効です。PHP 4.2.0 以降、この機能は常に有効となっています。

PHP: Configure オプション - Manual

  • --enable-force-cgi-redirect

--enable-force-cgi-redirect

サーバ内でのリダイレクトの際のセキュリティチェックを有効にします。 ApacheCGIバージョンを稼動させる場合、このオプションを 使用すべきです。

PHP: Configure オプション - Manual

つーことで、今回は全部なくても大丈夫ということになった。

php.ini

で、アプリを設置して動かしてみたら見事に文字化けします。php.iniの内容は本番環境と全く同じです。
なぜ?
まず、PHPがリクエストを受け取ってレスポンスを返すまでのデータの流れ、文字コードの変換ポイントとかを全く持って知らないので、これがわからないことには文字化けは直せません。直せるかもしれないけど、偶然直ったところでそれでは意味がありません。なので、いろいろ調べた結果、internal_encodingというのを知ったので確認してみると、

本番環境:EUC-JP
開発環境:ISO-8859-1

えー。
設定値同じなのになんで違うのかよくわかりませんが、php.iniでinternal_encodingをEUC-JPに指定することにしました。

そうしたら画面表示が変わったんだけどまだ文字化けしてます。今度はまたちょっと違う感じで、どうやらHTMLはSJISを主張してるのに実際はEUC-JPになってる模様。今度はhttp_outputというのをせっていしてやればいいっぽいのでこれをSJISに指定することで無事解決しました。

それにしてもまったく同じphp.iniを使用していてもデフォルト値とかが異なってこういう結果になるものなんでしょうか?どうもよくわかりません。何か勘違いしてる気もしますが、ま、解決したのでよしとしました。

文字化けも直ったのでプログラムの改修に入ります。

配列のしくみ

まず配列がよくわからなかったので学びました。配列とハッシュがごっちゃになっててよくわかんないよー。

PHP の配列は、実際には順番付けられたマップです。
PHP: 配列 - Manual

ふむ。どうやら配列もハッシュも区別がないようだということがわかり、Perlのハッシュでは順序が保証されないけどPHPのハッシュ(配列)は順序が定義順に保証されるようだということが判明。へー。文字列をキーにしたハッシュのように定義したあとで

$list[0] = 'hoge';

とかやってもこれは先頭に来ず、一番最後に追加される。ふむふむ。また、ここでphp-aという技(これはPHP5から?)を覚え、実際にコードを動かした試せるようになった。

でも、まだ順番を保証するっていうのがしっくりこないのでどういう仕組みになってるのか知りたいと思って調べたら絶好のページを発見して涙した。

PHPの配列管理方法を正しく理解する-ハッシュテーブルとZval - CPA-LABテクニカル

ハッシュスライス

Perlではハッシュスライスという技法?があり、こんなことができます。

my %hash = ('foo' => 'bar', 'hoge' => 'huga');
my @values = @hash{qw(foo hoge)};
# @values = ('bar', 'huga')

PHPはできないのかね。

implode()とexplode()

join()がしたくて調べたら

join ― implode() のエイリアス
PHP: join - Manual

とのこと。implode?

内破{ないは}する、内側{うちがわ}に破裂{はれつ}する、〔体制{たいせい}などが〕崩壊{ほうかい}する
implodeの意味・使い方|英辞郎 on the WEB:アルク

へー。じゃあexplodeとかあるんじゃね?と思ったらあった。

explode ― 文字列を文字列により分割する
PHP: explode - Manual

へー。

joinがimplodeでsplitがexplodeなわけですね。

join()のところにimplode()のエイリアスですって書いてあるってことは、本家はimplode()だよってことなのかな?
joinの方が分かりやすい気がするんだけどどうなんだろうか。

global

関数の先頭で

global $hoge;

とかやってるのが多くてよくわかんなかったのでPHPの変数を学ぶ。

PHP: 変数のスコープ - Manual

関数の内部からグローバル変数が見えないのでglobal宣言すると見えるようになるのね。

無名関数

特に使う機会はなかったけどmap()を見て疑問に思ったのでちょっと調べたら、無名関数を定義するのにcreate_function()というのがあるんだけど、コレビミョーですね。文字列で書かないといけないんだね。

PHP: create_function - Manual

$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " .
log($a * $b);');

配列定義のシンタックスシュガー

配列を定義するときは

$array = array('foo', 'bar');

と書く。

$array = ['foo', 'bar'];

って書きたい!

MySQL関数

プレースホルダー使おうと思ったらなくて泣いた。

http://jp2.php.net/manual/ja/book.mysql.php

SmartyのテンプレでJavaScriptを書く

SmartyのテンプレでJavaScriptのfor文を書いたらシンタックスエラーっていわれた。
どうやらJSのコードもテンプレのコードとして解析して文法エラーになるっぽい。
{literal}{/literal}で囲めばおk。

    • -

こんなところでしょうか。
3日間にしてはいろいろ盛りだくさんでおもしろかったです。若干、PHPをもっと知りたい感じがして名残惜しいです。

いろんな言語を知るってたのしいなーと思いました。