« 上一篇下一篇 »

用Apache服务器mod_rewrite 功能,生成你自己的短链接

 日常生活中,我们有时会在微信收到朋友的淘宝宝贝分享链接URL,链接是很简短的几个英文大小写,其实点击进去里面时的链接是非常长的,例如,bit.ly/INtravel https:/www.in.gov/ai/appfiles/dhs-countyMap/dhsCountyMap.html更容易记住。那么淘宝这样的技术是怎么实现的呢,如果你想预先共享一个链接,但还不知道最终地址,这时 URL 缩短服务可以派上用场。现在符数不重要了,但还有其他原因要缩短链接。首先,缩短服务可以提供分析功能 —— 你可以看到你分享的链接的受欢迎程度。它还简化了制作易于记忆的 URL。

   与任何技术一样,URL 缩短服务并非都是正面的。通过屏蔽最终地址,缩短的链接可用于指向恶意或冒犯性内容。但是,如果你仔细上网,URL 缩短服务是一个有用的工具。

我们之前在网站上发布过缩短服务的文章,但也许你想要运行一些由简单的文本文件支持的缩短服务。在本文中,我们将展示如何使用 Apache HTTP 服务器的 mod_rewrite 功能来设置自己的 URL 缩短服务。如果你不熟悉 Apache HTTP 服务器,请查看 David Both 关于安装和配置它的文章。

创建一个 VirtualHost
在本教程中,我假设你购买了一个很酷的域名,你将它专门用于 URL 缩短服务。例如,我的网站是 funnelfiasco.com,所以我买了 funnelfias.co 用于我的 URL 缩短服务(好吧,它不是很短,但它可以满足我的虚荣心)。如果你不将缩短服务作为单独的域运行,请跳到下一部分。

第一步是设置将用于 URL 缩短服务的 VirtualHost。有关 VirtualHost 的更多信息,请参阅 David Both 的文章。这步只需要几行:

    <VirtualHost *:80>
        ServerName funnelfias.co
    </VirtualHost>
创建重写规则
此服务使用 HTTPD 的重写引擎来重写 URL。如果你在上面的部分中创建了 VirtualHost,则下面的配置跳到你的 VirtualHost 部分。否则跳到服务器的 VirtualHost 或主 HTTPD 配置。

    RewriteEngine on
    RewriteMap shortlinks txt:/data/web/shortlink/links.txt
    RewriteRule ^/(.+)$ ${shortlinks:$1} [R=temp,L]
第一行只是启用重写引擎。第二行在文本文件构建短链接的映射。上面的路径只是一个例子。你需要使用系统上使用有效路径(确保它可由运行 HTTPD 的用户帐户读取)。最后一行重写 URL。在此例中,它接受任何字符并在重写映射中查找它们。你可能希望重写时使用特定的字符串。例如,如果你希望所有缩短的链接都是 “slX”(其中 X 是数字),则将上面的 (.+) 替换为 (sl\d+)。

我在这里使用了临时重定向(HTTP 302)。这能让我稍后更新目标 URL。如果希望短链接始终指向同一目标,则可以使用永久重定向(HTTP 301)。用 permanent 替换第三行的 temp。

构建你的映射
编辑配置文件 RewriteMap 行中的指定文件。格式是空格分隔的键值存储。在每一行上放一个链接:

    osdc https:/opensource.com/users/bcotton
    twitter https:/twitter.com/funnelfiasco
    swody1 https:/www.spc.noaa.gov/products/outlook/day1otlk.html

 

   我们大多数人都熟悉,看到这样的网址bit.ly或t.co我们的Twitter或Facebook饲料。 这些都是缩短的URL,这是一个简短的别名,或指向一个较长的页面链接的例子。 例如,我可以给你缩短网址http://bit.ly/SaaYw5 ,将转发给你一个很长的URL,谷歌就如何熨衬衫的搜索结果。 这将是更容易的文本20个字符bit.ly网址到您的儿子,谁是在大学和准备他的第一次大的工作面试。

