50.垃圾内容检测机制(二)
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 50 小节:Spam Detection Part 2
本节内容
在上一节我们实际上完成了对关键词的检测,本节我们来完成另外一种检测:无意义的连续按键输出的文本,如 'aaaaaaaaa'。我们首先来修改下我们上一节的测试:
forum\tests\Unit\SpamTest.php
<?php
namespace Tests\Unit;
use Tests\TestCase;
use App\Spam;
class SpamTest extends TestCase
{
/** @test */
public function it_checks_for_invalid_keywords()
{
$spam = new Spam();
$this->assertFalse($spam->detect('Innocent reply here.'));
$this->expectException('Exception');
$spam->detect('something forbidden');
}
/** @test */
public function it_checks_for_any_being_held_down()
{
$spam = new Spam();
$this->expectException('Exception');
$spam->detect('Hello word aaaaaaaaaa');
}
}
在这里我们修改了上一节建立的测试,并新增了一个测试,分别用来测试关键词跟连续按键。我们接下来修改Spam
类文件:
forum\app\Spam.php
.
.
class Spam
{
public function detect($body)
{
$this->detectInvalidKeywords($body);
$this->detectKeyHeldDown($body);
return false;
}
.
.
protected function detectKeyHeldDown($body)
{
if(preg_match('/(.)\\1{4,}/',$body)){
throw new \Exception('Your reply contains spam.');
}
}
}
当有连续 4 个字符相同时,我们抛出异常。现在我们运行测试:
为了后期维护,我们将spam
类从模型文件的位置抽取到一个单独的文件夹中,我们取名叫Inspections
,并且我们将已建立的两种检测机制单独抽取成新的类文件,并且以后新增一种检测机制,我们再新增一个类文件即可。
forum\app\Inspections\Spam.php
<?php
namespace App\Inspections;
class Spam
{
protected $inspections = [
InvalidKeywords::class,
KeyHeldDown::class,
];
public function detect($body)
{
foreach ($this->inspections as $inspection){
app($inspection)->detect($body);
}
return false;
}
}
forum\app\Inspections\InvalidKeywords.php
<?php
namespace App\Inspections;
use Exception;
class InvalidKeywords
{
protected $keywords = [
'something forbidden'
];
public function detect($body)
{
foreach ($this->keywords as $invalidKeyword){
if(stripos($body,$invalidKeyword) !== false){
throw new Exception('Your reply contains spam.');
}
}
}
}
forum\app\Inspections\KeyHeldDown.php
<?php
namespace App\Inspections;
use Exception;
class KeyHeldDown
{
public function detect($body)
{
if(preg_match('/(.)\\1{4,}/',$body)){
throw new Exception('Your reply contains spam.');
}
}
}
不要忘了我们更新我们在测试文件顶部地引用:
use App\Inspections\Spam;
现在我们来测试一下:
我们还有一个地方需要修改:
forum\app\Http\Controllers\RepliesController.php
<?php
namespace App\Http\Controllers;
use App\Reply;
use App\Inspections\Spam;
use App\Thread;
.
.
最后,依旧是运行全部测试: