Thỏa thuận với một dấu gạch dưới hàng đầu trong các phương thức lớp PHP là gì?


155

Trong khi xem qua các thư viện PHP khác nhau, tôi nhận thấy rằng nhiều người chọn tiền tố một số phương thức lớp với một dấu gạch dưới duy nhất, chẳng hạn như

public function _foo()

...thay vì...

public function foo()

Tôi nhận ra rằng cuối cùng điều này xuất phát từ sở thích cá nhân, nhưng tôi đã tự hỏi liệu có ai có cái nhìn sâu sắc về thói quen này đến từ đâu không.

Tôi nghĩ rằng nó có thể được chuyển sang từ PHP 4, trước khi các phương thức lớp có thể được đánh dấu là được bảo vệ hoặc riêng tư, như một cách ngụ ý "không gọi phương thức này từ bên ngoài lớp". Tuy nhiên, điều đó cũng xảy ra với tôi rằng có lẽ nó bắt nguồn từ đâu đó (một ngôn ngữ) mà tôi không quen thuộc hoặc có thể có lý do chính đáng đằng sau nó mà tôi sẽ được lợi từ việc biết.

Bất kỳ suy nghĩ, hiểu biết và / hoặc ý kiến ​​sẽ được đánh giá cao.


9
Cập nhật 2014: Cú pháp lỗi thời chính thức: github.com/php-fig/fig-stiterias/blob/master/accepted/
Kẻ

Câu trả lời:


155

