V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lml12377
V2EX  ›  程序员

想问问各位的 PHP 命名习惯

  •  
  •   lml12377 · 2016-09-28 14:17:46 +08:00 · 2883 次点击
    这是一个创建于 2969 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如最简单的创建对象, new UserModel(),变量名可能会是:

    • $userModel
    • $userModelObj / $userModelObject
    • $userModelInstance

    本人一般是第三种,但是这样有时候变量名会变得很长。。。

    类似的喜欢在复数后面加类型,比如 ItemCollection 里面有 Item 对象的数组 private 属性,一般我会这样写:

    private $_itemInstanceArray = [];
    private $_itemInstanceArr = [];
    

    但是很多人其实会这样:

    private $_items = [];
    

    还有一种比较小众的(可能并不是那么小众):

    private $_itemList = [];
    

    复数的写法在遇到去 y 加 ies 的时候很别扭(还有复数和单数一样的),另外 items 也不好一眼看出变量类型以及里面装的内容的类型。

    另外,引申一个,文件夹的命名,比如最常见的 assets ,里面的文件夹很可能会是这样: images / css / js ,为啥这个 image 复数了其它都是单数,个人觉得命名这东西贵在统一,但是 js 改成 scripts , css 却不好改。。。干脆都改成单数?

    类似的文件夹还有:

    Controllers / Services / Models / Views / configs
    Controller / Service / Model / View / config
    

    见过一些生产的项目,真实情况往往是这样:

    Controller / Service / Models / Views / config
    

    又是个值得纠结的问题。。。不知道大家都是怎么命名的?

    第 1 条附言  ·  2016-09-28 15:01:47 +08:00

    其实我觉得之所以一直不想抛弃 $itemArray 这种写法,还是因为 php 要向下兼容,大概只敢做到方法参数限定类型 / 返回值限定类型,虽说参数限定了类型,private + setter 可以保证属性的类型,但是:

    private array $items;
    

    private $items;
    

    明显直观性是不一样的。。。

    比如 isAllowOverride / allowOverride 属性,看名字基本知道是个 bool 值(除非故意抬杠。。。)

    但是遇到意义不是那么明确的又没有设置默认值:

    private $something;
    

    那只能通过赋值的语句才能知道它的类型(或者说是才能确定类型)。。。

    24 条回复    2016-09-28 19:54:04 +08:00
    klgd
        1
    klgd  
       2016-09-28 14:20:47 +08:00   ❤️ 1
    尽可能向 psr 规范靠拢,但是变量的命名 psr 也没给建议,所以根据个人喜好来吧
    lml12377
        2
    lml12377  
    OP
       2016-09-28 14:22:31 +08:00
    @klgd 是的, psr 也是各个作者提供的,感觉各个标准草稿之间在质量上也存在明显的差异。。。
    kideny
        3
    kideny  
       2016-09-28 14:27:29 +08:00   ❤️ 1
    有 PSR 规范的,请遵守行规,并力所能及的推广。
    xss
        4
    xss  
       2016-09-28 14:28:01 +08:00   ❤️ 1
    我一直觉得,只要命名规范整个项目统一就行, 见名知意就行.没必要纠结什么规范不规范的.
    young
        5
    young  
       2016-09-28 14:28:42 +08:00   ❤️ 1
    有 PSR 规范的,请遵守行规,并力所能及的推广。
    +1
    youngyezi
        6
    youngyezi  
       2016-09-28 14:33:43 +08:00   ❤️ 1
    基本都是按照 PSR 规范走
    1. 文件夹复数, model 单数, table_name 复数
    3. private 不加下滑
    4. users = new User();
    halfcoder
        7
    halfcoder  
       2016-09-28 14:35:46 +08:00   ❤️ 1
    复数写法还好吧,主要是这样比较靠近自然语言。既然是复数就表明这个变量至少是一个集合,其单数形式就是数据类型, Item 类数组就是 items , Course 类列表就是 courses 。

    image/css/js 可以对应的复数形式命名可以是 images/stylesheets/scripts

    不过文件夹命名我倾向于单数,尤其是这个文件夹和命名空间名称有关的时候
    feiyuanqiu
        8
    feiyuanqiu  
       2016-09-28 14:40:58 +08:00   ❤️ 1
    变量名长度跟它的作用域范围成正比

    在变量中带上类型是匈牙利命名法,但其实现在不怎么推荐这种命名法了,现代的 IDE 以及 php 逐渐完善的类型系统已经足够好了,带上类型只会显得很啰嗦

    你的第一个例子,我更愿意用 $user = new UserModel()
    数组类型的变量,用数组项名称的复数, $user => $users ,遍历的时候就很自然地 foreach($users as $user) {}

    命名空间的命名方式,根据你组织代码的方式不同而不同,一般是把领域逻辑相互关联的类放到一个包里面,保证包的内聚,比如 auth 下面会放权限验证逻辑相关的类 credentials , signature , authentication ...
    复数形式的一般是按照文件的类型来组织的,比如 Service 类都放在 Services 下面, Controller 都放在 Controllers , lumen 的 app 目录看起来就是这样的
    lml12377
        9
    lml12377  
    OP
       2016-09-28 14:51:10 +08:00
    @feiyuanqiu $user = new UserModel(),假设极端情况, UserService 和 UserModel 在同一段逻辑里出现了(比如在 Controller 里),那也不太好区分啊。。。
    pubby
        10
    pubby  
       2016-09-28 14:59:29 +08:00   ❤️ 1
    @lml12377 有歧义就 $userModule $userService
    feiyuanqiu
        11
    feiyuanqiu  
       2016-09-28 15:02:16 +08:00   ❤️ 1
    @lml12377
    用 user 作为 UserModel 实例的变量名,是因为 UserModel 代表用户实体, user 可以很清晰地表达这个意思
    但 UserService 使用 user 的话,就会让人迷惑,最好直接用 $userService ,在作用域里没有其他 service 存在的情况下我宁愿用 service ,也肯定不会用 $user
    Balthild
        12
    Balthild  
       2016-09-28 15:07:37 +08:00 via iPhone   ❤️ 1
    Model 类不加 Model ,直接用 User ,那变量就是 $user.
    UserController 不用自己实例化,不考虑
    作为服务,我更愿意用 AuthService
    Balthild
        13
    Balthild  
       2016-09-28 15:09:13 +08:00 via iPhone   ❤️ 1
    至于静态文件,可以用这两套:
    img/css/js
    images/styles/scripts
    统一用简称或者全称,不要混用
    V2Simon
        14
    V2Simon  
       2016-09-28 15:09:37 +08:00   ❤️ 1
    请直接遵循 PSR
    feiyuanqiu
        15
    feiyuanqiu  
       2016-09-28 15:16:40 +08:00   ❤️ 1
    针对你附注的内容,请尽量引导你的团队使用 IDE , php 现在的类型系统确实还不完善,但还是有解决的办法的...

    /**
    * 消息通知器
    *
    * @var Notifier
    */
    private $notifier;

    /**
    * 最大内存占用(MB)
    *
    * @var int
    */
    private $memoryLimits;

    /**
    * 程序休眠策略
    *
    * @var SleepingPolicy
    */
    private $sleepingPolicy;
    lml12377
        16
    lml12377  
    OP
       2016-09-28 15:23:07 +08:00
    @feiyuanqiu 好的,谢谢!
    lml12377
        17
    lml12377  
    OP
       2016-09-28 15:26:16 +08:00
    @halfcoder 我文件夹全是单数,可能我看问题的点比较奇怪:文件夹肯定是归类文件的,那里面肯定是 1+ 个文件,单独一个文件占用一个文件夹也存在,但我们建文件夹的初衷大多是存放多个文件的,那加 s 对文件夹来说感觉并没有多大意义、、、
    mooncakejs
        18
    mooncakejs  
       2016-09-28 15:35:34 +08:00   ❤️ 1
    尽可能向你的主框架靠拢,比如 laravel 项目尽量用复数形式
    lml12377
        19
    lml12377  
    OP
       2016-09-28 15:46:59 +08:00
    @feiyuanqiu 还有个。。。 Interface 和 Abstract 后缀, java 的抽象类一般是写在前面,比如: AbstractBeanFactory ,而接口直接是原名,比如: AliasRegistry ,但实现就比较奇怪了,比如 SimpleAliasRegistry ,有的是 Default 前缀。

    而 psr-2 的第一个例子里用的就是 FooInterface ,明显的是 Interface 后缀,但官方的原生接口却没有,比如: Iterator / ArrayAccess / Serializable 等等。

    还有,假如说 java 省略掉 Interface 是因为 IDE 在文件前面有个小标里面是 I 很明显的话,那加 Abstract 前缀就说不过去了,毕竟也是可以区分的( IDEA 是四分之三圆的 C )。

    另外还有很多在抽象类中间类前面加 Common 的,比如 Controller 文件夹中的 CommonController , Model 文件夹中的 CommonModel ,而 app 中的 CommonModel 往往继承自框架中的 ModelBase / Model 等。

    关于这些,有没有什么规范。。。
    aksoft
        20
    aksoft  
       2016-09-28 16:14:27 +08:00   ❤️ 1
    想怎么写怎么写呗。。。项目太大了又该研究 java 的命名的规则了。。
    feiyuanqiu
        21
    feiyuanqiu  
       2016-09-28 17:21:44 +08:00   ❤️ 1
    就像上面楼说的,尽量遵循正在使用的框架的代码风格,一致性很重要

    『 AliasRegistry ,但实现就比较奇怪了,比如 SimpleAliasRegistry 』
    这个没什么奇怪的吧,接口处于类型层次的高层,它是对概念抽象,相应地它的命名就比较泛化,实现在命名上比它的接口更具体是理所当然的

    为什么一般不建议接口名称里加上 Interface 后缀呢,因为啰嗦。『 clean code 』里是这么解释的,『我不想让用户知道我给他们的是接口,我就想让他们知道那是个 ShapeFactory 』
    对接口的使用者而言,他只需要知道使用这个对象能实现他需要的功能就行了,在类型名称上加上 interface 会很多余

    java 的命名跟某个具体的 IDE 的某个功能没有什么特别的关系( PhpStorm 最新版也支持对 interface/class/abstract/trait 用不同的图标展示)

    所以还是建议你找本代码整洁之道看看吧
    yxzblue
        22
    yxzblue  
       2016-09-28 17:53:56 +08:00   ❤️ 1
    去掉习惯,按照 PSR2 走起
    pubby
        23
    pubby  
       2016-09-28 18:00:41 +08:00   ❤️ 1
    代码规范参考 PSR-1 PSR-2 PSR-12(还只是 Draft)

    但是这些都没有规定你一定要
    $userModel
    还是
    $userModelObj / $userModelObject
    还是
    $userModelInstance

    只要某个 scope 内统一就行
    lml12377
        24
    lml12377  
    OP
       2016-09-28 19:54:04 +08:00
    @feiyuanqiu 谢谢耐心解答!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5965 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 02:30 · PVG 10:30 · LAX 18:30 · JFK 21:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.