繁体   English   中英

我什么时候应该在 PHP 命名中使用驼峰命名法/驼峰命名法或下划线?

[英]When should I use camelCase / Camel Case or underscores in PHP naming?

我一直在学习 PHP,发现人们命名东西的方式有很多变化。 我渴望至少与自己保持一致。

我应该在哪里使用 Camel Case 以及我应该在哪里使用下划线?

想法:

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

  • 类: MyCustomClassmyCustomClass

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

任何想法表示赞赏。

来自 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()
    {

    }
}

许多人有许多不同的偏好,而且在大多数情况下,他们往往就是偏好。 除了人们习惯或流行之外,很少有任何理由说明为什么普通人更喜欢特定风格。 不幸的是,当涉及到更实际的问题时,这往往不会让您知道为什么要使用任何特定的约定。

许多人依赖 PSR,这减轻了必须建立约定的任务。 在任何开发团队中都应该建立约定以简化一致性。 与自己做相比,PSR 可以节省一些时间。 虽然这是一个有用的开始,但您不应该觉得 PSR 建议是权威的。 最终取决于您如何编写 PHP,但如果您是从头开始,您应该首先调查其他人是如何编写的。 这并不意味着你必须以同样的方式去做,但这是一个开始。

PSR 有一定的局限性:

  1. 它是由共识而不是任何特定科学建立的,这意味着它往往是不一致的。
  2. 它并不完全彻底。 您最终会发现它没有指定任何选项的情况。
  3. 它最初的目的是提高框架之间的兼容性,但现在包括了品味问题而不是兼容性问题。 在很多情况下,您使用的约定对兼容性的影响与袜子的颜色对适合您的脚的影响一样大。
  4. 对于许多(如果不是大多数)项目来说,框架之间的兼容性往往很少或不重要。 特别是对于闭源商业项目。
  5. 它们纯粹是来自非官方第三方的建议。 有人可能更喜欢逆时针搅拌咖啡,并通过互联网推荐,但实际上,您搅拌的方向取决于您或您所在的团队。 星巴克、Nero 和 Costa 可能会发布联合声明,建议您顺时针搅拌,但如果您不想听,则不需要听他们的。

撇开这一点不谈,骆驼案例(骆驼)和蛇案例(蛇)之间存在一些语义和实际差异。

直接的区别是骆驼使用较少的字符来分隔单词; 它更紧凑。 如果您将对象转换为 JSON,然后将其压缩以发送到浏览器,则情况可能并非总是如此。 尽管在大多数情况下差异可以忽略不计,但骆驼在某些情况下会或多或少地有效压缩。 您可能不必担心这一点。 一般来说,两者之间存在非常微不足道的性能差异。

从人的角度和程序的角度来看,紧凑性是有代价的。 分离和使用术语可能会更加困难。 在再次压缩文件之前,我们先解压缩文件以处理它们是有原因的,尽管这里适用的相同原则更微妙,但压缩更难。 从某种意义上说,它也是有损的,即分隔符会改变字符。 这很不方便,因为它并不总是适用于第一个字符。 您不能简单地按情况拆分和加入。 一个重要的原因是动态访问或元编码,其中属性和方法可以自动确定,例如通过组合一组令牌。

如果我创建了一个生成器,它会自动创建对象来表示数据库中的表并充当存储库,那么我可能会在该类上生成方法,以便能够按每列获取。 我可以查看get_by_username|get_by_emailgetByUsername|getByEmail

如果我有(get_by|getBy)($field, $value)那么我将传递该字段的用户名或电子邮件,这些是原始表单。 在这种情况下,我必须在创建类时首先ucfirst每个字段。 更进一步,如果我通过__call动态提供这些怎么办? 在这种情况下,每次我需要至少使用lcfirst转换骆驼时,在使用蛇盒时,我所要做的就是将它固定在字符串的末尾,它一对一地映射而无需转换或担心它是否在结束或开始。 考虑将两个字段(例如操作和字段)映射到类成员:

  • lcfirst 如果追加或大写,按大小写拆分,将 lcfirst 映射到第二个
  • 拆分,如果附加到其余部分,则将 ucfirst 映射到全部,然后连接

对比:

  • 分裂
  • 加入

默认情况下,Snake 以原始形式保留标记,如果不是,则单独转换容易分离的单词往往会更容易。

在 PHP 中使用元编码来充分利用它是很常见的,这将包括大量基于字符串的运行时多态性。 您很可能最终会遇到这样一种情况,在这种情况下,您会发现使用蛇比使用骆驼更有利,因为您希望动态编码。

如果 CamelCase 真的那么棒,那么每个人都会回答像这样的 StackOverFlow 编程问题。 As You Can See For Anything But The Shortest PhrasesShortFormQuicklyBecomesTire. 您通常可以在编程中以小剂量和在白色空间中摆脱它。 骆驼案例的另一个烦恼是当你有缩写词或单字母词时。 它不是很好。

从语义上讲,人们也倾向于使用蛇来命名空间,而不是将它与短语一起使用。 相反,camel 往往用于按顺序或作为标题用简单英语阅读的小短语或句子。 这在 OOP 中尤为常见,其中类名往往提供第一个也是最常用的分类层,如今越来越多地允许嵌套命名空间(在 PHP 中完全支持)。 如果您正在做一些分类的事情,即按顺序组合来自不同类别的集合中的单词,而不是组合英语中的单词来创建短语,那么约定是使用蛇。 在这种情况下,您更有可能发现自己在进行元编码。

