# Persyaratan
- PHP >= 8.1
- Composer
- Laragon dan Xampp
# Instalasi
Mulai dari repository kosong.
git clone https://github.com/Captzuzo/haryadi.git
cd haryadi
composer install
cp .env.example .env
php haryadi layanan
# Struktur Proyek
Ringkasan direktori standar:
haryadi/
├─ app/
│ ├─ Controllers/
│ ├─ Models/
│ ├─ Middleware/
│ ├─ Providers/
│ └─ Services/
├─ core/
│ ├─ Router.php
│ ├─ View.php
│ ├─ Database.php
│ └─ ...
├─ public/
│ └─ index.php
├─ resources/
│ └─views/
│ └─welcome.haryadi.php
├─ database/
│ ├─ migrations/
│ └─ seeders/
├─ routes.php
└─ haryadi (CLI entry)
# Routing
Routing di Haryadi Framework mengatur hubungan
antara URL dan aksi (controller atau callback) yang akan
dijalankan. Sistem routing ini ringan, cepat, dan mendukung
berbagai metode HTTP seperti GET, POST,
PUT, PATCH, dan DELETE.
1. Contoh Dasar
use Haryadi\Core\Router;
use App\Controllers\WelcomeController;
Router::get('/', [WelcomeController::class, 'index'])->name('home');
Router::post('/user', [UserController::class, 'store']);
Router::delete('/user/{id}', [UserController::class, 'destroy']);
Masing-masing route dapat diberikan name() untuk
memudahkan referensi.
2. Struktur Kelas Route
Kelas Route merepresentasikan satu definisi rute
tunggal.
namespace Haryadi\Core;
class Route
{
public string $method;
public string $path;
public $handler;
public ?string $name = null;
public function __construct(string $method, string $path, $handler)
{
$this->method = strtoupper($method);
$this->path = $path;
$this->handler = $handler;
}
public function name(string $name): self
{
$this->name = $name;
return $this;
}
}
3. Kelas Router
Kelas Router bertanggung jawab mendaftarkan,
menyimpan, dan mengeksekusi rute. Ia juga mengelola instance
tunggal (singleton) agar semua route berada dalam satu konteks.
| Metode | Deskripsi | Contoh |
|---|---|---|
Router::get($path, $handler) |
Menangani request HTTP GET. |
Router::get('/', [HomeController::class, 'index']);
|
Router::post($path, $handler) |
Menangani request HTTP POST. |
Router::post('/login', [AuthController::class,
'store']);
|
Router::put($path, $handler) |
Menangani request HTTP PUT (update data). |
Router::put('/user/{id}', [UserController::class,
'update']);
|
Router::patch($path, $handler) |
Menangani request HTTP PATCH (partial update). |
Router::patch('/user/{id}', [UserController::class,
'patch']);
|
Router::delete($path, $handler) |
Menangani request HTTP DELETE. |
Router::delete('/user/{id}', [UserController::class,
'destroy']);
|
$route->name('nama') |
Memberi nama pada route untuk kemudahan referensi. |
Router::get('/dashboard', [DashController::class,
'index'])->name('dashboard');
|
4. Dispatching Request
Fungsi dispatch() digunakan untuk mencocokkan request
pengguna dengan daftar route yang telah didaftarkan.
public static function dispatch(Request $request): Response
{
$uri = rtrim(strtok($_SERVER['REQUEST_URI'], '?'), '/') ?: '/';
$method = $_SERVER['REQUEST_METHOD'];
$router = self::getInstance();
foreach ($router->getRoutes() as $route) {
if ($route->method === $method && $route->path === $uri) {
if (is_array($route->handler)) {
[$controller, $func] = $route->handler;
$response = (new $controller())->$func();
return $response instanceof Response ? $response : new Response($response);
} elseif (is_callable($route->handler)) {
$response = call_user_func($route->handler, $request);
return $response instanceof Response ? $response : new Response($response);
}
}
}
// Route tidak ditemukan
return new Response('404 Not Found', 404);
}
⚠️ Catatan: Jika tidak ada rute yang cocok,
framework akan mengembalikan 404 Not Found.
5. Helper Fungsi Terkait
Beberapa helper berguna untuk mendukung sistem routing:
-
env($key, $default = null)— Membaca konfigurasi dari file.env. -
view($view, $data = [])— Render tampilan dari direktoriviews/. -
config($key, $default = null)— Mengambil nilai dari file konfigurasi. -
throw_if($condition, $exception)— Melempar exception jika kondisi terpenuhi. -
base_path($path = '')— Mendapatkan path absolut project.
💡 Tips: Helper dapat diperluas di file
src/Core/helpers.php untuk fungsi-fungsi tambahan.
# Controllers
Controller standar di Haryadi Framework adalah kelas yang berisi method untuk menangani request dan mengembalikan response (view, redirect, atau JSON).
namespace App\Controllers;
use Haryadi\Core\Controller;
class UserController extends Controller
{
public function index()
{
$users = \App\Models\User::all();
return $this->view('users.index', compact('users'));
}
public function store()
{
$data = $this->input();
$this->validate([
'nama' => 'required',
'email' => 'required|email',
], $data);
\App\Models\User::create($data);
return $this->redirect('/users');
}
}
Kelas Dasar: Haryadi\Core\Controller
Kelas Controller adalah fondasi utama yang digunakan
oleh semua controller dalam framework Haryadi. Menyediakan method
bantu seperti view(), redirect(),
input(), validate(), dan
json().
| Metode | Deskripsi | Contoh |
|---|---|---|
view(string $view, array $data = []) |
Render view dengan data tertentu. |
$this->view('welcome', ['title' => 'Halo Dunia']);
|
redirect(string $url) |
Mengarahkan pengguna ke URL lain. | $this->redirect('/login'); |
input(?string $key = null, $default = null)
|
Ambil data dari $_GET atau $_POST.
|
$username = $this->input('username'); |
validate(array $rules, array $data) |
Validasi sederhana dengan aturan seperti
required dan email.
|
$this->validate(['email' => 'required|email'],
$data);
|
json(array|object $data, int $status = 200)
|
Mengirim response dalam format JSON. | $this->json(['success' => true]); |
namespace Haryadi\Core;
class Controller
{
protected function view(string $view, array $data = [])
{
return View::make($view, $data);
}
protected function redirect(string $url)
{
header("Location: {$url}");
exit;
}
protected function input(?string $key = null, $default = null)
{
$input = array_merge($_GET ?? [], $_POST ?? []);
return $key ? ($input[$key] ?? $default) : $input;
}
protected function validate(array $rules, array $data): void
{
foreach ($rules as $field => $rule) {
$value = $data[$field] ?? null;
$parts = explode('|', $rule);
foreach ($parts as $r) {
if ($r === 'required' && empty($value)) {
throw new \Exception("Field '{$field}' wajib diisi.");
}
if ($r === 'email' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
throw new \Exception("Field '{$field}' harus berupa email valid.");
}
}
}
}
protected function json(array|object $data, int $status = 200): void
{
http_response_code($status);
header('Content-Type: application/json');
echo json_encode($data);
exit;
}
}
💡 Tips: Semua controller di aplikasi sebaiknya mewarisi (extends) kelas ini agar memiliki akses ke seluruh utilitas built-in framework.
Models
Model di Haryadi Framework digunakan untuk berinteraksi dengan
database menggunakan pendekatan ORM sederhana berbasis PDO.
Setiap model mewarisi Haryadi\Core\Model dan otomatis
terhubung ke konfigurasi database melalui
Database::connect().
1. Contoh Model
namespace App\Models;
use Haryadi\Core\Model;
use Haryadi\Core\Factories\HasFactory;
class User extends Model
{
use HasFactory;
protected static string $table = 'users';
protected array $fillable = [
'name', 'email', 'password'
];
public bool $timestamps = true;
}
2. Properti Penting
- $table → Nama tabel database
- $primaryKey → Default
id, bisa diubah - $fillable → Field yang dapat diisi massal (mass assignment)
- $hidden → Field yang disembunyikan saat serialisasi
- $casts → Konversi otomatis tipe data (int, bool, datetime, dll)
-
$timestamps → Aktifkan kolom
created_atdanupdated_at
3. Metode Utama
| Metode | Deskripsi | Contoh |
|---|---|---|
all() |
Ambil semua data dari tabel | User::all(); |
find($id) |
Cari data berdasarkan primary key | User::find(1); |
where($column, $value) |
Ambil 1 data sesuai kondisi | User::where('email', 'mail@test.com'); |
create($data) |
Simpan data baru ke tabel | $user->create($_POST); |
update($id, $data) |
Perbarui data berdasarkan ID | $user->update(1, ['name' => 'Deni']); |
delete($id) |
Hapus data berdasarkan ID | User::delete(3); |
4. Contoh Lengkap
$user = new User();
// Simpan data baru
$user->create([
'name' => 'Deni Agus Haryadi',
'email' => 'deni@example.com',
'password' => password_hash('123456', PASSWORD_BCRYPT)
]);
// Ambil semua user
$users = User::all();
// Cari user
$single = User::find(1);
// Update data
$user->update(1, ['name' => 'Deni A. Haryadi']);
// Hapus data
User::delete(2);
5. CLI Generator
Untuk membuat model baru dengan cepat, gunakan perintah CLI bawaan:
php haryadi make:model NamaModel
📁 File akan otomatis dibuat di
app/Models/NamaModel.php.
protected $timestamps = true; agar otomatis
menambahkan created_at dan updated_at.
Views (Templating)
Sistem View di Haryadi Framework menggunakan pendekatan
sederhana: file PHP murni yang berada di
resources/views dan dapat dipanggil melalui helper
view().
📁 Struktur View
resources/
└── views/
├── users/
│ └── index.haryadi.php
└── layout/
└── main.haryadi.php
1. Contoh Penggunaan
// Controller
namespace App\Controllers;
use Haryadi\Core\Controller;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}
}
2. File View
// resources/views/users/index.haryadi.php
<?php foreach($users as $user): ?>
<div class="user">
<?= e($user['name']) ?>
</div>
<?php endforeach; ?>
Setiap file .haryadi.php dapat berisi HTML, PHP, atau
kombinasi keduanya. Framework akan melakukan
render dengan output buffering sehingga hasilnya
dikembalikan sebagai string.
3. Kelas View
namespace Haryadi\Core;
class View
{
public static function make($view, $data = [])
{
$file = BASE_PATH . "/resources/Views/" . str_replace('.', '/', $view) . ".haryadi.php";
if (!file_exists($file)) {
throw new \Exception("View '{$view}.haryadi.php' tidak ditemukan!");
}
extract($data); // Konversi array ke variabel
ob_start();
include $file;
return ob_get_clean(); // Kembalikan hasil render
}
}
4. Helper Fungsi
view($view, $data = [])— Render file viewredirect($path)— Redirect ke URL laine($value)— Escape output agar aman dari XSS
5. Contoh Lengkap
// Controller
public function showProfile()
{
$user = User::find(1);
return view('profile.show', ['user' => $user]);
}
// resources/views/profile/show.haryadi.php
<h1>Profil Pengguna</h1>
<p>Nama: <?= e($user->name) ?></p>
<p>Email: <?= e($user->email) ?></p>
view('dashboard.user.profile') akan mencari
resources/views/dashboard/user/profile.haryadi.php.
Middleware
Middleware dapat didefinisikan di app/Middleware dan
diregistrasi di provider router.
// app/Middleware/AuthMiddleware.php
class AuthMiddleware
{
public function handle($request, $next)
{
if(empty($_SESSION['user'])){
return redirect('/login');
}
return $next($request);
}
}
view('dashboard.user.profile') akan mencari
resources/views/dashboard/user/profile.haryadi.php.
CLI — php haryadi
CLI tool sederhana untuk menjalankan server, migrasi, make commands.
php haryadi layanan : Menjalankan server lokal
php haryadi route:list : Menampilkan semua route
php haryadi buat:model : Membuat model baru
php haryadi buat:controller : Membuat controller baru
php haryadi buat:view : Membuat view baru
php haryadi buat:migration : Membuat migration baru
php haryadi buat:seeder : Menjalankan seeder baru
php haryadi migrasi : Menjalankan migrasi database
php haryadi db:seed : Menjalankan seeder database
php haryadi bantuan : Menampilkan daftar command
Migrations & Seeders
Migrations adalah file PHP di
database/migrations yang digunakan untuk membuat dan
mengubah struktur tabel database. Setiap migration memiliki method
up() untuk membuat tabel atau kolom, dan
down()
untuk rollback.
class CreateUsersTable {
public function up() {
// buat tabel users
}
public function down() {
// drop tabel
}
}
php haryadi buat:migration create_nama_table
untuk kemudahan generate nama tabel.
1. Contoh Migration
// database/migrations/2025_10_29_123456_create_users_table.php
return new class {
public function up() {
Tabel::create('users', function (Bagan $tabel) {
$tabel->id();
$tabel->string('name');
$tabel->timestamps();
});
}
public function down() {
Tabel::dropIfExists('users');
}
};
2. Seeders
Seeders digunakan untuk mengisi data awal database. File disimpan
di
database/seeders dengan method run().
// database/seeders/UserSeeder.php
namespace Database\Seeders;
use Haryadi\Core\Model;
class UserSeeder extends Seeder
{
public function run(): void
{
Model::factory(10)->create();
}
}
php haryadi make:seeder UserSeeder dan panggil
call(UserSeeder::class) untuk mengeksekusi.
Authentication & Authorization
Kerangka menyediakan helper auth sederhana:
auth()->user(), guest(), dan trait
role-based basic.
// contoh register
$user = App\Models\User::create([
'name'=>'Deni',
'email'=>'d@example.com',
'password'=>password_hash('secret', PASSWORD_DEFAULT) ]);
// middleware pengecekan role
if(!in_array('admin', $user->roles ?? [])) abort(403);
Configuration & Environment
Gunakan file .env untuk konfigurasi. Config di
config/ sebagai array PHP.
// .env
APP_ENV=local
DB_HOST=127.0.0.1
DB_DATABASE=haryadi
DB_USERNAME=root
DB_PASSWORD=
Error Handling & Debug
Core menyediakan handler error yang bisa ditoggle via
APP_DEBUG. Untuk page error khusus, letakkan file di
resources/errors.
// contoh menangani exception
try{
// kode
}catch(\Exception $e){
if(config('app.debug')){
dd($e->getMessage(), $e->getTrace());
}
view('errors.500');
}
Testing
Tidak terikat ke framework testing tertentu. Direkomendasikan menggunakan PHPUnit.
composer require --dev phpunit/phpunit
./vendor/bin/phpunit --configuration phpunit.xml
Deployment
Langkah umum:
- Set environment production pada file
.env - Upload kode ke server (Git/FTP)
-
Install composer:
composer install --no-dev --optimize-autoloader -
Jalankan migrasi:
php haryadi migrate --force - Set webroot ke folder
public/ - Pastikan permission storage & uploads writable
Troubleshooting & FAQ
Pastikan namespace & path sesuai composer.json; jalankan
composer dump-autoload -o.
Periksa path file view di resources/views dan
helper view('path.name') menggunakan tanda titik.
Cek kredensial di .env dan coba
php -r "new PDO('mysql:host=...')" untuk quick
test.
Contribute & Development
Panduan singkat untuk kontributor:
- Fork repo, buat branch feature/nama
- Tulis test untuk fitur baru
- Submit PR dengan deskripsi perubahan
- Ikuti code style PSR-12