PSR-2:PHP编码规范

本规范继承并扩展自PSR-1,基本编码规范。

本文档中的关键词”必须(MUST)”,”禁止(MUST NOT)”,”必须(REQUIRED)”,”必须(SHALL)”,”禁止(SHALL NOT)”,”SHOULD(应该)”,“不应该(SHOULD NOT)”, “建议(RECOMMENDED)”, “可能(MAY)”和 “可选(OPTIONAL)” 遵循RFC2119约定。

1、概览

  • 代码必须遵守代码规范PSR[PSR-1]。
  • 代码必须使用四个空格缩进,不能使用tabs。
  • 禁止硬性限制行长度;必须限制在120个字符;应该在80个字符以内。
  • namespace声明后必须有一个空行,并且use声明块后必须有一个空行。
  • 类的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。
  • 方法的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。
  • 的属性和方法 必须 添加访问修饰符(privateprotected 以及 public),abstract 以及 final 必须 声明在访问修饰符之前,而 static 必须 声明在访问修饰符之后。
  • 控制结构的关键字后 必须 要有一个空格符,而调用方法或函数时则 一定不可 有。
  • 控制结构的开始花括号({) 必须 写在声明的同一行,而结束花括号(}) 必须 写在主体后自成一行。
  • 控制结构的开始左括号后和结束右括号前,都 禁止 有空格符。

1.1、例子

<?php
namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
{
    public function sampleMethod($a, $b = null)
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

    final public static function bar()
    {
        // method body
    }
}

2、通则

2.1、基础编码规范

代码必须遵循所有PSR-1概述的规范。

2.2、文件

  • 所有PHP文件必须使用Unix LF(换行)作为行结尾。
  • 所有PHP文件必须以一个空行作为结尾。
  • 只包含PHP的文件中必须删除结束标签?>。

2.3、行

  • 行字符长处禁止有硬性限制。
  • 行字符必须在120字符内;自动样式检查必须提醒但禁止抛错。
  • 不应该超过80个字符;超过长度应该分为不超过80个字符的多行。
  • 非空行末禁止有空格。
  • 为了提高可读性以及标识代码块应该添加空行。
  • 每行禁止超过一个声明。

2.4、缩进

  • 代码必须使用4个空格作为缩进,禁止使用tab缩进。

注:仅仅使用空格,而不是空格和tab混合,以帮助避免在对比,补丁,历史和注释问题。使用空格可以使行内对齐更简单。

2.5、关键词和True/False/Null

PHP关键词必须小写。

PHP常量 truefalse和 null 必须小写。

3、namespace和use声明

  • 当遇到时,在 namespace 声明后必须有一个空行。
  • 当遇到时,所有 use 声明必须在 namespace 声明后。
  • 每个声明必须一个 use 关键词。
  •  在 use 代码块后必须有一个空格。
<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...

4、类、属性和方法

此 “class” 泛指所有 classes, interfaces 和 traits。

4.1、Extends 和 Implements

  •  extends 和 implements 关键词必须和class名称在同一行声明。
  • 类的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。
<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}

多个implements应该拆分到多行, 每行添加一个缩进。当这么做时,第一个必须在下一行,并且每个接口必须占一行。

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // constants, properties, methods
}

4.2、属性

  • 所有属性必须声明可见性。
  •  var 关键字禁止用于声明属性。
  • 每个声明禁止超过一个属性。
  • 属性名不应该以一个下划线开头来说明为protected或private可见性。

声明一个属性看起来如下。

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}

4.3、方法

  • 所有方法必须声明可见性。
  • 方法名不应该使用单个下划线来说明为protected或private可见性。
  • 方法名后禁止有空格。方法的开始花括号({) 必须 写在函数声明后自成一行,结束花括号(})也 必须 写在函数主体后自成一行。方法的开始花括号后禁止有空格,并且方法的结束花括号前禁止有空格。
 声明一个方法看起来如下。注意括号,逗号,空格和大括号的位置:
<?php
namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

4.4、方法参数

  • 在参数列表中, 在逗号前禁止有空格,在逗号后边必须有一个空格。
  • 有默认值的参数必须在参数列表的后边。
<?php
namespace Vendor\Package;

class ClassName
{
    public function foo($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

参数列表可能拆分为多行,每行缩进一个。当这么做的时候,列表中的第一个参数必须在下一行,并且必须每行只能有一个参数。

当参数拆分为多行,结束括号和开始大括号之前必须有一个空格并且放在同一行。

<?php
namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // method body
    }
}

4.5、abstract、final和static

当遇到时, abstract 和 final 声明必须优先于可见性声明。