在本文中,您将学习如何创建一个功能齐全的URL缩短为您的网站,将工作是否使用前端控制器/框架与否。 如果您使用的是前端控制器中,我将讨论如何轻松集成这个URL缩短,而不必深入到控制器的编程。

回答一些常见的问题
因此,与bit.ly和许多其他网址shorteners喜欢它的存在并且可自由查看的,我们为什么要费心建造我们自己的? 大多数缩短服务的甚至有一个易于使用的API,使我们可以通过编程生成一个缩短的URL,而我们的PHP脚本中使用它。

最好的理由是为了方便,美观和品牌知名度。 例如,如果你的网站有,创造了大量的报道,一个非常活跃的博客或大相册的应用程序,就会有大量的链接。 一个URL缩短器将允许您以编程方式创建,可以通过电子邮件发送给你的读者或发布在您的网站一个干净,简单的链接。 最明显的优势,拥有自己的是你的读者有瞬间的品牌知名度与您的网站。

你可能想知道为什么你总是看到信件,在缩短网址的数字混合。 由有十余个选项(0-9)每个数字,我们能够有显着更多的组合,同时保持代码尽可能短。

我们将要使用的字符包括数字1-9以及各种大/小写字母。 我已经删除了所有的元音,以防止其创建的链接这是意想不到的不好的话,我已删除,可能相互混淆的任何字符。 这给了我们大约50个字符可用于每个数字的列表,这意味着使用两个字符,我们有2500种可能的组合,125,000的可能性有三个字符,而高达650万的组合只有四个大字!

规划数据库
让我们建立short_urls表。 这是一个简单的表和下面的create语句被找到:


