├── .gitignore
├── .htaccess
├── LICENSE
├── README.md
├── api
├── index.php
└── set.php
├── asset
├── .gitkeep
├── css
│ └── main.css
└── js
│ └── app.js
├── config.php
├── inc
├── class
│ ├── database.db
│ ├── db.class.php
│ └── url.class.php
├── functions.php
├── index.php
└── require.php
├── index.php
└── info.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # CakePHP 3
2 |
3 | /vendor/*
4 | /config/app.php
5 |
6 | /tmp/cache/models/*
7 | !/tmp/cache/models/empty
8 | /tmp/cache/persistent/*
9 | !/tmp/cache/persistent/empty
10 | /tmp/cache/views/*
11 | !/tmp/cache/views/empty
12 | /tmp/sessions/*
13 | !/tmp/sessions/empty
14 | /tmp/tests/*
15 | !/tmp/tests/empty
16 |
17 | /logs/*
18 | !/logs/empty
19 |
20 | # CakePHP 2
21 |
22 | /app/tmp/*
23 | /app/Config/core.php
24 | /app/Config/database.php
25 | /vendors/*
26 |
--------------------------------------------------------------------------------
/.htaccess:
--------------------------------------------------------------------------------
1 | Options -Indexes
2 | order deny,allow
3 |
4 |
45 | Unless otherwise stated, everything on this GitHub is released under the [MIT](https://cyrilwong.mit-license.org/) license.
46 |
--------------------------------------------------------------------------------
/api/index.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/api/set.php:
--------------------------------------------------------------------------------
1 | set_url($request_arr['url'], $config['length']);
21 | } else if(strstr($request_arr['url'], $_SERVER['HTTP_HOST'])) {
22 | $opt['content'] = '链接已经是短地址了。';
23 | } else if(!$is_link) {
24 | $opt['content'] = '请输入正确格式的网址。';
25 | }
26 | } else {
27 | $opt['content'] = '调用参数不能为空。';
28 | }
29 |
30 | echo json_encode($opt);
31 |
32 | ?>
--------------------------------------------------------------------------------
/asset/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nov23e/YSurl/436ef783bd0da7600684e0ed347ae333e4f5a185/asset/.gitkeep
--------------------------------------------------------------------------------
/asset/css/main.css:
--------------------------------------------------------------------------------
1 | /* Reset */
2 | * {
3 | margin: 0;
4 | padding: 0;
5 | }
6 | html, body, input, text, textarea {
7 | outline: none;
8 | font-family: 'Arial', 'Microsoft YaHei', '黑体', '宋体', sans-serif;
9 | font-size: 12px;
10 | }
11 | html, body {
12 | background: #fff;
13 | }
14 | a {
15 | text-decoration: none;
16 | }
17 | a:hover {
18 | text-decoration: underline;
19 | }
20 |
21 | /* Main */
22 | .wrap {
23 | text-align: center;
24 | overflow: hidden;
25 | }
26 | .wrap .meta {
27 | margin: 160px 0 0 0;
28 | opacity: 0;
29 | transform: translateY(-150px);
30 | transition: .5s all ease;
31 | }
32 | .on .wrap .meta {
33 | opacity: 1;
34 | transform: translateY(0);
35 | }
36 | .wrap .meta .title {
37 | line-height: 1em;
38 | color: #ff4665;
39 | font-size: 42px;
40 | text-transform: uppercase;
41 | }
42 | .wrap .meta .description {
43 | margin: 10px 0 0 0;
44 | line-height: 1em;
45 | color: #7e7e7e;
46 | font-size: 16px;
47 | font-weight: normal;
48 | }
49 | .wrap .link-area {
50 | margin: 50px 0 0 0;
51 | opacity: 0;
52 | transition: .5s opacity ease;
53 | }
54 | .on .wrap .link-area {
55 | opacity: 1;
56 | }
57 | .wrap .link-area input {
58 | display: inline-block;
59 | vertical-align: middle;
60 | }
61 | .wrap .link-area #url {
62 | width: 320px;
63 | height: 32px;
64 | line-height: 32px;
65 | padding: 0 10px;
66 | border: 3px solid #bdc3c7;
67 | border-radius: 5px;
68 | color: #333;
69 | }
70 | .wrap .link-area #url.focus,
71 | .wrap .link-area #url:focus {
72 | border-color: #ff4665;
73 | transition: .2s border ease;
74 | }
75 | .wrap .link-area #submit {
76 | width: 90px;
77 | height: 38px;
78 | margin: 0 0 0 5px;
79 | background: #ff4665;
80 | border-radius: 5px;
81 | color: #fff;
82 | border: none;
83 | cursor: pointer;
84 | transition: .2s opacity ease;
85 | }
86 | .wrap .link-area #submit:hover {
87 | opacity: .75;
88 | }
89 | .wrap .link-area #submit:active {
90 | opacity: .9;
91 | }
92 | .wrap .footer {
93 | width: 100%;
94 | bottom: 80px;
95 | left: 0;
96 | position: absolute;
97 | color: #7e7e7e;
98 | }
99 | .wrap .footer a {
100 | color:#ff4665;
101 | }
--------------------------------------------------------------------------------
/asset/js/app.js:
--------------------------------------------------------------------------------
1 |
2 | var APP = (function(){
3 |
4 | var fn = {
5 |
6 | // 生成短地址
7 | setUrl: function(self) {
8 | var urlEl = document.getElementById('url'),
9 | tips = 'https://',
10 | request = {
11 | "url": urlEl.value
12 | };
13 | fn.getJson('api/set.php', true, JSON.stringify(request), function(res) {
14 | if(res.success == 'true') {
15 | urlEl.className = 'focus';
16 | urlEl.value = res.content.url;
17 | } else {
18 | urlEl.className = '';
19 | urlEl.value = '';
20 | urlEl.setAttribute('placeholder', res.content);
21 | setTimeout(function() {
22 | urlEl.setAttribute('placeholder', tips);
23 | }, 2000);
24 | }
25 | });
26 | },
27 |
28 | // 获取 JSON 数据
29 | getJson: function(url, post, data, callback) {
30 | var xhr = new XMLHttpRequest(),
31 | type = (post) ? 'POST' : 'GET';
32 | xhr.onreadystatechange = function() {
33 | if(xhr.readyState == 4 && xhr.status == 200) {
34 | var json = JSON.parse(xhr.responseText);
35 | callback(json);
36 | } else if(xhr.readyState == 4) {
37 | callback(false);
38 | }
39 | }
40 | xhr.open(type, url, true);
41 | xhr.send(data);
42 | }
43 |
44 | },
45 |
46 | init = function() {
47 | setTimeout(function() {
48 | var el = document.getElementsByTagName('html')[0];
49 | el.className = 'on';
50 | }, 10);
51 | };
52 |
53 | return {
54 | fn: fn,
55 | init: init
56 | }
57 |
58 | })();
59 |
60 |
61 | document.addEventListener('DOMContentLoaded', function() {
62 | APP.init();
63 | })
--------------------------------------------------------------------------------
/config.php:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/inc/class/database.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nov23e/YSurl/436ef783bd0da7600684e0ed347ae333e4f5a185/inc/class/database.db
--------------------------------------------------------------------------------
/inc/class/db.class.php:
--------------------------------------------------------------------------------
1 | db = new PDO('sqlite:' . dirname(__FILE__) . '/database.db');
7 | $this->init_tab();
8 | }
9 |
10 | // 初始化数据库结构
11 | function init_tab() {
12 | // 网址表
13 | $this->db->exec("CREATE TABLE urls(
14 | id char(8) PRIMARY KEY,
15 | url longtext,
16 | ip varchar(16),
17 | ua varchar(255)
18 | )");
19 | }
20 |
21 | // 查询表内容
22 | function query($name, $rule = '') {
23 | $query = $this->db->prepare("SELECT * FROM $name $rule");
24 | $query->execute();
25 | $result = $query->fetchAll();
26 | return $result;
27 | }
28 |
29 | // 插入表内容
30 | function insert($tab, $key, $val) {
31 | $exec = $this->db->exec("INSERT INTO $tab ($key) VALUES($val)");
32 | if(!$exec) return false;
33 | $this->db->beginTransaction();
34 | }
35 |
36 | // 删除表内容
37 | function delete($tab, $rule = '') {
38 | $exec = $this->db->exec("DELETE FROM $tab $rule");
39 | if(!$exec) return false;
40 | $this->db->beginTransaction();
41 | }
42 |
43 | }
44 |
45 | ?>
--------------------------------------------------------------------------------
/inc/class/url.class.php:
--------------------------------------------------------------------------------
1 | db = $db_c;
8 | }
9 |
10 | // 生成短地址
11 | public function set_url($url, $size = 4) {
12 | $id = $this->get_id($url);
13 | if(!$id) {
14 | $id = $this->create_id($url, $size);
15 | $ip = get_ip();
16 | $ua = get_ua();
17 | $this->db->insert('urls', 'id, url, ip, ua', "'$id', '$url', '$ip', '$ua'");
18 | }
19 | $s_url = get_uri() . $id;
20 | return $s_url;
21 | }
22 |
23 | // 生成地址 ID
24 | public function create_id($url, $size = 4) {
25 | $md5 = md5($url);
26 | // 随机抽取 MD5 中的字符作为 ID
27 | $id = '';
28 | for($i = 0; $i < $size; $i++) {
29 | $rand_id = rand(0, strlen($md5) - 1);
30 | $id .= $md5[$rand_id];
31 | }
32 | // ID 检测
33 | if($this->has_id($id)) {
34 | return $this->create_id($url, $size);
35 | } else {
36 | return $id;
37 | }
38 | }
39 |
40 | // 查询 ID 号
41 | public function get_id($url) {
42 | $result = $this->db->query('urls', "WHERE url = '$url'");
43 | (count($result) > 0) ? $opt = $result[0]['id'] : $opt = false;
44 | return $opt;
45 | }
46 |
47 | // 查询目标地址
48 | public function get_url($id) {
49 | $result = $this->db->query('urls', "WHERE id = '$id'");
50 | (count($result) > 0) ? $opt = $result[0]['url'] : $opt = false;
51 | return $opt;
52 | }
53 |
54 | // 检测 ID 是否已经存在
55 | public function has_id($id) {
56 | $result = $this->db->query('urls', "WHERE id = '$id'");
57 | (count($result) > 0) ? $opt = true : $opt = false;
58 | return $opt;
59 | }
60 |
61 | // 清空短地址
62 | public function clean_urls() {
63 | $del = $this->db->delete('urls');
64 | if($del) return true;
65 | return false;
66 | }
67 |
68 | }
69 |
70 | ?>
--------------------------------------------------------------------------------
/inc/functions.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/inc/index.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/inc/require.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | get_url($_GET['id']);
12 | // 重定向至目标网址
13 | if($url) {
14 | header('Location: ' . $url);
15 | exit;
16 | }
17 |
18 | }
19 |
20 | ?>
21 |
22 |
23 |