Apa properti dalam kode php?

Properti kelas yang diketik telah ditambahkan dalam PHP 7. 4 dan memberikan peningkatan besar pada sistem tipe PHP. Perubahan ini sepenuhnya ikut serta dan tidak merusak versi sebelumnya

Dalam posting ini kita akan melihat fitur secara mendalam, tapi pertama mari kita mulai dengan meringkas poin yang paling penting

  • Mereka tersedia mulai dari PHP 7. 4, yang dijadwalkan akan dirilis pada November 2019
  • Mereka hanya tersedia di kelas dan memerlukan pengubah akses.
    class Foo
    {
        public int $bar;
    }
    
    $foo = new Foo;
    7,
    class Foo
    {
        public int $bar;
    }
    
    $foo = new Foo;
    8 atau
    class Foo
    {
        public int $bar;
    }
    
    $foo = new Foo;
    9;
  • Semua jenis diperbolehkan, kecuali
    var_dump($foo->bar);
    
    Fatal error: Uncaught Error: Typed property Foo::$bar 
    must not be accessed before initialization
    1 dan
    var_dump($foo->bar);
    
    Fatal error: Uncaught Error: Typed property Foo::$bar 
    must not be accessed before initialization
    2

Beginilah penampilan mereka saat beraksi

class Foo
{
    public int $a;

    public ?string $b = 'foo';

    private Foo $prop;

    protected static string $static = 'default';
}
_

Jika Anda tidak yakin tentang manfaat tambahan dari tipe, saya sarankan Anda membaca posting ini terlebih dahulu

Tidak diinisialisasi

Sebelum melihat hal-hal menyenangkan, ada aspek penting tentang properti yang diketik yang penting untuk dibicarakan terlebih dahulu

Terlepas dari apa yang mungkin Anda pikirkan pada pandangan pertama, kode berikut ini valid

class Foo
{
    public int $bar;
}

$foo = new Foo;

Meskipun nilai

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
3 bukan bilangan bulat setelah membuat objek
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
4, PHP hanya akan menampilkan kesalahan saat
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
3 diakses

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization

Seperti yang dapat Anda baca dari pesan kesalahan, ada "status variabel" jenis baru. tidak diinisialisasi

Jika

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
_3 tidak memiliki tipe, nilainya hanya
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
7. Jenis dapat dibatalkan, jadi tidak mungkin untuk menentukan apakah properti nullable yang diketik telah ditetapkan, atau hanya dilupakan. Itu sebabnya "tidak diinisialisasi" ditambahkan

Ada empat hal penting yang perlu diingat tentang uninitialized

  • Anda tidak dapat membaca dari properti yang tidak diinisialisasi, hal itu akan mengakibatkan kesalahan fatal
  • Karena status yang tidak diinisialisasi dicentang saat mengakses properti, Anda dapat membuat objek dengan properti yang tidak diinisialisasi, meskipun jenisnya tidak dapat dibatalkan
  • Anda dapat menulis ke properti yang tidak diinisialisasi sebelum membacanya
  • Menggunakan
    var_dump($foo->bar);
    
    Fatal error: Uncaught Error: Typed property Foo::$bar 
    must not be accessed before initialization
    _8 pada properti yang diketik akan membuatnya tidak diinisialisasi, sedangkan menghapus properti yang tidak diketik akan membuatnya
    var_dump($foo->bar);
    
    Fatal error: Uncaught Error: Typed property Foo::$bar 
    must not be accessed before initialization
    7

Terutama perhatikan bahwa kode berikut, di mana properti yang tidak diinisialisasi dan tidak dapat dibatalkan ditetapkan setelah membuat objek, valid

class Foo
{
    public int $a;
}

$foo = new Foo;

$foo->a = 1;

Sementara status yang tidak diinisialisasi hanya diperiksa saat membaca nilai properti, validasi tipe dilakukan saat menulisnya. Ini berarti Anda dapat yakin bahwa tidak ada tipe yang tidak valid yang akan berakhir sebagai nilai properti

