Sfoglia il codice sorgente

init shorturl-miles project

Miles 10 anni fa
commit
e9559c06f3
8 ha cambiato i file con 382 aggiunte e 0 eliminazioni
  1. 4 0
      .gitignore
  2. 11 0
      .htaccess
  3. 242 0
      ShortUrl.php
  4. 7 0
      config.sample.php
  5. 13 0
      index.php
  6. 50 0
      init.sql
  7. 28 0
      s2u.php
  8. 27 0
      u2s.php

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+.project
+.buildpath
+.settings
+config.php

+ 11 - 0
.htaccess

@@ -0,0 +1,11 @@
+#BEGIN Short URL
+#<IfModule mod_rewrite.c>
+RewriteEngine On
+Options +FollowSymLinks
+RewriteCond %{SCRIPT_FILENAME} !-d
+RewriteCond %{SCRIPT_FILENAME} !-f
+#RewriteBase /  
+RewriteCond %{REQUEST_URI}  ^/([^/]+)/?$    [NC]
+RewriteRule .*       s2u.php?c=%1 [L]
+#</IfModule>
+#END Short URL

+ 242 - 0
ShortUrl.php

@@ -0,0 +1,242 @@
+<?php
+class ShortUrl
+{
+    protected static $chars = "123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
+    protected static $table = "short_urls";
+    protected static $checkUrlExists = true;
+ 
+    protected $pdo;
+    protected $timestamp;
+ 
+    public function __construct(PDO $pdo) {
+        $this->pdo = $pdo;
+        $this->timestamp = $_SERVER["REQUEST_TIME"];
+    }
+ 
+    public function urlToShortCode($url) {
+        if (empty($url)) {
+            throw new Exception("No URL was supplied.");
+        }
+ 
+        if ($this->validateUrlFormat($url) == false) {
+            throw new Exception(
+                "URL does not have a valid format.");
+        }
+ 
+        if (self::$checkUrlExists) {
+            if (!$this->verifyUrlExists($url)) {
+                throw new Exception(
+                    "URL does not appear to exist.");
+            }
+        }
+ 
+        $shortCode = $this->urlExistsInDb($url);
+        if ($shortCode == false) {
+            $shortCode = $this->createShortCode($url);
+        }
+ 
+        return $shortCode;
+    }
+ 
+    protected function validateUrlFormat($url) {
+        return filter_var($url, FILTER_VALIDATE_URL,
+            FILTER_FLAG_HOST_REQUIRED);
+    }
+ 
+    protected function verifyUrlExists($url) {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_NOBODY, true);
+        curl_setopt($ch,  CURLOPT_RETURNTRANSFER, true);
+        curl_exec($ch);
+        $response = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        curl_close($ch);
+ 
+        return (!empty($response) && $response != 404);
+    }
+ 
+    protected function urlExistsInDb($url) {
+        $query = "SELECT short_code FROM " . self::$table .
+            " WHERE long_url = :long_url LIMIT 1";
+        $stmt = $this->pdo->prepare($query);
+        $params = array(
+            "long_url" => $url
+        );
+        $stmt->execute($params);
+ 
+        $result = $stmt->fetch();
+        return (empty($result)) ? false : $result["short_code"];
+    }
+ 
+    protected function createShortCode($url) {
+        $id = $this->insertUrlInDb($url);
+        
+//     $shortCode = $this->convertIntToShortCode($id);	//Aborted
+		/* --------------------------New Algorithm Start----------------------------- */
+        $shortCode = $this->createCode($id, $url);				//Accepted
+        $number = rand(0, 3);
+        $shortCode = $shortCode[$number];
+        /* --------------------------New Algorithm End----------------------------- */
+        
+        $this->insertShortCodeInDb($id, $shortCode);
+        return $shortCode;
+    }
+ 
+    protected function insertUrlInDb($url) {
+        $query = "INSERT INTO " . self::$table .
+            " (long_url, date_created) " .
+            " VALUES (:long_url, :timestamp)";
+        $stmnt = $this->pdo->prepare($query);
+        $params = array(
+            "long_url" => $url,
+            "timestamp" => $this->timestamp
+        );
+        $stmnt->execute($params);
+ 
+        return $this->pdo->lastInsertId();
+    }
+     
+    /**
+     * @param unknown $id
+     * @throws Exception
+     * @return string
+     * Aborted
+     */
+    protected function convertIntToShortCode($id) {
+        $id = intval($id);
+        if ($id < 1) {
+            throw new Exception(
+                "The ID is not a valid integer");
+        }
+ 
+        $length = strlen(self::$chars);
+        // make sure length of available characters is at
+        // least a reasonable minimum - there should be at
+        // least 10 characters
+        if ($length < 10) {
+            throw new Exception("Length of chars is too small");
+        }
+ 
+        $code = "";
+        while ($id > $length - 1) {
+            // determine the value of the next higher character
+            // in the short code should be and prepend
+            $code = self::$chars[fmod($id, $length)] .
+                $code;
+            // reset $id to remaining value to be converted
+            $id = floor($id / $length);
+        }
+ 
+        // remaining value of $id is less than the length of
+        // self::$chars
+        $code = self::$chars[$id] . $code;
+ 
+        return $code;
+    }
+    
+    /**
+     * @param unknown $id
+     * @param unknown $url
+     * @return multitype:string 
+     * Accepted
+     */
+    protected function createCode($id, $url){
+    	$base32 = array (
+    			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+    			'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+    			'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+    			'y', 'z', '0', '1', '2', '3', '4', '5'
+    	);
+    	
+    	$hex = md5($url);
+    	$hexLen = strlen($hex);
+    	$subHexLen = $hexLen / 8;
+    	$output = array();
+    	
+    	for ($i = 0; $i < $subHexLen; $i++) {
+    		$subHex = substr ($hex, $i * 8, 8);
+    		$int = 0x3FFFFFFF & (1 * ('0x'.$subHex));
+    		$out = '';
+    	
+    		for ($j = 0; $j < 6; $j++) {
+    			$val = 0x0000001F & $int;
+    			$out .= $base32[$val];
+    			$int = $int >> 5;
+    		}
+    	
+    		$output[] = $out;
+    	}
+    	
+    	return $output;
+    }
+ 
+    protected function insertShortCodeInDb($id, $code) {
+        if ($id == null || $code == null) {
+            throw new Exception("Input parameter(s) invalid.");
+        }
+        $query = "UPDATE " . self::$table .
+            " SET short_code = :short_code, code = :short_code WHERE id = :id";
+        $stmnt = $this->pdo->prepare($query);
+        $params = array(
+            "short_code" => $code,
+            "id" => $id
+        );
+        $stmnt->execute($params);
+ 
+        if ($stmnt->rowCount() < 1) {
+            throw new Exception(
+                "Row was not updated with short code.");
+        }
+ 
+        return true;
+    }
+    
+    public function shortCodeToUrl($code, $increment = true) {
+    	if (empty($code)) {
+    		throw new Exception("No short code was supplied.");
+    	}
+    
+    	if ($this->validateShortCode($code) == false) {
+    		throw new Exception(
+    				"Short code does not have a valid format.");
+    	}
+    
+    	$urlRow = $this->getUrlFromDb($code);
+    	if (empty($urlRow)) {
+    		throw new Exception(
+    				"Short code does not appear to exist.");
+    	}
+    
+    	if ($increment == true) {
+    		$this->incrementCounter($urlRow["id"]);
+    	}
+    
+    	return $urlRow["long_url"];
+    }
+    
+    protected function validateShortCode($code) {
+    	return preg_match("|[" . self::$chars . "]+|", $code);
+    }
+    
+    protected function getUrlFromDb($code) {
+    	$query = "SELECT id, long_url FROM " . self::$table .
+    	" WHERE short_code = :short_code LIMIT 1";
+    	$stmt = $this->pdo->prepare($query);
+    	$params=array(
+    			"short_code" => $code
+    	);
+    	$stmt->execute($params);
+    	$result = $stmt->fetch();
+    	return (empty($result)) ? false : $result;
+    }
+    
+    protected function incrementCounter($id) {
+    	$query = "UPDATE " . self::$table .
+    	" SET counter = counter + 1 WHERE id = :id";
+    	$stmt = $this->pdo->prepare($query);
+    	$params = array(
+    			"id" => $id
+    	);
+    	$stmt->execute($params);
+    }
+}

