2

私は変数名、like$varとその値を知っています。

チェックするisset($GLOBALS[$var_name]) && $GLOBALS[$var_name] == $varと、変数が実際にはグローバルではなくても、肯定的な結果が得られる可能性がありますが、既存のグローバル変数と同じ名前と値を持っています:(

渡された変数のタイプに関する詳細情報を表示するために、作成しているデバッグ関数にこれが必要です。

変数が静的であるかどうかも確認できますか?:)

ps:リフレクションは私を助けません..それはオブジェクトまたは関数の情報しか取得できません...

4

3 に答える 3

7

変数が相互に参照している場合(これは基本的にチェックしたいものです)、それらは同じzvalを使用します。したがって、これは少し厄介ですが、うまくいくでしょう、それを行う方法:

<?php

    function vars_are_referenced (&$var1, &$var2) {

        // What we are doing *will* throw an error (I said it was nasty ;-) )
        $oldER = error_reporting();
        $oldDE = ini_get('display_errors');
        error_reporting(0);
        ini_set('display_errors', 0);

        // We need to use output buffering, we don't want to break any existing
        // buffering so we cache the contents of the buffer
        $oldBuffer = ob_get_length() ? ob_get_clean() : NULL;

        // If the values are not identical, definitely not a match
        if ($var1 !== $var2) return FALSE;

        // Now we inspect the zval of $var1
        ob_start();
        debug_zval_dump(&$var1);
        preg_match('/\brefcount\((\d+)\)(?:\b|$)/', ob_get_clean(), $matches);
        $var1RefCountBefore = (int) $matches[1];

        // If they are the same, this will increase the refcount
        $temp = &$var2;

        // Inspect the zval of $var1 again
        ob_start();
        debug_zval_dump(&$var1);
        preg_match('/\brefcount\((\d+)\)(?:\b|$)/', ob_get_clean(), $matches);
        $var1RefCountAfter = (int) $matches[1];

        // If refcount is now greater, they are the same
        $result = $var1RefCountAfter > $var1RefCountBefore;

        // Repopulate the output buffer if necessary
        if ($oldBuffer !== NULL) {
            ob_start();
            echo $oldBuffer;
        }

        // Turn error reporting back to correct level
        error_reporting($oldER);
        ini_set('display_errors', $oldDE);

        return $result;

    }

    function test_ref_fail () {
        $a = 1;
        $var_name = 'a';
        var_dump(vars_are_referenced($GLOBALS['a'], $a));
    }

    function test_ref_success_1 () {
        global $a;
        $var_name = 'a';
        var_dump(vars_are_referenced($GLOBALS['a'], $a));
    }

    function test_ref_success_2 (&$a) {
        $var_name = 'a';
        var_dump(vars_are_referenced($GLOBALS['a'], $a));
    }

    $a = 1;
    $b = &$a;
    var_dump(vars_are_referenced($a, $b));
    test_ref_fail();
    test_ref_success_1();
    test_ref_success_2($a);

これは(zvalを調べることによって)それを行うための最良の方法ですが、あなたが見ることができると確信しているように、これは現在PHPで利用可能な関数を備えたきれいな方法ではありません。必要に応じて動作させるために必要な呼び出し時の参照渡しが原因で、エラーが発生debug_zval_dump()します。呼び出し時の参照渡しが削除されたため、PHP>=5.4で致命的なエラーが発生します。

ですから、これは別の方法です-変数の変更が含まれるため、私は好きではありませんが、何も壊してはならず、重要なことに、エラーが発生することはなく、どこでも機能します:

<?php

    function vars_are_referenced (&$var1, &$var2) {

        // If the values are not identical, definitely not a match
        if ($var1 !== $var2) return FALSE;

        // Make a copy of the old value
        $oldVal = $var1;

        // Get a new value we can assign that is different to the old value
        $newVal = ($oldVal === 1) ? 2 : 1;

        // Assign the value to $var1
        $var1 = $newVal;

        // See if $var2 has changed
        $result = $var1 === $var2;

        // Put the value of $var1 right again
        $var1 = $oldVal;

        return $result;

    }

vars_are_referenced()文字列としての変数の名前と変数自体に基づいて、変数がグローバルであるかどうかを具体的に判断するためのヘルパー関数(上記の定義のいずれかで機能します)を次に示します。

<?php

    function var_is_global ($name, &$var) {
        return vars_are_referenced($GLOBALS[$name], $var);
    }

任意の変数がオブジェクトのコンテキスト外で静的であるかどうかを正確にチェックする方法を考えることはできません。

于 2012-07-18T15:43:31.777 に答える
3

グローバルステートメントをeval()するのはどうですか?

function isglobal($name)
{
    return eval('global $'. $name .'; return isset($'. $name .');');
}

ただし、チェックする名前を適切にエスケープするように注意してください。

于 2012-07-18T15:38:52.900 に答える
3

定義されたすべての変数の配列を返すget_defined_vars()関数を確認する必要があります。

var_dump(get_defined_vars())

ただし、適切に実行したい場合は、Xdebugを参照してください。ここでは、設定された変数をプレビューできるだけでなく、それらをトレースすることもできます。詳細については、ここをクリックしてください。

于 2012-07-18T15:41:50.857 に答える