例如database_statement_row_read_next()不完全是一个有效或典型的英语短语。 其中最后的Database\\Statement::readNextRow成为有效且标准的英语表达式。

虽然英语更舒服和熟悉,但也有一些问题。 事情并不总是以相同的顺序或以相同的方式表达(这是不一致的),这再次可能使元编码变得更加尴尬,因为元编码很自然地处理单词集并将它们组合起来,而不必担心有时需要两个而不是一个词,顺序或词,短语的轮换等。

如果你根据经验将名字写成简单英语的片段,你应该主要使用骆驼,因为这是绝大多数使用的约定。 如果您不严格关心单词的顺序与它们应该在英语中的顺序相匹配,但确实关心分类和组织,那么显式分隔符往往是标准。

他们没有告诉你关于骆驼的一点是,按照惯例,你几乎总是希望在编写它的同时还要遵守英语语法规则,这些规则并不总是像在偶尔的情况下那样锻炼和分类命名。

更正确的术语是:

  • 下划线分隔 = alpha_beta
  • 大小写分隔 = alphaBeta
  • 大写字母分隔 = AlphaBeta

在最后一种情况下,第一个大写字母没有分隔。

在编程世界中,一般使用大小写分隔(大写和非大写的混合)往往是 OOP 的标准。 一般来说,您通常最终也会更加一致地坚持 PHP 中的内容,尤其是对于任何与 OOP 相关的名称(例如方法)。

相反,对于过程变量、函数变量和局部变量,流行语言中使用蛇的趋势相当强烈。

无论你选择什么,都尽量保持一致,如果有差异,你应该有理由和约定。 如果您将两者混合,那么您可能会将一个放在立面后面。 Camel 倾向于供人类消费,并被视为有效的英语,而如果需要元编码,蛇可能是你可以嵌套在外观后面的东西。

专门为您的建议:

变量/属性:

  • userid将变得难以阅读,并且最终还会创建其他单词。 也无法将其转换为另一种标准格式。
  • user_id
  • userId
  • userID不好。 它将转换为 user_i_d 而不是 user_id。

课程:

  • MyCustomClass是一个通用且非常一致的标准,这也很有意义,因为类名是标题并且应该大写。
  • myCustomClass可能会让他们看起来像某人在他们想要放置类名时放置了一个方法。

功能/方法:

  • my_custom_function这是最简单的事情,可以(在合理范围内)工作,尽管不遵守英语语法的约定,但将英语单词用于命名空间,您可以将其称为function_customfunction_default
  • my_Custom_Function不是可能工作的最简单的东西。 大写是多余的,没有任何意义,它揭示了专用字符分隔的隐藏好处,它可以保留大小写。

有些人可能会被哄骗使用两者来提供一个或多个级别的嵌套。 无论你为此做什么,它最终都会变得丑陋。 它与 CSV 中的 CSV 或二维数组的概念相同。 骆驼和蛇都用于表示单个单词的数组。 如果你想表示两个单词数组,那么你需要一些特殊的东西,比如两个或多个分隔符的组合,其中可能包含一个多字符分隔符。 如果您处于这种情况,很可能是 YAGNI 的情况,因为实际上骆驼或蛇本身几乎总是足够的。 如果您要将它们混合在一起,那么这应该是一种不仅仅是肤浅的、记录在案的或显而易见的策略的一部分。

一个相关的例子可能是get_by_username|get_by_email案例。 我可能会决定始终使用[$operation, $field] 操作和字段可能都需要用一个以上的词来描述。 这可能会导致使用骆驼进行现场和操作,但使用蛇来分离现场和操作。 这将给出例如getBy_usernamedeleteBy_usernamegetBy_firstName 它并不漂亮,但可能会被认为是出于实际目的。 以蛇开始提供命名空间然后以骆驼结束也有些常见,这本质上是您使用 OOP 命名空间、类和方法所得到的。 如果有充分的理由,将事情混在一起并没有错,但更多情况下,像这样的风格混合往往是一种糟糕的代码气味,导致您进入未冲水的马桶。

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

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

  • Zend不允许使用下划线
  • Symfony也鼓励使用驼峰命名法
  • Wordpress鼓励下划线,不喜欢驼峰式大小写
  • CodeIgniter还提倡下划线

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

但是对于 PHP 开发人员的基本命名约定,我发现它可以使用。

对于变量

我们可以使用小写下划线。 喜欢

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

(大多数 php 开发人员和 L​​V 等框架都使用这个。wordpress 也使用这个命名约定来声明变量。)

对于常量

我们可以使用 ALL CAPS 案例。 喜欢

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

(大多数 php 开发人员和框架以及 CMS 使用这种命名约定来声明 php 常量。)

对于班级名称

我们可以使用帕斯卡案例。 喜欢

class UserDetails {
    // 
}

(像 LV 这样的 PHP 框架使用这个约定,许多 php 开发人员使用这个命名约定。)

对于函数和类方法名称

我们可以使用骆驼情况。 喜欢

function getName() {
    // Do something
}

(像 LV 这样的 PHP 框架使用这个约定,许多 php 开发人员使用这个命名约定。)

注意:但 wordpress 遵循小写 under_score 来声明函数。

function get_name() {
    // Do something
}

您可以在此处获得更多详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM