[PHP-users 15452]Re: $HTTP_POST_VARSなどをarray_map()で処理する場合の問題について

Osamu Shigematsu m5issige @ mr.hitachi-medical.co.jp
2003年 5月 23日 (金) 17:11:00 JST


重松です。こんにちは。

環境ですが、以下の通りです。

PHP Version 4.3.2RC4


System         SunOS msun189 5.6 Generic_105181-28 sun4u

               './configure' '--prefix=/home/isg/hmissige'
Configure      '--disable-cli--disable-all' '--without-mysql' '--with-pcre-regex'
Command        '--with-regex=php' '--enable-mbstring' '--enable-mbregex'
               '--enable-zend-multibyte' '--enable-session'

Server API     CGI

謎なバージョンを書いてました。失礼しました。

その後、気づいたのですが、

#!/path/to/php
<?php
var_dump($_GET);
?>

$ w3m -dump http://www.example.com/test.cgi?xx%00xx=yy%00yy
array(1) { ["xx"]=> string(6) "yy\0yy" }
             ^^(1)             ^^^^^^(2)

のように

	(1) 連想配列のキーは NULL byte 以降は切り捨てられる
	(2) インストールしただけの状態では、NULL 文字は quote される

ようです。まあ、(2) に関しては、常識だと思うのですが、(1) は
浅学のため、知りませんでした。

もっとも、キー側を詐称しても、連想配列のキー自体はバイナリセーフで
将来、この問題が改善されたとしても、影響はないと思います。

そして、array_map() が、配列を再帰的に走査可能か、という問題ですが、
再度私の環境で試したところ、動作しないことが確認できました。

友人に RedHat 7.x? x86 (DSO, 4.1) でもテストを依頼したところ、
やはり再帰処理されないことが確認されました。

しかし、いろいろ配列の入れ子状態を変えて試しているのですが、
ルールが今ひとつつかめません。

そのため、合間を見つけて array_map() のソースを読みましたが、
単に指定した関数をコールバックしているだけなので、
この動作は、コールバック関数の仕様に基づく可能性が濃厚、
というと頃まではわかりました。

引き続き調べてみますが、何か、情報、アドバイス等ありましたら、
お知らせください。

テストスクリプト:
<?php

function make_array($n, $m)
{
        $a = array();
        for ($i = 1; $i <= $n; $i++) {
                $a[$i] = "$i\0xxx";
                if (!($i % $m)) $a = array($a);
        }
        return $a;
}

if (false /* get_magic_quotes_gpc() */) {
        define(NUL, '\0');
}
else {
        define(NUL, "\0");
}

function remove_null($x)
{
        /*
        if (is_array($x)) {
                foreach ($x as $k => $v) {
                        $x[$k] = remove_null($v);
                }
                return $x;
        }
        */
        return str_replace(NUL, '', $x);
}

var_dump($a = make_array(5, 2));
var_dump(array_map('remove_null', $a));
?>

結果:
array(2) {
  [0]=>
  array(3) {
    [0]=>
    array(2) {
      [1]=>
      string(5) "1^@xxx"
      [2]=>
      string(5) "2^@xxx"
    }
    [3]=>
    string(5) "3^@xxx"
    [4]=>
    string(5) "4^@xxx"
  }
  [5]=>
  string(5) "5^@xxx"
}
array(2) {
  [0]=>
  array(3) {
    [0]=>
    array(2) {
      [1]=>
      string(5) "1^@xxx"
      [2]=>
      string(5) "2^@xxx"
    }
    [3]=>
    string(4) "3xxx"
    [4]=>
    string(4) "4xxx"
  }
  [5]=>
  string(4) "5xxx"
}

-- 
Osamu Shigematsu <m5issige @ mr.hitachi-medical.co.jp>



PHP-users メーリングリストの案内