13

特定のクラスが内部クラス( などDateTime) であるか、ユーザー クラス( ) であるかを (プログラム的に、明らかに) 伝える方法は PHP にありclass MyClassますか?

疑問に思っている方のために説明すると (きっとそう思うと思います)、これはReflectionClass::newInstanceWithoutConstructor()が内部クラスで使用されると例外がスローされるためです。内部クラス。

はい、キャッチできReflectionExceptionますが、この例外は他の理由 (存在しないクラスなど) でもスローされ、すべてのシステム クラスに対してスローされるわけではありません。そのため、私のニーズを正確に満たしていません。

4

7 に答える 7

3

興味深い質問です。私が考えることができる 1 つの方法は、名前空間を確認することです。たとえば、すべてのクラスを以下で定義しnamespace MyAppて確認します。

if(class_exists('\\DateTime')){
    continue;
}

ちょっと醜い、私は知っています。

于 2013-06-06T11:45:03.807 に答える
2

Дамян Станчев の提案に基づく考察の材料:

を介して PHP インタープリターを実行するだけで、shell_exec()吐き出すことができget_declared_classes()ます。その出力をキャプチャすると、システム クラスの「クリーンな」リストが得られます。


Mogriaの答えを拡張すると、これはうまくいくはずです(ただし、正しくなったのはMogriaの答えだったので、これを信用しないでください;-)):

function getUserDefinedClasses() {
    return array_filter(get_declared_classes(),
                        function ($class) {
                           $reflectionClass = new ReflectionClass($class);
                           return $reflectionClass->isUserDefined();
                         });
}
于 2013-06-06T11:59:09.633 に答える
0

このでは、クラスがリストの最後にあるように見えるすべてのクラスを出力します。多分これが役立つかもしれません。

于 2013-06-06T11:51:38.857 に答える
0

__constructコピーしようとしているクラスを拡張し、関数をオーバーライドすることで、リフレクションの動作を模倣できるはずです。

<?php
    class MyClass extends ExtendingClass {
        public function __construct() {
            /* Override default constructor */
        }
    }
?>

基本的に、次を使用して動的にすることができますeval

<?php
    function newInstanceWithoutConstructor($class) {
        $className = $class . "Extended" . rand(0, 99999999);
        while (class_exists($className)) {
            $className = $class . "Extended" . rand(0, 99999999);
        }
        eval("class " . $className . " extends " . $class . " { public function __construct() { } }");
        return new $className();
    }
    $newInstance = newInstanceWithoutConstructor("DateTime");
?>

HOWEVER :evalこの場合、 を使用すると便利ですが、ユーザーが送信したものを何らかの方法で送信して の内容を変更できる場合、かなり大きなセキュリティ ホールが明らかになります$class。これらの制限とセキュリティへの影響を理解していれば、これを使用できるはずです。

于 2013-06-06T11:48:11.003 に答える
0

get_declared_classes()スクリプトの先頭で使用し、データを配列array_diff()に保存してから、保存されたデータとからの応答をget_declared_classes()使用して、チェックしているクラスが を使用して違いがあるかどうかを確認できませんin_array()か?

于 2013-06-06T11:50:12.560 に答える
0

autoloading/include/require が行われる前にget_declared_classes()データの呼び出しを保存し、後でこのストレージでクラス名をチェックするのはどうですか?

于 2013-06-06T11:57:21.620 に答える