Schwache Referenzen

Fragen zum Thema HTML, JavaScript, PHP
Antworten
Benutzeravatar
Architekt
Beiträge: 172
Registriert: Sa Mai 24, 2014 12:04 pm

Schwache Referenzen

Beitrag von Architekt » Mi Dez 21, 2016 9:02 pm

Moin zusammen. Ich bin grad am überlegen & suchen, wie man schwache Referenzen in PHP hin bekommt. Es gibt eine externe PECL Biblitohek, aber ich dachte ich versuche es mal so. Dabei fiel mir etwas auf: PHP scheint die $this Variable speziell zu behandeln. Ich habe als Beispiel diesen Code:

Code: Alles auswählen

<?php

class A
{
    public $b;

    public function __construct()
    {
        $this->b = new B($this);
    }

    public function __destruct()
    {
        print 'A::DTor' . PHP_EOL;
    }
}

class B
{
    public $a;

    public function __construct(A &$a)
    {
        $this->a = &$a;
    }

    public function __destruct()
    {
        print 'B::DTor' . PHP_EOL;
    }
}

function foo()
{
    print 'foo starts' . PHP_EOL;
    $a = new A();
    $a = null;
    print 'foo ends' . PHP_EOL;
}

foo();

print 'end' . PHP_EOL;
Der die folgende Ausgabe erzeugt:

Code: Alles auswählen

foo starts foo ends end A::DTor B::DTor
Ich hätte aber diese Ausgabe erwartet:

Code: Alles auswählen

foo starts foo ends A::DTor B::DTor end
da ich ja mit expliziten Referenzen gearbeitet habe. Dennoch entsteht scheinbar eine zyklische Referenz und ich bin mir nicht ganz sicher warum. Mache ich die "Verlinke" nämlich "manuell", scheint alles zu klappen:

Code: Alles auswählen

<?php

class A
{
    public $b;

    public function __destruct()
    {
        print 'A::DTor' . PHP_EOL;
    }
}

class B
{
    public $a;

    public function __destruct()
    {
        print 'B::DTor' . PHP_EOL;
    }
}

function foo()
{
    print 'foo starts' . PHP_EOL;
    $a = new A();
    $b = new B();

    $a->b = &$b;
    $b->a = &$a;

    $a = null;
    print 'foo ends' . PHP_EOL;
}

foo();

print 'end' . PHP_EOL;
Das gibt mir (wie erwartet) folgende Ausgabe:

Code: Alles auswählen

foo starts A::DTor foo ends B::DTor end
Und wenn ich $a = null; weglassen, bekomme ich (auch wie erwartet)

Code: Alles auswählen

foo starts foo ends end A::DTor B::DTor
Also scheint das ganze nur zu passieren, wenn $this verwendet wird.

Antworten