工作中的 PHP 编码标准:疯了,还是我疯了?

发布于 2024-09-24 06:40:40 字数 1499 浏览 4 评论 0原文

我更喜欢合乎逻辑的编码标准。这就是我对为什么以下一组标准不是这样的论点。

我需要知道以下两件事之一:(1) 为什么我错了,或者 (2) 如何说服我的团队进行更改


camelCase:函数、类名、方法和变量必须采用驼峰命名法。

  • 难以区分变量和类 与
  • PHP 的小写/下划线变量/函数和大驼峰命名法的类背道而驰

示例:

$customerServiceBillingInstance = new customerServiceBillingInstance(); // theirs
$customer_service_billing_instance = new CustomerServiceBillingInstance();


函数/方法必须始终返回一个值(并且返回值必须始终被存储)。

这出现在我们的数百个 php 页面上:

$equipmentList = new equipmentList();
$success = $equipmentList->loadFromDatabase(true, '');
$success = $equipmentList->setCustomerList();
$success = $equipmentList->setServerList();
$success = $equipmentList->setObjectList();
$success = $equipmentList->setOwnerList();
$success = $equipmentList->setAccessList();

返回值很少使用,但总是被存储。它鼓励使用复制和粘贴。


没有静态方法

像下面这样的行在代码库中出现了数千次:

$equipmentList = new equipmentList();
$success = $equipmentList->loadFromDatabase();

我更喜欢:

$equipmentList = equipmentList::load();

有什么理由不使用静态方法或属性?静态方法不负责非特定于实例的逻辑吗?喜欢初始化或填充新实例吗?


除非所有内容都返回一个对象,否则您的代码不是 OOP

有一段代码执行查询,以多种方式检查错误,然后处理结果数组。它被重复(复制+粘贴)多次,所以我把它放在基类中。然后我被告知返回数组不是 OOP。


你如何捍卫这些做法?我真的需要知道。我感觉我正在服用疯狂的药片。

如果你不能为他们辩护,你如何说服顽固的作者他们需要改变?

I prefer coding standards to be logical. This is my argument for why the following set of standards are not.

I need to know one of two things: (1) why I'm wrong, or (2) how to convince my team to change them.

camelCase: Functions, class names, methods, and variables must be camelCase.

  • Makes it hard to differentiate between variables and classes
  • Goes against PHP's lowercase/underscored variables/functions and UpperCamelCase classes

Example:

$customerServiceBillingInstance = new customerServiceBillingInstance(); // theirs
$customer_service_billing_instance = new CustomerServiceBillingInstance();

Functions/methods must always return a value (and returned values must always be stored).

This appears on hundreds of our php pages:

$equipmentList = new equipmentList();
$success = $equipmentList->loadFromDatabase(true, '');
$success = $equipmentList->setCustomerList();
$success = $equipmentList->setServerList();
$success = $equipmentList->setObjectList();
$success = $equipmentList->setOwnerList();
$success = $equipmentList->setAccessList();

The return value is rarely used but always stored. It encourages the use of copy-and-paste.

No static methods

Lines like the following appear thousands of times in the codebase:

$equipmentList = new equipmentList();
$success = $equipmentList->loadFromDatabase();

I would prefer:

$equipmentList = equipmentList::load();

What reason is there to not use static methods or properties? Aren't static methods responsible for non-instance-specific logic? Like initializing or populating a new instance?

Your code is not OOP unless everything returns an object

There's a piece of code that performs a query, checks it several ways for errors, and then processes the resulting array. It is repeated (copied+pasted) several times, so I put it in the base class. Then I was told returning an array is not OOP.

How do you defend these practices? I really do need to know. I feel like I'm taking crazy pills.

If you can't defend them, how do you convince the adamant author they need to be changed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

·深蓝 2024-10-01 06:40:40

我建议尝试列出编码标准的目标,并根据哪些目标最重要、哪些目标不太重要来权衡它们。

PS:我不会说 PHP,因此其中一些参数可能包含明显不正确的 PHP 代码。

驼峰命名法:函数、类名、方法和变量必须采用驼峰命名法。

工作场所的明显原因:以“名义上的信息密度”为代价的“一致性”。

论点:

1)由于“new”关键字后面应该始终跟一个类,那么您可以轻松发现非法实例化,例如:

$value = new functionName();
$value = new local_variable();
$value = new GLOBAL_VARIABLE();

会发出警报,因为“new”后面应该跟一个 TitleCase 名称。

$value = new MyClass(); // correct

依靠 Case 可以很容易地发现这些错误。

