{"id":25880911,"url":"https://github.com/leopardd/urlshortenerbundle","last_synced_at":"2025-03-02T14:26:25.895Z","repository":{"id":19304384,"uuid":"86065209","full_name":"leopardd/UrlShortenerBundle","owner":"leopardd","description":":tada: UrlShortenerBundle for Symfony 3","archived":false,"fork":false,"pushed_at":"2022-06-07T13:48:41.000Z","size":18,"stargazers_count":4,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-27T17:41:25.832Z","etag":null,"topics":["bitly","symfony-bundle","url-shortener"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/leopardd/url-shortener-bundle","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leopardd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-24T12:23:04.000Z","updated_at":"2022-04-30T05:20:41.000Z","dependencies_parsed_at":"2022-09-17T19:11:53.274Z","dependency_job_id":null,"html_url":"https://github.com/leopardd/UrlShortenerBundle","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leopardd%2FUrlShortenerBundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leopardd%2FUrlShortenerBundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leopardd%2FUrlShortenerBundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leopardd%2FUrlShortenerBundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leopardd","download_url":"https://codeload.github.com/leopardd/UrlShortenerBundle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241519062,"owners_count":19975589,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitly","symfony-bundle","url-shortener"],"created_at":"2025-03-02T14:26:25.250Z","updated_at":"2025-03-02T14:26:25.886Z","avatar_url":"https://github.com/leopardd.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UrlShortenerBundle\n\n[![Latest Version on Packagist][ico-version]][link-packagist]\n[![Software License][ico-license]](LICENSE.md)\n[![Build Status][ico-travis]][link-travis]\n\n## Getting started\n\n```\n1. Install\n$ composer require leopardd/url-shortener-bundle\n\n2. Register bundle\n\u003c?php\n// app/AppKernel.php\n\npublic function registerBundles()\n{\n    $bundles = [\n        // ...\n        new Leopardd\\Bundle\\UrlShortenerBundle\\LeoparddUrlShortenerBundle(),\n    ];\n    \n    // ...\n}\n  \n3. (optional) Setup parameter\n\n// config.yml\nleopardd_url_shortener:\n    hashids:\n        salt: new salt\n        min_length: 10\n        alphabet: abcdefghijklmnopqrstuvwxyz1234567890\n\n4. Update database schema\n$ php app/console doctrine:schema:update --force\n```\n\n## Folder structure\n\n```\nController\nDependencyInjection\nEntity..................represent table structure\nEvent\nException\nFactory.................create Entity instance\nRepository..............all interaction with database\nResources\nService.................contain business logic\n```\n\n## Feature \u0026 Update \u0026 Note\n\n- [x] Example project: [leopardd/bitly](https://github.com/leopardd/bitly)\n- [x] Support PHP 5.6, 7.0\n- [ ] Message queue\n- [ ] Caching (e.g. Redis)\n- Scaling\n  - [ ] Separate host/db/table/id\n  - [ ] Docker swarm setup\n  - [ ] what happened when ID reach maximum of MySQL\n  - [ ] Many databases\n  - [ ] Random bulk generate URL for test\n- [x] Case-sensitive\n- [x] Remove trailing before processing\n- [ ] Change naming `EncodeService` to `ProcessService`\n- [ ] Test `EventDispatcher`\n- [ ] Using [Symfony\\Component\\Validator](https://symfony.com/doc/current/validation.html) as a service + JMS to validate data\n- [ ] Implement [FriendsOfSymfony/FOSRestBundle](https://github.com/FriendsOfSymfony/FOSRestBundle)\n- Properties\n  - [ ] Custom code\n  - [ ] Hits\n  - [ ] Expiry date\n- Validate url\n  - [x] Is url\n  - [x] Remove trailing slash\n  - [x] No more than 255 character\n- Research\n  - [ ] [Ph3nol/UrlShortenerBundle](https://github.com/Ph3nol/UrlShortenerBundle)\n  - [ ] [mremi/UrlShortenerBundle](https://github.com/mremi/UrlShortenerBundle)\n  - [x] gomeeki/url-shortener-bundle](https://github.com/gomeeki/url-shortener-bundle/)\n- Test\n  - [x] phpspec\n  - [x] PHP CodeSniffer\n\n## Algorithm\n\n### Get \"short-url\" process\n\n1. Insert \"long-url\" into database then return `row-id`\n2. Encode `row-id` then save it\n\n### Redirect \"short-url\" process\n\n1. Decode incoming \"short-url\" then we get `row-id`\n2. Return item in that `row-id`\n\n### Reason behind \"row-id\" approach\n\nShort url: produce shortened version of url\n1. Generate: produce a shortened version of the URL submitted\n2. Lookup: when the shortened version is called, look up this reference in database then return it\n\nAnd the challenge is\n1. Lookup time\n2. Allow very very large number of unique ids and at the same time\n3. Keep the ID length as small as possible\n4. ID should be sort of user friendly and possibly a memorable (if possible)\n5. Scale with multiple instances (Sharding)\n6. What happens when ID reach the maximum value e.g. (if the length is 7 containing [A-Z, a-z, 0-9], we can serve 62^7 (~35k billion) urls)\n7. Replication, database can be crashed by many problems, how to replicate instances, recover fast ?, keep read / write consistent ?\n\nIn this bundle, we will focus on point 1.\nHow we can reduce loop-up time.\n\n```\nTable stucture\nid: number\ncode: shortened version of long url\nurl: long url\n\nAttempt 1\n- Generate: random id\n- Lookup: simple loop up (O(n))\n\nAttempt 2\n- Generate: hash function from long url\n- Lookup: simple loop up (O(n))\n\nAttempt 3\n- Generate: hash function from long url\n- Lookup: bloom filters\n\nAttempt 4\n- Generate: hash function from record id\n- Lookup: decoding (O(1))\n```\n\nSo, In this project decide to using \"Attemp 4\" by using [Hashids](http://hashids.org/php/) for hash function (Hashids will generate unique code from difference id)\n\n## Reference \u0026\u0026 Tool\n\n- Inspired by [gomeeki/url-shortener-bundle](https://github.com/gomeeki/url-shortener-bundle/)\n- [Hashids](http://hashids.org/php/)\n- [RegExr](http://regexr.com/)\n\n### Algorithm\n\n- [How to code a URL shortener?](http://stackoverflow.com/questions/742013/how-to-code-a-url-shortener)\n- [What are the http://bit.ly and t.co shortening algorithms?](https://www.quora.com/What-are-the-http-bit-ly-and-t-co-shortening-algorithms)\n- [Create a TinyURL System](http://blog.gainlo.co/index.php/2016/03/08/system-design-interview-question-create-tinyurl-system/)\n- Bloom filter\n  - [What are Bloom filters?](https://blog.medium.com/what-are-bloom-filters-1ec2a50c68ff)\n  - [Practical uses of bloom filter – SPAM filter and URL shortener and Weak Password Dict](https://theworldsoldestintern.wordpress.com/2012/11/03/practical-uses-of-bloom-filter-spam-filter-and-url-shortener/)\n  - [Bloom Filters by Example](https://llimllib.github.io/bloomfilter-tutorial/)\n  - [What is the advantage to using bloom filters?](http://stackoverflow.com/questions/4282375/what-is-the-advantage-to-using-bloom-filters)\n\n[ico-version]: https://img.shields.io/packagist/v/leopardd/url-shortener-bundle.svg?style=flat-square\n[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\n[ico-travis]: https://img.shields.io/travis/leopardd/UrlShortenerBundle/master.svg?style=flat-square\n\n[link-packagist]: https://packagist.org/packages/leopardd/url-shortener-bundle\n[link-travis]: https://travis-ci.org/leopardd/UrlShortenerBundle\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleopardd%2Furlshortenerbundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleopardd%2Furlshortenerbundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleopardd%2Furlshortenerbundle/lists"}