0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

mb_ereg()の第三引数に未定義変数を入れて失敗した場合の動作 オマケ:preg_matchの場合

Last updated at Posted at 2015-10-05

概要

mb_eregは第三引数にarrayを入れた場合は、
一致した部分文字列が格納されます。
ここにarray以外を入れてみました。

きっかけは

  • 未定義の変数が指定されていたコードが元気に動いているのを見つけた(IDEが警告してくる)
  • mb_eregの第三引数が参照渡しになっていない
  • mb_eregに失敗時の第三引数の結果が書いていない

結論

mb_eregの第三引数は配列以外でも動作し、失敗時は引き渡したままの値が残る。
ただし、未定義変数を渡した場合はNULLに設定される。

これがmb_eregのリファレンスに&がついていない理由かは不明。
(&がついているpreg_matchとは失敗時の動作が異なる)

未定義の変数を渡すこと自体は、褒められた書き方ではないと思われるが、
nullに上書きされるため、危険は無いと思われる。
現状存在するコードが意図的に行っているとは言えないのがリスクだが…

mb_ereg 成功パターン

すべてarrayの正常な結果に上書きされる。

コード

succsess_mb_ereg.php

// 成功系
$pattern = 'test';
$string  = 'test';

test($pattern, $string, array());                 // array(1) {[0]=> string(4) "test"}
test($pattern, $string, array('hoge' => 'huga')); // array(1) {[0]=> string(4) "test"}
test($pattern, $string, null);                    // array(1) {[0]=> string(4) "test"}
test($pattern, $string, 'string');               // array(1) {[0]=> string(4) "test"}
test($pattern, $string, 100);                    // array(1) {[0]=> string(4) "test"}
test($pattern, $string, true);                   // array(1) {[0]=> string(4) "test"}
test($pattern, $string, false);                  // array(1) {[0]=> string(4) "test"}
test($pattern, $string, new stdClass());         // array(1) {[0]=> string(4) "test"}
test($pattern, $string, $regs);                  // array(1) {[0]=> string(4) "test"}

function test($pattern, $string, $regs) {
    mb_ereg($pattern, $string, $regs);
    var_dump($regs);
    echo "\n\n";
}


mb_ereg 失敗パターン

引数の値が保持される。
ただし、未定義の変数の場合はNULLが定義される。

コード

failure_mb_ereg.php

// 失敗系
$pattern = 'test';
$string  = 'bad';

test($pattern, $string, array());                 // array(0) {}
test($pattern, $string, array('hoge' => 'huga')); // array(1) {["hoge"] => string(4) "huga"}
test($pattern, $string, null);                   // NULL
test($pattern, $string, 'string');               // string(6) "string"
test($pattern, $string, 100);                    // int(100)
test($pattern, $string, true);                   // bool(true)
test($pattern, $string, false);                  // bool(false)
test($pattern, $string, new stdClass());         // object(stdClass)#1 (0) {}
test($pattern, $string, $regs);                  // NULL
var_dump($undefined);                            // NULL ただし PHP Notice:  Undefined variable: undefined

function test($pattern, $string, $regs) {
    mb_ereg($pattern, $string, $regs);
    var_dump($regs);
    echo "\n\n";
}


失敗パターンのつかいどころ?

引数の値が保存されるので、デフォルト値として使える?
成功時は一致結果配列、失敗時はその他の値を返したいとき、
mb_eregの実行結果は不要になる。

普通に使う.php

$regs = array()
if (mb_ereg($pattern, $string, $regs)) {
    return $regs;
} else {
    return '失敗しました';
}

横着.php

$regs = '失敗しました';
mb_ereg($pattern, $string, $regs)
return $regs

失敗時にNULLを返すなら初期化も不要

NULLを返す.php

mb_ereg($pattern, $string, $regs)
return $regs

また、


null[0]         // null
(string)null[0] // string(0) ""

で、エラーも出ないので、

一致文字列の追加.php

mb_ereg($pattern, $string, $regs)
return 'test' . $regs[0]; // もし$patternがあれば追加

とかもできる。


ついでに似たような関数preg_matchではどうなるか調べました。

preg_match 成功パターン

同じくarrayの結果に上書きされる。

コード

succsess_preg_match.php


// 成功系
$pattern = 'test';
$string  = 'test';

test($pattern, $string, array());                 // array(1) {[0]=> string(4) "test"}
test($pattern, $string, array('hoge' => 'huga')); // array(1) {[0]=> string(4) "test"}
test($pattern, $string, null);                    // array(1) {[0]=> string(4) "test"}
test($pattern, $string, 'string');               // array(1) {[0]=> string(4) "test"}
test($pattern, $string, 100);                    // array(1) {[0]=> string(4) "test"}
test($pattern, $string, true);                   // array(1) {[0]=> string(4) "test"}
test($pattern, $string, false);                  // array(1) {[0]=> string(4) "test"}
test($pattern, $string, new stdClass());         // array(1) {[0]=> string(4) "test"}
test($pattern, $string, $regs);                  // array(1) {[0]=> string(4) "test"}

function test($pattern, $string, $regs) {
    preg_match($pattern, $string, $regs);
    var_dump($regs);
    echo "\n\n";
}


preg_match 失敗パターン

すべて空配列で上書きされる。

コード

failure_preg_match.php

// 失敗系
$pattern = '/test/';
$string  = 'bad';

test($pattern, $string, array());                 // array(0) {}
test($pattern, $string, array('hoge' => 'huga')); // array(0) {}
test($pattern, $string, null);                   // array(0) {}
test($pattern, $string, 'string');               // array(0) {}
test($pattern, $string, 100);                    // array(0) {}
test($pattern, $string, true);                   // array(0) {}
test($pattern, $string, false);                  // array(0) {}
test($pattern, $string, new stdClass());         // array(0) {}
test($pattern, $string, $regs);                  // array(0) {}


function test($pattern, $string, $regs) {
    preg_match($pattern, $string, $regs);
    var_dump($regs);
    echo "\n\n";
}

直感ではpreg_matchのほうが普通かなぁ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?