Đó là từ những ngày xưa tồi tệ của PHP hướng đối tượng (PHP 4). Việc triển khai OO đó khá tệ và không bao gồm những thứ như phương pháp riêng tư. Để bù đắp, các nhà phát triển PHP đã đặt trước các phương thức được dự định là riêng tư với dấu gạch dưới. Trong một số lớp học cũ hơn, bạn sẽ thấy /**private*/ __foo() {tăng thêm trọng lượng.

Tôi chưa bao giờ nghe nói về các nhà phát triển mở đầu tất cả các phương thức của họ bằng dấu gạch dưới, vì vậy tôi không thể bắt đầu giải thích nguyên nhân nào.


12
Tôi đặt dấu gạch dưới trước các phương thức trong bộ điều khiển của mình là riêng tư đối với lớp và không được sử dụng trong định tuyến. Bởi vì tôi làm việc với khung riêng của mình, điều này tăng thêm tính bảo mật khi tôi thực thi chính sách không có dấu gạch dưới hàng đầu đối với tên của bộ điều khiển trong các tuyến. Nhưng điều này hiếm khi vượt quá 1-2 phương thức cho mỗi bộ điều khiển.
Robert K

6
Theo quy ước, với perl, phương thức bắt đầu bằng dấu gạch dưới là riêng tư. Nhưng đó chỉ là một quy ước. Trong thực tế, các phương thức này vẫn có thể truy cập từ bên ngoài lớp.
Luc M

Dấu gạch dưới thậm chí còn ít ý nghĩa hơn nếu một lớp mở rộng quyết định công khai phương thức được bảo vệ của cha mẹ nó. Đó là một trường hợp cạnh, nhưng nó xảy ra. Các nhà phát triển API cũng có thể chọn hiển thị một phương thức riêng tư dưới dạng công khai, nghĩa là họ phải cấu trúc lại tên phương thức bên cạnh việc thay đổi công cụ sửa đổi truy cập. Không có vấn đề gì, nhưng dù sao cũng là một mối phiền toái.
Johan Fredrik Varen

Johan - tái cấu trúc là một mối phiền toái? Trình chỉnh sửa của tôi có một tính năng gọi là "Tìm và thay thế". Hoạt động tuyệt vời!
DaveWalley

Đó là một quy ước C # mà bạn có thể sử dụng, để tiền tố các thành viên riêng tư với chính xác một dấu gạch dưới. Do đó, đây là quy ước của Zend Framework 1 (2012) để thực hiện theo cách tương tự.
alpham8

73

Tôi tin rằng nguồn có thẩm quyền nhất cho các loại quy ước này cho PHP ngay bây giờ sẽ là Hướng dẫn về Phong cách mã hóa PSR-2 vì Khung công tác Zend là một phần của PSR :

Tên thuộc tính KHÔNG NÊN được tiền tố với một dấu gạch dưới duy nhất để biểu thị khả năng hiển thị được bảo vệ hoặc riêng tư.


9
Sử dụng một quy ước đặt tên không phải là một lý do để yêu một ngôn ngữ, tôi nghĩ.
sepehr

4
Khi tôi lần đầu tiên đọc về điều này, tôi đã hiểu lý do là để bạn có thể xem một phương pháp và biết nó là công khai hay riêng tư. Điều đó sẽ có ý nghĩa hơn nhiều nếu đó là một yêu cầu hơn là một quy ước. Bởi vì nếu 1 lập trình viên trong một nhóm thêm một dấu gạch dưới ở những nơi không cần thiết hoặc làm cho công khai với một dấu gạch dưới, bạn sẽ gặp nhiều rắc rối. Hóa ra, điều này xuất phát từ PHP4 khi Jeremy chỉ ra, & #ZF dựa trên quy ước của họ về quy ước PEAR. PEAR đã gỡ bỏ nó và tôi tin rằng #ZF sẽ làm theo.
tham gia

Câu trả lời này là chính xác. Đó là tất cả các nơi chết tiệt ở Magento, và như Sliq đã lưu ý dưới đây, đó là một quy ước thường không được tán thành.
siliconrockstar

Đây là liên kết cập nhật liên quan đến điều này. framework.zend.com/manual/1.12/vi/ cường
Shapeshifter

FYI (và @joedevon) Zend 2.4 đã được phát hành vài tháng trước và họ vẫn sử dụng dấu gạch dưới cho khung riêng tư và được bảo vệ.zend.com/manual/civerse/en/ref/ đấm .
James

40

Bây giờ, vào năm 2013, đây là phong cách xấu "chính thức" theo hướng dẫn mã hóa PSR-2:

Tên thuộc tính KHÔNG NÊN tiền tố với một dấu gạch dưới duy nhất để biểu thị khả năng hiển thị được bảo vệ hoặc riêng tư`

Nguồn: https://github.com/php-fig/fig-stiterias/blob/master/accepted/PSR-2-coding-style-guide.md


6
theo PSR-2-> "KHÔNG NÊN" có nghĩa là "KHÔNG GIỚI THIỆU" không bị cấm Điều đó có nghĩa là trong một số trường hợp có thể được chấp nhận. PSR Doc -> ietf.org/rfc/rfc2119.txt
ahmed

14

Tôi đã mạnh mẽ chống lại tiền tố các phương thức riêng tư / được bảo vệ bằng dấu gạch dưới vì bạn có thể sử dụng từ khóa riêng tư / được bảo vệ cho điều đó và IDE sẽ đánh dấu nó cho bạn.

Và tôi vẫn vậy, nhưng, tôi đã tìm thấy một lý do tại sao nó có thể là một thực hành tốt. Hãy tưởng tượng rằng bạn có phương thức công khai addFoo()và bên trong phương thức đó bạn có một phần nhiệm vụ chung với các phương thức khác addFooWhenBar(), addFooWhenBaz()... Bây giờ, tên tốt nhất cho phương thức phổ biến đó sẽ là addFoo(), nhưng nó đã được sử dụng, vì vậy bạn phải đưa ra một số Tên xấu như addFooInternal()hoặc addFooCommon()hoặc ... nhưng _addFoo()phương thức riêng tư trông giống như tốt nhất.


Vâng, đồng ý. Tôi thực sự đã đến đây để xem những gì người khác nghĩ về dấu gạch dưới vì tôi hiếm khi sử dụng chúng và nó luôn cảm thấy sai, nhưng ví dụ này là một lần tôi có. Tôi cũng đã sử dụng chúng cho một số trường hợp mẫu phương thức mẫu trong đó phương thức công khai gọi các phương thức được bảo vệ trừu tượng mà trẻ em đã ghi đè, đó là một ý tưởng tương tự. Đôi khi một phương thức công khai và một phương thức được bảo vệ trừu tượng mà nó gọi là rất giống nhau hoặc có liên quan đến mức việc đặt tên chúng khác nhau có vẻ lạ hơn là chỉ đặt tiền tố _ cho phương thức trừu tượng.
John Pancoast

12

Dấu gạch dưới hàng đầu thường được sử dụng cho các thuộc tính và phương thức riêng . Không phải là một kỹ thuật mà tôi thường sử dụng, nhưng vẫn phổ biến trong một số lập trình viên.


10

Tôi sử dụng một dấu gạch dưới hàng đầu trong lớp PHP 5 tôi viết cho các phương thức riêng tư. Đó là một gợi ý trực quan nhỏ cho nhà phát triển rằng một thành viên lớp cụ thể là riêng tư. Loại gợi ý này không hữu ích khi sử dụng IDE phân biệt các thành viên công cộng và riêng tư cho bạn. Tôi nhặt nó từ những ngày C # của tôi. Thói quen cũ ...


5

Tôi tin rằng giả định ban đầu của bạn là chính xác, tôi đã thấy đó là thông lệ chung đối với một số ngôn ngữ để thêm tiền tố vào các phương thức / thành viên, v.v. có nghĩa là được giữ riêng tư cho "đối tượng". Chỉ là một cách trực quan để nói mặc dù bạn có thể, bạn không nên gọi đây!


5

Tôi đang tìm kiếm cùng một câu trả lời, tôi đã thực hiện một số nghiên cứu và tôi vừa phát hiện ra rằng các khung php đề xuất các phong cách khác nhau:

Mã đánh lửa

Hướng dẫn chính thức có phần kiểu mã hóa khuyến khích thực hành này :

Phương thức riêng và biến

Các phương thức và biến chỉ được truy cập nội bộ, chẳng hạn như các hàm tiện ích và trợ giúp mà các phương thức công khai của bạn sử dụng để trừu tượng mã, nên được thêm tiền tố vào dấu gạch dưới.

public function convert_text()

private function _convert_text()

Các khung khác làm tương tự, như

Bánh kem:

làm như vậy :

Tầm nhìn của thành viên

Sử dụng các từ khóa riêng tư và được bảo vệ của PHP5 cho các phương thức và biến. Ngoài ra, tên phương thức hoặc tên biến không công khai bắt đầu bằng một dấu gạch dưới (_). Thí dụ:

class A
{
    protected $_iAmAProtectedVariable;

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

    private $_iAmAPrivateVariable;

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

Và cũng

làm như vậy :

Các thành viên lớp tư nhân được đi trước bởi một dấu gạch dưới duy nhất. Ví dụ:

$_status    _sort()     _initTree()

Trong khi

Drupal

kiểu mã đặc biệt cảnh báo chống lại điều này :

  1. Các thuộc tính và phương thức được bảo vệ hoặc riêng tư không nên sử dụng tiền tố gạch dưới.

Bản giao hưởng

mặt khác, tuyên bố :

Symfony tuân theo các tiêu chuẩn được xác định trong các tài liệu PSR-0, PSR-1, PSR-2 và PSR-4.


Câu trả lời rất kỹ lưỡng.
chấm

4

Tôi biết nó từ python, trong đó tiền tố các biến của bạn có dấu gạch dưới khiến trình biên dịch dịch một số chuỗi chữ cái và số ngẫu nhiên trước tên biến thực tế. Điều này có nghĩa là mọi nỗ lực truy cập biến từ bên ngoài lớp sẽ dẫn đến lỗi "biến không xác định".

Tôi không biết nếu đây vẫn là quy ước để sử dụng trong python, mặc dù


3

Trong Drupal (một php CMS), dấu gạch dưới có thể được sử dụng để ngăn các hook được gọi ( https://api.drupal.org/api/drupal/includes!module.inc/group/hooks/7 ).

Nếu tôi có một mô-đun gọi là "my_module" và muốn đặt tên cho hàm my_module_insert thì nó sẽ "hook" trên hàm hook_insert. Để ngăn chặn điều đó tôi có thể đổi tên hàm của mình thành _my_module_insert.

ps Cách hook hoạt động trong Drupal có thể thực hiện một hook do nhầm lẫn, điều này rất tệ.


1
Tôi đã coi đó là một lỗ hổng thiết kế của drupal trong một thời gian. Sẽ có ý nghĩa hơn khi đăng ký rõ ràng móc của bạn để tránh nhầm lẫn và hoạt động thất thường. Giả định nói chung là một điều xấu, và các cấu trúc can thiệp vào lập trình bình thường hoặc chiếm quyền điều khiển chúng thường là kiến ​​trúc kém.
mopsyd

3

Drupal và sử dụng dấu gạch dưới:

Nói chung, dấu gạch dưới là đơn giản để đánh dấu thực tế là một hàm có thể chỉ được gọi bởi một hàm cha có liên quan ...

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>';
}

Tất nhiên, chỉ là một ví dụ đơn giản ...


0

Sử dụng dấu gạch dưới chỉ để ghi nhớ mục đích mà chúng ta sẽ không 'sửa đổi biến' / 'gọi hàm' bên ngoài lớp.

Khi chúng ta khai báo các biến const trong tất cả các chữ hoa để trong khi nhìn thấy tên của biến có thể đoán rằng đó là một biến const. Tương tự như biến mà chúng tôi không muốn sửa đổi bên ngoài lớp, chúng tôi khai báo nó với dấu gạch dưới cho quy ước riêng của chúng tôi.


"Biến const" nghĩa là gì? Làm thế nào bạn có thể định nghĩa một hằng số là biến?
Nico Haase

-21

Chúng được gọi là "phương pháp ma thuật" .


39
_foo()với một dấu gạch dưới hàng đầu duy nhất không phải là một phương pháp kỳ diệu. Phương pháp ma thuật được biểu thị bằng hai dấu gạch dưới hàng đầu liên tiếp. Câu hỏi ở đây chỉ nói về một.
BoltClock
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.