当遇到时, static 声明必须在可见性声明之后。

<?php
namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}

4.6、方法调用

当进行方法调用时候,在方法名和开始括号间禁止有空格,在开始括号后禁止有空格,在结束括号后禁止有空格,在结束括号前禁止有空格。在参数列表中,在每个逗号前禁止有空格,逗号后必须有空格。

<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

参数列表可能拆分到多行中,每行缩进一个。当这么做时,列表中的第一项必须在下一行,并且必须每行一个参数。

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

5、控制结构

对控制结构的一般规则如下:

  • 控制结构关键字后必须有一个空格。
  • 开始括号后禁止有空格。
  • 结束括号前禁止有空格。
  • 在结束括号和开始大括号之间必须有一个空格。
  • 控制结构体必须缩进一个。
  • 结束大括号必须自成一行。

每个结构体必须在花括号中。这样标准化可以跟好看,并且在添加新行的话可以减少出错。

5.1、 if、elseif、else

if 结构如下。注意括号、空格和大括号的位置;并且 else 以及 elseif 和之前的结束大括号在同一行。

<?php
if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}

关键词 elseif应该代替 else if 来使用,以此让所有控制关键词看起来都是一个词。

5.2、switch、case

switch 结构如下。注意括号、空格和大括号的位置。 case 声明相对switch必须有一个缩进, 并且 break 关键字 (或者其他结束关键字) 必须和 case 体有相同缩进. 当有意通过一个非空的 case 体,必须有一个注释像// no break 。

<?php
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;
}

5.3.、while, do while

while 结构如下。注意括号、空格和大括号的位置。

<?php
while ($expr) {
    // structure body
}

相似的, do while 结构如下。注意括号、空格和大括号的位置。

<?php
do {
    // structure body;
} while ($expr);

5.4、for

for 结构如下。注意括号、空格和大括号的位置。

<?php
for ($i = 0; $i < 10; $i++) {
    // for body
}

5.5、foreach

foreach 结构如下。注意括号、空格和大括号的位置。

<?php
foreach ($iterable as $key => $value) {
    // foreach body
}

5.6、try, catch

try catch 结构如下。注意括号、空格和大括号的位置。

<?php
try {
    // try body
} catch (FirstExceptionType $e) {
    // catch body
} catch (OtherExceptionType $e) {
    // catch body
}

6、闭包(Closures)

闭包声明在 function 关键词后必须有一个空格, 并且在 use 关键词前后必须各有一个空格。

开始大括号必须在同一行,并且结束大括号必须自成一行。

在参数或者变量列表的开头括号后禁止有空格,并且在结束括号前禁止有空格。

在参数和变量变量列表中,在每个空格前禁止有空格,在每个空格后必须有一个空格。

闭包带默认值的参数必须在参数列表的后端。

闭包声明如下。注意括号、逗号、空格和大括号的位置:

<?php
$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};

参数和变量列表可能拆分为多行,每行缩进一个。当这么做时,在里表中第一项必须在下一行,并且每行必须一个参数或者变量。

当结束的那个列表(无论是参数或者变量)分布于多行,结束括号和开始大括号必须用空格隔开并自称一行。

如下是带参数列表和不带参数列表以及参数列表分布于多行的闭包的例子。

<?php
$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
    // body
};

$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
    // body
};

$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
    // body
};

注意在闭包被作为参数直接传给方法的时候,也采用本样式规范。

<?php
$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);

7、总结(Conclusion)

以上规范难免有疏忽,其中包括但不仅限于:

  • 全局变量和常量的定义
  • 函数的定义
  • 操作符和赋值
  • 行内对齐
  • 注释和文档描述块
  • 类名的前缀及后缀
  • 最佳实践

本规范之后的修订与扩展将弥补以上不足。

 

本文参考:

PSR-1:PHP基本编码规范

本规范制定了代码基本元素的相关标准,以确保共享的PHP代码间具有较高程度的技术互通性。

本文档中的关键词”必须(MUST)”,”禁止(MUST NOT)”,”必须(REQUIRED)”,”必须(SHALL)”,”禁止(SHALL NOT)”,”SHOULD(应该)”,“不应该(SHOULD NOT)”, “建议(RECOMMENDED)”, “可能(MAY)”和 “可选(OPTIONAL)” 遵循RFC2119约定。

