Panduan PHP & Framework

Panduan ini merupakan sebuah standar 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


1. General Standard

a. 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

b. Gunakan penamaan variable atau method yang singkat & jelas, serta tidak membingungkan.

good:

$user, $storeData, $debetAccount

bad:

$aaaa, $name1, $thisistoloongvariableyoumaynotseeit

c. Variable atau method menggunakan format CamelCase

d. Error message / debug message hanya boleh ditampilkan pada mode development atau staging. Gunakan default error message ketika di mode production

e. 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.

f. Source code tidak mengandung backdoor atau shell script yang berbahaya.

g. Semua form harus menggunakan CSRF Protection


2. PHP Coding Standard

a. Harus mengikuti PHP PSR-1: Basic Coding Standard

b. (DEPRECATED) Harus Mengikuti PHP PSR-2: Coding Style Guide

c. Harus mengikuti PHP PSR-12: Extended Coding Style

PSR-2 overview (Deprecated):

<?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
    }
}

PSR-12 overview:

<?php

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;

use function Vendor\Package\{functionA, functionB, functionC};

use const Vendor\Package\{ConstantA, ConstantB, ConstantC};

class Foo extends Bar implements FooInterface
{
    public function sampleFunction(int $a, int $b = null): array
    {
        if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        } else {
            BazClass::bar($arg2, $arg3);
        }
    }

    final public static function bar()
    {
        // method body
    }
}

c. Jika menggunakan autoloading, ikuti standard PSR-4: Autoloading

d. 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

    }
}

e. 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
    //
    //}
}

f. Penggunaan PHP framework yang disarankan adalah Laravel atau microframework Lumen.


3. Laravel / Lumen / PHP Framework Engineering Guideline

a. Untuk project yang bersifat longterm disarankan menggunakan framework versi LTS (Long Term Support) atau disesuaikan dengan kebutuhan.

b. 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 $exception) {
    // if error happened, rollback transaction & report this error
    DB::rollback();
    report($exception);
    return false;
}

c. 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
│   ├── Models
│   │   ├── User.php
│   │   ├── Order.php
├── resources
│   ├── views
│   │   ├── dashboard
│   │   ├── administrator
│   │   │   ├── index.blade.php
│   │   │   ├── create.blade.php
│   │   │   ├── edit.blade.php
│   │   │   ├── detail.blade.php
│   │   ├── ordermanagement

d. 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

e. Gunakan perintah berikut untuk optimasi saat deployment Laravel terutama di staging & production:

php artisan route:cache
php artisan config:cache
composer dump-autoload --classmap-authoritative

khusus untuk route:cache tidak boleh ada fungsi closure pada file route

f. Manfaatkan fitur event untuk fungsi yang tidak dependen dengan hasil outputnya. Misal: kirim email, logging, push notification. Dokumentasi event Laravel

g. Gunakan eager loading untuk optimasi penggunaan relationship di eloquent. Baca implementasi Eager Loading.

h. Selalu 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 lalu php artisan migrate lagi. Baca implementasi migration

i. Dalam kasus tertentu pengambilan data menggunakan Eloquent akan memakan terlalu banyak resource. Bentuk optimalisasinya bisa dari salah satu cara berikut:

  • Ganti relationship dengan menggunakan operasi join sehingga query cukup dijalankan satu kali.
  • Ganti operasi menggunakan Query Builder

j. 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', ''),
    ]
];

l. Saat production mode pastikan hal berikut:

  • APP_ENV=production
  • APP_DEBUG=false
  • APP_KEY harus di generate ulang menggunakan perintah php artisan key:generate

4. Package & libraries

Berikut merupakan daftar library / package PHP & Laravel yang biasa digunakan dalam proses development.

  1. Laravel Debugbar - debug & monitor resource laravel
  2. Laravel Flash - Flash message wrapper
  3. Laravel CORS - Cross Origin Resource Sharing header
  4. Laravel Excel - Spreadsheet wrapper
  5. Socialite - OAuth authentication untuk Facebook, Twitter, Google, Linkedin, Github, Bitbucket
  6. L5 Repository - Laravel 5 repository abstraction
  7. Laravel Horizon - Dashboard untuk monitoring Laravel Queue dengan Redis
  8. Codeception - Testing suite functional, API, Acceptance, Unit, dll
  9. Doctrine DBAL - Doctrine Database Abstraction Layer untuk support laravel migration
  10. Predis Laravel - Redis client untuk PHP
  11. Laravel Sentry - Laravel error tracking menggunakan sentry.io
  12. Laravelcollective HTML - HTML & form laravel wrapper
  13. Faker - Untuk generate data dummy
  14. Laravel Datatable - Laravel JQuery datatable library
  15. Laravel Tinker - REPL untuk laravel
  16. Laravel PDF, laravel dompdf - Wrapper & generate pdf di Laravel
  17. Laravel Self Diagnosis - self diagnosis test laravel
  18. Intervention Image - PHP image handling & manipulation
  19. JWT auth - JWT wrapper untuk laravel & lumen
  20. Laravel Passport - Oauth2 Server Laravel
  21. Laravel fractal wrapper - Data transformasi wrapper laravel
  22. Activity Log - Pencatatan aktivitas aplikasi ke dalam log
  23. LDAP Authentication - integrasi auth dengan LDAP
  24. Laravel Backup - backup direktori laravel & dump database
  25. Laravel ER Diagram generator - Generate Entity Relationship Diagram dari Model Laravel