【实例】自建库短链接生成 [复制链接]
【作者】凌晓纳 2020年4月14日 01:16:58

短链接 - 自建Mysql数据库版(非第三方)

本篇文章适合自己有想法建库和自己有短域名的小伙伴

可以学到的技术:
  1. 实现短链接生成(62进制)
  2. mysqli预处理操作数据库(查、增)
  3. 使用Apache伪静态.htaccess配置重定向规则
开发环境:
  • PHPStorm2019.2
  • Apache2.4
  • MySQL5.6
  • PHP 7.x

项目文件目录结构如下:

文件名 用途
index.php 入口文件
link.php 生成短链接
other.php 定义各个类
.htaccess Apache伪静态

创建用于储存短链接及长链接数据的数据表:

  1. CREATE TABLE `短链接` (
  2. `序号` int(11) NOT NULL AUTO_INCREMENT,
  3. `长链接` text,
  4. `短链接` text,
  5. `主动` text,
  6. `增加时间` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  7. PRIMARY KEY (`序号`)
  8. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4

index.php

  1. <?php
  2. define("domain", "sls.fun");
  3. use other\mysql\mysql;
  4. $page = $_GET['page'];
  5. if (strlen($page) != 6) {
  6. die("<h1>" . domain . "</h1>");
  7. }
  8. require_once "other.php";
  9. $mysql = new mysql();
  10. $longLink = $mysql->get_longLink($page);
  11. if ($longLink == false || $longLink == "") {
  12. die("<h1>" . domain . "</h1>");
  13. }
  14. header("location:" . $longLink);
  15. return;
  1. <?php
  2. /**
  3. * 生成短链接
  4. *
  5. * @author Shawna<1070175533@qq.com>
  6. * @since 1.0
  7. */
  8. define("domain", "sls.fun");
  9. $request_json = $_POST['request'];
  10. if ($request_json == "") {
  11. die(json_encode(array(
  12. "code" => "-1",
  13. "msg" => "缺少参数request",
  14. )));
  15. }
  16. $request = json_decode($request_json, true);
  17. if ($request['link'] == "") {
  18. die(json_encode(array(
  19. "code" => "-1",
  20. "msg" => "json缺少参数link",
  21. )));
  22. }
  23. require_once "other.php";
  24. use other\mysql\mysql;
  25. use other\tool\tool;
  26. $mysql = new mysql();
  27. $tool = new tool();
  28. if ($tool->verifyUrl($request['link']) != 200) {
  29. die(json_encode(array(
  30. "code" => -1,
  31. "msg" => "URL访问超时或无法访问",
  32. )));
  33. }
  34. $Hex62 = $tool->Hex62(crc32($request['link']));
  35. $longLink = $mysql->get_longLink($Hex62);
  36. if ($longLink == false || $longLink == "") {
  37. if ($mysql->set_link($request['link'], $Hex62, $_SERVER['REMOTE_ADDR'])) {
  38. die(json_encode(array(
  39. "code" => 1,
  40. "msg" => domain . "/" . $Hex62,
  41. )));
  42. } else {
  43. die(json_encode(array(
  44. "code" => -1,
  45. "msg" => "服务器繁忙",
  46. )));
  47. }
  48. }
  49. die(json_encode(array(
  50. "code" => 1,
  51. "msg" => domain . "/" . $Hex62,
  52. )));

other.php

  1. <?php
  2. namespace other\mysql;
  3. use mysqli;
  4. class mysql
  5. {
  6. private $mysql_ip = "";//数据库IP
  7. private $mysql_user = "";//用户名
  8. private $mysql_password = "";//密码
  9. private $mysql_dbname = "";//数据库名
  10. private $mysqli;//储存数据库连接句柄
  11. private $sql;//储存sql语句
  12. //构造函数
  13. public function __construct()
  14. {
  15. $this->mysqli = @new mysqli($this->mysql_ip, $this->mysql_user, $this->mysql_password, $this->mysql_dbname);//mysqli连接数据库
  16. if (mysqli_connect_errno()) {
  17. die(json_encode(array(
  18. "code" => -1,
  19. "msg" => "Mysqli连接失败: " . mysqli_connect_error(),
  20. )));//连接失败结束
  21. }
  22. $this->sql = array(
  23. "SetLink" => "insert into `短链接`(`长链接`,`短链接`,`主动`) values(?, ?, ?);",//写短链接长链接到数据库
  24. "GetLongLink" => "SELECT `长链接` FROM `短链接` WHERE `短链接` = ?;",//短链接查长链接
  25. );
  26. }
  27. //析构函数
  28. public function __destruct()
  29. {
  30. // TODO: Implement __destruct() method.
  31. mysqli_close($this->mysqli);//断开mysql连接
  32. }
  33. /**
  34. * 写短链接到数据表
  35. *
  36. * @access public
  37. * @param string $l_link 长链接
  38. * @param string $s_link 短链接
  39. * @param string $host 主动
  40. * @return boolean
  41. * @since 1.0
  42. */
  43. function set_link($l_link, $s_link, $host)
  44. {
  45. $stmt = $this->mysqli->prepare($this->sql['SetLink']);
  46. $stmt->bind_param("sss", $l_link, $s_link, $host);
  47. if (!$stmt->execute()) {
  48. $stmt->close();
  49. return false;
  50. }
  51. $stmt->close();
  52. return true;
  53. }
  54. /**
  55. * 短链接查长链接
  56. *
  57. * @access public
  58. * @param string $s_link 短链接
  59. * @return string|boolean
  60. * @since 1.0
  61. */
  62. function get_longLink($s_link)
  63. {
  64. $stmt = $this->mysqli->prepare($this->sql['GetLongLink']);
  65. $stmt->bind_param("s", $s_link);
  66. $stmt->bind_result($result);
  67. if (!$stmt->execute()) {
  68. $stmt->free_result();
  69. $stmt->close();
  70. return false;
  71. }
  72. $tmp = "";
  73. while ($stmt->fetch()) {
  74. $tmp = $result;
  75. }
  76. $stmt->free_result();
  77. $stmt->close();
  78. return $tmp;
  79. }
  80. }
  81. namespace other\tool;
  82. class tool
  83. {
  84. /**
  85. * 转62进制
  86. *
  87. * @access public
  88. * @param string $data 10进制数据
  89. * @return string
  90. * @since 1.0
  91. */
  92. function Hex62($data)
  93. {
  94. $base = array(
  95. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  96. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  97. 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  98. 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
  99. 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
  100. 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
  101. 'Y', 'Z',
  102. );
  103. $result = "";
  104. do {
  105. $result = $base[$data % 62] . $result;
  106. $data = intval($data / 62);
  107. } while ($data != 0);
  108. return $result;
  109. }
  110. /**
  111. * 验证URL是否有效
  112. *
  113. * @access public
  114. * @param string $url url地址
  115. * @return string
  116. * @since 1.0
  117. */
  118. function verifyUrl($url)
  119. {
  120. $ch = curl_init();
  121. curl_setopt($ch, CURLOPT_URL, $url);
  122. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  123. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  124. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  125. $response = curl_exec($ch);
  126. return curl_getinfo($ch, CURLINFO_HTTP_CODE);
  127. }
  128. }

.htaccess

  1. RewriteEngine On
  2. RewriteCond %{REQUEST_URI} !\.(css|js|png|jpe?g)$
  3. RewriteCond $1 !^(index.php|favicon.ico|404.html|link.php)
  4. RewriteRule ^(.*)$ http://sls.fun/?page=$1 [R=302,L]

Shawna
2020年4月14日