Apa perbedaan antara :: (titik dua) dan -> (panah) di PHP?

196

Ada dua cara berbeda untuk mengakses metode dalam PHP, tetapi apa bedanya?

$response->setParameter('foo', 'bar');

dan

sfConfig::set('foo', 'bar');

Saya berasumsi ->(tanda hubung dengan tanda atau chevron) digunakan untuk fungsi untuk variabel, dan ::(titik dua) digunakan untuk fungsi untuk kelas. Benar?

Apakah =>operator penugasan hanya digunakan untuk menetapkan data dalam array? Apakah ini berbeda dengan =operator penugasan yang digunakan untuk instantiate atau memodifikasi variabel?

Joe
sumber
3
kemungkinan rangkap dari Referensi - Apa arti simbol ini dalam PHP?
Gordon
1
Kemungkinan duplikat Perbedaan antara operator titik dua dan panah di PHP?
Advokat Organik

Jawaban:

172

Ketika bagian kiri adalah contoh objek, Anda gunakan ->. Jika tidak, Anda gunakan ::.

Ini berarti bahwa ->sebagian besar digunakan untuk mengakses anggota instance (meskipun itu juga dapat digunakan untuk mengakses anggota statis, penggunaan seperti itu tidak disarankan), sementara ::biasanya digunakan untuk mengakses anggota statis (meskipun dalam beberapa kasus khusus, ini digunakan untuk mengakses anggota contoh ).

Secara umum, ::digunakan untuk resolusi lingkup , dan mungkin memiliki sebuah nama kelas, parent, self, atau (di PHP 5.3) staticke kiri. parentmengacu pada ruang lingkup kelas superclass di mana ia digunakan; selfmengacu pada ruang lingkup kelas di mana ia digunakan; staticmengacu pada "ruang lingkup yang disebut" (lihat binding statis akhir ).

Aturannya adalah bahwa panggilan dengan ::adalah panggilan instan jika dan hanya jika:

  • metode target tidak dinyatakan sebagai statis dan
  • ada konteks objek yang kompatibel pada saat panggilan, artinya ini harus benar:
    1. panggilan dibuat dari konteks di mana $thisada dan
    2. kelasnya $thisadalah kelas dari metode yang dipanggil atau subkelasnya.

Contoh:

class A {
    public function func_instance() {
        echo "in ", __METHOD__, "\n";
    }
    public function callDynamic() {
        echo "in ", __METHOD__, "\n";
        B::dyn();
    }

}

class B extends A {
    public static $prop_static = 'B::$prop_static value';
    public $prop_instance = 'B::$prop_instance value';

    public function func_instance() {
        echo "in ", __METHOD__, "\n";
        /* this is one exception where :: is required to access an
         * instance member.
         * The super implementation of func_instance is being
         * accessed here */
        parent::func_instance();
        A::func_instance(); //same as the statement above
    }

    public static function func_static() {
        echo "in ", __METHOD__, "\n";
    }

    public function __call($name, $arguments) {
        echo "in dynamic $name (__call)", "\n";
    }

    public static function __callStatic($name, $arguments) {
        echo "in dynamic $name (__callStatic)", "\n";
    }

}

echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";

echo '$b->func_instance():', "\n", $b->func_instance(), "\n";