1、概览

  • 文件 必须 只能用<?php和<?=标签。
  • 文件 必须 只能使用UTF-8(无BOM)编码格式。
  • PHP代码中 应该 只定义类、函数、常量等声明,或其他会产生 副作用 的操作(如:生成文件输出以及修改 .ini 配置文件等),二者只能选其一;
  • 命名空间以及类 必须 符合 PSR 的自动加载规范:PSR-0,PSR-4 中一个;
  • 类名称必须使用大驼峰(StudlyCaps)。
  • 类常量必须全部大写,用下划线分割。
  • 方法名必须使用小驼峰(camelCase)。

2. 文件

2.1、 PHP标签

PHP代码必须使用<?php ?>或者<?= ?>标签;禁止使用其他变形标签。

2.2、编码格式

PHP代码必须使用UTF-8(无BOM)编码格式。

2.3、副作用(Side Effects)

一个文件应该 只定义类、函数、常量等声明并且不会引起其他副作用,或者应该执行逻辑,但是只能二选一。
“副作用(Side Effects)”这个词指可执行的逻辑,而非直接声明类、函数、常量等,只是在include file的情况下。
“副作用(Side Effects)”包括但不限于:产生输出,显式使用requiredinclude,链接外部服务,修改ini配置,触发错误或异常,修改全局或者静态变量,读取或写入文件等等。
下来是一个既包含声明又包含副作用的实例;例如,一个反例:

<?php
// side effect: change ini settings
ini_set('error_reporting', E_ALL);

// side effect: loads a file
include "file.php";

// side effect: generates output
echo "\n";

// declaration
function foo()
{
    // function body
}

下边的例子仅包含声明无副作用;一个仿真示例:

<?php
// declaration
function foo()
{
    // function body
}

// conditional declaration is *not* a side effect
if (! function_exists('bar')) {
    function bar()
    {
        // function body
    }
}

3、命名空间和类名称

命名空间以及类 必须 符合 PSR 的自动加载规范:PSR-0,PSR-4 中的一个。

这意味着每个类独立一个文件,并且必须处在一个命名空间下:一个顶层vendor下。

类名称必须使用大驼峰(StudlyCaps)。

PHP5.3之后版本书写的代码必须使用标准命名空间。

例如:

<?php
// PHP 5.3 and later:
namespace Vendor\Model;

class Foo
{
}

5.2.x之前的版本书写的代码应该使用在类名中用下划线的伪命名约定Vendor_

<?php
// PHP 5.2.x and earlier:
class Vendor_Model_Foo
{
}

4、类常量、属性以及方法

此处“类”(class)反之所有的classes, interfaces和traits。

4.1、类常量

类常量必须全部大写并使用下划线分开。例如:

<?php 
namespace Vendor\Model;

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

4.2、属性

本规范对使用$StudlyCaps,$camelCase或者$under_score作为属性名故意不做任何建议。
使用任何命名约定在一个合理范围内应该保持一致。范围应该是vendor级别,package级别,class级别或者method级别。

4.3、方法

方法名必须使用小驼峰(camelCase)。

职位要求: 
具备良好的编程习惯,熟练掌握OOP编程和常见设计模式;
良好的编程风格和项目文档编写习惯

web开发中各类缓存设计

1、缓存

缓存即指一种存储着数据的硬件或者软件组件,可加速数据请求;缓存中的数据可以是之前的运算结果,或者是其他地方存储的数据的备份。

In computing, a cache /ˈkæʃ/ KASH,[1] is a hardware or software component that stores data so future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation, or the duplicate of data stored elsewhere.

其实说白了缓存就是一个临时放数据地方。你可以放到本地缓存中、可以放到memcache、redis、tair等缓存系统中,也可以放到MySQL中等等。

缓存主要解决一个问题就是加速数据请求速度。每次从网络接口请求数据,改成在本地缓存一份,这个在APP开发中经常用到,从而可以减少网络请求耗时,还能节省用户流量,体验更好。每次从数据库通过SQL查数据,如果每次请求的结果是固定的,那就可以考虑将查询结果缓存到redis等缓存里,减少数据库压力。

2、缓存设计

2.1 考虑的问题

  • 数据量
  • 响应时间
  • 扩展性
  • 数据一致性
  • 更新策略

 

<未完待续>

Centos搭建LAMPP环境(极速)

在Centos上安装Apache、PHP、MySQL是每个PHP程序员的基本技能,下边的方法可以快速便捷地帮你完成搭建:

sudo yum install httpd mysql mysql-devel mysql-server php php-devel php-mysql php-gd libjpeg* php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-bcmath php-mhash libmcrypt -y

执行完上述命令,我们的环境就搭建完成了。
执行启动命令即可让apache、MySQL、PHP跑起来:

sudo service mysqld start
sudo service httpd start

此时在浏览器访问:http://localhost,就可以看到It works!了。大功告成。