* PHPメモ [#v37e7e81] #contents ** はまったところメモ [#ndb837db] *** include の振る舞い [#cdc00d1f] include というのは、外部ファイルを読み込む演算子。 include 'ファイル名'; 読み込まれるのはわかるが、 include をしたファイルは、 HTMLモードで展開される、ということを知らなかったためにハマった。 どういうことかというと、include ファイルは php スクリプトが書かれている前提ではなく、 HTML(というか、スクリプトではない単純テキスト)として読み込まれる。 つまり、 <?php // phpコード1 include 'xxxx.inc'; // phpコード2 ?> というのは、 <?php // phpコード1 ?> <!-- xxx.inc の内容 --> <?php // phpコード2 ?> ということ。 なので、include ファイルの内容を php スクリプトとする場合は、 include ファイルにも php の開始タグと終了タグを書く必要がある。 逆にいえば、ファイルの内容を HTML として出力したいのなら、 読み込んだ内容を echo や print などする必要はなく、include するだけでOK。 これは require(require_once)も同じ。 ''参考'' - [[include - PHP マニュアル:http://www.phppro.jp/phpmanual/php/function.include.html]] *** PHP4 と PHP5 のインスタンスの扱い [#te5ecde8] インスタンスを生成し、それを別の変数に代入した場合の扱いが PHP4 と PHP5 で異なるらしい。 具体的には、 <?php class hoge { var $fuga = 'default'; } $src = new hoge(); $dst = $src; $dst->fuga = 'modify'; echo $src->fuga; ?> としたとき、PHP4 では 'default' になり、PHP5 では 'modify' になる。 つまり、PHP5 では元の値が変更されるが、PHP4 では変更されない。 その理由が次のページで解説されていた。 - [[PHPでの内部変数の扱われ方 - PHPプロ!:http://www.phppro.jp/news/304]] なんかいろいろ書かれてるけど、 つまり、オブジェクトにおける代入演算子('=')の挙動は、 PHP4 はコピーの扱いで、PHP5 は参照の扱いになるってこと。 PHP4 では参照はできないのかといえば、明示的に '=&' を使えば参照の代入になる。 ''PHP4 で参照による代入をする場合'' <?php ... $dst =& $src; ... ?> PHP5 からは、オブジェクトの代入はデフォルトで参照になったということなので、 PHP4 のときのようにコピーをとりたい場合は、clone を使う必要がある。 ''PHP5 でコピーによる代入をする場合'' <?php ... $dst = clone $src; ... ?> *** allow_url_fopen が無効にされちゃったYO! [#wa20e503] allow_url_fopen というのは、PHPでリモートファイルを開いて参照できるかどうかを設定するスイッチ。これが OFF に設定されると、fopen() でリモートファイル(URL)を開くことができなくなる。 最近はどのサーバでもセキュリティを厳しくする傾向にあり、このスイッチは大抵 OFF に設定されるようになっている模様。 そんな場合は、HTTP_Request を使う。 PEAR のライブラリに HTTP/Request というものがあるので、これがサーバにインストールされていれば、そのまま利用する。 例えば、次のような感じでリモートのファイル内容を参照できる。 #code(PHP){{ <?php require_once "HTTP/Request.php"; function getRemoteFile($url) { $http_req =& new HTTP_Request($url); if ( !PEAR::isError( $http_req->sendRequest() ) ) { $code = $http_req->getResponseCode(); if ( $code >= 300 && $code < 400 ) { $http_hdr = $http_req->getResponseHeader(); if ( isset($http_hdr['location']) ) { return getRemoteFile($http_hdr['location']); } } else { return $http_req->getResponseBody(); } } return null; } ?> }} 上記では、応答コードが300番台の場合は「リダイレクトしてくれ」ってことなので、 ヘッダ情報に書かれている location を取得して関数を再起させている。 fopen() を使ってファイルを開いて内容を読み出している部分のコードを、マルッとコイツに置き換えれば解決。 HTTP/Request がインストールされていない場合は、[[PEAR:http://pear.php.net/]] のサイトから HTTP/Request, Net/URL, Net/Socket の3つのライブラリ(依存関係の都合でこの3つが必要)をダウンロードしてきて、上記スクリプトのファイルと同じ階層(ディレクトリ)に配置すれば OK。 注意すべきは、PEAR のライブラリはパスが通った場所に置かれている前提で require が書かれているので、HTTP というディレクトリの下に Net ディレクトリを配置しないと動かない(若しくは、HTTP/Request.php の require を書き換えるか)。 つまり、こんな感じで。 (root) | +- [DIR] HTTP | | | +- [DIR] Net | | | | | +- Socket.php | | +- URL.php | | | +- Request.php | +- 上のスクリプトを書いたファイル ** 参考サイト [#uea0ee84] - [[日本PHPユーザ会:http://www.php.gr.jp/]] - [[PHPプロ!:http://www.phppro.jp/]] - [[PHP Hypertext Preprocessor:http://php.benscom.com/]] -- [[PHPマニュアル:http://php.benscom.com/manual/ja/]] - [[初心者がおくるPHP入門:http://ww7.tiki.ne.jp/~inabah/php/index.htm]] - [[PHP入門:http://www.scollabo.com/banban/php/]] - [[Planet PHP Japan:http://planet.php.gr.jp/]] ----- [[MLEXP. Wiki]]