gallu’s blog

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

…まてや

酔いどれ源譜たん
経由
http://www.php.net/ChangeLog-5.php
経由
http://bugs.php.net/bug.php?id=47704

PHP crashes on some "bad" operations with string offsets

えと…

<?php
$s = "abd";
$s[0]->a += 4;
echo "ok\n";

で、シグセグで落ちる、と orz


実験。
まず念のために

$s = "abd";
var_dump($s[0]->a);

で確認。returnにはNULLがくる。


…えと………
おそらく。


PHPは、その「スンバラシイ」仕様によりまして。StdClassってのがあります。
「宣言しないのに使えちゃうクラス」という…なんて言いましょうか…おいちゃん的にはあまりにも度し難いとしか感じ得ないものがあるのですが。

マジックメソッド( http://www.php.net/manual/ja/language.oop5.magic.php )とかいう、やっぱりおいちゃん的に「理解不能」なものがありまして。
その中に「__call」「__callStatic」なるものがあります。これは「存在しないメソッドをcallした時に叩いてくれる関数」だそうです。


ここから仄見えるのですが。PHPは「未定義を許容する」方向の哲学を持っています(つまりその哲学そのものがおいちゃん的に大嫌いなのですが…おいといて)。


で。
矢印演算子だと…おそらく
・矢印演算子なので、その左辺値をクラスインスタンスであると見なしてみる
・右辺値に括弧が付いてないから変数をさしているはず
・でもその変数は未定義
・だから未定義であるnullを返す
という挙動なのだろうと思います。

$ss = 10;
var_dump($ss->a);

で普通にnull帰ってきますし。


んで、次。

$s = "abd";
$s[0]->a += 4;

で落ちるのだから…
まずはここから。

$s = null;
var_dump($s->a);

あれ? 落ちない。


次。

$s = "abd";
$s[0]->a = $s[0]->a + 4;

Fatal error: Cannot use string offset as an array in t.php on line 6

………あれ?
+=だとコケるのに=で+だとコケない?
えと………どゆ語句解析とか意味解析してるの?


んで。

$s = null;
var_dump($s);
var_dump($s[0]);
var_dump($s[0]->a);
var_dump($s[0]->a += 4);

NULL
NULL
NULL
int(4)

………うを?
落ちるおもたのに…


追加。

$s = 1;
var_dump($s);
var_dump($s[0]);
var_dump($s[0]->a);
var_dump($s[0]->a += 4);

int(1)
NULL
NULL

Warning: Cannot use a scalar value as an array in t.php on line 10
int(4)

10行目は「var_dump($s[0]->a += 4);」ここ。


予想。
「$s[0]->a += 4」において。
まず左辺値が評価される。
…おそらく。型のチェックが左辺値全体ではなくて、矢印演算子の左辺「$s[0]」に対して行われている。
で…「矢印演算子の左辺としてはあるんだけど左辺値全体としてはnullである」場合に、チェック漏れがあるのではなかろうか、と。


ただ…そも「+=」と「=の右辺に+」で「間違いなく別ロジックを持っている」というのは…果たして如何なものなのだろうか? と。
相変わらず…ぷりちぃな言語である orz