PHPackages                             mattmezza/shrtnr - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. mattmezza/shrtnr

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

mattmezza/shrtnr
================

Your super simple and fast private goo·gl/bit·ly system, privately hosted wherever you want, completely frontend agnostic.

0.0.4(8y ago)017MITPHPPHP ^7.0

Since Mar 28Pushed 8y ago1 watchersCompare

[ Source](https://github.com/mattmezza/shrtnr)[ Packagist](https://packagist.org/packages/mattmezza/shrtnr)[ RSS](/packages/mattmezza-shrtnr/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (2)Versions (5)Used By (0)

shrtnr
======

[](#shrtnr)

Your super simple and fast private goo·gl/bit·ly system, privately hosted wherever you want, completely frontend agnostic.

Installation
------------

[](#installation)

- `composer require mattmezza/shrtnr`
- define the env variables needed and set up the DB (check below)

Usage
-----

[](#usage)

The `Shrtnr` class offers a very simple API:

- `shrtn(string $from, string $ip = null) : string` -&gt; Given a URI gives back the destination URL of the rule matching with the `from` field (or throws a `NoRuleException` if no rule is associated with the passed URI)

Can be used like this (in this example we forward the query string to the destination URL):

```
$both = explode("?", $_SERVER["REQUEST_URI"]);
$uri = $both[0];
$shrtnr = new Shrtnr();
try {
    $to = $shrtnr->shrtn($uri);
    if (count($both) > 1) {
        $to .= "?" . $_SERVER["QUERY_STRING"];
    }
    header("Location: $to");
} catch (NoRuleException $e) {
    die($e->getMessage());
}
```

Admin usage
-----------

[](#admin-usage)

To add, edit, remove and search for clicks and rules you can check out the DAOs `Clicks` and `Rules` that are exposing a couple of methods for CRUD ops.

DB
--

[](#db)

`shrtnr` connects to the DB using three ENV variables `DB` which is the DSN (e.g. `mysql:host=127.0.0.1;dbname=shrtnr`), `DB_USER` and `DB_PASS` respectively for the db user and password.

The DB itself should be built as follows:

```
CREATE TABLE IF NOT EXISTS `clicks` (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `rule_id` int(11) unsigned NOT NULL,
        `clicked_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `from` varchar(256) NOT NULL DEFAULT '',
        `to` varchar(256) NOT NULL DEFAULT '',
        `ip` varchar(16) DEFAULT NULL,
        PRIMARY KEY (`id`),
        KEY `rule_id` (`rule_id`),
        CONSTRAINT `clicks_ibfk_1` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `rules` (
        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
        `user_id` varchar(256) DEFAULT NULL,
        `from` varchar(256) NOT NULL,
        `to` varchar(256) NOT NULL,
        `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `enabled` tinyint(1) NOT NULL DEFAULT '1',
        `modified_at` datetime DEFAULT NULL,
        PRIMARY KEY (`id`),
        UNIQUE KEY `from` (`from`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8
```

Entities
--------

[](#entities)

`shrtnr` works with two main entities: `Rule` and `Click`.

### Rule

[](#rule)

It is the rule that instructs the system what to do for a specific URI. It has info about the matching URI and the destination URL. It also has a field `user_id` that should report an id of the user who created the rule (can be either a string or a numeric id).

### Click

[](#click)

It represents an applied rule, it is created when somebody goes to the URI and gets redirected to the matching destination. It reports info about the IP address and references the applied rule.

Development
-----------

[](#development)

- `git clone https://github.com/mattmezza/shrtnr.git`
- `cd shrtnr`
- define the `DB`, `DB_USER`, `DB_PASS` env variable
- `composer migrate`
- `composer test`

##### Matteo Merola

[](#matteo-merola-mattmezzagmailcom)

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~7 days

Total

4

Last Release

2944d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d6a2ff3ef032e7f54115b382f0a85ed15ae8dc7854f242fbe49f1ac299d7f0a4?d=identicon)[mattmezza](/maintainers/mattmezza)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mattmezza-shrtnr/health.svg)

```
[![Health](https://phpackages.com/badges/mattmezza-shrtnr/health.svg)](https://phpackages.com/packages/mattmezza-shrtnr)
```

###  Alternatives

[vinkius-labs/laravel-page-speed

Laravel Page Speed

2.5k5.4k1](/packages/vinkius-labs-laravel-page-speed)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
