├── .htaccess ├── LICENSE ├── README.md ├── admin ├── footer.php ├── header.php ├── index.php ├── login.php └── logout.php ├── assets ├── admin.css ├── admin.js └── headerbg.png ├── config.php ├── functions.php ├── html └── index.php ├── index.php ├── redirect.php └── shorturl.sql /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine on 3 | RewriteOptions MaxRedirects=1 4 | RewriteBase / 5 | RewriteCond %{REQUEST_FILENAME} !-f 6 | RewriteCond %{REQUEST_FILENAME} !-d 7 | RewriteCond %{REQUEST_FILENAME} !-l 8 | RewriteRule ^([a-zA-Z0-9_-]+)$ redirect.php?alias=$1 [L] 9 | # 如不需要使用SSL加密,请注释下方两行代码 10 | RewriteCond %{SERVER_PORT} !^443$ 11 | RewriteRule ^(.*)?$ https://%{SERVER_NAME}/$1 [L,R] 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 CollageTomato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ShortUrl 2 | 萌娘短网址的(官方 (の´v`の))开源程序 3 | # 什么是ShortUrl 4 | ShortUrl 是一个极简短网址程序,包含后台管理界面和清晰的配置文本。 5 | # Demo 6 | [Demo Web](https://v7.gs) 7 | # 安装方式 8 | 将“shorturl.sql”导入数据库,并编辑“config.php” 9 | ```java 10 | 11 | define('DB_HOSTNAME', 'localhost'); //数据库地址 12 | define('DB_USERNAME', ''); //数据库用户名 13 | define('DB_PASSWORD', ''); //数据库密码 14 | define('DB_NAME', ''); //数据库名 15 | define('DB_VERSION', '4');//数据库版本号,请勿修改 16 | define('DB_PREFIX', 'shorturl_'); //数据库前缀 17 | define('SITE_URL', 'https://demo.domain.org'); //你的网站地址,开头添加协议名,结尾不带“/” 18 | define('SITE_TITLE', 'ShortUrl'); //网页标题 19 | define('ADMIN_USERNAME', 'admin'); //管理员用户名 20 | define('ADMIN_PASSWORD', 'password'); //管理员密码 21 | define('URL_PROTOCOLS', 'http|https|ftp|ftps|mailto|news|mms|rtmp|rtmpt|ed2k'); //允许缩短的网址的协议 22 | define('SHORTURL_VERSION', '1.0.4');//版本号,请勿修改 23 | define('SHORTURL_NUMERICVERSION', '104');//版本号比对形式,请勿修改 24 | define('INDIRECTLYGO','0'); //开启跳转等待请将值更改为“1”,反之为“0” 25 | define('GOTIME','10'); //跳转等待的时间 26 | 27 | ``` 28 | # 伪静态方式 29 | Apache 30 | ```java 31 | 32 | RewriteEngine on 33 | RewriteOptions MaxRedirects=1 34 | RewriteBase / 35 | RewriteCond %{REQUEST_FILENAME} !-f 36 | RewriteCond %{REQUEST_FILENAME} !-d 37 | RewriteCond %{REQUEST_FILENAME} !-l 38 | RewriteRule ^([a-zA-Z0-9_-]+)$ redirect.php?alias=$1 [L] 39 | 40 | ``` 41 | Nginx 42 | ```java 43 | 44 | location / { 45 | rewrite ^/(.+)$ /redirect.php?alias=$1 last; 46 | } 47 | 48 | ``` 49 | # 注意 50 | Nginx环境下访问后台需要在admin后面加上“/”才能登录。 51 | 如果无需SSL,请按以下程序操作: 52 | 1. 编辑“index.php”, 注释第108行并取消注释第107行。 53 | 2. 编辑“.htaccess”, 注释第9-10行。 54 | -------------------------------------------------------------------------------- /admin/footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /admin/header.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 短网址 - 后台管理 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 |
短网址 后台管理 返回首页退出
21 | $current && $version !== $current) { 28 | echo "

一个新版本的ShortUrl已经可以使用,请前往下载: https://github.com/CollageTomato/ShortUrl


"; 29 | } 30 | elseif ($version < $current && $version !== $current) { 31 | echo "

你正在使用开发版的ShortUrl,我们期待你的反馈


"; 32 | 33 | } 34 | ?> 35 | 53 | 54 | -------------------------------------------------------------------------------- /admin/index.php: -------------------------------------------------------------------------------- 1 |  0) { 18 | mysql_query("DELETE FROM ".DB_PREFIX."urls WHERE id = '$delete_id'") or db_die(__FILE__, __LINE__, mysql_error()); 19 | } 20 | if (@$_GET['new_url'] <> "" and @$_GET['old_url'] <> "") { 21 | update_url($_GET['old_url'],$_GET['new_url']); 22 | } 23 | $page = (int) @$_GET['page']; 24 | 25 | if ($page < 1) { 26 | $page = 1; 27 | } 28 | 29 | $db_query = "1 AND "; 30 | 31 | $search_alias = mysql_real_escape_string(@$_GET['search_alias']); 32 | $search_url = mysql_real_escape_string(@$_GET['search_url']); 33 | 34 | if (!empty($search_alias)) { 35 | $db_query .= "(code = '$search_alias' OR alias = '$search_alias') AND "; 36 | } 37 | 38 | if (!empty($search_url)) { 39 | $db_query .= "url LIKE '%$search_url%' AND "; 40 | } 41 | 42 | $db_query = substr($db_query, 0, -5); 43 | 44 | $db_result = mysql_query("SELECT COUNT(id) FROM ".DB_PREFIX."urls WHERE $db_query") or db_die(__FILE__, __LINE__, mysql_error()); 45 | $db_row = mysql_fetch_row($db_result); 46 | $db_count = (int) $db_row[0]; 47 | $db_start = ($page - 1) * 25; 48 | $db_pages = ceil($db_count / 25); 49 | 50 | $db_result = mysql_query("SELECT * FROM ".DB_PREFIX."urls WHERE $db_query ORDER BY date_added DESC LIMIT $db_start, 25") or db_die(__FILE__, __LINE__, mysql_error()); 51 | 52 | echo "\n".""; 53 | echo "\n". 54 | "\n". 55 | "\n". 56 | "\n". 57 | "\n". 58 | "\n". 59 | "\n". 60 | "\n". 61 | "\n"; 62 | echo ""; 63 | while ($db_row = mysql_fetch_assoc($db_result)) { 64 | $db_row = array_filter($db_row, "stripslashes"); 65 | 66 | extract($db_row, EXTR_OVERWRITE|EXTR_PREFIX_ALL, "u"); 67 | 68 | if (empty($u_alias)) { 69 | $u_alias = ""; 70 | } 71 | $st = $db_row['st']; 72 | if ($st=="") { 73 | $st="0"; 74 | } 75 | 76 | echo 77 | "\n". 78 | "\n". 79 | "\n". 80 | "\n". 81 | "\n". 82 | "\n". 83 | "\n". 84 | "\n". 85 | "\n"; 86 | unset($u_id, $u_code, $u_alias, $u_url, $u_date_added); 87 | } 88 | 89 | echo "
ID短代码别名原网址添加日期次数操作
$u_id$u_code" . htmlentities($u_alias) . "". htmlentities($u_url)."$u_date_added".$st."删除修改
\n"; 90 | 91 | if ($db_count > 25) { 92 | echo "

\n"; 93 | 94 | if ($page > 1) { 95 | echo "« 上一页 "; 96 | } 97 | 98 | if ($page < $db_pages) { 99 | echo "下一页 »"; 100 | } 101 | 102 | echo "

\n"; 103 | } 104 | 105 | require_once("footer.php"); 106 | 107 | -------------------------------------------------------------------------------- /admin/login.php: -------------------------------------------------------------------------------- 1 | ADMIN_USERNAME) { 8 | echo ""; 9 | }elseif ($_POST['password'] <> ADMIN_PASSWORD) { 10 | echo ""; 11 | }else{ 12 | echo ""; 16 | } 17 | } 18 | ?> 19 | 20 | 21 | 22 | 登录 - Administrator 23 | 24 | 78 | 79 | 80 |
81 |
82 |

Administrator 登录

83 | 84 | 85 | 86 |
87 |
88 | 89 | -------------------------------------------------------------------------------- /admin/logout.php: -------------------------------------------------------------------------------- 1 | 行: $line
信息: $message"); 4 | } 5 | 6 | function db_ins_die($filename, $line, $message) { 7 | die('

安装向导无法连接到使用指定的证书数据库。请返回再试一次。

'); 8 | } 9 | 10 | function db_connect() { 11 | mysql_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD) or db_die(__FILE__, __LINE__, mysql_error()); 12 | mysql_select_db(DB_NAME) or db_die(__FILE__, __LINE__, mysql_error()); 13 | 14 | if (DB_VERSION > 4) { 15 | mysql_query("SET NAMES 'utf8'") or db_die(__FILE__, __LINE__, mysql_error()); 16 | } 17 | } 18 | 19 | function db_ins_connect() { 20 | mysql_connect(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD) or db_ins_die(__FILE__, __LINE__, mysql_error()); 21 | mysql_select_db(DB_NAME) or db_ins_die(__FILE__, __LINE__, mysql_error()); 22 | 23 | if (DB_VERSION > 4) { 24 | mysql_query("SET NAMES 'utf8'") or db_ins_die(__FILE__, __LINE__, mysql_error()); 25 | } 26 | } 27 | 28 | function get_last_number() { 29 | $db_result = mysql_query("SELECT last_number FROM ".DB_PREFIX."settings") or db_die(__FILE__, __LINE__, mysql_error()); 30 | $db_row = mysql_fetch_row($db_result); 31 | 32 | return $db_row[0]; 33 | } 34 | 35 | function increase_last_number() { 36 | mysql_query("UPDATE ".DB_PREFIX."settings SET last_number = (last_number + 1)") or db_die(__FILE__, __LINE__, mysql_error()); 37 | 38 | return (mysql_affected_rows() > 0) ? true : false; 39 | } 40 | 41 | function code_exists($code) { 42 | $db_result = mysql_query("SELECT COUNT(id) FROM ".DB_PREFIX."urls WHERE BINARY code = '$code'") or db_die(__FILE__, __LINE__, mysql_error()); 43 | $db_row = mysql_fetch_row($db_result); 44 | 45 | return ($db_row[0] > 0) ? true : false; 46 | } 47 | 48 | function alias_exists($alias) { 49 | $db_result = mysql_query("SELECT COUNT(id) FROM ".DB_PREFIX."urls WHERE BINARY alias = '$alias'") or db_die(__FILE__, __LINE__, mysql_error()); 50 | $db_row = mysql_fetch_row($db_result); 51 | 52 | return ($db_row[0] > 0) ? true : false; 53 | } 54 | 55 | function url_exists($url) { 56 | $db_result = mysql_query("SELECT id, code, alias FROM ".DB_PREFIX."urls WHERE url LIKE '$url'") or db_die(__FILE__, __LINE__, mysql_error()); 57 | 58 | if (mysql_num_rows($db_result) > 0) { 59 | return mysql_fetch_row($db_result); 60 | } 61 | 62 | return false; 63 | } 64 | 65 | function generate_code($number) { 66 | $out = ""; 67 | $codes = "abcdefghjkmnpqrstuvwxyz23456789ABCDEFGHJKMNPQRSTUVWXYZ"; 68 | 69 | while ($number > 53) { 70 | $key = $number % 54; 71 | $number = floor($number / 54) - 1; 72 | $out = $codes{$key}.$out; 73 | } 74 | 75 | return $codes{$number}.$out; 76 | } 77 | 78 | function insert_url($url, $code, $alias) { 79 | mysql_query("INSERT INTO ".DB_PREFIX."urls (url, code, alias, date_added, st) VALUES ('$url', '$code', '$alias', NOW(), '0')") or db_die(__FILE__, __LINE__, mysql_error()); //插入数据 80 | 81 | return mysql_insert_id(); 82 | } 83 | 84 | function update_url($id, $alias) { 85 | mysql_query("UPDATE ".DB_PREFIX."urls SET url = '$alias' WHERE id = '$id'") or db_die(__FILE__, __LINE__, mysql_error()); 86 | } 87 | /* 88 | function update_url_st(){ 89 | mysql_query("INSERT INTO ").DB_PREFIX."urls SET st" 90 | } 91 | */ 92 | function get_url($alias) { 93 | $db_result = mysql_query("SELECT url FROM ".DB_PREFIX."urls WHERE BINARY code = '$alias' OR alias = '$alias'") or db_die(__FILE__, __LINE__, mysql_error()); 94 | 95 | if (mysql_num_rows($db_result) > 0) { 96 | $db_row = mysql_fetch_row($db_result); 97 | return $db_row[0]; 98 | } 99 | 100 | return false; 101 | } 102 | 103 | function get_st($alias) { 104 | $db_result = mysql_query("SELECT st FROM ".DB_PREFIX."urls WHERE BINARY code = '$alias' OR alias = '$alias'") or db_die(__FILE__, __LINE__, mysql_error()); 105 | if (mysql_num_rows($db_result) > 0) { 106 | $db_row = mysql_fetch_row($db_result); 107 | 108 | $st = (INT)$db_row[0] + 1; 109 | 110 | mysql_query("UPDATE ".DB_PREFIX."urls SET st = $st WHERE alias = '$alias' OR code = '$alias'") or db_die(__FILE__, __LINE__, mysql_error()); 111 | } 112 | } 113 | 114 | 115 | function get_hostname() { 116 | $data = parse_url(SITE_URL); 117 | 118 | return $data['host']; 119 | } 120 | 121 | function get_domain() { 122 | $hostname = get_hostname(); 123 | 124 | preg_match("/\.([^\/]+)/", $hostname, $domain); 125 | 126 | return $domain[1]; 127 | } 128 | 129 | function print_errors() { 130 | global $_ERROR; 131 | 132 | if (count($_ERROR) > 0) { 133 | echo "
\n"; 134 | 135 | foreach ($_ERROR as $key => $value) { 136 | echo "

$value

\n"; 137 | } 138 | 139 | echo "
\n"; 140 | } 141 | } 142 | function is_admin_login() { 143 | if (@$_SESSION['admin'] == 1) { 144 | return true; 145 | } 146 | 147 | return false; 148 | } -------------------------------------------------------------------------------- /html/index.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | <?php echo SITE_TITLE; ?> 12 | 13 | 95 | 96 | 97 |
98 |
99 | 100 |

101 |

原始链接

102 | 103 |

自定义后缀

104 | 105 | 106 | 107 | 108 |
109 |
110 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 安装向导 ,这将帮助你在瞬间建立起新的网址缩短服务。

如果你已经安装了ShortUrl,你需要删除“install”目录。"); 8 | } //安装向导还未启用 9 | ?> 10 | 0) { 17 | 18 | $url = mysql_real_escape_string(trim($_GET['url'])); 19 | $alias = mysql_real_escape_string(trim($_GET['alias'])); 20 | 21 | if (!preg_match("/^(".URL_PROTOCOLS.")\:\/\//i", $url)) { 22 | $prefix = explode(":", $url); 23 | if ($prefix[0] == 'mailto') { 24 | $url = $url; 25 | } else { 26 | $url = "http://".$url; 27 | } 28 | } 29 | 30 | $last = $url[strlen($url) - 1]; 31 | 32 | if ($last == "/") { 33 | $url = substr($url, 0, -1); 34 | } 35 | 36 | $data = @parse_url($url); 37 | //print_r($data); 38 | if ($prefix[0] == 'mailto') { 39 | $data['scheme'] = 'mailto'; 40 | $data['host'] = 'none'; 41 | } 42 | if (strlen($url) == 0) { 43 | $_ERROR[] = "

请输入一个真实链接.

"; 44 | } 45 | else if (empty($data['scheme']) || empty($data['host'])) { 46 | $_ERROR[] = "

请输入一个有效的链接.

"; 47 | } 48 | else { 49 | $hostname = get_hostname(); 50 | $domain = get_domain(); 51 | 52 | /* if (preg_match("/($hostname)/i", $data['host'])) { 53 | $_ERROR[] = "The URL you have entered is not allowed."; 54 | }*/ 55 | } 56 | 57 | if (strlen($alias) > 0) { 58 | if (!preg_match("/^[a-zA-Z0-9_-]+$/", $alias)) { 59 | $_ERROR[] = "

自定义别名只能包含字母,数字,下划线和破折号.

"; 60 | } 61 | else if (code_exists($alias) || alias_exists($alias)) { 62 | $_ERROR[] = "

您输入的自定义代码已经存在.

"; 63 | } 64 | } 65 | 66 | if (count($_ERROR) == 0) { 67 | $create = true; 68 | 69 | if (($url_data = url_exists($url))) { 70 | $create = false; 71 | $id = $url_data[0]; 72 | $code = $url_data[1]; 73 | $old_alias = $url_data[2]; 74 | 75 | if (strlen($alias) > 0) { 76 | if ($old_alias != $alias) { 77 | $create = true; 78 | } 79 | } 80 | } 81 | 82 | if ($create) { 83 | do { 84 | $code = generate_code(get_last_number()); 85 | 86 | if (!increase_last_number()) { 87 | die("System error!"); 88 | } 89 | 90 | if (code_exists($code) || alias_exists($code)) { 91 | continue; 92 | } 93 | 94 | break; 95 | } while (1); 96 | 97 | $id = insert_url($url, $code, $alias); 98 | } 99 | 100 | if (strlen($alias) > 0) { 101 | $code = $alias; 102 | } 103 | 104 | $short_url = SITE_URL."/".$code; 105 | $_GET['url'] = ""; 106 | $_GET['alias'] = ""; 107 | //$info = "

短地址创建成功!新地址:".htmlentities($short_url)."

"; 108 | $info = "

短地址创建成功!新地址:".htmlentities($short_url)."

"; 109 | require_once("html/index.php"); 110 | exit(); 111 | } 112 | } 113 | require_once("html/index.php"); -------------------------------------------------------------------------------- /redirect.php: -------------------------------------------------------------------------------- 1 | 点击直接进入"; 20 | exit(); 21 | 22 | } 23 | 24 | }else{ 25 | if (($url = get_url($alias))) { 26 | header("Location: $url", true, 301); 27 | exit(); 28 | } 29 | } 30 | echo ""; 31 | //header("Location: ".SITE_URL, true, 301); -------------------------------------------------------------------------------- /shorturl.sql: -------------------------------------------------------------------------------- 1 | SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 2 | SET time_zone = "+08:00";-- 中国时区 3 | 4 | 5 | -- 6 | -- 数据库: `shorturl` 7 | -- 8 | 9 | -- -------------------------------------------------------- 10 | 11 | -- 12 | -- 表的结构 `shorturl_settings` 13 | -- 14 | 15 | CREATE TABLE IF NOT EXISTS `shorturl_settings` ( 16 | `last_number` bigint(20) unsigned NOT NULL DEFAULT '0', 17 | KEY `last_number` (`last_number`) 18 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; 19 | 20 | -- 21 | -- 转存表中的数据 `shorturl_settings` 22 | -- 23 | 24 | INSERT INTO `shorturl_settings` (`last_number`) VALUES 25 | (145), 26 | (145); 27 | 28 | -- -------------------------------------------------------- 29 | 30 | -- 31 | -- 表的结构 `shorturl_urls` 32 | -- 33 | 34 | CREATE TABLE IF NOT EXISTS `shorturl_urls` ( 35 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 36 | `url` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, 37 | `code` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', 38 | `alias` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '', 39 | `date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', 40 | `st` int(11) NOT NULL DEFAULT '0', 41 | PRIMARY KEY (`id`), 42 | UNIQUE KEY `code` (`code`), 43 | KEY `alias` (`alias`) 44 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; --------------------------------------------------------------------------------