A lightweight, self-hosted PHP photography portfolio.
Hafif, kendi sunucunda çalışan PHP fotoğraf portföy scripti.
Lightframe is a single-file PHP photography portfolio script. Drop it on any PHP server, add your photos into folders, and you have a clean, fast, fully functional portfolio — no database, no framework, no build step required.
Key Features
- Zero database — folder structure is your data model
- Auto-generated thumbnails with EXIF orientation correction
- EXIF data viewer (camera, ISO, aperture, focal length, exposure)
- Lightbox with zoom and scroll, mobile swipe support
- Clean URLs (
/albums,/album/your-album-name) - Nonce-based Content Security Policy (CSP)
- Path traversal protection on all file operations
- Responsive design — mobile, tablet, desktop
photos/directory locked down via.htaccesswhitelist
| Requirement | Version |
|---|---|
| PHP | 8.0 or higher |
| Apache | with mod_rewrite enabled |
| PHP Extensions | gd, exif |
⚠️ PHP 8.0+ is required because the code usesstr_starts_with()andmatchexpressions.
your-domain.com/
│
├── index.php ← Main application file
├── .htaccess ← URL routing + security headers
│
├── assets/
│ ├── style.css ← Stylesheet
│ ├── main.js ← Frontend JavaScript
│ └── pp.jpg ← Your profile / hero photo
│
└── photos/
├── .htaccess ← Locks down the photos directory
├── My Trip/
│ ├── cover.jpg ← (optional) album cover image
│ ├── photo1.jpg
│ └── photo2.jpg
└── Another Album/
├── photo1.jpg
└── photo2.webp
1. Upload files
Upload all files to your web server's public directory (public_html, www, or htdocs).
index.php
.htaccess
assets/style.css
assets/main.js
assets/pp.jpg
photos/.htaccess
2. Add your photos
Create folders inside the photos/ directory. Each folder becomes an album.
photos/
Summer 2024/
photo1.jpg
photo2.jpg
Architecture/
building1.jpg
Optionally place a cover.jpg inside any album folder — this image will be used as the album cover on the albums listing page. If no cover.jpg is present, the first photo in the folder is used.
3. Configure your profile
Open index.php and edit the $config array near the top of the file:
$config = [
"name" => "YOUR NAME",
"title" => "Visual Artist & Photographer",
"logo" => "YN/STUDIO",
"location" => "CITY, COUNTRY",
"since" => "2020",
"biography" => "Your bio text here.",
"avatar" => "assets/pp.jpg", // relative path, no leading slash
"social" => [
["name" => "Instagram", "url" => "https://instagram.com/yourhandle", "icon" => "fa-brands fa-instagram"],
["name" => "Behance", "url" => "https://behance.net/yourhandle", "icon" => "fa-brands fa-behance"],
["name" => "Email", "url" => "mailto:hello@yourdomain.com", "icon" => "fa-solid fa-envelope"],
],
];4. Enable mod_rewrite (Apache)
Ensure mod_rewrite is enabled on your server. Most shared hosting providers have this enabled by default.
If you are running locally with XAMPP or similar, open httpd.conf or httpd-vhosts.conf and make sure AllowOverride All is set for your directory.
💡 The
.htaccessfile has noRewriteBasedirective — the application detects its own URL path automatically, so it works correctly whether installed at the domain root or inside a subdirectory (e.g.localhost/Lightframe/). No manual configuration needed.
5. Set permissions
chmod 644 index.php .htaccess
chmod 755 assets/ photos/
chmod 644 assets/*The script will automatically create _thumbs/ subdirectories inside each album folder when thumbnails are generated for the first time. Make sure the photos/ directory is writable by the web server.
| URL | Page |
|---|---|
/ |
Homepage |
/albums |
Albums list |
/album/my-album-name |
Single album |
Album slugs are automatically generated from folder names. Special characters and spaces are normalized (e.g. My Trip 2024 → my-trip-2024).
jpg · jpeg · png · webp
Both uppercase and lowercase extensions are supported.
| Action | Result |
|---|---|
| Click photo | Open lightbox |
| Click image | Zoom in / out |
| Scroll (when zoomed) | Pan around the image |
Arrow keys ← → |
Previous / next photo |
Escape |
Close lightbox |
| Swipe left / right (mobile) | Navigate photos |
ℹ button |
Toggle EXIF info panel |
- Content Security Policy is generated per-request with a unique nonce — inline scripts are blocked
- Path traversal is prevented on all file read operations via
realpath()validation - photos/.htaccess blocks all requests except image files, and disables PHP execution inside the directory
- No user input is ever written to disk or executed
MIT License — free to use, modify, and distribute.
Credit appreciated but not required.
Lightframe, tek dosyalı bir PHP fotoğraf portföy scriptidir. Herhangi bir PHP sunucusuna yükle, fotoğraflarını klasörlere ekle — veritabanı, framework veya derleme adımı olmadan temiz, hızlı ve tam işlevli bir portföy sitene sahip ol.
Özellikler
- Veritabanı yok — klasör yapısı veri modelidir
- Otomatik thumbnail üretimi, EXIF yön düzeltmesi ile
- EXIF veri görüntüleyici (kamera, ISO, diyafram, odak uzaklığı, pozlama)
- Zoom ve scroll destekli lightbox, mobil swipe desteği
- Temiz URL'ler (
/albumler,/album/albüm-adı) - Nonce tabanlı Content Security Policy (CSP)
- Tüm dosya işlemlerinde path traversal koruması
- Duyarlı tasarım — mobil, tablet, masaüstü
photos/dizini.htaccessbeyaz listesiyle kilitlenmiş
| Gereksinim | Sürüm |
|---|---|
| PHP | 8.0 veya üzeri |
| Apache | mod_rewrite etkin olmalı |
| PHP Eklentileri | gd, exif |
⚠️ PHP 8.0+ zorunludur; kodstr_starts_with()vematchifadelerini kullanmaktadır.
alan-adiniz.com/
│
├── index.php ← Ana uygulama dosyası
├── .htaccess ← URL yönlendirme + güvenlik başlıkları
│
├── assets/
│ ├── style.css ← Stil dosyası
│ ├── main.js ← Frontend JavaScript
│ └── pp.jpg ← Profil / hero fotoğrafın
│
└── photos/
├── .htaccess ← photos dizinini kilitler
├── İstanbul Gezisi/
│ ├── cover.jpg ← (isteğe bağlı) albüm kapak fotoğrafı
│ ├── foto1.jpg
│ └── foto2.jpg
└── Mimari/
├── foto1.jpg
└── foto2.webp
1. Dosyaları yükle
Tüm dosyaları sunucunun genel dizinine yükle (public_html, www veya htdocs).
index.php
.htaccess
assets/style.css
assets/main.js
assets/pp.jpg
photos/.htaccess
2. Fotoğrafları ekle
photos/ dizininin içinde klasörler oluştur. Her klasör bir albüm olur.
photos/
Yaz 2024/
foto1.jpg
foto2.jpg
Mimari/
bina1.jpg
Herhangi bir albüm klasörüne isteğe bağlı olarak cover.jpg ekleyebilirsin — bu fotoğraf albümler listesinde kapak görseli olarak kullanılır. cover.jpg yoksa klasördeki ilk fotoğraf kullanılır.
3. Profil ayarlarını yap
index.php dosyasını aç ve dosyanın üst kısmındaki $config dizisini düzenle:
$config = [
"name" => "ADINIZ SOYADINIZ",
"title" => "Görsel Sanatçı ve Fotoğrafçı",
"logo" => "AS/STUDIO",
"location" => "ŞEHİR, TR",
"since" => "2020",
"biography" => "Kısa biyografi metniniz.",
"avatar" => "assets/pp.jpg", // leading slash olmadan göreceli yol
"social" => [
["name" => "Instagram", "url" => "https://instagram.com/kullanici", "icon" => "fa-brands fa-instagram"],
["name" => "Behance", "url" => "https://behance.net/kullanici", "icon" => "fa-brands fa-behance"],
["name" => "Email", "url" => "mailto:merhaba@siteadiniz.com", "icon" => "fa-solid fa-envelope"],
],
];4. mod_rewrite'ı etkinleştir (Apache)
Sunucunda mod_rewrite etkin olmalıdır. Çoğu paylaşımlı hosting sağlayıcısında bu varsayılan olarak açıktır.
XAMPP gibi yerel bir ortamda çalışıyorsan, httpd.conf veya httpd-vhosts.conf dosyasında ilgili dizin için AllowOverride All satırının aktif olduğundan emin ol.
💡
.htaccessdosyasındaRewriteBasedirektifi yoktur — uygulama kendi URL yolunu otomatik olarak tespit eder. Bu sayede hem kök dizinde (localhost/) hem de alt dizinde (localhost/Lightframe/) çalışır. Herhangi bir manuel ayar gerekmez.
5. Dosya izinlerini ayarla
chmod 644 index.php .htaccess
chmod 755 assets/ photos/
chmod 644 assets/*Script, albümlere ilk kez erişildiğinde her albüm klasörü içine otomatik olarak _thumbs/ alt dizini oluşturur. photos/ dizininin web sunucusu tarafından yazılabilir olduğundan emin ol.
| URL | Sayfa |
|---|---|
/ |
Ana sayfa |
/albumler |
Albümler listesi |
/album/albüm-adı |
Tekil albüm |
Albüm slug'ları klasör adlarından otomatik üretilir. Özel karakterler ve boşluklar normalleştirilir (örn. İstanbul Gezisi 2024 → istanbul-gezisi-2024).
jpg · jpeg · png · webp
Büyük ve küçük harf uzantıların ikisi de desteklenir.
| İşlem | Sonuç |
|---|---|
| Fotoğrafa tıkla | Lightbox'ı aç |
| Görüntüye tıkla | Yakınlaştır / uzaklaştır |
| Scroll (zoom'da) | Görüntüde gezin |
Ok tuşları ← → |
Önceki / sonraki fotoğraf |
Escape |
Lightbox'ı kapat |
| Sola / sağa kaydır (mobil) | Fotoğraflar arası geçiş |
ℹ butonu |
EXIF bilgi panelini aç/kapat |
- Content Security Policy her istek için benzersiz nonce ile üretilir — satır içi scriptler engellenir
- Path traversal tüm dosya okuma işlemlerinde
realpath()doğrulamasıyla engellenir - photos/.htaccess görsel dosyalar dışındaki tüm istekleri engeller ve PHP çalıştırmayı devre dışı bırakır
- Hiçbir kullanıcı girdisi diske yazılmaz veya çalıştırılmaz
MIT Lisansı — özgürce kullanabilir, değiştirebilir ve dağıtabilirsin.
Kaynak belirtmek takdirle karşılanır, zorunlu değildir.