FAQ - Pertanyaan Umum Laravel Bootcamp
Bootcamp Laravel - Sistem Pengelolaan Dokumen (SiDoku)
📋 Daftar Isi
- Instalasi dan Setup
- PHP dan OOP
- Laravel Basics
- Routing dan Controllers
- Database dan Eloquent
- Authentication
- API Development
- Testing
- Deployment
- Troubleshooting
Instalasi dan Setup
Q: Laragon tidak bisa dijalankan, muncul error "Port 80 is used"?
A: Port 80 sedang digunakan aplikasi lain (biasanya Skype, IIS, atau XAMPP).
Solusi:
- Buka Laragon > Menu > Preferences > Services & Ports
- Ubah port Apache dari
80ke8080 - Atau matikan aplikasi yang menggunakan port 80
Untuk mencari aplikasi yang menggunakan port 80:
netstat -ano | findstr :80Q: Composer install gagal dengan error "Your requirements could not be resolved"?
A: Biasanya karena versi PHP atau extension tidak sesuai.
Solusi:
- Cek versi PHP:
php -v- Cek extension yang aktif:
php -m- Aktifkan extension yang diperlukan di
php.ini:
extension=curl
extension=fileinfo
extension=mbstring
extension=openssl
extension=pdo_mysql
extension=zip- Jalankan composer update:
composer updateQ: Bagaimana cara mengubah versi PHP di Laragon?
A:
- Download PHP versi yang diinginkan dari https://windows.php.net/download/
- Extract ke
C:\laragon\bin\php\php-8.x.x-Win32-vs16-x64 - Klik kanan Laragon > PHP > Pilih versi baru
- Restart Laragon
PHP dan OOP
Q: Apa bedanya == dan === di PHP?
A:
| Operator | Nama | Penjelasan |
|---|---|---|
== | Loose comparison | Membandingkan nilai saja |
=== | Strict comparison | Membandingkan nilai DAN tipe data |
Contoh:
$a = 5;
$b = "5";
var_dump($a == $b); // true (nilai sama)
var_dump($a === $b); // false (tipe berbeda: int vs string)Best Practice: Selalu gunakan === untuk menghindari bug yang tidak terduga.
Q: Kapan menggunakan public, protected, dan private?
A:
| Visibility | Akses dari Class Sendiri | Akses dari Child Class | Akses dari Luar |
|---|---|---|---|
public | Ya | Ya | Ya |
protected | Ya | Ya | Tidak |
private | Ya | Tidak | Tidak |
class User {
public $nama; // Bisa diakses dari mana saja
protected $email; // Hanya class ini dan turunannya
private $password; // Hanya class ini saja
}Best Practice: Gunakan visibility seketat mungkin. Mulai dengan private, ubah ke protected atau public jika diperlukan.
Q: Apa itu Traits dan kapan menggunakannya?
A: Traits adalah mekanisme untuk menggunakan kembali kode di multiple class tanpa inheritance.
trait Timestampable {
public function getCreatedAt() {
return $this->created_at->format('d/m/Y');
}
}
class Dokumen {
use Timestampable;
}
class User {
use Timestampable;
}Gunakan traits ketika:
- Butuh fungsi yang sama di beberapa class yang tidak terkait
- Menghindari inheritance chain yang panjang
Laravel Basics
Q: Apa bedanya config() dan env()?
A:
| Function | Penggunaan | Cached |
|---|---|---|
env() | Membaca langsung dari file .env | Tidak |
config() | Membaca dari file config | Ya |
Best Practice: Selalu gunakan config() di kode aplikasi:
// [X] Jangan
$dbHost = env('DB_HOST');
// [OK] Gunakan ini
$dbHost = config('database.connections.mysql.host');Kenapa? Karena setelah php artisan config:cache, env() tidak akan bekerja.
Q: Apa itu Service Container dan Service Provider?
A:
Service Container adalah "kotak" yang menyimpan semua class dan cara membuatnya. Laravel menggunakannya untuk Dependency Injection.
Service Provider adalah tempat untuk mendaftarkan service ke container.
// Di AppServiceProvider
public function register(): void
{
$this->app->bind(PaymentInterface::class, StripePayment::class);
}
// Di Controller
public function __construct(PaymentInterface $payment)
{
$this->payment = $payment; // Otomatis di-inject
}Q: Bagaimana cara membuat helper function sendiri?
A:
- Buat file
app/Helpers/helpers.php - Tambahkan function:
<?php
if (!function_exists('format_rupiah')) {
function format_rupiah($angka) {
return 'Rp ' . number_format($angka, 0, ',', '.');
}
}- Tambahkan di
composer.json:
"autoload": {
"files": [
"app/Helpers/helpers.php"
]
}- Jalankan:
composer dump-autoload- Gunakan:
echo format_rupiah(5000000); // Rp 5.000.000Routing dan Controllers
Q: Bagaimana cara membuat route dengan multiple middleware?
A:
// Array middleware
Route::get('/admin', [AdminController::class, 'index'])
->middleware(['auth', 'verified', 'role:admin']);
// Group middleware
Route::middleware(['auth', 'verified'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::middleware('role:admin')->group(function () {
Route::resource('users', UserController::class);
});
});Q: Bagaimana cara membuat route yang menerima parameter opsional?
A:
Route::get('/dokumen/{id?}', function ($id = null) {
if ($id) {
return "Dokumen ID: $id";
}
return "Semua dokumen";
});Q: Bagaimana cara redirect dari controller?
A:
// Redirect ke URL
return redirect('/home');
// Redirect ke named route
return redirect()->route('dokumen.index');
// Redirect dengan parameter
return redirect()->route('dokumen.show', ['id' => 1]);
// Redirect back
return redirect()->back();
// Redirect dengan flash message
return redirect()->route('dokumen.index')
->with('success', 'Data berhasil disimpan!');
// Redirect dengan input (untuk form)
return redirect()->back()->withInput();
// Redirect dengan errors
return redirect()->back()->withErrors(['email' => 'Email tidak valid']);Database dan Eloquent
Q: Apa bedanya find(), first(), dan get()?
A:
| Method | Return | Contoh |
|---|---|---|
find($id) | Single model atau null | User::find(1) |
findOrFail($id) | Single model atau 404 error | User::findOrFail(1) |
first() | Single model atau null | User::where('active', true)->first() |
firstOrFail() | Single model atau 404 error | User::where('active', true)->firstOrFail() |
get() | Collection (array of models) | User::where('active', true)->get() |
Q: Bagaimana cara melakukan soft delete?
A:
- Tambahkan column
deleted_atdi migration:
$table->softDeletes();- Tambahkan trait di Model:
use Illuminate\Database\Eloquent\SoftDeletes;
class Dokumen extends Model
{
use SoftDeletes;
}- Operasi:
// Soft delete
$dokumen->delete();
// Restore
$dokumen->restore();
// Force delete (permanen)
$dokumen->forceDelete();
// Query termasuk soft deleted
Dokumen::withTrashed()->get();
// Hanya soft deleted
Dokumen::onlyTrashed()->get();Q: Bagaimana mengatasi N+1 Query Problem?
A: Gunakan Eager Loading:
// [X] N+1 Problem (query untuk setiap dokumen)
$dokumens = Dokumen::all();
foreach ($dokumens as $dok) {
echo $dok->kategori->nama;
}
// [OK] Eager Loading (hanya 2 query)
$dokumens = Dokumen::with('kategori')->get();
foreach ($dokumens as $dok) {
echo $dok->kategori->nama;
}Tips: Install laravel-debugbar untuk melihat query yang dijalankan:
composer require barryvdh/laravel-debugbar --devQ: Bagaimana cara menjalankan raw SQL query?
A:
use Illuminate\Support\Facades\DB;
// Select
$users = DB::select('SELECT * FROM users WHERE active = ?', [1]);
// Insert
DB::insert('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
// Update
DB::update('UPDATE users SET active = ? WHERE id = ?', [1, 1]);
// Delete
DB::delete('DELETE FROM users WHERE id = ?', [1]);
// Statement (DDL)
DB::statement('DROP TABLE users');Authentication
Q: Bagaimana cara cek apakah user sudah login?
A:
// Di Controller
if (auth()->check()) {
$user = auth()->user();
}
// Di Blade
@auth
<p>Halo, {{ auth()->user()->name }}!</p>
@endauth
@guest
<a href="/login">Login</a>
@endguestQ: Bagaimana cara membuat guard custom?
A:
- Edit
config/auth.php:
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],- Gunakan guard:
// Login
Auth::guard('admin')->attempt($credentials);
// Cek auth
Auth::guard('admin')->check();
// Get user
Auth::guard('admin')->user();Q: Bagaimana cara logout user dari semua device?
A:
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
// Logout dari semua session (perlu database session driver)
DB::table('sessions')
->where('user_id', auth()->id())
->delete();
// Atau dengan Sanctum (hapus semua token)
$user->tokens()->delete();API Development
Q: Bagaimana cara handle CORS di Laravel?
A:
Laravel 11+ sudah include CORS middleware. Edit config/cors.php:
return [
'paths' => ['api/*'],
'allowed_origins' => ['*'], // Atau domain spesifik
'allowed_methods' => ['*'],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];Q: Bagaimana cara handle API versioning?
A:
// routes/api.php
// Versi 1
Route::prefix('v1')->group(function () {
Route::apiResource('dokumens', Api\V1\DokumenController::class);
});
// Versi 2
Route::prefix('v2')->group(function () {
Route::apiResource('dokumens', Api\V2\DokumenController::class);
});Struktur folder:
app/Http/Controllers/Api/
V1/
DokumenController.php
V2/
DokumenController.phpQ: Bagaimana format response API yang baik?
A:
Konsisten dengan struktur:
{
"success": true,
"message": "Data berhasil diambil",
"data": {
// data here
},
"meta": {
"current_page": 1,
"per_page": 15,
"total": 100
}
}Error response:
{
"success": false,
"message": "Validasi gagal",
"errors": {
"email": ["Email tidak valid"],
"password": ["Password minimal 8 karakter"]
}
}Testing
Q: Bagaimana cara test dengan database terpisah?
A:
- Buat database testing atau gunakan SQLite memory:
<!-- phpunit.xml -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>- Gunakan
RefreshDatabasetrait:
use Illuminate\Foundation\Testing\RefreshDatabase;
class DokumenTest extends TestCase
{
use RefreshDatabase;
}Q: Bagaimana cara mock external service di test?
A:
use Illuminate\Support\Facades\Http;
public function test_external_api_call()
{
// Mock HTTP response
Http::fake([
'api.example.com/*' => Http::response([
'status' => 'success',
'data' => ['name' => 'John']
], 200),
]);
// Test kode yang memanggil API
$response = $this->get('/fetch-external');
$response->assertStatus(200);
}Deployment
Q: Apa yang harus dilakukan setelah deploy kode baru?
A:
# 1. Pull kode terbaru
git pull origin main
# 2. Install dependencies
composer install --optimize-autoloader --no-dev
# 3. Build assets
npm ci && npm run build
# 4. Jalankan migration
php artisan migrate --force
# 5. Clear dan cache
php artisan optimize:clear
php artisan optimize
# 6. Restart queue worker
php artisan queue:restartQ: Bagaimana cara debug di production tanpa expose error?
A:
- Set di
.env:
APP_DEBUG=false
LOG_LEVEL=errorCek log di
storage/logs/laravel.logGunakan service seperti Sentry atau Bugsnag
Untuk debug sementara, gunakan
Log::debug():
Log::debug('Debug info', ['user_id' => $userId, 'action' => 'login']);Troubleshooting
Q: Error "Class not found" setelah membuat file baru?
A:
composer dump-autoloadQ: Error "SQLSTATE[42S02]: Table doesn't exist"?
A:
php artisan migrate
# atau
php artisan migrate:fresh --seedQ: Error "The page has expired due to inactivity"?
A: CSRF token expired. Pastikan form memiliki @csrf:
<form method="POST">
@csrf
<!-- fields -->
</form>Q: Error "419 Page Expired" di AJAX?
A: Tambahkan CSRF token di header:
// jQuery
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
// Fetch
fetch('/api/endpoint', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});Q: Error "Target class [Controller] does not exist"?
A: Di Laravel 8+, pastikan menggunakan full namespace di routes:
use App\Http\Controllers\DokumenController;
Route::get('/dokumen', [DokumenController::class, 'index']);Q: Error "No application encryption key has been specified"?
A:
php artisan key:generateQ: Storage link tidak bekerja di shared hosting?
A: Buat manual di public/index.php:
// Tambahkan di awal file setelah <?php
$targetFolder = $_SERVER['DOCUMENT_ROOT'].'/../storage/app/public';
$linkFolder = $_SERVER['DOCUMENT_ROOT'].'/storage';
if (!is_link($linkFolder)) {
symlink($targetFolder, $linkFolder);
}Atau buat file PHP sementara:
<?php
symlink('../storage/app/public', './storage');
echo 'Symlink created!';📚 Resources Tambahan
Official Documentation
Video Tutorials
Packages Berguna
Komunitas
- Laravel Indonesia (Telegram)
- Laravel News
- Laracasts Forum
Tip: Jika ada pertanyaan yang belum terjawab, jangan ragu untuk bertanya di forum komunitas atau menggunakan fitur search di dokumentasi Laravel!