Överbelastning

Från Wiki.linux.se
Hoppa till navigering Hoppa till sök

Överlagring

Överlagring i PHP ger möjligheter att dynamiskt skapa egenskaper och metoder. Dessa dynamiska entiteter hanteras via magiska metoder som man kan definiera i en klass för olika typer av åtgärder.

Överlagringsmetoder anropas när man interagerar med egenskaper eller metoder som inte har deklarerats eller inte är synliga i den aktuella kontexten. Resten av den här sektionen kommer att använda termerna otillgängliga egenskaper och otillgängliga metoder för att referera till denna kombination av deklaration och synlighet.

Alla överlagringsmetoder måste vara deklarerade som public.

Notera: Inga av argumenten till dessa magiska metoder kan skickas som referens.

Notera: PHP:s tolkning av överlagring skiljer sig från de flesta objektorienterade språk. Traditionellt ger överlagring möjligheten att ha flera metoder med samma namn men olika antal och typer av argument.

Egenskap överlagring

public __set(string $name, mixed $value): void
public __get(string $name): mixed
public __isset(string $name): bool
public __unset(string $name): void

`__set()` körs när man skriver data till otillgängliga (protected eller private) eller icke-existerande egenskaper.

`__get()` används för att läsa data från otillgängliga (protected eller private) eller icke-existerande egenskaper.

`__isset()` triggas av anrop till `isset()` eller `empty()` på otillgängliga (protected eller private) eller icke-existerande egenskaper.

`__unset()` anropas när `unset()` används på otillgängliga (protected eller private) eller icke-existerande egenskaper.

Argumentet `$name` är namnet på den egenskap som interageras med. Metoden `__set()` har även ett argument `$value` som specificerar vilket värde den egenskap med namnet `$name` ska tilldelas.

Egenskap överlagring fungerar endast i objektkontext. Dessa magiska metoder kommer inte att triggas i statisk kontext. Därför bör dessa metoder inte deklareras som statiska. En varning utfärdas om någon av de magiska överlagringsmetoderna deklareras som statisk.

Notera: Returvärdet för `__set()` ignoreras på grund av hur PHP bearbetar tilldelningsoperatorn. På samma sätt anropas aldrig `__get()` när man kedjar ihop tilldelningar som i:

$a = $obj->b = 8;

Notera:

PHP kommer inte att anropa en överlagrad metod från samma överlagrade metod. Det betyder till exempel att om du skriver `return $this->foo` inuti `__get()` kommer detta att returnera `null` och generera en E_WARNING om det inte finns någon `foo`-egenskap definierad, istället för att anropa `__get()` en gång till. Dock kan överlagringsmetoder anropa andra överlagringsmetoder implicit (som att `__set()` triggar `__get()`).

Exempel #1 Överlagring av egenskaper via metoderna __get(), __set(), __isset() och __unset()

class PropertyTest
{
    /**  Plats för överlagrad data.  */
    private $data = array();

    /**  Överlagring används inte på deklarerade egenskaper.  */
    public $declared = 1;

    /**  Överlagring används endast på detta när det nås utanför klassen.  */
    private $hidden = 2;

    public function __set($name, $value)
    {
        echo "Tilldelar '$name' till '$value'\n";
        $this->data[$name] = $value;
    }

    public function __get($name)
    {
        echo "Hämtar '$name'\n";
        if (array_key_exists($name, $this->data)) {
            return $this->data[$name];
        }

        $trace = debug_backtrace();
        trigger_error(
            'Odefinierad egenskap via __get(): ' . $name .
            ' i ' . $trace[0]['file'] .
            ' på rad ' . $trace[0]['line'],
            E_USER_NOTICE);
        return null;
    }

    public function __isset($name)
    {
        echo "Är '$name' satt?\n";
        return isset($this->data[$name]);
    }

    public function __unset($name)
    {
        echo "Tar bort '$name'\n";
        unset($this->data[$name]);
    }

    /**  Inte en magisk metod, bara här som exempel.  */
    public function getHidden()
    {
        return $this->hidden;
    }
}

echo "<pre>\n";

$obj = new PropertyTest;

$obj->a = 1;
echo $obj->a . "\n\n";

var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n";

echo $obj->declared . "\n\n";

echo "Låt oss experimentera med den privata egenskapen som heter 'hidden':\n";
echo "Privata är synliga inom klassen, så __get() används inte...\n";
echo $obj->getHidden() . "\n";
echo "Privata är inte synliga utanför klassen, så __get() används...\n";
echo $obj->hidden . "\n";

Utdata från ovanstående exempel:

Tilldelar 'a' till '1'
Hämtar 'a'
1

Är 'a' satt?
bool(true)
Tar bort 'a'
Är 'a' satt?
bool(false)

1

Låt oss experimentera med den privata egenskapen som heter 'hidden':
Privata är synliga inom klassen, så __get() används inte...
2
Privata är inte synliga utanför klassen, så __get() används...
Hämtar 'hidden'

Notice:  Odefinierad egenskap via __get(): hidden i <fil> på rad 70 i <fil> på rad 29

Metod överlagring

public __call(string $name, array $arguments): mixed
public static __callStatic(string $name, array $arguments): mixed

`__call()` triggas när man anropar otillgängliga metoder i objektkontext.

`__callStatic()` triggas när man anropar otillgängliga metoder i statisk kontext.

Argumentet `$name` är namnet på metoden som anropas. Argumentet `$arguments` är en uppräknad array som innehåller de parametrar som skickats till den namngivna metoden `$name`.

Exempel #2 Överlagring av metoder via metoderna __call() och __callStatic()

class MethodTest
{
    public function __call($name, $arguments)
    {
        // Notera: värdet av $name är skiftlägeskänsligt.
        echo "Anropar objektmetod '$name' "
             . implode(', ', $arguments). "\n";
    }

    public static function __callStatic($name, $arguments)
    {
        // Notera: värdet av $name är skiftlägeskänsligt.
        echo "Anropar statisk metod '$name' "
             . implode(', ', $arguments). "\n";
    }
}

$obj = new MethodTest;
$obj->runTest('i objektkontext');

MethodTest::runTest('i statisk kontext');

Utdata från ovanstående exempel:

Anropar objektmetod 'runTest' i objektkontext
Anropar statisk metod 'runTest' i statisk kontext


Sidslut

Orginalhemsidan på Engelska : https://www.php.net/manual/en/language.oop5.overloading.php
PHP
Språkreferens
Språkreferens#Klasser_och_Objekt


Det här är en maskinöversättning av PHP-manualen till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på https://www.linux.se/kontaka-linux-se/