Website Logo. Upload to /source/logo.png ; disable in /source/_includes/logo.html

Hacker School Log

Laura Skelton | Summer 2014 Batch

Hacker School Day 14: URL Shortener

I went to the Jobs Practice session on Friday and worked on the assigned project of making a quick URL shortener in 2 hours, which is practice for interview projects. I’d never done a URL shortener before, and hadn’t worked on web/PHP type stuff in awhile since I switched to iOS apps, so I was excited for the change of pace and the well-defined project.

I was confident that I could write a PHP script very quickly to do the URL shortening and routing, but as I put this up under a subdomain of an existing server I had running for another site, I had to make some tricky changes to the .htaccess file so that Apache would reroute all of the URLs for my shortener to the index.php file with all of my routing scripts. This proved trickier than I expected, since I’m not super familiar with the syntax of the .htaccess file and had some trouble getting it to route things properly.

Finally I got the .htaccess file to send things to my script so I could actually write the shortener, but I’d like to revisit it this week and learn enough that I can write that part more confidently in the future, and so that I can implement this version better than it currently is written.

I catch short URLs by grabbing the URL with PHP, then look up the short link in the MySQL database, and then redirect the page to the long URL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
if ((strlen($shorturl) > 0) && $shorturl != "shorten") {
        # should redirect to this url

  $query = "
        SELECT
        id,
        short,
        url
        FROM urllinks
        WHERE
        short = :shortlink
        ";
        $query_params = array(
                              ':shortlink' => $shorturl
                              );

        try{
            $stmt = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch(PDOException $ex){ die("Failed to run query: " . $ex->getMessage()); }
        $goturl_ok = false;
        $row = $stmt->fetch();
        if($row){
            $goturl_ok = true;
        }

        if($goturl_ok){
            # redirect to the url
            header("Location: " . $row[url]);
            die("Redirecting to: " . $row[url]);
        } else{
            print("Redirect Failed. No such link.");
        }

}

If it’s not a short URL, then I look for POST variables to see if the user is trying to shorten their own URL. If so, and if it’s a valid URL, I generate a random string of 6 characters and store them in the database with the URL they should point to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
if(!empty($_POST['urltoshorten'])){

    if (filter_var($_POST['urltoshorten'], FILTER_VALIDATE_URL) === FALSE) {
        echo "<p>URL '" . $_POST['urltoshorten'] . "' is not valid.</p>";
    } else {

        function random_string($length = 6, $chars = '1234567890qwrtypsdfghjklzxcvbnmQWRTYPSDFGHJKLZXCVBNM')
        {
            $chars_length = (strlen($chars) - 1);
            $string = $chars{rand(0, $chars_length)};

            for ($i = 1; $i < $length; $i = strlen($string))
            {
                $r = $chars{rand(0, $chars_length)};
                $string .=  $r;
            }
            return $string;
        }

        $shortstring = random_string();

        $query = "
        INSERT INTO urllinks (short, url)
        VALUES (:shortstring, :urltoshorten)
        ";
        $query_params = array(
                              ':shortstring' => $shortstring,
                              ':urltoshorten' => $_POST['urltoshorten']
                              );

        try{
            $stmt = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch(PDOException $ex){ die("Failed to run query: " . $ex->getMessage()); }
        $goturl_ok = false;
        $row = $stmt->rowCount();
        # share the new short url
        echo '<p>Shortened URL to <a href="http://prty.us/' . $shortstring . '">' . 'http://prty.us/' . $shortstring . '</a></p>';
    }

}

Otherwise, I return a pretty form for URL shortening that posts to this same page.

1
2
3
4
5
6
7
8
9
<form method="post" action="http://prty.us/shorten" id="shortenurlform">
  <div>
      <label for="urltoshorten">Enter your URL to shorten:</label>
      <input type="text" class="input-field" id="urltoshorten" name="urltoshorten" value="">
  </div>
  <div>
      <input type="submit" class="btn btn-default">
  </div>
</form>

Check it out! It was cool how simple this was to implement (the PHP part at least). I used Twitter Bootstrap along with a template I’ve used previously to get something nice-looking up very quickly. It’s also responsive (everything rearranges nicely if the screen size is smaller, like on your phone) without putting really any extra work into it, since that’s part of Bootstrap.

This made me miss doing web stuff and I’m thinking of doing more web development while I’m here. I find that every project I make needs a good website even just for marketing, and responsive mobile-friendly websites can be a great way to extend an iOS app’s functionality to other device platforms.