PHP & Framework Quality Guideline DOT Indonesia merupakan sebuah standar dan panduan bagi backend engineer DOT Indonesia atau vendor yang menggunakan PHP atau framework PHP sebagai server side programming.
Kunjungi Development Stack & Tools untuk melihat daftar aplikasi dan perangkat development yang dibutuhkan
- General Standard
- PHP Coding Standard
- Laravel / Lumen / PHP Framework Engineering Guideline
- Package & Libraries
Hal-hal berikut ini seharusnya dimasukkan ke dalam list .gitignore
dan tidak boleh di push ke dalam repository:
- direktori
vendors
,node_modules
- file upload dari user
- file
.env
- Informasi credential penting atau krusial
Gunakan penamaan variable atau method yang singkat & jelas, serta tidak membingungkan.
good:
$user
, $storeData
, $debetAccount
bad:
$aaaa
, $name1
, $thisistoloongvariableyoumaynotseeit
Variable atau method menggunakan format CamelCase
Error message / debug message hanya boleh ditampilkan pada mode development
atau staging
. Gunakan default error message ketika di mode production
Tidak meletakkan endpoint atau informasi credential yang bersifat private secara hard code di dalam source code. Contoh:
protected $secretKey = 'ThisIsN0tSuppOs3dToBeHere';
protected $ProdUrl = 'https://someprivateip/api';
Manfaatkan file .env
untuk menyimpan value sensitif tanpa terekspose di dalam source code.
Source code tidak boleh mengandung backdoor atau shell script yang berbahaya. Jika menggunakan script dari referensi luar, pastikan script tersebut aman & verified.
Semua form harus menggunakan CSRF Protection
Harus mengikuti PHP PSR-1: Basic Coding Standard
Harus Mengikuti PHP PSR-2: Coding Style Guide
PSR-2 overview:
<?php
namespace Vendor\Package;
use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;
class Foo extends Bar implements FooInterface
{
public function sampleMethod($a, $b = null)
{
if ($a === $b) {
bar();
} elseif ($a > $b) {
$foo->bar($arg1);
} else {
BazClass::bar($arg2, $arg3);
}
}
final public static function bar()
{
// method body
}
}
Jika menggunakan autoloading, ikuti standard PSR-4: Autoloading
Agar source code lebih mudah dibaca dan dipahami sertakan DockBlock
pada fungsi atau attribute. Manfaatkan DockBlock untuk menginformasikan proses, variable, dan output yang digunakan. Acuan penggunaan DockBlock dapat dilihat di PHPDOC - DOCKBLOCK Basic Syntax
Overview:
<?php
class Foo {
/**
* @var string
*/
protected $propertiesOne;
/**
* @var string
*/
protected $propertiesTwo;
/**
* This is description of this class
* this class may use recursion bla bla bla
*
* @param string $arg1
* @param integer $arg2
* @return array
*/
public function bar($arg1, $arg2)
{
// some code
}
}
Tidak boleh ada Dead Code
saat merge ke branch master
. Dead Code
adalah source code (method, attributes, class) yang sudah tidak digunakan akan tetapi masih tersimpan di dalam codebase dan biasanya hanya dinonaktifkan menggunakan comment
Overview:
<?php
class Foo {
/**
* This is description of this class
* this class may use recursion bla bla bla
*
* @param string $arg1
* @param integer $arg2
* @return array
*/
public function bar($arg1, $arg2)
{
// some code
}
//public function deadcode($arg1, $arg2)
//{
// some DEAD CODE
//
//}
}
- Penggunaan PHP framework yang disarankan adalah Laravel atau microframework Lumen.
- Jika terpaksa menggunakan framework lain, mohon kordinasikan dengan AVP.
- Untuk project yang bersifat longterm disarankan menggunakan framework versi LTS (Long Term Support) atau disesuaikan dengan kebutuhan.
- Jika tidak ada kebutuhan URGENT, dilarang mengupgrade versi framework pada project yang sedang berjalan.
Gunakan fitur Database Transaction
untuk operasi persistence yang menggunakan lebih dari 1 tabel database.
overview:
try {
DB::beginTransaction();
// first persistence operation
// second persistence operation
// operation success, then commit transaction
DB::commit();
return true;
} catch(\Exception $e) {
// if error happened, rollback transaction
DB::rollback();
return false;
}
Untuk aplikasi yang kompleks, kumpulkan class Model
, Controller
, atau Views
dalam direktori tersendiri sesuai dengan konteks / domain aplikasinya.
simple case:
├── app
│ ├── Http
│ │ ├── Controller
│ │ │ ├── Authentication
│ │ │ ├── OrderManagement
│ │ │ │ ├── OrderController.php
│ │ │ │ ├── ReportOrderController.php
├── Model
│ ├── User.php
│ ├── Order.php
├── resources
│ ├── views
│ │ ├── dashboard
│ │ ├── administrator
│ │ │ ├── index.blade.php
│ │ │ ├── create.blade.php
│ │ │ ├── edit.blade.php
│ │ │ ├── detail.blade.php
│ │ ├── ordermanagement
Untuk efisiensi dan efektivitas masa development, gunakan library yang sudah umum digunakan dengan kriteria sebagai berikut:
- library aktif di maintain oleh kontributor / owner
- Sesuai dengan kebutuhan engineering project
- Sesuai dengan development stack yang sedang digunakan
- Penggunaan library harus benar-benar dapat mempermudah proses development
Gunakan perintah berikut untuk optimasi saat deployment Laravel terutama di staging & production:
php artisan route:cache
php artisan config:cache
composer dumpautoload --classmap-authoritative
khusus untuk
route:cache
tidak boleh ada fungsi closure pada file route
Manfaatkan fitur event
untuk fungsi yang tidak dependen dengan hasil outputnya. Misal: kirim email, logging, push notification. Dokumentasi event Laravel
Gunakan eager loading
untuk optimasi penggunaan relationship di eloquent. Baca implementasi Eager Loading.
- Selalu (WAJIB) gunakan
migration
untuk pembuatan atau modifikasi skema database saat development baik itu menambah kolom, edit kolom, hapus kolom, atau modifikasi index. - Metode ini lebih baik daripada merubah satu file migration lalu menjalankan perintah
php artisan migrate:rollback
laluphp artisan migrate
lagi. Baca implementasi migration
Dalam kasus tertentu pengambilan data menggunakan Eloquent
akan memakan terlalu banyak resource. Bentuk optimalisasinya bisa dari salah satu cara berikut:
- Ganti
relationship
dengan menggunakan operasijoin
sehingga query cukup dijalankan satu kali. - Ganti operasi menggunakan
Query Builder
- Gunakan blok
try - catch
untuk handling exception terutama di operasi yang berkaitan dengan I/O seperti database, HTTP request, file, service layer. - Try & Catch berfungsi untuk menangkap
error exception
yang terjadi & memungkinkan aplikasi melakukan aksi tertentu terkait error tersebut.
DONT:
- Jangan biarkan technical error muncul / terbaca oleh client app/frontend.
/**
* This is description of this class
*
* @param Request $request
* @return Response
*/
public function register(Request $request)
{
try {
$service = $this->applicationService->registerUser($user);
return response()->json($service);
} catch(Exception $e) {
return response()->json(['error' => $e->getMessage()]);
}
}
DO:
- Gunakan fitur
report($exception)
untuk menulis detail exception di filelaravel.log
. - Dan tampilkan pesan error yang human friendly ke client app / frontend.
/**
* This is description of this class
*
* @param Request $request
* @return Response
*/
public function register(Request $request)
{
try {
$service = $this->applicationService->registerUser($user);
return response()->json($service);
} catch(Exception $e) {
report($e);
return response()->json(['error' => "Human Friendly Message"]);
}
}
Semua konfigurasi credential dari pihak ketiga harus diset melalui config/service.php
dan value harus diambil dari file .env
overview:
<?php
// config/service.php
return [
'zenziva' => [
'userkey' => env('ZENZIVA_USER', ''),
'passkey' => env('ZENZIVA_PASS', ''),
'subdomain' => '',
'masking' => false,
],
'tcast' => [
'user' => env('TCAST_USER', ''),
'password' => env('TCAST_PASSWORD', ''),
'senderid' => env('TCAST_SENDERID', ''),
]
];
Saat production mode pastikan hal berikut:
APP_ENV=production
APP_DEBUG=false
APP_KEY
harus di generate ulang menggunakan perintahphp artisan key:generate
Berikut merupakan daftar library / package PHP & Laravel yang biasa digunakan dalam proses development.
- Laravel Debugbar - debug & monitor resource laravel
- Laravel Flash - Flash message wrapper
- Laravel CORS - Cross Origin Resource Sharing header
- Laravel Excel - Spreadsheet wrapper
- Socialite - OAuth authentication untuk Facebook, Twitter, Google, Linkedin, Github, Bitbucket
- L5 Repository - Laravel 5 repository abstraction
- Laravel Horizon - Dashboard untuk monitoring Laravel Queue dengan Redis
- Codeception - Testing suite functional, API, Acceptance, Unit, dll
- Doctrine DBAL - Doctrine Database Abstraction Layer untuk support laravel migration
- Predis Laravel - Redis client untuk PHP
- Laravel Sentry - Laravel error tracking menggunakan sentry.io
- Laravelcollective HTML - HTML & form laravel wrapper
- Faker - Untuk generate data dummy
- Laravel Datatable - Laravel JQuery datatable library
- Laravel Tinker - REPL untuk laravel
- Laravel PDF, laravel dompdf - Wrapper & generate pdf di Laravel
- Laravel Self Diagnosis - self diagnosis test laravel
- Intervention Image - PHP image handling & manipulation
- JWT auth - JWT wrapper untuk laravel & lumen
- Laravel Passport - Oauth2 Server Laravel
- Laravel fractal wrapper - Data transformasi wrapper laravel
- Activity Log - Pencatatan aktivitas aplikasi ke dalam log
- LDAP Authentication - integrasi auth dengan LDAP
- Laravel Backup - backup direktori laravel & dump database
- Laravel ER Diagram generator - Generate Entity Relationship Diagram dari Model Laravel
Internal engineer silakan berkontribusi untuk membuat guideline ini bisa lebih lengkap dan lebih baik. Caranya:
- Fork repository ini
- Buat branch baru di repository hasil fork
- Edit file readme sesuai dengan kebutuhan lalu commit.
- Ajukan pull request
- AVP divisi atau VP of engineering akan melakukan review dan melakukan approval Pull Request.
Jika ada pertanyaan atau permintaan update silakan untuk mengajukan issue di repository terkait.