Apa properti dalam kode php?

Apa yang baru di PHP 8. 2

Default dan konstruktor

Mari kita lihat lebih dekat bagaimana nilai yang diketik dapat diinisialisasi. Dalam kasus tipe skalar, dimungkinkan untuk memberikan nilai default

class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}

Perhatikan bahwa Anda hanya dapat menggunakan

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
_7 sebagai default jika jenisnya benar-benar dapat dibatalkan. Ini mungkin tampak jelas, tetapi ada beberapa perilaku lama dengan default parameter yang mengizinkan hal berikut

function passNull(int $i = null)
{ /* … */ }

passNull(null);

Untungnya perilaku membingungkan ini tidak diperbolehkan dengan properti yang diketik

Perhatikan juga bahwa tidak mungkin memiliki nilai default dengan

class Foo
{
    public int $a;
}

$foo = new Foo;

$foo->a = 1;
1 atau tipe kelas. Anda harus menggunakan konstruktor untuk menyetel defaultnya

Tempat yang jelas untuk menginisialisasi nilai yang diketik tentu saja adalah konstruktor

class Foo
{
    private int $a;

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

Tapi juga ingat apa yang saya sebutkan sebelumnya. sah untuk menulis ke properti yang tidak diinisialisasi, di luar konstruktor. Selama tidak ada yang membaca dari properti, pemeriksaan yang tidak diinisialisasi tidak dilakukan

Jenis jenis

Jadi apa sebenarnya yang bisa diketik dan bagaimana caranya?

Berdasarkan jenis yang tersedia, hampir semua jenis dapat digunakan, kecuali

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
1 dan
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
2

Karena

var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
_1 berarti tidak adanya nilai, masuk akal bahwa itu tidak dapat digunakan untuk mengetikkan nilai.
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
2 namun sedikit lebih bernuansa

Lihat, "callable" di PHP bisa ditulis seperti itu

$callable = [$this, 'method'];

Katakanlah Anda memiliki kode (rusak) berikut

class Foo
{
    public callable $callable;
    
    public function __construct(callable $callable)
    { /* … */ }
}

class Bar
{
    public Foo $foo;
    
    public function __construct()
    {
        $this->foo = new Foo([$this, 'method'])
    }
    
    private function method()
    { /* … */ }
}

$bar = new Bar;

($bar->foo->callable)();

Dalam contoh ini,

class Foo
{
    public int $a;
}

$foo = new Foo;

$foo->a = 1;
_7 mengacu pada
class Foo
{
    public int $a;
}

$foo = new Foo;

$foo->a = 1;
8 pribadi, tetapi disebut dalam konteks
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
4. Karena masalah ini, diputuskan untuk tidak menambahkan dukungan
var_dump($foo->bar);

Fatal error: Uncaught Error: Typed property Foo::$bar 
must not be accessed before initialization
2

Ini bukan masalah besar, karena

class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}
_1 adalah tipe yang valid, yang akan mengingat konteks
class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}
2 di mana itu dibangun

Dengan itu, berikut adalah daftar semua jenis yang tersedia

  • bool
  • int
  • mengambang
  • rangkaian
  • Himpunan
  • dapat diubah
  • obyek
  • ?
  • diri dan orang tua
  • Kelas & antarmuka

Jenis pemaksaan dan ketat

PHP, sebagai bahasa dinamis yang kita sukai dan benci, akan mencoba memaksa atau mengonversi tipe jika memungkinkan. Katakanlah Anda melewatkan string di mana Anda mengharapkan bilangan bulat, PHP akan mencoba dan mengonversi string itu secara otomatis

function coerce(int $i)
{ /* … */ }

coerce('1'); // 1

Prinsip yang sama berlaku untuk properti yang diketik. Kode berikut ini valid dan akan mengonversi

class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}
3 menjadi
class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}
4

class Foo
{
    public int $bar;
}

$foo = new Foo;
0

Jika Anda tidak menyukai perilaku ini, Anda dapat menonaktifkannya dengan mendeklarasikan tipe yang ketat

class Foo
{
    public int $bar;
}

$foo = new Foo;
_1

Jenis varians dan pewarisan

Meskipun PHP7. 4 diperkenalkan , properti yang diketik masih invarian. Ini berarti bahwa yang berikut ini tidak valid

class Foo
{
    public int $bar;
}

$foo = new Foo;
_2

Jika contoh di atas tampaknya tidak signifikan, Anda harus melihat yang berikut ini

class Foo
{
    public int $bar;
}

$foo = new Foo;
_3

PHP akan mengganti

class Foo
{
    public int $bar = 4;
    
    public ?string $baz = null;
    
    public array $list = [1, 2, 3];
}
_5 di belakang layar dengan kelas konkret yang dirujuknya, sebelum menjalankan kode. Ini berarti bahwa kesalahan yang sama akan dilemparkan dalam contoh ini. Satu-satunya cara untuk mengatasinya, adalah dengan melakukan hal berikut

class Foo
{
    public int $bar;
}

$foo = new Foo;
_4

Berbicara tentang pewarisan, Anda mungkin kesulitan menemukan kasus penggunaan yang baik untuk menimpa jenis properti yang diwariskan

Meskipun saya setuju dengan sentimen itu, perlu dicatat bahwa adalah mungkin untuk mengubah jenis properti yang diwariskan, tetapi hanya jika pengubah akses juga berubah dari

class Foo
{
    public int $bar;
}

$foo = new Foo;
9 menjadi
class Foo
{
    public int $bar;
}

$foo = new Foo;
8 atau
class Foo
{
    public int $bar;
}

$foo = new Foo;
7

Kode berikut ini valid

class Foo
{
    public int $bar;
}

$foo = new Foo;
5

Namun, mengubah jenis dari nullable menjadi non-nullable atau sebaliknya, tidak diperbolehkan

class Foo
{
    public int $bar;
}

$foo = new Foo;
_6

Melihat tpyo? . Jika Anda ingin tetap mendapatkan informasi terbaru tentang apa yang terjadi di blog ini, Anda dapat mengikuti saya di Twitter atau berlangganan buletin saya. Email Berlangganan

Masih ada lagi

Seperti yang dikatakan di awal posting ini, properti yang diketik adalah tambahan utama untuk PHP. Masih banyak lagi yang bisa dikatakan tentang mereka. Saya sarankan Anda membaca RFC untuk mengetahui semua detail kecil yang rapi

Jika Anda baru menggunakan PHP 7. 4, Anda mungkin ingin membaca daftar lengkap perubahan yang dibuat dan fitur yang ditambahkan. Sejujurnya, ini adalah salah satu rilis terbaik dalam waktu yang lama, dan sepadan dengan waktu Anda

Terakhir, jika Anda memiliki pemikiran yang ingin Anda bagikan tentang topik ini, saya ingin mendengar pendapat Anda. Anda dapat menghubungi saya melalui Twitter atau email

Apa itu properti di PHP?

Dalam php, properti sama dengan atribut, variabel sederhana tanpa fungsi . Mereka harus disebut atribut, bukan properti.

Apa properti dalam kode?

Properti adalah anggota yang menyediakan mekanisme fleksibel untuk membaca, menulis, atau menghitung nilai bidang pribadi . Properti dapat digunakan seolah-olah mereka adalah anggota data publik, tetapi mereka adalah metode khusus yang disebut pengakses.

Apa itu metode dan properti di PHP?

Kelas berisi variabel dan fungsi. variabel data ini disebut properti dan fungsi data disebut metode data .

Apa itu properti di kelas?

Properti adalah atribut atau fitur yang mencirikan kelas . Sementara kelas adalah kelompok objek, sebuah instance adalah objek spesifik yang benar-benar dimiliki oleh sebuah kelas.