+ 7 - 0
config.sample.php

@@ -0,0 +1,7 @@
+<?php
+define('DB_PDODRIVER', 'mysql');
+define('DB_HOST', 'localhost');
+define('DB_DATABASE', 'tableName');
+define('DB_USERNAME', 'username');
+define('DB_PASSWORD', 'pwd');
+define('SHORTURL_PREFIX', '');

+ 13 - 0
index.php

@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>Input Your website</title>
+</head>
+<body>
+<form action="u2s.php"  method="POST">
+	<input type="text" name="url" />
+	<input type="submit" />
+</form>
+</body>
+</html>

+ 50 - 0
init.sql

@@ -0,0 +1,50 @@
+-- phpMyAdmin SQL Dump
+-- version 4.2.12deb2
+-- http://www.phpmyadmin.net
+--
+-- Host: localhost
+-- Generation Time: 2015-07-08 17:18:45
+-- 服务器版本: 5.6.24-0ubuntu2
+-- PHP Version: 5.6.4-4ubuntu6.2
+
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+--
+-- Database: `shorturl`
+--
+
+-- --------------------------------------------------------
+
+--
+-- 表的结构 `short_urls`
+--
+
+CREATE TABLE IF NOT EXISTS `short_urls` (
+`id` int(10) unsigned NOT NULL,
+  `long_url` varchar(255) NOT NULL,
+  `code` varchar(32) NOT NULL,
+  `short_code` varbinary(6) NOT NULL,
+  `date_created` int(10) unsigned NOT NULL,
+  `counter` int(10) unsigned NOT NULL DEFAULT '0'
+) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;
+
+--
+-- Indexes for dumped tables
+--
+
+--
+-- Indexes for table `short_urls`
+--
+ALTER TABLE `short_urls`
+ ADD PRIMARY KEY (`id`), ADD KEY `short_code` (`short_code`);
+
+--
+-- AUTO_INCREMENT for dumped tables
+--
+
+--
+-- AUTO_INCREMENT for table `short_urls`
+--
+ALTER TABLE `short_urls`
+MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=1;