3)只能调用函数,不能调用变量。通过依赖 Case 规则,我们可以很容易地发现可疑的函数调用,例如:

$value = $inst->ClassName();
$value = $inst->instance_variable();
$value = $GLOBAL_VARIABLE(); 

3)分配给函数名称和全局变量是一件大事,因为它们通常会导致难以遵循的行为。这就是为什么任何看起来像这样的声明:

$GLOBAL = $value;
$someFunction = $anotherFunction;

都应该受到严格审查。使用案例规则,很容易发现这些潜在的问题线。

虽然确切的大小写规则可能有所不同,但最好对每种不同类型的名称采用不同的大小写规则。

函数/方法必须始终返回一个值(并且返回的值必须始终被存储)。

工作场所的明显原因:显然是出于盲目一致性而诞生的另一条规则。优点是每行不是流程控制的代码(例如循环、条件)都是赋值。

论据:

1)强制分配会产生不必要的长行,这会损害可读性,因为它增加了屏幕上不相关信息的数量。

2)代码稍微慢一些,因为每个函数调用都会涉及两个不必要的操作:值返回和赋值。

更好的约定:

学习函数式编程范例。区分“子程序”和“函数”。子例程通过副作用完成其所有工作,并且不返回值,因此它的返回值永远不需要存储在任何地方(子例程不应返回错误代码;如果确实是这样,则使用异常)必要的)。函数不得有任何副作用,因此必须立即使用其返回值(用于进一步计算或存储在某处)。通过无副作用函数策略,调用函数并忽略其返回值会浪费处理器周期;因此该线可以被移除。

因此,存在三种类型的正确调用:

mySubroutine(arg);            // subroutine, no need to check return value
$v = myFunction(arg);         // return value is stored
if (myFunction(arg)) { ... }  // return value used immediately

例如,您永远不应该这样做:

$v = mySubroutine(arg);  // subroutine should never have a return value!
myFunction(arg);         // there is no point calling side-effect free function and ignoring its return value

并且它们应该发出警告。您甚至可以创建命名规则来区分子例程和函数,从而更容易发现这些错误。

特别禁止拥有同时具有副作用和返回值的“functiroutine”怪物。

没有静态方法

工作场所 明显原因:可能有人在某处读到静态是邪恶的,并且盲目跟随而没有真正对其优缺点进行任何批判性评估

更好的约定:

静态方法应该是无状态的(不修改全局状态)。静态方法应该是函数,而不是子例程,因为测试无副作用函数比测试子例程的副作用更容易。静态方法应该很小(最多~4行)并且应该是独立的(即不应该太深入地调用太多其他静态方法)。大多数静态方法应该存在于Utility类中;值得注意的例外是类工厂。该约定的例外情况是允许的,但应事先进行严格审查。

除非所有内容都返回一个对象,否则您的代码不是 OOP。

Workplace 明显原因:对 OOP 的理解存在缺陷。

论证:

基本数据类型在概念上也是一个对象,即使语言的基本数据类型不是从其 Object 类继承的。

I would suggest trying to list down the goals of your coding standards, and weigh them down depending on which goals is the most important and which goals are less important.

PS: I don't speak PHP, so some of these arguments may contain blatantly incorrect PHP code.

camelCase: Functions, class names, methods, and variables must be camelCase.

Workplace's Apparent Reason: "consistency" at the cost of "information density in name".

Argument:

1) Since 'new' keyword should always be followed by a class, then you can easily spot illegal instantiation, e.g.:

$value = new functionName();
$value = new local_variable();
$value = new GLOBAL_VARIABLE();

would raise an alarm, because 'new' should be followed by a TitleCase name.

$value = new MyClass(); // correct

Relying on Case makes it easy to spot these errors.

3) Only functions can be called, you can never call variables. By relying on Case Rule, then we can easily spot fishy function calls like:

$value = $inst->ClassName();
$value = $inst->instance_variable();
$value = $GLOBAL_VARIABLE(); 

3) Assigning to a function name and global variables is a huge deal, since they often lead to behavior that is difficult to follow. That's why any statement that looks like:

$GLOBAL = $value;
$someFunction = $anotherFunction;

should be heavily scrutinized. Using Case Rule, it is easy to spot these potential problem lines.

While the exact Case Rule may vary, it is a good idea to have different Case Rule for each different type of names.

Functions/methods must always return a value (and returned values must always be stored).

Workplace's Apparent Reason: apparently another rule born out of blind consistency. The advantage is that every line of code that isn't a flow control (e.g. looping, conditionals) is an assignment.

Argument:

1) Mandatory assignment makes unnecessary long lines, which harms readability since it increases the amount of irrelevant information on screen.

2) Code is slightly slower as every function call will involve two unnecessary operation: value return and assignment.

Better Convention:

Learn from functional programming paradigm. Make a distinction between "subroutine" and "functions". A subroutine does all of its works by side-effect and does not return a value, and therefore its return value never need to be stored anywhere (subroutine should not return error code; use exception if it is really necessary). A function must not have any side-effect, and therefore its return value must be used immediately (either for further calculations or stored somewhere). By having side-effect free function policy, it is a waste of processor cycle to call a function and ignoring its return value; and the line can therefore be removed.

So, there is three type of correct calls:

mySubroutine(arg);            // subroutine, no need to check return value
$v = myFunction(arg);         // return value is stored
if (myFunction(arg)) { ... }  // return value used immediately

you should never have, for example:

$v = mySubroutine(arg);  // subroutine should never have a return value!
myFunction(arg);         // there is no point calling side-effect free function and ignoring its return value

and they should raise warning. You can even create a naming rule to differentiate between subroutine and functions to make it even easier to spot these errors.

Specifically disallow having a "functiroutine" monster that have both a side-effect and return value.

No static methods

Workplace Apparent Reason: probably someone read somewhere that static is evil, and followed blindly without really doing any critical evaluation of its advantages and disadvantages

Better Convention:

Static methods should be stateless (no modifying global state). Static methods should be a function, not subroutine since it is easier to test a side-effect-free function than to test the side-effects of a subroutine. Static method should be small (~4 lines max) and should be self-contained (i.e. should not call too many other static methods too deeply). Most static methods should live in the Utility class; notable exceptions to this is Class Factories. Exceptions to this convention is allowed, but should be heavily scrutinized beforehand.

Your code is not OOP unless everything returns an object

Workplace Apparent Reason: flawed understanding of what is OOP.

Argument:

Fundamental datatypes is conceptually also an object even if a language's fundamental datatype doesn't inherit from their Object class.

做个少女永远怀春 2024-10-01 06:40:40

如果你不能保护他们,你怎么办?
说服他们需要的坚定作者
要改变吗?

通过给出强有力/有效的论据!不过我认为只有当你的论点非常有力时你才应该改变它们!因为大多数工作中的程序员都习惯了这些编码标准,这是使用它们的一个重要原因。

==

就像其他人之前所说的那样,这是相当主观的,但这些是我的意见/论点。

1.驼峰命名法:函数、类名、方法和变量必须采用驼峰命名法。

如果我用 PHP 编写代码,我会使用 PHP 风格;如果我用 Java 编码,我会使用 Camelcase 风格。但只要保持一致,选择哪种风格并不重要。

2.函数/方法必须始终返回一个值(并且返回的值必须始终被存储)。

在我看来这是无稽之谈。在几乎所有编程语言中,都有某种“void”类型。但从测试的角度来看,大多数时候,如果您的函数没有副作用,那么它是有用的。我不同意您的生产代码应该始终使用返回值,特别是如果它没有任何用处。

3.没有静态方法

我建议您阅读静态方法是可测试性的死亡来自misko

在实例化期间,我连接了
与模拟/友谊的依赖关系
它取代了真正的依赖项。
通过过程化编程,有
没有什么可以“接线”的,因为没有
对象,代码和数据是
分开。

尽管 PHP 是一种动态语言,所以这并不是一个大问题。最新的 PHP 仍然支持输入,所以我仍然认为大多数时候静态方法是不好的。

4.你的代码不是 OOP,除非一切都返回一个对象

我相信(不是 100% 确定)真正的 OOP 语言应该这样做(返回一个对象),但我不同意这一点,就像类似的语言一样例如 Java(我认为它不是真正的 OOP)。很多时候你的方法应该只返回像 String/Int/Array/etc 这样的基元。当您复制和粘贴大量代码时,这应该表明您的设计并不完全正确。您应该重构它(但首先准备好测试(TDD),这样就不会破坏任何代码)。

If you can't defend them, how do you
convince the adamant author they need
to be changed?

By giving strong/valid arguments! Still I think you should only change them when your arguments are really strong! Because most of the programmers at work are used to these coding standards which is a big point why to use them.

==

Like others told before this is pretty subjective, but these are mine opinions/arguments.

1. camelCase: Functions, class names, methods, and variables must be camelCase.

I would use the PHP style if I code in PHP and the Camelcase style if I code in Java. But it does not matter which style you choose as long as you stay consistent.

2. Functions/methods must always return a value (and returned values must always be stored).

This is nonsense in my opinion. In almost all programming languages you have some sort of 'void' type. But from a testing point of view most of the times it is useful if your function are side effect free. I don't agree that your production code should always use the return value especially if it does not have any use.

3. No static methods

I would advice you to read static methods are death to testability from misko

During the instantiation I wire the
dependencies with mocks/friendlies
which replace the real dependencies.
With procedural programing there is
nothing to “wire” since there are no
objects, the code and data are
separate.

Although PHP is a dynamic language so it is not really a big problem. Still the latest PHP does support typing so that I still think most of times static methods are bad.

4. Your code is not OOP unless everything returns an object

I believe(not 100% sure) a truly OOP language should do this(return an object), but I don't agree with this like a of like languages like for example Java(which I believe is not trully OOP). A lot of the times your methods should just return primitives like String/Int/Array/etc. When you are copying and pasting a lot of code it should be a sign that something is not totally right with your design. You should refactor it(but first have a tests(TDD) ready so that you don't break any code).

疧_╮線 2024-10-01 06:40:40

其中许多编码标准非常主观,但需要考虑的一些重要事项是:

  1. 获取一组代码命名和样式规则,并遵循它们。如果您还没有定义规则,请确保弄清楚规则。然后重构代码以遵循它们。这是一个重要的步骤,可以让新开发人员更轻松地加入,并保持开发人员之间的编码一致。

  2. 改变公司制定的编码标准需要时间和精力。对规则的任何更改都意味着确实必须再次检查代码以更新所有内容以与新标准保持一致。

牢记上述内容,并更多地关注特定的 PHP 编码标准。首先要考虑的是,如果您的公司使用任何类型的框架,请查看该框架的编码标准,因为您可能希望坚持使用这些标准,以便在所有代码中保持一致。我在下面列出了几个流行的 PHP 框架的链接:

  1. Zend Framework 命名约定Zend Framework 代码样式< /a>
  2. Pear 代码标准

我个人对特定编码风格的偏好:

<强>1。驼峰命名法:函数、类名、方法和变量必须采用驼峰命名法

类名应采用帕斯卡命名法(大驼峰命名法)。

所以在你的例子中:

class CustomerServiceBillingInstance
{
// Your class code here
}

变量函数我通常认为应该是驼峰式大小写。

因此,无论是其中之一,具体取决于您对下划线的偏好:

$customerServiceBillingInstance = whatever;
$customer_service_billing_instance = whatever;

2。函数/方法必须始终返回一个值(并且返回的值必须始终被存储)。

这看起来像是额外的代码,并且您最终可能会使用额外的资源。如果函数不需要返回任何内容,则不要返回任何内容。同样,如果您不关心函数返回什么,则不要存储它。使用额外的内存来存储您永远不会查看的内容是没有意义的。

您可能想尝试的一件有趣的事情是运行一些基准测试。看看是否需要额外的时间来归还某些东西并将其存储起来,即使您没有查看它。

3.除非所有内容都返回一个对象,否则你的代码不是 OOP

在这种情况下,我觉得你必须在某个地方划清界限。就性能而言,执行以下操作比执行

return false;

以下操作更快:

return new Boolean(false); // This would use up unnecessary resources but not add very much to readability or maintainability in my opinion.

捍卫编码标准

为了捍卫您认为正确的编码标准(或说明为什么另一个标准不那么好),您确实是必须提出两点之一。

  1. 性能。如果您可以证明特定的编码标准对性能产生不利影响,您可能需要考虑切换。

  2. 可维护性/可读性。您的代码应该易于阅读/理解。

目标是找到性能和可维护性/可读性之间的最佳中值。有时这是一个简单的决定,因为最可维护的选项也是性能最好的,而有时则需要做出更困难的选择。

Many of these coding standards are very subjective, but some important things to consider are:

  1. Get a single set of code naming and style rules, and follow them. If you don't have already defined rules, make sure to get rules figured out. Then work at refactoring the code to follow them. This is an important step in order to make it easier for new developers to jump on board, and keep the coding consistent among developers.

  2. It takes time and effort to change the coding standards your company puts in place. Any change to the rules means that the code really has to be gone through again to update everything to be consistent with the new standards.

Keeping the above in mind, and looking more along the lines of specific PHP coding standards. The first thing to look at is if your company uses any sort of framework, look at the coding standards for that framework as you may want to stick with those in order to stay consistent across all the code. I have listed links to a couple of the popular PHP frameworks below:

  1. Zend Framework Naming Conventions and Zend Framework Code Style
  2. Pear Code Standards

My personal preference in regards to your specific coding styles:

1. camelCase: Functions, class names, methods, and variables must be camelCase

Class names should be Pascal Case (Upper Camel Case).

So in your example:

class CustomerServiceBillingInstance
{
// Your class code here
}

Variables and functions I generally feel should be camel case.

So either one of these, depending on your preference in terms of underscores:

$customerServiceBillingInstance = whatever;
$customer_service_billing_instance = whatever;

2. Functions/methods must always return a value (and returned values must always be stored).

This one seems like extra code and like you could end up using extra resources. If a function doesn't need to return anything, don't return anything. Likewise, if you do not care about what a function returns, don't store it. There is no point in using the extra memory to store something you are never going to look at.

An interesting thing you may want to try on this one, is running some benchmarks. See if it takes extra time to return something and store it even though you are not looking at it.

3. Your code is not OOP unless everything returns an object

In this instance, I feel you have to draw the line somewhere. Performance wise, it is faster for you to do:

return false;

Than to do:

return new Boolean(false); // This would use up unnecessary resources but not add very much to readability or maintainability in my opinion.

Defending a coding standard

To defend a coding standard that you feel is right (or showing why another is not as good), you really are going to have to bring up one of two points.

  1. Performance. If you can show that a particular coding standard is adversely affecting performance, you may want to consider switching.

  2. Maintainability/Readability. Your code should be easy to read/understand.

The goal is to find the happy median between performance and the maintainability/readability. Sometimes it is an easy decision because the most maintainable option is also the best performing, other times there is a harder choice to be made.

甜警司 2024-10-01 06:40:40

标准和约定的存在有很多原因,但大多数原因都归结为“它们使代码更易于编写和维护”。而不是问“这是做 X 的正确方法吗?”直接切入正题,询问是否满足这个标准。最后一点只是一个定义问题。 OOP是一种手段,而不是目的。

Standards and conventions exist for many reasons, but most of these reasons boil down to "they make code easier to write and maintain." Instead of asking "is this the correct way to do X?" just cut right to the chase and ask if this criterion is met. The last point in particular is simply a matter of definition. OOP is a means, not an end.

三生殊途 2024-10-01 06:40:40

其中许多都是品味问题。你可以整天争论支持或反对驼峰命名法。

然而,存储从未使用过的返回值是错误的。代码没有任何价值。代码没有被执行。您也可以在代码周围添加 $foo = 47 * 3;

任何没有做有用事情的代码都必须被删除。

更大的问题是,如果你为一位无能的经理工作,那么可能是时候跳槽了。

Many of those are matters of taste. You can argue for or against camelCase all day.

However, the storing of return values that are never used is Wrong. There is no value to the code. The code is not executed. You might as well sprinkle $foo = 47 * 3; around the code.

Any code that is not doing something useful must be removed.

The bigger issue is, if you're working for a clueless manager, it may be time to move.

顾冷 2024-10-01 06:40:40

我没有看到其他人评论的一方面是“2.函数/方法必须始终返回一个值(并且返回的值必须始终被存储)”。

如果您不使用异常,则任何可能失败的函数都必须返回一个值。最后一句措辞错误;返回值并不总是需要存储,但总是需要检查。再说一遍,如果您不使用异常,这在当今并不常见,但仍然值得一提。

The one aspect of this that I don't see anybody else commenting on is the "2. Functions/methods must always return a value (and returned values must always be stored)."

If you're not using exceptions, then any function that can fail does have to return a value. The last clause is misworded; return values don't always need to be STORED, but they do always need to be CHECKED. Again, that's IF you're not using exceptions, which isn't common these days, but it's still worth mentioning.

白首有我共你 2024-10-01 06:40:40

据我所知,您发布的许多约定也受到 Zend PHP 框架的鼓励。您并不孤单,我是 Codeigniter 用户,我的工作主要是使用 Zend Framework。这些命名约定绝对是荒谬的,老实说,我只能看到使用驼峰命名法作为变量名称的优点,而不是函数名称,因为它使事情变得混乱。

阅读此内容: http://framework.zend.com/manual/ en/coding-standard.naming-conventions.html

这些编码约定您看起来熟悉吗?

As far as I know quite a few of the conventions you posted are encouraged by the Zend PHP Framework as well. You're not alone, I'm a Codeigniter user and my work is pretty big on using Zend Framework. These kind of naming conventions are absolutely ridiculous and I honestly can only see an advantage of using camelCase for variable names, not function names as it makes things confusing.

Read this: http://framework.zend.com/manual/en/coding-standard.naming-conventions.html

Do these coding conventions look familiar to you?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文