/* This is more tricky
 * in the first case, a static call is made because $this is an
 * instance of A, so B::dyn() is a method of an incompatible class
 */
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
 * instance of B (despite the fact we are in a method of A), so
 * B::dyn() is a method of a compatible class (namely, it's the
 * same class as the object's)
 */
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";

Keluaran:

B :: $ prop_static: B :: nilai $ prop_static
B :: func_static (): dalam B :: func_static

$ b-> prop_instance: B :: nilai $ prop_instance
$ b-> func_static (): dalam B :: func_static

$ b-> func_instance ():
dalam B :: func_instance
dalam A :: func_instance
dalam A :: func_instance

$ a-> dyn ():
dalam A :: callDynamic
dalam dyn dinamis (__callStatic)

$ b-> dyn ():
dalam A :: callDynamic
dalam dyn dinamis (__call)
Artefacto
sumber
3
" ->Sebagian besar digunakan untuk mengakses anggota instance (meskipun itu juga dapat digunakan untuk mengakses anggota statis, penggunaan seperti itu tidak disarankan)" Saya tidak tahu itu bisa terjadi. Jadi jika "berfungsi" dengan cara tertentu ketika digunakan untuk mengakses anggota statis - perbedaan perilaku apa yang diharapkan seseorang jika salah menggunakannya seperti ini? Hanya karena penasaran.
lucideer
4
@ lucideer Dalam kasus metode statis, ini adalah pertanyaan praktik yang baik (metode ini milik kelas itu sendiri), tetapi PHP tidak mengeluh jika memanggil metode statis dengan ->. Tentu saja, Anda mungkin perlu membuat instance kelas hanya untuk memanggil metode statis, jadi ada juga hit kinerja. Namun, dengan properti, ada lebih banyak masalah. Peringatan STRICT dinaikkan dan itu mungkin atau mungkin tidak bekerja . Perhatikan bahwa kebalikannya juga benar - Anda dapat memanggil metode instance secara statis, tetapi ini bahkan lebih buruk (dan Anda tidak dapat menggunakan $thisimplementasi metode seperti itu).
Artefacto
52

::digunakan dalam konteks statis , yaitu. ketika beberapa metode atau properti dinyatakan sebagai statis:

class Math {
    public static function sin($angle) {
        return ...;
    }
}

$result = Math::sin(123);

Juga, ::operator (Operator Penyelesaian Ruang Lingkup, alias Paamayim Nekudotayim ) digunakan dalam konteks dinamis ketika Anda memanggil metode / properti dari kelas induk:

class Rectangle {
     protected $x, $y;

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

class Square extends Rectangle {
    public function __construct($x) {
        parent::__construct($x, $x);
    }
}

->digunakan dalam konteks dinamis , yaitu. ketika Anda berurusan dengan beberapa instance dari beberapa kelas:

class Hello {
    public function say() {
       echo 'hello!';
    }
}

$h = new Hello();
$h->say();

Ngomong-ngomong: Saya tidak berpikir bahwa menggunakan Symfony adalah ide yang baik ketika Anda tidak memiliki pengalaman OOP.

Crozin
sumber
24

Sebenarnya dengan simbol ini kita dapat memanggil metode kelas yang statis dan tidak bergantung pada inisialisasi lainnya ...

class Test {

    public $name;

    public function __construct() {
        $this->name = 'Mrinmoy Ghoshal';
    }

    public static function doWrite($name) {
        print 'Hello '.$name;
    }

    public function write() {
        print $this->name;
    }
}

Di sini doWrite()fungsinya tidak tergantung pada metode atau variabel lain apa pun, dan ini merupakan metode statis. Itu sebabnya kita dapat memanggil metode ini oleh operator ini tanpa menginisialisasi objek kelas ini.

Test::doWrite('Mrinmoy'); // Output: Hello Mrinmoy.

Tetapi jika Anda ingin memanggil writemetode dengan cara ini, itu akan menghasilkan kesalahan karena tergantung pada inisialisasi.

Mrinmoy Ghoshal
sumber
15

The =>operator yang digunakan untuk pasangan kunci-nilai assign dalam array asosiatif. Sebagai contoh:

$fruits = array(
  'Apple'  => 'Red',
  'Banana' => 'Yellow'
);

Makna itu serupa dalam foreachpernyataan:

foreach ($fruits as $fruit => $color)
  echo "$fruit is $color in color.";
casablanca
sumber
14

Perbedaan antara metode statis dan instantiated dan properti tampaknya menjadi salah satu kendala terbesar bagi mereka yang baru memulai dengan OOP PHP di PHP 5.

Operator usus ganda (yang disebut Paamayim Nekudotayim dari bahasa Ibrani - trivia) digunakan ketika memanggil objek atau properti dari konteks statis . Ini berarti turunan dari objek belum dibuat.

Operator panah, sebaliknya, memanggil metode atau properti yang dari referensi instance objek.

Metode statis dapat sangat berguna dalam model objek yang ditautkan ke database untuk membuat dan menghapus metode, karena Anda dapat mengatur nilai kembali ke id tabel yang disisipkan dan kemudian menggunakan konstruktor untuk instantiate objek dengan id baris.

DeaconDesperado
sumber
2

Ya, saya baru saja memukul pertama saya 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'. Buruk saya, saya punya $instance::method()yang seharusnya $instance->method(). Saya konyol.

Yang aneh adalah bahwa ini masih berfungsi dengan baik pada mesin lokal saya (menjalankan PHP 5.3.8) - tidak ada, bahkan peringatan dengan error_reporting = E_ALL - tetapi tidak sama sekali pada server uji, di sana ia meledak dengan kesalahan sintaksis dan layar putih di browser. Karena logging PHP dimatikan di mesin uji, dan perusahaan hosting terlalu sibuk untuk menyalakannya, itu tidak terlalu jelas.

Jadi, kata peringatan: ternyata, beberapa instalasi PHP akan membiarkan Anda menggunakan $ instance :: method (), sementara yang lain tidak.

Jika ada yang bisa memperluas mengapa itu terjadi, silakan lakukan.

PapaFreud
sumber