

以下はphpコードの抜粋ですが、以下のコードで`"true"` と表示される結果にするためには、 `$value`
にはどのような値を入れればよろしいでしょうか？ また、そもそもそのような`$value`の値が存在するのでしょうか？ `"true"`
と表示される条件が見つかりません。

[code]

    <?php 
    $value =？; 
    if (!isset($value)) return; 
    if (is_null($value)) return; 
    if (is_scalar($value) && $value === "") return; 
    if (is_array($value) && count($value) == 0) return; 
    
    if ($value != true && $value != false){ 
            echo "true"; 
    }else{ 
            echo "false"; 
    } 
    
[/code]

$valueに、`true`、`false`、`1`、`0`、`1`、`"1"`、`"0"`、`'1'`、`'0'`、`array("a","b")`とかを入れてもダメでした。


CC BY-SA 3.0
2014-12-18T13:52:17.797
2048
2014-12-19T13:19:34.453
2014-12-19T13:19:34.453
47
299
question
php
PHPのif文の条件式で、$valueにどんな値が入っていれば trueが表示される結果となりますか？


変数名が変わってしまっているのでそこがダメですが、 以下の様な いかさまをすれば trueは出力させることができるという事で。

マジックメソッドのうち __issetをオーバーロードして常に1を返しながら、
__getをオーバーロードしてプロパティにアクセスするとtrueとfalseになるような値が交互に取れるようにしています。  
（評価するたびに値が変わるので !=true 且つ !=false が成り立ってしまいます。完全に副作用です。）

[code]

    <?php
    
    class TestClass{
       public function __isset($name){
           return 1;
       }
    
       private $v="1";
       public function __get($name){
            if($this->v=="1"){
                   $this->v="0";
            }else{
                   $this->v="1";
            }
            return $this->v;
       }
    }
    
    $x = new TestClass();
    // $value ではなく $x->value にしているので、質問とは異なる。
    
    if (!isset($x->value)) return;         
       // valueは宣言されてませんが issetが常に1を返すので通過
    if (is_null($x->value)) return;
    if (is_scalar($x->value) && $x->value === "") return;
    if (is_array($x->value) && count($x->value) == 0) return;
    
    // この段階で次に$x->valueを取り出すと"0"が取れ、文字列"0"はfalseとされるので != trueです。
    // 且つ、 その次のアクセスでは $x->value は "1"が取れるので、文字列"1"は !=falseです。
    
    if ($x->value != true && $x->value != false){
            echo "true";
    }else{
            echo "false";
    }
    
[/code]


CC BY-SA 3.0
2014-12-18T16:24:44.560
2056
2014-12-18T16:24:44.560
728
2048
answer


マジックメソッドがアリならSPLもアリだよね。配列のインデックス指定でもごまかせる。

[code]

    <?php 
    class SplDamn extends ArrayObject {
        private $pos = 0;
        public function offsetGet($i) {
            return parent::offsetGet(++$this->pos - 1);
        }
    }
    
    $value = new SplDamn(array(
        "isset",
        "!is_null",
        "is_scalar",
        "!is_array",
        false,
        true
    ));
    
    if (!isset($value[0])) return; 
    if (is_null($value[0])) return; 
    if (is_scalar($value[0]) && $value[0] === "") return; 
    if (is_array($value[0]) && count($value[0]) == 0) return; 
    
    if ($value[0] != true && $value[0] != false){ 
        echo "true"; 
    } else {
        echo "false"; 
    }
    
[/code]


CC BY-SA 3.0
2014-12-18T16:40:12.153
2059
2014-12-18T16:40:12.153
62
2048
answer


gmp の演算子のオーバーロードが実装されている PHP のバージョン限定です（5.6）。

[code]

    <?php
    $value = gmp_init(2);
    
    if (!isset($value)) return;
    if (is_null($value)) return;
    if (is_scalar($value) && $value === "") return;
    if (is_array($value) && count($value) == 0) return;
    
    if ($value != true && $value != false){
            echo "true";
    }else{
            echo "false";
    }
    
[/code]

実行すると、

[code]

    $ php a.php
    true
    
[/code]

個々の理由は次の通りです。

[code]

    <?php
    $value = gmp_init(2);
    
    var_dump(!isset($value));       // false オブジェクトです
    var_dump(is_null($value));      // false null ではない
    var_dump(is_scalar($value));    // false スカラーではない
    var_dump($value === "");        // false 空文字ではない
    var_dump(is_array($value));     // false 配列ではない
    var_dump(count($value) == 0);   // false なぜか count すると 1 です → count(2) になっている？
    var_dump($value != true);       // true  2 != 1 になっている？
    var_dump($value != false);      // true  2 != 0 になっている？
    
[/code]


CC BY-SA 3.0
2014-12-19T01:58:00.580
2078
2014-12-19T01:58:00.580
2494
2048
answer