在PHP命名中,什么情况下应该使用驼峰式命名法(camelCase)或下划线命名法(underscores)?

33

我一直在学习PHP,发现人们对命名方式有很多不同的看法,我希望至少自己能够保持一致。

在哪些地方应该使用驼峰式命名,在哪些地方应该使用下划线命名?

想法:

  • 变量/属性:$userid$user_id$userID

  • 类:MyCustomClassmyCustomClass

  • 函数/方法:my_custom_function()my_Custom_Function()

感谢任何想法。

3个回答

43

来自PSR基本编码规范 (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)

类名必须采用StudlyCaps (即PascalCase)。

类常量必须使用全部大写字母和下划线分隔符声明。

方法名必须采用camelCase

本指南有意避免了对$StudlyCaps、$camelCase或$under_score属性名称的任何推荐

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';

    private $StudlyCapsProp = null;
    protected $camelCaseProp = null;
    public $under_score_prop = null;

    public function fooBar()
    {

    }
}

2
谢谢。同一指南继续说:“本指南有意避免对使用$StudlyCaps、$camelCase或$under_score属性名称做出任何建议”,因此也澄清了属性/变量。 - Linz Darlington
@LinzDarlington 是的,谢谢你提醒我,我会更新答案。 - Accountant م

20
许多人有很多不同的偏好,大多数情况下仅仅是个人喜好。除了人们习惯或它流行之外,一般很少有任何理由来解释为什么普通人更喜欢某种特定风格。不幸的是,这通常不能给你任何有关更实际事项时使用任何特定约定的想法。
许多人依赖 PSR 约定,从而简化了建立约定的任务。在任何开发团队中,都应该建立规范以提高一致性。与自己制定约定相比,PSR 可以节省一些时间。虽然作为一个有用的起点,但不应认为 PSR 的建议是权威的。最终如何编写 PHP 取决于您自己,但如果您从头开始,则应首先调查其他人的做法。这并不意味着您必须以相同的方式进行操作,但这是一个起点。
PSR 有一定的局限性:
  1. 它是通过共识建立的,而不是任何特定的科学原则,这意味着它往往是不一致的。
  2. 它并不完全详尽。您最终会发现某些情况没有指定任何选项。
  3. 最初旨在提高框架之间的兼容性,但现在包括了一些品味问题而不是兼容性。在许多情况下,您使用的约定对兼容性的影响与您袜子的颜色对其适合脚的影响一样大。
  4. 对于许多项目,如果不是大多数项目,框架之间的兼容性往往无关紧要。尤其对于闭源商业项目。
  5. 它们仅仅是来自非官方第三方的建议。某人可能喜欢顺时针搅动咖啡并通过互联网推荐,但实际上你或你所在的团队可以自己决定如何搅拌。星巴克、尼罗和 Costa 可能会发布一份联合声明建议您顺时针搅动,但如果您不想听从他们,您也不需要这么做。
抛开这些局限性之后,驼峰命名法(camel)和下划线命名法(snake)之间有几个语义和实际差异。
直接的区别是驼峰命名法使用一个字符来分隔单词,它更加紧凑。如果将对象转换为 JSON,然后压缩以发送到浏览器,则情况可能并非总是如此。虽然在大多数情况下,两者之间的差异将是可以忽略不计的,但在某些情况下,驼峰命名法将更或更少有效地进行压缩。您不太可能需要担心这个问题。总体而言,在两者之间存在非常微小且无关紧要的性能差异。
紧凑性带来了代价,从人类和程序员的角度来看都是如此。它可能更难分离和处理术语。我们解压文件以便于操作它们再压缩回去有一个原因,尽管这种原理在这里更加微妙,但同样适用,紧凑更难以处理。从某种意义上如果我有 (get_by|getBy)($field, $value),那么 $field 将会是用户名或电子邮件的形式。在创建类时,这些字段都需要使用 ucfirst 进行转换。如果我通过 __call 动态提供这些字段,那么每次都需要将驼峰命名法转换为以小写字母开头的字符串,而使用蛇形命名法则只需将其附加到字符串末尾即可,一一对应且无需进行转换或太过担心它是在字符串的开头还是结尾。例如将两个字段(如操作和字段)映射到一个类成员:
  • 如果是追加,则使用 lcfirst 进行小写字母开头,然后按大小写分割并从第二个开始映射到数组中;
  • 按大小写分割,并将 ucfirst 映射到所有值,否则映射到剩余的值,最后进行连接。

与:

  • 按大小写分割
  • 连接

相比,蛇形命名法默认保留标记的原始形式,而如果不这样做,则通常更容易单独转换已经分离的词语。

在 PHP 中,使用元编程来充分利用它非常常见,这将包括相当数量的基于字符串的运行时多态性。您很可能最终会遇到一种情况,您希望使用蛇形而不是驼峰来动态编码。

如果驼峰命名法真的那么好,每个人都会像这样在 Stack Overflow 上回答编程问题。但是你可以看到,除了最短的短语之外,对于任何东西而言,简写形式很快就会变得令人疲倦。在编程中,由于其量是小剂量且淹没在空格的海洋中,通常可以逃避这种情况。另一个烦恼是当您有缩写或单词缩写语时,它并不总是有效。

从语义上讲,人们也倾向于使用蛇形来命名空间,并且不会与短语使用蛇形。相反,驼峰往往用于按顺序阅读的小短语或句子,或作为标题。这在面向对象编程(OOP)中特别常见,其中类名往往提供第一个和最常需要的分类层,今天越来越允许嵌套命名空间(在 PHP 中完全支持)。如果您正在按类别做某些事情,即组合来自不同类别集的单词而不是组合英语中的单词以创建短语,则约定使用蛇形。在这种情况下,您更可能使用元编程。

