起因
- 某客户安全报告提示有一个过期网站的链接,且该过期网站变成了羞羞网站~~
- 这个问题是他们平时发文的时候直接复制了别的网站内容,又没有用编辑器的清理工具导致的。
- 事后,客户提出能不能把所有内容都查一遍,并去掉所有链接?
- 很显然,他想当然了~~
思路
- 一种是找到所有链接,然后和客户说按照他的要求把链接干光了,客户一开始可能会谢谢,但没多久就会来和你说,怎么这个没有,怎么那个不能用,所以别自找麻烦了
- 一种是找到所有带链接的信息,系统判断是否为无效链接后自动清除,但问题如果这个无效链接已经变成了有效的羞羞站,那么你怎么判断?难道还要判断外链的网站是否带有羞羞内容或不合规内容?为了这件小事,我有病?嗯~~等以后发病的时候再说吧
- 一种是,也就剩这种,人工判断后手动删除,毕竟我怎么知道哪些链接是你要的?哪些不是,既然不是所有的外网链接都要去掉,既然需要“人”的参与,那自然就用这个方法了。而且让客户自己去删,避免了误删的纠纷,让客户参与其中,体会操控的乐趣。。。。
当然,我事先数据库搜了一遍,涉及到外链的也就300多篇文章,就算客户不愿意自己手动,我们来手工的整一遍,也不累。
结构
数据库中基础数据放在tableN
表中,内容等数据放在tableN_data
表中,主要字段有tableN.id
,tableN.category
,tableN.title
,tableN.showtime
,tableN_data.id
,tableN_data.did
,tableN_data.content
,其中id
为两张表的关联字段
比如直接在数据库里查的时候就用下面的sql语句搜一遍带http
的内容,也可以看看www
或者特定字符的。
select * from table1 as a join table1_data as b on b.id=a.id where content like "%http%";
select * from table2 as a join table2_data as b on b.id=a.id where content like "%http%";
select * from table3 as a join table3_data as b on b.id=a.id where content like "%http%";
select * from table4 as a join table4_data as b on b.id=a.id where content like "%http%";
select * from table5 as a join table5_data as b on b.id=a.id where content like "%http%";
// ...
这样写的搜索结果就会分成N张表供你仔细端详
但给客户的当然不能这么弄,肯定要弄一个页面让其操作。
好了,最后就是人懒,用传统的php单页面直接完成这个事情了。
代码
不分段解析了,整合在一段里自己看,实用代码有些内容不能泄露,所以发文的时候略作修改,如果期间有bug不能运行,可以留个言~~有可以用的也留个言
<!DOCTYPE html>
<html>
<head>
<title>超链接清理</title>
<meta charset="utf-8">
</head>
<body>
<?php
// 连接数据库
$dsn = "mysql:host=127.0.0.1;dbname=testDb;charset=utf8mb4";
$username = "test";
$password = "test";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
echo "连接数据库失败:" . $e->getMessage();
exit;
}
// 分块查询数据
$perPage = 5;
$page = isset($_GET['page']) ? $_GET['page'] : 1;
// 表结构是一样的,先放一个数组里,以后好调整
$tables = array(
'table1 ',
'table2',
'table3',
'table4',
'table5',
'table6',
'table7'
);
// 想用哪个条件自己选,注意mysql支持正则查询
$condition = array(
//"content like '%http:%'",
//"content like '%http:%'",
//"content like '%www%'",
//"content like '%<a%'",
//"content REGEXP '<a[^>]+href\s*=\s*[\"\'][^\"\']*www[^\"\']*'",
"content REGEXP '<a[^>]+href\s*=\s*[\"\'][^\"\']*http[^\"\']*'"
);
$conditionString = implode(' or ', $condition);
// 用union联合查询的方式生成sql
$selects = array();
$countSql = '';
$selectSql = array();
//data表的id字段改名为id2输出,以防冲突,将当前表名作为moudle字段输出
foreach ($tables as $table) {
$selectSql[] = "(SELECT a.*,b.id as id2,b.content,b.did,'{$table}' as moudle FROM {$table} as a join {$table}_data as b ON b.id=a.id where (".$conditionString."))";
}
$selectSqlUnion = implode(' UNION ', $selectSql);
// 查询
$selectSqlString = "SELECT * FROM (".$selectSqlUnion.") as alldata";
$sql = $selectSqlString . ' LIMIT ' . (($page - 1) * $perPage) . ',' . $perPage;
$result = $pdo->query($sql);
$selected_rows = array();
if ($result->rowCount() > 0) {
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$column_value = $row["content"];
$selected_rows[] = $row;
}
}
// 总数
$total = 0;
$countSqlString = "SELECT COUNT(*) FROM (".$selectSqlUnion.") as alldata WHERE (".$conditionString.")";
$countResult = $pdo->query($countSqlString);
if ($countResult->rowCount() > 0) {
while ($row = $countResult->fetch(PDO::FETCH_NUM)) {
$total = $row[0];
}
}
$totalPages = ceil($total / $perPage);
// 在前端页面将选中的行列出来让用户判断后勾选
$n = 0;
echo "<form method='post' action=''>";
foreach ($selected_rows as $row) {
$n++;
echo "<div style='border:1px solid gray;padding:20px;margin:20px;'>
<!--链接到网站预览-->
<h2>【{$n}】 <a href='http://127.0.0.1/{$row["id"]}.html' target='_blank'>{$row["title"]}</a></h2>
<p style='padding:5px;background-color:#F3F3F3;'>
发布时间:{$row["showtime"]}
所在栏目:{$row["category"]}
所在模型:{$row["moudle"]}
模型编号:{$row["id"]}
模型序号:{$row["did"]}
</p>
<p>{$row["content"]}</p>
<label style='display:block;padding:5px;background-color:#CBC2EB;'>
<!--存储本条信息的表名、id号-->
<input type='checkbox' name='selected_rows[]' value='{$row["moudle"]}|{$row["id"]}'>选择
</label>
</div>";
}
echo "<div style='text-align:center;padding:28x;line-height:3;'><input type='submit' value='提交去除超链接' style='font-size:18px;font-weight:bold;' /></div>";
echo "</form>";
// 分页
if ($totalPages > 1) {
echo "<div style='text-align:center;'>";
if ($page > 1) {
echo " <a href=\"?page=" . ($page - 1) . "\">上一页</a> ";
}
for ($i = 1; $i <= $totalPages; $i++) {
if ($i == $page) {
echo " <span>{$i}</span> ";
} else {
echo " <a href=\"?page={$i}\">{$i}</a> ";
}
}
if ($page < $totalPages) {
echo " <a href=\"?page=" . ($page + 1) . "\">下一页</a> ";
}
echo "</div>";
}
// 处理用户提交的数据
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (!empty($_POST["selected_rows"])) {
foreach ($_POST["selected_rows"] as $selected_row) {
// 读取数据,判断该表是否存在该数据
$p_row = explode('|',$selected_row);
$p_data_sql = "SELECT * FROM {$p_row[0]}_data WHERE id='{$p_row[1]}'";
$p_result = $pdo->query($p_data_sql);
$row = $p_result->fetch(PDO::FETCH_ASSOC);
if(!empty($row)) {
// 将超链接替换为链接内容
$text = preg_replace('/<a\s+[^>]*>(.*?)<\/a>/is', '$1', $row["content"]);
$stmt = $pdo->prepare("UPDATE {$p_row[0]}_data SET content = REPLACE(content, ?, ?) WHERE id = ?");
$stmt->execute(array($row["content"], $text, $row["id"]));
}
}
echo "数据更新成功";
} else {
echo "请选择要更新的数据行";
}
}
// 关闭连接
$pdo = null;
?>
</body>
</html>