Platform pemendek URL (URL Shortener) berbasis PHP dengan database PostgreSQL. Desain UI bergaya retro khas situs 2000-an, dengan fokus pada privasi pengguna.
- Pemendekan URL dengan custom alias & masa kedaluwarsa opsional
- Privasi utama: slug/kode shortlink tidak pernah ditampilkan terbuka di halaman publik — selalu tersensor (mis.
Je***h) - Form pembuatan link bersifat "sekali pakai" — me-refresh browser setelah submit akan memicu dialog konfirmasi pengiriman ulang formulir (perilaku klasik, disengaja — bukan menggunakan pola Post/Redirect/Get)
- Redirect instan
/:idvia rewrite.htaccess→go.php?id= - Halaman 404 khusus untuk slug yang tidak ditemukan/kedaluwarsa/dihapus
- Statistik publik (
stats.php) — tersensor; admin panel (admin/dashboard.php) — data lengkap - Admin bisa: hapus link, sembunyikan/tampilkan link dari statistik publik, blokir IP
- Satu-satunya endpoint publik:
api/createnew.php(mirip TinyURL), dilindungi rate limiting per-IP - Proteksi CSRF di semua form, prepared statements di semua query, sanitasi input URL
nvshort/
├── .env.example # Contoh konfigurasi environment
├── .htaccess # Rewrite /:id -> go.php, security headers
├── schema.sql # Skema database Neon PostgreSQL
├── config.php # Bootstrap: load .env, konstanta, DB
├── index.php # Beranda + form pemendekan URL
├── go.php # Handler redirect shortlink
├── stats.php # Statistik publik (tersensor)
├── about.php # Tentang & Syarat Ketentuan
├── 404.php # Halaman 404 kustom
├── includes/
│ ├── db.php # Koneksi PDO ke Neon
│ ├── functions.php # Helper: validasi, sensor, rate limit, dst
│ ├── header.php # Header retro (dipakai semua halaman)
│ └── footer.php # Footer retro
├── admin/
│ ├── login.php # Login admin (+ ?expired=true, ?action=logout)
│ └── dashboard.php # Panel admin (?action=delete|visibility|ban-ip)
├── api/
│ └── createnew.php # API publik: GET/POST ?dest=... (rate limited)
└── assets/
└── style.css # Tema retro 2000-an
- Buat database PostgreSQL baru
sudo -u <user_postgresql> createdb <nama_database>
- Rakit connection string (format
postgres://user:pass@localhost:5432/db?sslmode=disable). - Jalankan SQL schema dengan
sudo -u <user_postgresql> -d <nama_database> -f ./schema.sql
cp .env.example .envEdit .env:
DATABASE_URL=postgres://user:pass@localhost:5432/db?sslmode=disable
ADMIN_PASSWORD_HASH=
BASE_URL=https://domainkamu.com
APP_TIMEZONE=Asia/JakartaBuat hash password admin (jangan simpan password polos!):
php -r "echo password_hash(password_rahasiamu, PASSWORD_DEFAULT), PHP_EOL;"Tempel hasilnya ke ADMIN_PASSWORD_HASH.
- PHP 8.1+ dengan ekstensi
pdo_pgsqlaktif - Apache dengan
mod_rewrite&mod_headersaktif (untuk.htaccess) AllowOverride Alldiaktifkan pada konfigurasi Virtual Host agar.htaccessterbaca
Menggunakan Nginx atau server lain? Kamu perlu menerjemahkan aturan di
.htaccesske konfigurasi rewrite yang setara (proxy semua request non-file/direktori kego.php?id=$1, kecuali path/admin,/api,/assets,/includes, dan file PHP inti).
Upload seluruh isi folder ke document root hosting kamu (atau jalankan lokal via php -S localhost:8000 untuk testing cepat — catatan: server bawaan PHP tidak membaca .htaccess, jadi rewrite /:id tidak akan berjalan di mode ini, gunakan Apache untuk pengujian penuh).
| Rute | Deskripsi |
|---|---|
GET / |
Beranda + form pemendekan URL |
GET /:id |
Redirect ke destination (via rewrite ke go.php?id=) |
GET /stats.php |
Statistik publik semua link (tersensor) |
GET /stats.php?id={slug} |
Statistik detail satu link (tersensor tampilan, perlu kode persis) |
GET /about.php |
Tentang NvShort & Ketentuan Layanan |
GET/POST /admin/login.php |
Login admin. ?expired=true untuk pesan sesi habis. ?action=logout untuk logout |
GET/POST /admin/dashboard.php |
Panel admin. ?action=delete|visibility|ban-ip|unban-ip |
GET/POST /api/createnew.php?dest={url} |
Satu-satunya API publik, rate limited (5 req/60 detik per IP) |
- Ganti
ADMIN_PASSWORD_HASHdengan password yang kuat & unik. - Jangan pernah commit file
.envke repository publik. - Rate limit API bisa disesuaikan lewat konstanta
API_RATE_LIMIT&API_RATE_WINDOWdiconfig.php. - Validasi URL saat ini memblokir target ke
localhost/IP privat untuk mengurangi potensi penyalahgunaan, namun tidak melakukan pengecekan reputasi domain (judi/phishing/malware) secara otomatis — pertimbangkan integrasi Google Safe Browsing API jika dibutuhkan moderasi otomatis.