So überprüfen Sie, ob eine Funktion in PHP öffentlich oder geschützt ist

Lesezeit: 4 Minuten

Ich baue eine API, bei der der Benutzer einen “Befehl” anfordert, der an eine Klasse übergeben wird. Unter der Annahme, dass der Befehl mit einer PUBLIC-Funktion übereinstimmt, wird er erfolgreich ausgeführt. Wenn der Befehl mit einer PROTECTED-Funktion übereinstimmt, muss er einen Fehler ausgeben.

Die Idee ist, dass Funktionen deaktiviert werden können, indem sie von PUBLIC zu PROTECTED geändert werden, anstatt sie umzubenennen oder zu entfernen.

Ich mache das derzeit, aber es spielt keine Rolle, ob der Befehl öffentlich oder geschützt ist.

<?php
/**
 * Look for Command method
 */
$sMethod = "{$sCommand}Command";
if (method_exists($this, $sMethod))
{
    /**
     * Run the command
     */
    return $this->$sMethod($aParameters);
}

Einfach verwenden Reflexionsmethode:

/**
 * Look for Command method
 */
if (method_exists($this, $sMethod))
{
    $reflection = new ReflectionMethod($this, $sMethod);
    if (!$reflection->isPublic()) {
        throw new RuntimeException("The called method is not public.");
    }
    /**
     * Run the command
     */
    return $this->$sMethod($aParameters);
}

  • Ich wollte diesen, aber du kamst vor mir 🙂

    – David Conde

    12. November 2010 um 1:45 Uhr

Mit der Funktion is_callable können Sie ermitteln, ob die Schutzstufe Sie einschränken soll: Beispiel:

<?php
class FooBar {
    protected function Foo() { return; }
    public function Bar() { return; }
}

$foo = new FooBar();

var_dump(is_callable(array($foo, 'Foo')));
var_dump(is_callable(array($foo, 'Bar')));

  • Ich glaube nicht, dass is_callable funktioniert, wenn ich innerhalb derselben Klasse aufrufe (so dass geschützte Methoden aufrufbar sind).

    – Stefan RC

    12. November 2010 um 2:03 Uhr

  • Sie haben Recht – is_callable berücksichtigt den aktuellen Bereich

    – Rollencamp

    13. November 2010 um 1:32 Uhr

  • Ein Beispiel dafür, wie is_callable() gibt unterschiedliche Ergebnisse zurück, je nachdem, wo die Funktion aufgerufen wird: 3v4l.org/fLaYN

    – Liebesina

    7. April 2019 um 10:58 Uhr

Obwohl Sie nicht unterscheiden können, ob die Methode privat oder geschützt ist, können Sie mit einer externen Methode testen, ob sie öffentlich oder nicht verwendet wird is_callable. Ich habe einen Vergleich mit “meze” beantwortet.

So:

function testIfCallable($object, $method) {
    return is_callable(array($object, $method));
}

function testIfCallable2($object, $method) {
    if (method_exists($object, $method))
    {
        $reflection = new ReflectionMethod($object, $method);
        return $reflection->isPublic();
    }

    return false;
}

class Test {

    private function privateMethod() {

    }

    protected function protectedMethod() {

    }

    public function publicMethod() {

    }

    public function testAccessibility() {
        if (testIfCallable($this, 'privateMethod')) echo "YYY<br>"; else echo 'NNN<br>';
        if (testIfCallable($this, 'protectedMethod')) echo "YYY<br>"; else echo 'NNN<br>';
        if (testIfCallable($this, 'publicMethod')) echo "YYY<br>"; else echo 'NNN<br>';
    }

    public function testAccessibility2() {
        if (testIfCallable2($this, 'privateMethod')) echo "YYY<br>"; else echo 'NNN<br>';
        if (testIfCallable2($this, 'protectedMethod')) echo "YYY<br>"; else echo 'NNN<br>';
        if (testIfCallable2($this, 'publicMethod')) echo "YYY<br>"; else echo 'NNN<br>';
    }       

    public function testSpeedAccessibility() {
        return $results = [
                testIfCallable($this, 'privateMethod'),
                testIfCallable($this, 'protectedMethod'),
                testIfCallable($this, 'publicMethod')
        ];
    }

    public function testSpeedAccesibility2() {
        return $results = [
                testIfCallable2($this, 'privateMethod'),
                testIfCallable2($this, 'protectedMethod'),
                testIfCallable2($this, 'publicMethod')
        ];
    }
}

Die Methode testIfCallable sollte in eine Common-Klasse oder ähnliches aufgenommen werden, die Sie in Ihrem eigenen Toolkit haben, da globale Methoden nicht empfohlen werden.

Ich verwende dies in Verbindung mit den magischen Methoden __get und __set um sicherzustellen, dass eine öffentliche “get/set”-Methode existiert.

Tests :

//Test functionality
$t = new Test();
$t->testAccessibility();
$t->testAccessibility2();

//Test speed
$start = microtime(true);
for($i = 0; $i < 10000; $i++) {
    $t->testSpeedAccessibility();
}
echo "Is Callable way: " . (microtime(true) - $start) . "ms<br>";

$start = microtime(true);
for($i = 0; $i < 10000; $i++) {
    $t->testSpeedAccesibility2();
}
echo "Reflection way: " . (microtime(true) - $start) . "ms<br>";

Ausgänge:

NNN
NNN
YYY
NNN
NNN
YYY
Is Callable way: 0.23506498336792ms
Reflection way: 0.45829010009766ms

Abschließende Gedanken

Wenn Sie zwischen allen Sichtbarkeitsmöglichkeiten testen müssen, bleibt Ihnen nur die Verwendung testIfCallable2, so die Antwort der “Meze”. Ansonsten ist mein Weg etwa doppelt so schnell. Da Ihre Frage nur zwischen öffentlich oder nicht war, könnten Sie davon profitieren. Wenn Sie es nicht oft verwenden, ist der Unterschied nicht signifikant.

  • Denken Sie daran, dass die Art und Weise, wie Sie es eingerichtet haben, mit den aufrufenden Funktionen is_callable() befinden sich “außerhalb” der Klasse, die Sie testen, werden andere Ergebnisse zurückgeben, als wenn sich Ihre Funktionen “innerhalb” der Klasse befänden: 3v4l.org/fLaYN

    – Liebesina

    7. April 2019 um 10:57 Uhr

1180100cookie-checkSo überprüfen Sie, ob eine Funktion in PHP öffentlich oder geschützt ist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy