本规范基于 PSR 和实际项目经验整理而成,目前已在公司内部推行使用,特分享如下。
分为编码格式篇和程序设计篇两大部分。
基于 PSR-1、PSR-2、PSR-12 。
<?php
/**
* this is a example class
*/
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use function Vendor\Package\{functionA, functionB, functionC};
use const Vendor\Package\{ConstantA, ConstantB, ConstantC};
class Foo extends Bar implements FooInterface
{
public function sampleFunction(int $a, int $b = null): array
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// method body
}
}
<?php ?>
标签,如果是纯 PHP 代码,则不带结束标签 ?>
;<?php
、declare
、namespace
、use
块必须按照顺序编写,并且后面必须跟一个空行;use
块:类、函数(use function
)、常量(use const
)的 use
需按照此顺序书写,且每个小块之间必须有一空行;$a
、$ddd
这样毫无意义的命名;$list
,$users
更符合上下文,更易于理解和维护;$cls = new MyClass();
无论有无参数,都要加括号;traits
: use traits
:必须放在类左大括号下一行,每个 trait
单独一行,有自己的 use
。use traits block 后面要有一个空行;例:
class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
// constants, properties, methods
}
class ClassName extends ParentClass implements
\ArrayAccess,
\Countable,
\Serializable
{
// constants, properties, methods
}
class ClassName
{
use FirstTrait;
use SecondTrait;
use ThirdTrait;
}
class Talker
{
use A, B, C {
B::smallTalk insteadof A;
A::bigTalk insteadof C;
C::mediumTalk as FooBar;
}
}
ORDER_TYPE
;$order
;var
修饰属性;submitOrder
;例:
class ClassName
{
private $name =‘lisi‘;
public function aVeryLongMethodName(
ClassTypeHint $arg1,
&$arg2,
array $arg3 = []
) {
// 方法的内容
}
}
abstract
或 final
声明时,必须写在访问修饰符前;static
必须写在其后;例:
abstract class ClassName
{
protected static $foo;
abstract protected function zim();
final public static function bar()
{
// method body
}
}
例:
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);
$foo->bar(
$longArgument,
$longerArgument,
$muchLongerArgument
);
elseif
代替 else if
;switch
: case
语句 必须 相对 switch
进行一次缩进,而 break
语句以及 case
内的其它语句都 必须 相对 case
进行一次缩进;例:
if ($expr1) {
// if body
} elseif ($expr2) {
// elseif body
} else {
// else body;
}
if (
$expr1
&& $expr2
) {
// if body
} elseif (
$expr3
&& $expr4
) {
// elseif body
}
switch ($expr) {
case 0:
echo ‘First case, with a break‘;
break;
case 1:
echo ‘Second case, which falls through‘;
// no break
case 2:
case 3:
case 4:
echo ‘Third case, return instead of break‘;
return;
default:
echo ‘Default case‘;
break;
}
while ($expr) {
// structure body
}
for ($i = 0; $i < 10; $i++) {
// for body
}
foreach ($iterable as $key => $value) {
// foreach body
}
try {
// try body
} catch (FirstExceptionType $e) {
// catch body
} catch (OtherExceptionType $e) {
// catch body
}
}
后面不可跟注释或其它语句;例:
class Foo extends Bar implements FooInterface
{
public function sampleFunction($a, $b = null)
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
}
!
后面不可有空格;例:
if ($a === $b) {
$foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
$variable = $foo ? ‘foo‘ : ‘bar‘;
}
function
后以及关键词 use
的前后都必须要有一个空格;例:
$closureWithArgs = function ($arg1, $arg2) {
// body
};
$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
// body
};
$noArgs_longVars = function () use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$longArgs_longVars = function (
$longArgument,
$longerArgument,
$muchLongerArgument
) use (
$longVar1,
$longerVar2,
$muchLongerVar3
) {
// body
};
$foo->bar(
$arg1,
function ($arg2) use ($var1) {
// body
},
$arg3
);
// 如果用户存在
if ($user) {
// do something...
}
注:本规范没有考虑历史项目现状,历史项目可能在某些地方并不符合,可根据实际情况决定是否遵守。
*
查询数据库字段,应当明确字段;last_update_time
这样的字段必须设置 on update current_timestamp
保证更新性;Controller
中写 Action,即基类 Controller
不能对外提供 API(否则任何子类都拥有该 API,后面无法知道外界实际上到底访问了哪些控制器的该 API);$login->verify($username, $password);
多参数传参,具有自解释性;$login->verify(LoginDTO $loginDTO);
因为对象具有明确的定义,也具有解释性;$login->verify($params);
谁都不知道这个 $params 里面到底有什么;$login->verify($request->params())
,直接将浏览器输入一股脑全部丢进去,你让后人如何维护?原文:https://www.cnblogs.com/linvanda/p/12779370.html