无论你的项目是独自一人或者是整个团队,无论项目是大还是小,有一个要求从来没有改变,那就是代码质量。所以大型项目和团队项目更难维护代码质量。
在代码质量变得难以控制之前,有一种好方法就是使用静态分析工具。静态分析是软件分析过程中的一种方法,但是并没有真正的执行程序——类似于一种自动化的code review。静态分析工具将会检测代码错误,代码编写是否标准,甚至还会自动清除代码的空白部分。使用php -l filename的日子并没有结束,但是现在我们发现了许多可以更好的维护代码质量的工具。
说道php -l filename,可以对目标文件执行语法分析的并且输出所有找到的错误。我在我的PHP发送邮件的代码中使用了这个方法,我们的分析开了个好头。
class Email{
//Constructor
function Email( $subject, $message, $senderName, $senderEmail, $toList, $ccList=0, $bccList=0, $replyTo=0 ){
$this->sender = $senderName . " <$senderEmail>";
$this->replyTo = $replyTo;
$this->subject = $subject;
$this->message = $message;
// Set the To recipients
if( is_array($toList)){
$this->to = join( $toList, "," );
}else{
$this->to = $toList;
}
// Set the cc list
if( is_array($ccList) && sizeof($ccList)){
$this->cc = join( $ccList, "," );
}else{
$this->cc = $ccList;
}
// Set the bcc list
if( is_array($bccList) && sizeof($bccList)){
$this->bcc = join( $bccList, "," );
}else{
$this->bcc = $bccList;
}
}
function sendMail(){
//create the headers for PHP mail() function
$this->headers = "From: " . $this->sender . "\n";
if( $this->replyTo ){
$this->headers .= "Reply-To: " . $this->replyTo . "\n";
}
if( $this->cc ){
$this->headers .= "Cc: " . $this->cc . "\n";
}
if( $this->bcc ){
$this->headers .= "Bcc: " . $this->bcc . "\n";
}
print "To: " . $this->to ."
Subject: " . $this->subject . "
Message: " . $this->message . "
Headers: " . $this->headers;
return mail( $this->to, $this->subject, $this->message, $this->headers );
}
}
如你所看到的,这是一个简单的发送邮件的类。如果我们对这个文件执行PHP lint,我们会看到没有什么错误。
php -l Email.php
下面是执行结果:
No syntax errors detected in Email.php
在2016年,这样的结果已经不能够满足我们的需求了,因为我们还需要考虑代码质量和编码规范。
PHPSA 是一个用于PHP的静态分析工具。
PHPSA
可以通过.phar
安装 ,或者通过 Composer, 命令如下:
composer require ovr/phpsa
命令行会自动在我们的项目中创建
vendor/bin
文件夹。
安装完成以后,我们可以运行 ./vendor/bin/phpsa
.
上面的运行结果和我们使用list命令的运行结果是一样的。help命令将会列出PHPSA的帮助信息。check命令将会执行给定的目标文件或文件夹的静态分析。
因为我们之前执行了PHP lint,也就说明PHPSA同样不会给我们找出代码中的语法错误。但是如果我们故意在代码中插入一段错误的代码呢?PHPSA可以找出吗?
让我们在这个邮件类中做一点小小的改动。
class Email{
//Constructor
function Email( $subject, $message, $senderName, $senderEmail, $toList, $ccList=0, $bccList=0, $replyTo=0 ){
$this->sender = $senderName . " <$senderEmail>";
$this->replyTo = $replyTo;
$this->subject = $subject;
$this->message = $message;
// Set the To recipients
if( is_array($toList)){
$this->to = join( $toList, "," );
}else{
$this->to = $toList;
}
// Set the cc list
if( is_array($ccList) && sizeof($ccList)){
$this->cc = join( $ccList, "," )
}else{
$this->cc = $ccList;
}
// Set the bcc list
if( is_array($bccList) && sizeof($bccList)){
$this->bcc = join( $bccList, "," );
}else{
$this->bcc = $bccList;
}
}
function sendMail(){
//create the headers for PHP mail() function
$this->headers = "From: " . $this->sender . "\n";
if( $this->replyTo ){
$this->headers .= "Reply-To: " . $this->replyTo . "\n";
}
if( $this->cc ){
$this->headers .= "Cc: " . $this->cc . "\n";
}
if( $this->bcc ){
$this->headers .= "Bcc: " . $this->bcc . "\n";
}
print "To: " . $this->to ."
Subject: " . $this->subject . "
Message: " . $this->message . "
Headers: " . $this->headers;
return mail( $this->to, $this->subject, $this->message, $this->headers );
}
}
让我们来运行PHPSA来检测一下结果。
就如我们所看到的,PHPSA很快就检测出了语法错误。但是这没有什么新鲜的,PHP lint同样可以检测出。所以让我们一起看一下PHPSA还为我们做了一些什么额外的工作。
现在出来了更多的信息!
Notice: Missing docblock for Email() method in src/Email.php on 6 [missing-docblock]
Notice: join() is an alias of function. Use implode(...). in src/Email.php on 15 [fcall.alias]
Notice: sizeof() is an alias of function. Use count(...). in src/Email.php on 21 [fcall.alias]
Notice: Property sender does not exist in Email scope in src/Email.php on 38 [undefined-property]
PHPSA给我了我们许多警告。从我们的函数只是别的函数的别名到未定义的变量和丢失的属性,PHPSA的确从编码的规范上给了我们许多好的建议。
所以现在让门来一起修改一下上面的代码。
/**
* Simple email sender class
*
*/
class Email
{
/**
* The email headers
*/
var $headers;
/**
* The email sender
*/
var $sender;
/**
* The email recipients
*/
var $to;
/**
* Reply To
*/
var $replyTo;
/**
* Email cc list
*/
var $cc;
/**
* Email bcc list
*/
var $bcc;
/**
* Email content
*/
var $message;
/**
* The subject of the email
*/
var $subject;
/**
* This is the constructor for the Email class
*/
function Email(
$subject,
$message,
$senderName,
$senderEmail,
$toList,
$ccList = 0,
$bccList = 0,
$replyTo = 0
) {
$this->sender = $senderName . " <$senderEmail>";
$this->replyTo = $replyTo;
$this->subject = $subject;
$this->message = $message;
// Set the To recipients
if (is_array($toList)) {
$this->to = implode($toList, ",");
} else {
$this->to = $toList;
}
// Set the cc list
if (is_array($ccList) && count($ccList)) {
$this->cc = implode($ccList, ",");
} else {
$this->cc = $ccList;
}
// Set the bcc list
if (is_array($bccList) && count($bccList)) {
$this->bcc = implode($bccList, ",");
} else {
$this->bcc = $bccList;
}
}
/**
* The function that actually sends the email
*
* @return boolean Returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise.
*/
function sendMail()
{
//create the headers for PHP mail() function
$this->headers = "From: " . $this->sender . "\n";
if ($this->replyTo) {
$this->headers .= "Reply-To: " . $this->replyTo . "\n";
}
if ($this->cc) {
$this->headers .= "Cc: " . $this->cc . "\n";
}
if ($this->bcc) {
$this->headers .= "Bcc: " . $this->bcc . "\n";
}
print "To: " . $this->to . "
Subject: " . $this->subject . "
Message: " . $this->message . "
Headers: " . $this->headers;
return mail($this->to, $this->subject, $this->message, $this->headers);
}
}
尽管没有太多变化但PHPSA却足以让我们了解他的用处。我们从一开始的没有注释的、懒散的代码编程了现在有明确注释和清晰的代码。现在可以让我们更容易清晰的理解我们代码中的每一个属性和函数。使用PHPSA不仅可以让我们发现代码中的错误和警告,更可以让我们在代码质量的层面上进行进一步的提升。
PHPSA是开源的,这就意味着我们可以向它提出我们的需求并且提交自己的代码。PHPSA是一款专注静态分析检测的工具,所以它是快速并且轻量级的。同时PHPSA也还处于alpha版本,有可能在不同平台下的运行结果会变得不同,同时,它的功能还没有那么完善。
静态分析是提升我们代码质量和编码标准很有力的一个工具。尤其在团队合作中,它可以让每个人都遵守相同的编程标准。尽管也有一些相同功能的工具比如Code Sniffer和Mess Detector, PHPSA 是一个非常有用的工具,它给我们提供了一些相当实用的功能。 如果你需要检测语法错误并且做一些分析的工具,PHPSA是你的一种选择。