例如,database_statement_row_read_next() 不完全是一个有效或典型的英语短语。但是最终 Database\Statement::readNextRow 变成了一个有效和标准的英语表达式。

虽然英语更舒适和熟悉,但它也存在某些问题。事物并不总是以相同的顺序或方式说出来(不一致),这可能使得在元编程方面更加尴尬,因为自然而然地需要处理单词集并将它们组合在一起他们没有告诉你的是,按照惯例,你几乎总是需要遵循英语语法规则来编写camel命名,但在某些情况下不一定适用于分类命名。

更正确的术语应该是:
- 下划线分隔符 = alpha_beta - 大小写分隔符 = alphaBeta - 大小写大写分隔符 = AlphaBeta
最后一种情况中,第一个大写字母不会分隔。
通常情况下,在面向对象编程中,使用大小写混合的大小写分隔符是标准做法。在PHP中,特别是对于任何与OOP相关的名称(如方法),保持一致性通常是更好的选择。
相反,在流程式、函数式和局部变量中,流行语言通常倾向于使用蛇形命名法。
无论你选择什么方式,都应尽可能保持一致,并且对于存在差异的地方,你应该有一个原因和一个约定。如果你混合两种方式,那么你可以把其中一种放在幕后。camel命名通常用于人类阅读,以便作为有效的英语读取,而snake命名如果需要元编码,可以是你可以嵌套在门面后面的东西。
具体针对您的建议:
变量/属性:
- `userid` 将变得难以阅读,而且会创建其他单词。它也不可能转换成另一种标准格式。 - `user_id` 是可以的。 - `userId` 是可以的。 - `userID` 不好。它将转换成 `user_i_d` 而不是 `user_id`。
类:
- `MyCustomClass` 是一种通用而非常一致的标准,因为类名是标题,应该大写。 - `myCustomClass` 可能会让人误认为某人在方法中放置了一个方法,而实际上是一个类名。
函数/方法:
- `my_custom_function` 这是可能的最简单的方法(合理范围内),虽然不遵循英语语法的惯例,但它使用命名空间,你可以将其称为 `function_custom` 或 `function_default`。 - `my_Custom_Function` 不是可能的最简单的方法。前面的大写字母是多余的,并没有任何作用,但它揭示了一个专用字符分隔符的隐藏优点,它可以保留大小写。
有些人可能会被诱导使用两者来提供一个或多个嵌套级别。无论你选择什么,都会变得丑陋。这与CSV中的CSV或二维数组的概念相同。camel和snake都用于表示单个单词的数组。如果您想表示两个单词数组,则需要某些特殊的东西,例如两者的组合或多个分隔符,其中可能包括多字符分隔符。如果您处于这种情况下,实际上很可能是YAGNI的情况,因为在实践中,单独使用camel或snake几乎总是足够的。如果你要混合它们,那么应该是超过表面的策略的一部分,要么记录下来,要么明显。一个相关的例子可能是 get_by_username|get_by_email。我可能会决定始终使用 [$operation, $field]。操作和字段可能需要用多个单词来描述。这可能导致在字段和操作上都使用驼峰命名法,但在字段和操作之间使用蛇形命名法进行分隔。例如,getBy_usernamedeleteBy_usernamegetBy_firstName。虽然不太美观,但可以说是有实际用途的。通常也很常见地以蛇形作为命名空间的开头,然后以驼峰结尾,这基本上就是使用 OOP 命名空间、类和方法所得到的结果。如果有充分的理由混合使用它们也不算错,但经常混用这些风格则往往是糟糕的代码气味,就像让你走进了一个还没冲洗的马桶里。

4

根据我们使用的框架,命名规则可能不同。我们应该遵循开发应用程序所使用的框架遵循的命名约定。

每个框架都遵循不同的命名约定。例如:

  • Zend不允许使用下划线
  • Symfony也鼓励驼峰命名
  • WordPress鼓励使用下划线,不喜欢驼峰命名
  • CodeIgniter也推广下划线

所以:使用您的框架或创建自己的命名约定。

但是对于PHP开发人员的基本命名约定,我发现可以采用以下方式。

对于变量:

我们可以使用小写下划线。例如:

$first_name = "John";
$last_name = "Doe";

大多数PHP开发者和框架(如LV)使用这种命名约定,WordPress也使用这种命名约定声明变量。

对于常量

我们可以使用全大写字母。例如:

define('DB_HOST', 'localhost'); 
define('DB_USER', 'db_user');

大多数PHP开发者、框架和CMS使用这种命名约定来声明PHP常量。

对于类名

我们可以使用帕斯卡命名法。例如:

class UserDetails {
    // 
}

(PHP框架如LV使用此约定,许多PHP开发人员使用此命名约定。)

对于函数和类方法名称:

我们可以使用驼峰式命名法。例如:

function getName() {
    // Do something
}

(像LV这样的PHP框架使用这种规则,许多PHP开发人员也使用这种命名规则。)

注意:但WordPress使用小写下划线来声明函数。

function get_name() {
    // Do something
}

您可以在此处获取更多详情。


我认为每种编程语言都应该使用下划线的原因是,例如对于这个函数名"Yii Instructor",你可以看到yii_instructor(){}yiiInstructor(){}更易读。 - MaXi32
Codeigniter 4已更改为驼峰式命名法 - James John McGuire 'Jahmic'
是的,CodeIgniter 4将命名约定更改为驼峰式。此外,它还进行了许多更改,并引入了许多新功能,如迁移和种子生成器,这些对于开发大型应用程序并进行管理非常有用。 - Syed Imran Ertaza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接