Konstruktorer och destruktorer

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

Konstruktorer och Destruktorer

Konstruktor

`__construct(mixed ...$values = ""): void`

PHP tillåter utvecklare att deklarera konstruktormetoder för klasser. Klasser som har en konstruktormetod anropar denna metod på varje nysskapad objekt, så det är lämpligt för all initialisering som objektet kan behöva innan det används.

Observera: Föräldrakonstruktörer anropas inte implicit om barnklassen definierar en konstruktor. För att köra en föräldrakonstruktor måste man anropa `parent::__construct()` inom barnklassens konstruktor. Om barnklassen inte definierar en konstruktor kan den ärva konstruktor från föräldraklassen precis som en vanlig klassmetod (om den inte deklarerades som privat).

Exempel #1 Konstruktörer i arv

<?php
class BaseClass {
    function __construct() {
        print "In BaseClass constructor\n";
    }
}

class SubClass extends BaseClass {
    function __construct() {
        parent::__construct();
        print "In SubClass constructor\n";
    }
}

class OtherSubClass extends BaseClass {
    // ärver BaseClass's konstruktor
}

// In BaseClass constructor
$obj = new BaseClass();

// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();

// In BaseClass constructor
$obj = new OtherSubClass();
?>

Till skillnad från andra metoder är `__construct()` undantagen från de vanliga reglerna för signaturkompatibilitet vid arv.

Konstruktörer är vanliga metoder som anropas under instansieringen av sitt motsvarande objekt. Som sådana kan de definiera ett godtyckligt antal argument, vilka kan vara obligatoriska, ha en typ eller ha ett standardvärde. Konstruktorns argument anropas genom att placera argumenten inom parentes efter klassens namn.

Exempel #2 Använda konstruktionsargument

<?php
class Point {
    protected int $x;
    protected int $y;

    public function __construct(int $x, int $y = 0) {
        $this->x = $x;
        $this->y = $y;
    }
}

// Passera båda parametrarna.
$p1 = new Point(4, 5);
// Passera bara den obligatoriska parametern. $y kommer att ta sitt standardvärde 0.
$p2 = new Point(4);
// Med namngivna parametrar (från och med PHP 8.0):
$p3 = new Point(y: 5, x: 4);
?>

Om en klass inte har någon konstruktor, eller om konstruktorn inte har några obligatoriska argument, kan parenteserna utelämnas.

Konstruktor Promotion

Från och med PHP 8.0.0 kan konstruktorns parametrar också befordras till att motsvara en objektproperty. Det är mycket vanligt att konstruktorns parametrar tilldelas en property i konstruktorn men annars inte används. Konstruktorbefordran tillhandahåller en förkortning för detta användningsfall.

Exempel #3 Använda konstruktorpropertybefordran

<?php
class Point {
    public function __construct(protected int $x, protected int $y = 0) {
    }
}
?>

När ett konstruktionsargument inkluderar en modifierare, kommer PHP att tolka det som både en objektproperty och ett konstruktionsargument, och tilldela argumentets värde till egenskapen. Konstruktorkroppen kan sedan vara tom eller kan innehålla andra uttalanden.

Nytt i initierare

Från och med PHP 8.1.0 kan objekt användas som standardparameter, statiska variabler och globala konstanter, samt i attributargument.

Exempel #4 Använda new i initierare

<?php

// Alla tillåtna:
static $x = new Foo;

const C = new Foo;
 
function test($param = new Foo) {}
 
#[AnAttribute(new Foo)]
class Test {
    public function __construct(
        public $prop = new Foo,
    ) {}
}

// Alla inte tillåtna (kompileringstidfel):
function test(
    $a = new (CLASS_NAME_CONSTANT)(), // dynamiskt klassnamn
    $b = new class {}, // anonym klass
    $c = new A(...[]), // argumentupplösning
    $d = new B($abc), // ej stödd konstantuttryck
) {}
?>

Statiska skapningsmetoder

PHP stöder endast en konstruktor per klass. I vissa fall kan det dock vara önskvärt att tillåta ett objekt att konstrueras på olika sätt med olika indata. Det rekommenderade sättet att göra detta är genom att använda statiska metoder som konstruktorsomslag.

Exempel #5 Använda statiska skapningsmetoder

<?php
class Product {

    private ?int $id;
    private ?string $name;

    private function __construct(?int $id = null, ?string $name = null) {
        $this->id = $id;
        $this->name = $name;
    }

    public static function fromBasicData(int $id, string $name): static {
        $new = new static($id, $name);
        return $new;
    }

    public static function fromJson(string $json): static {
        $data = json_decode($json, true);
        return new static($data['id'], $data['name']);
    }

    public static function fromXml(string $xml): static {
        // Anpassad logik här.
        $data = convert_xml_to_array($xml);
        $new = new static();
        $new->id = $data['id'];
        $new->name = $data['name'];
        return $new;
    }
}

$p1 = Product::fromBasicData(5, 'Widget');
$p2 = Product::fromJson($some_json_string);
$p3 = Product::fromXml($some_xml_string);
?>

Destruktor

`__destruct(): void`

PHP har ett destruktorkoncept som liknar andra objektorienterade språk, som C++. Destruktormetoden kommer att anropas så snart det inte finns några andra referenser till ett visst objekt, eller i vilken ordning som helst under nedstängningssekvensen.

Exempel #6 Destruktorexempel

<?php

class MyDestructableClass 
{
    function __construct() {
        print "In constructor\n";
    }

    function __destruct() {
        print "Destroying " . __CLASS__ . "\n";
    }
}

$obj = new MyDestructableClass();
?>

Liksom konstruktörer kommer inte föräldradestruktörer att anropas implicit av motorn. För att köra en föräldradestruktor måste man uttryckligen anropa `parent::__destruct()` i destruktorkroppen. Precis som med konstruktörer kan en barnklass ärva förälderns destruktor om den inte implementerar en egen.

Sidslut

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