CREATE TABLE IF NOT EXISTS short_urls(
  ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  long_url VARCHAR (255)NOT NULL ,
  short_code VARBINARY(6)NOT NULL ,
  DATE_CREATED INTEGER UNSIGNED NOT NULL ,
  计数器INTEGER UNSIGNED NOT NULL DEFAULT '0' ,
 
  PRIMARY KEY (ID),
  主要short_code(short_code)

ENGINE = InnoDB的;
我们有我们的标准自动递增的主键和字段的完整URL,URL的缩短代码(更快的检索索引),创建行时的时间戳,和时代的短网址已经被浏览的次数。

请注意, long_url场有255个字符的最大长度,这应该对于大多数应用是足够的。 如果你需要存储较长的URL,那么你就需要将其定义更改为TEXT 。

现在到PHP的!

创建一个URL短码
创建和解码短URL编码的代码将在一个名为SHORTURL类。 首先,让我们来看看负责创建短代码的代码:



<?PHP
类SHORTURL
{
    保护静态的$字符= “123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ” ;
    保护静态$表= “short_urls” ;
    保护静态$ checkUrlExists = TRUE;
 
    保护$ PDO ;
    保护$时间戳;
 
    公共函数__construct(PDO $ PDO ){
        $本- > PDO = $ PDO ;
        $本- >时间戳= $ _SERVER [ “REQUEST_TIME” ];
    }
 
    公共功能urlToShortCode($网址){
        如果(空($ URL )){
            抛出新的异常(“没有网址所提供的。” );
        }
 
        如果($这个- > validateUrlFormat($网址)== FALSE){
            抛出新的异常(
                “URL没有一个有效的格式。” );
        }
 
        如果(个体经营:: $ checkUrlExists ){
            如果(!$这个- > verifyUrlExists($ URL )){
                抛出新的异常(
                    “URL不会出现存在。” );
            }
        }
 
        $简码= $这个- > urlExistsInDb($ URL );
        如果($简码== FALSE){
            $简码= $这个- > createShortCode($ URL );
        }
 
        返回$简码;
    }
 
    保护功能validateUrlFormat($网址){
        返回filter_var($网址,FILTER_VALIDATE_URL,
            FILTER_FLAG_HOST_REQUIRED);
    }
 
    保护功能verifyUrlExists($网址){
        $ CH = curl_init();
        中curl_setopt($通道,CURLOPT_URL,$ URL );
        中curl_setopt($通道,CURLOPT_NOBODY,真实);
        中curl_setopt($通道,CURLOPT_RETURNTRANSFER,真实);
        curl_exec($ CH );
        $反应= curl_getinfo($通道,CURLINFO_HTTP_CODE);
        curl_close($ CH );
 
        返回(!空($回应)&& $反应= 404!);
    }
 
    保护功能urlExistsInDb($网址){
        $查询= “选择short_code FROM” 。自:: $表。
            “WHERE long_url =:long_url LIMIT 1” ;
        $ stmt的= $这个- > PDO->准备($查询);
        $ PARAMS = 阵列(
            “long_url” => $网址
        );
        $ stmt的- >执行($ PARAMS );
 
        $结果= $ stmt的- > fetch()方法;
        返回(空($结果))?假:$结果[ “short_code” ];
    }
 
    保护功能createShortCode($网址){
        $ ID = $这个- > insertUrlInDb($ URL );
        $简码= $这个- > convertIntToShortCode($编号);
        $本- > insertShortCodeInDb($ ID ,$简码);
        返回$简码;
    }
 
    保护功能insertUrlInDb($网址){
        $查询= “INSERT INTO” 。自:: $表。
            “(long_url,DATE_CREATED)” 。
            “VALUES(:long_url,:时间戳)” ;
        $ stmnt = $这个- > PDO->准备($查询);
        $ PARAMS = 阵列(
            “long_url” => $网址,
            “时间戳” => $这个- >时间戳
        );
        $ stmnt - >执行($ PARAMS );
 
        返回$这个- > PDO-> lastInsertId();
    }
 
    保护功能convertIntToShortCode($编号){
        $ ID = INTVAL ($编号);
        如果($编号<1){
            抛出新的异常(
                “该ID是不是一个有效的整数” );
        }
 
        $长度= strlen的(自我:: $字符);
        / /确保可用字符长度为
        / /至少有一个合理的最低 - 应该有
        / /至少10个字符
        如果($长度<10){
            抛出新的异常(“字符的长度过小” );
        }
 
        $代码= “” ;
        而($编号> $长度- 1){
            / /判断下一个更高的字符的值
            / /在短期代码应该是和前置
            $代码=自:: $字符[ FMOD ($ ID ,$长度)]。
                $代码;
            / /复位$ id来剩余价值转换
            $ ID = 楼($编号/ $长度);
        }
 
        $的id / /剩余值小于长度
        / /自:: $字符
        $代码=自:: $字符[ $ ID ]。$代码;
 
        返回$代码;
    }
 
    保护功能insertShortCodeInDb($ ID ,$代码){
        如果(的$ id == NULL | | $代码== NULL){
            抛出新的异常(“输入参数(S)无效。” );
        }
        $查询= “UPDATE” 。自:: $表。
            “SET short_code =:short_code WHERE ID =:ID” ;
        $ stmnt = $这个- > PDO->准备($查询);
        $ PARAMS = 阵列(
            “short_code” => $代码,
            “ID” => $编号
        );
        $ stmnt - >执行($ PARAMS );
 
        如果($ stmnt - > rowCount等()<1){
            抛出新的异常(
                “行未更新与短码。” );
        }
 
        返回真;
    }

重启 HTTPD
最后一步是重启 HTTPD 进程。这是通过 systemctl restart httpd 或类似命令完成的(命令和守护进程名称可能因发行版而不同)。你的链接缩短服务现已启动并运行。当你准备编辑映射时,无需重新启动 Web 服务器。你所要做的就是保存文件,Web 服务器将获取到差异。

小结:
此示例为你提供了基本的 URL 缩短服务。如果你想将开发自己的管理接口作为学习项目,它可以作为一个很好的起点。或者你可以使用它分享容易记住的链接到那些容易忘记的 URL。

  当我们实例化ShortUrl类,我们将通过它我们的PDO对象实例。 构造函数存储此引用,并设置$timestamp成员。

 以上为URL缩短服务技术,大家可以参考下