+ 28 - 0
s2u.php

@@ -0,0 +1,28 @@
+<?php
+include "./config.php";
+include "./ShortUrl.php";
+ 
+$code = $_GET["c"];
+ 
+try {
+    $pdo = new PDO(DB_PDODRIVER . ":host=" . DB_HOST .
+        ";dbname=" . DB_DATABASE,
+        DB_USERNAME, DB_PASSWORD);
+}
+catch (PDOException $e) {
+    trigger_error("Error: Failed to establish connection to database.");
+    exit;
+}
+ 
+$shortUrl = new ShortUrl($pdo);
+try {
+    $url = $shortUrl->shortCodeToUrl($code);
+    header("Location: " . $url);
+    exit;
+}
+catch (Exception $e) {
+    // log exception and then redirect to error page.
+// 	header("Location: /error");
+    header("Location: index.php");
+    exit;
+}

+ 27 - 0
u2s.php

@@ -0,0 +1,27 @@
+<?php
+include "./config.php";
+include "./ShortUrl.php";
+
+try {
+    $pdo = new PDO(DB_PDODRIVER . ":host=" . DB_HOST .
+        ";dbname=" . DB_DATABASE,
+        DB_USERNAME, DB_PASSWORD);
+}
+catch (PDOException $e) {
+    trigger_error("Error: Failed to establish connection to database.");
+    exit;
+}
+ 
+$shortUrl = new ShortUrl($pdo);
+try {
+    $code = $shortUrl->urlToShortCode($_POST["url"]);
+    printf('<p><strong>Short URL:</strong> <a href="%s/%2$s">%2$s</a></p>',$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'],
+        SHORTURL_PREFIX . $code);
+    exit;
+}
+catch (Exception $e) {
+    // log exception and then redirect to error page.
+//     header("Location: /error");
+    header("Location: index.php");
+    exit;
+}