Apa masalahnya dengan garis bawah terkemuka dalam metode kelas PHP?

155

Sambil melihat-lihat berbagai pustaka PHP, saya perhatikan bahwa banyak orang memilih untuk mengawali beberapa metode kelas dengan satu garis bawah, seperti

public function _foo()

...dari pada...

public function foo()

Saya menyadari bahwa pada akhirnya ini tergantung pada preferensi pribadi, tetapi saya bertanya-tanya apakah ada yang tahu dari mana kebiasaan ini berasal.

Pikir saya adalah bahwa itu mungkin dibawa dari PHP 4, sebelum metode kelas dapat ditandai sebagai dilindungi atau pribadi, sebagai cara menyiratkan "jangan panggil metode ini dari luar kelas". Namun, terlintas dalam benak saya bahwa mungkin itu berasal dari suatu tempat (suatu bahasa) yang tidak saya kenal atau mungkin ada alasan yang baik di baliknya bahwa saya akan mendapat manfaat dari mengetahuinya.

Setiap pemikiran, wawasan, dan / atau opini akan dihargai.

nocash
sumber
9
Pembaruan 2014: Ini sintaks usang yang resmi: github.com/php-fig/fig-standards/blob/master/accepted/…
Sliq

Jawaban:

155

Ini dari masa lalu yang buruk dari Object Oriented PHP (PHP 4). Implementasi OO itu sangat buruk, dan tidak termasuk hal-hal seperti metode pribadi. Untuk mengimbangi, pengembang PHP memilih metode yang dimaksudkan untuk menjadi pribadi dengan garis bawah. Di beberapa kelas yang lebih tua, Anda akan melihat/**private*/ __foo() { memberikan bobot tambahan.

Saya belum pernah mendengar tentang pengembang yang memasang semua metode mereka dengan garis bawah, jadi saya tidak bisa mulai menjelaskan apa penyebabnya.

Jeremy DeGroot
sumber
12
Saya menempatkan garis bawah sebelum metode di controller saya yang pribadi ke kelas, dan tidak digunakan dalam routing. Karena saya bekerja dengan kerangka kerja saya sendiri, ini menambah keamanan karena saya menegakkan kebijakan tidak ada garis bawah pada nama-nama pengontrol dalam rute. Tetapi ini jarang melebihi 1-2 metode per controller.
Robert K
6
Secara konvensional, dengan perl, metode yang dimulai dengan garis bawah bersifat pribadi. Tapi itu hanya konvensi. Bahkan, metode ini masih dapat diakses dari luar kelas.
Luc M
Menggarisbawahi bahkan lebih tidak masuk akal jika kelas yang diperluas memutuskan untuk membuat metode yang dilindungi orang tuanya publik. Ini kasus tepi, tetapi itu terjadi. Pengembang API juga dapat memilih untuk mengekspos metode pribadi sebagai publik, yang berarti mereka harus memperbaiki nama metode selain mengubah pengubah akses. Bukan masalah besar, tapi tetap saja gangguan.
Johan Fredrik Varen
Johan - refactoring adalah gangguan? Editor saya memiliki fitur yang disebut "Temukan dan Ganti". Bagus sekali!
DaveWalley
Ini adalah konvensi C # yang dapat Anda gunakan, untuk mengawali anggota pribadi dengan tepat satu garis bawah. Oleh karena itu konvensi Zend Framework 1 (2012) untuk melakukannya dengan cara yang sama.
alpham8
73

Saya percaya sumber paling otoritatif untuk konvensi semacam ini untuk PHP saat ini adalah PSR-2: Panduan Gaya Pengkodean karena Zend Framework adalah bagian dari PSR :

Nama properti TIDAK HARUS diawali dengan garis bawah tunggal untuk menunjukkan visibilitas yang dilindungi atau pribadi.

joedevon
sumber
9
Menggunakan konvensi penamaan bukan alasan untuk mencintai bahasa, saya pikir.
sepehr
4
Ketika saya pertama kali membaca tentang ini, saya mengerti alasannya agar Anda dapat melihat metode dan mengetahui apakah itu metode publik atau pribadi. Yang akan jauh lebih masuk akal jika itu adalah persyaratan daripada konvensi. Karena jika 1 programmer dalam sebuah tim menambahkan garis bawah di mana tidak dibutuhkan, atau membuat garis bawah publik dengan garis bawah, Anda berakhir dengan banyak kebingungan. Ternyata, ini berasal dari PHP4 seperti yang ditunjukkan Jeremy, & #ZF mendasarkan konvensi mereka dari konvensi PEAR. PEAR telah menghapusnya & saya yakin #ZF akan mengikutinya.
joedevon
Jawaban ini benar. Ini semua tempat sialan di Magento, dan seperti dicatat oleh Sliq di bawah ini, itu adalah konvensi yang umumnya sudah usang.
siliconrockstar
Inilah tautan yang diperbarui tentang ini. framework.zend.com/manual/1.12/en/…
Shapeshifter
FYI (dan @joedevon) Zend 2.4 dirilis beberapa bulan lalu, dan mereka masih menggunakan garis bawah untuk kerangka kerja pribadi dan yang dilindungi.zend.com/manual/current/en/ref/… .
James
14

Saya sangat menentang awalan metode privat / terproteksi dengan garis bawah karena Anda dapat menggunakan kata kunci privat / terlindungi untuk itu dan IDE akan menandainya untuk Anda.

Dan saya masih, tetapi, saya menemukan satu alasan mengapa itu bisa menjadi praktik yang baik. Bayangkan Anda memiliki metode publik addFoo()dan di dalam metode itu Anda memiliki beberapa bagian tugas yang sama dengan metode lain addFooWhenBar(), addFooWhenBaz()... Sekarang, nama terbaik untuk metode umum itu adalah addFoo(), tetapi sudah diambil, jadi Anda harus membuat beberapa nama jelek seperti addFooInternal()atau addFooCommon()atau ... tetapi _addFoo()metode pribadi sepertinya yang terbaik.

umpirsky
sumber
Ya, setuju. Saya benar-benar datang ke sini untuk melihat apa yang dipikirkan orang lain tentang garis bawah karena saya jarang menggunakannya, dan selalu terasa salah, tetapi contoh ini adalah satu kali yang saya miliki. Saya juga telah menggunakannya untuk beberapa kasus pola metode templat di mana metode publik memanggil metode yang dilindungi abstrak yang telah ditimpa anak-anak, yang merupakan ide serupa. Kadang - kadang metode publik dan metode yang dilindungi abstrak yang disebutnya sangat mirip atau terkait sehingga penamaan mereka tampak lebih aneh daripada hanya awalan _ ke yang abstrak.
John Pancoast
12

Garis bawah utama biasanya digunakan untuk properti dan metode pribadi . Bukan teknik yang biasa saya pakai, tetapi tetap populer di kalangan beberapa programmer.

Johnstjohn
sumber
10

Saya menggunakan garis bawah terkemuka di kelas PHP 5 yang saya tulis untuk metode pribadi. Ini adalah isyarat visual kecil bagi pengembang bahwa anggota kelas tertentu bersifat pribadi. Jenis petunjuk ini tidak berguna ketika menggunakan IDE yang membedakan anggota publik dan pribadi untuk Anda. Saya mengambilnya dari hari C # saya. Kebiasaan lama ...

GloryFish
sumber
5

Saya percaya asumsi awal Anda benar, saya telah menemukan itu menjadi praktik umum untuk beberapa bahasa untuk awalan garis bawah untuk metode / anggota dll yang dimaksudkan untuk dirahasiakan dengan "objek". Hanya cara visual untuk mengatakan meskipun Anda bisa, Anda tidak harus memanggil ini!

Quintin Robinson
sumber
5

Saya mencari jawaban yang sama, saya melakukan riset, dan saya baru saja menemukan bahwa kerangka kerja php menyarankan gaya yang berbeda:

Penyala kode

Manual resmi memiliki bagian gaya pengkodean yang mendorong praktik ini :

Metode dan Variabel Pribadi

Metode dan variabel yang hanya diakses secara internal, seperti fungsi utilitas dan pembantu yang digunakan metode publik Anda untuk abstraksi kode, harus diawali dengan garis bawah.

public function convert_text()

private function _convert_text()

Kerangka kerja lain melakukan hal yang sama, seperti

Cakephp:

melakukan hal yang sama :

Visibilitas Anggota

Gunakan kata kunci pribadi dan dilindungi PHP5 untuk metode dan variabel. Selain itu, metode non-publik atau nama variabel mulai dengan garis bawah tunggal (_). Contoh:

class A
{
    protected $_iAmAProtectedVariable;

    protected function _iAmAProtectedMethod()
    {
       /* ... */
    }

    private $_iAmAPrivateVariable;

    private function _iAmAPrivateMethod()
    {
        /* ... */
    }
}

Dan juga

PIR

melakukan hal yang sama :

Anggota kelas pribadi didahului oleh satu garis bawah tunggal. Sebagai contoh:

$_status    _sort()     _initTree()

Sementara

Drupal

gaya kode secara khusus memperingatkan ini :

  1. Properti dan metode yang dilindungi atau pribadi tidak boleh menggunakan awalan garis bawah.

Simfoni

di sisi lain, nyatakan :

Symfony mengikuti standar yang ditentukan dalam dokumen PSR-0, PSR-1, PSR-2 dan PSR-4.

Tuanito
sumber
Jawaban yang sangat teliti.
colonelclick
4

Saya tahu itu dari python, di mana awalan variabel Anda dengan garis bawah menyebabkan kompiler menerjemahkan beberapa urutan acak huruf dan angka di depan nama variabel yang sebenarnya. Ini berarti bahwa setiap upaya untuk mengakses variabel dari luar kelas akan menghasilkan kesalahan "variabel tidak terdefinisi".

Saya tidak tahu apakah ini masih merupakan konvensi untuk digunakan dalam python

Matius
sumber
3

Dalam Drupal (a php CMS) garis bawah dapat digunakan untuk mencegah agar kait tidak dipanggil ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Jika saya memiliki modul yang disebut "my_module" dan ingin memberi nama fungsi my_module_insert itu akan "kait" pada fungsi hook_insert. Untuk mencegahnya, saya dapat mengubah nama fungsi saya menjadi _my_module_insert.

ps Cara kait bekerja di Drupal dimungkinkan untuk menerapkan hook secara tidak sengaja, yang sangat buruk.

maho
sumber
1
Saya menganggap itu sebagai cacat desain drupal selama beberapa waktu. Akan lebih masuk akal untuk mendaftarkan kait Anda secara eksplisit untuk mencegah kebingungan dan operasi yang tidak menentu. Asumsi umumnya adalah hal yang buruk, dan konstruksi yang mengganggu pemrograman normal atau membajaknya biasanya arsitektur yang buruk.
mopsyd
3

Drupal, dan gunakan garis bawah:

Secara umum garis bawah adalah untuk menandai fakta bahwa suatu fungsi mungkin hanya akan dipanggil oleh fungsi induk terkait ...

function mymodule_tool($sting="page title"){
    $out ='';
    //do stuff 
    $out  .= _mymodule_tool_decor($sting);
    return $out;
}

function _mymodule_tool_decor($sting){
    return '<h1>'.$string.'</h1>';
}

Tentu saja, hanya sebuah contoh sederhana ...

pengguna3613677
sumber
0

Menggunakan garis bawah hanya untuk tujuan mengingat bahwa kita tidak akan 'memodifikasi variabel' / 'memanggil fungsi' di luar kelas.

Seperti kita mendeklarasikan variabel const di semua huruf besar sehingga sambil melihat nama variabel dapat menebak bahwa itu adalah variabel const. Serupa dengan variabel yang tidak ingin kami modifikasi di luar kelas, kami mendeklarasikannya dengan garis bawah untuk konvensi kami sendiri.

Tassawer
sumber
Apa yang Anda maksud dengan "variabel const"? Bagaimana Anda bisa mendefinisikan konstanta yang variabel?
Nico Haase
-21

Mereka disebut "metode ajaib" .

Tristan
sumber
39
_foo()dengan garis bawah utama tunggal bukanlah metode ajaib. Metode sihir dilambangkan oleh dua garis bawah terkemuka berturut-turut. Pertanyaan di sini hanya berbicara tentang satu.
BoltClock