└── readme.md /readme.md: -------------------------------------------------------------------------------- 1 | # PHP & Framework Quality Guideline 2 | 3 | **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. 4 | 5 | Kunjungi [Development Stack & Tools](https://github.com/pt-dot/development-stack-tools) untuk melihat daftar aplikasi dan perangkat development yang dibutuhkan 6 | 7 | --- 8 | # Table of Contents 9 | 1. [General Standard](#1-general-standard) 10 | 2. [PHP Coding Standard](#2-php-coding-standard) 11 | 3. [Laravel / Lumen / PHP Framework Engineering Guideline](#3-laravel--lumen--php-framework-engineering-guideline) 12 | 4. [Package & Libraries](#4-package--libraries) 13 | --- 14 | 15 | ## 1. General Standard 16 | 17 | ### a .gitignore 18 | Hal-hal berikut ini seharusnya dimasukkan ke dalam list `.gitignore` dan tidak boleh di push ke dalam repository: 19 | 20 | + direktori `vendors`, `node_modules` 21 | + file upload dari user 22 | + file `.env` 23 | + Informasi credential penting atau krusial 24 | 25 | ### b. Variable Naming Conversion 26 | Gunakan penamaan variable atau method yang singkat & jelas, serta tidak membingungkan. 27 | 28 | **good**: 29 | 30 | `$user`, `$storeData`, `$debetAccount` 31 | 32 | **bad**: 33 | 34 | `$aaaa`, `$name1`, `$thisistoloongvariableyoumaynotseeit` 35 | 36 | ### c. CamelCase 37 | Variable atau method menggunakan format `CamelCase` 38 | 39 | ### d. Error message 40 | Error message / debug message hanya boleh ditampilkan pada mode `development` atau `staging`. Gunakan **default error message** ketika di mode `production` 41 | 42 | ### e. Sensitive Information 43 | Tidak meletakkan endpoint atau informasi credential yang bersifat private secara hard code di dalam source code. Contoh: 44 | 45 | ```php 46 | protected $secretKey = 'ThisIsN0tSuppOs3dToBeHere'; 47 | 48 | protected $ProdUrl = 'https://someprivateip/api'; 49 | ``` 50 | 51 | Manfaatkan file `.env` untuk menyimpan value sensitif tanpa terekspose di dalam source code. 52 | 53 | ### f. Secure & Verified Code 54 | Source code tidak boleh mengandung *backdoor* atau shell script yang berbahaya. 55 | Jika menggunakan script dari referensi luar, pastikan script tersebut aman & verified. 56 | 57 | ### g. CSRF Token 58 | Semua form harus menggunakan `CSRF Protection` 59 | 60 | --- 61 | 62 | ## 2. PHP Coding Standard 63 | 64 | ### a. PSR-1 65 | Harus mengikuti PHP [PSR-1: Basic Coding Standard](http://www.php-fig.org/psr/psr-1/) 66 | 67 | ### b. PSR-2 68 | Harus Mengikuti PHP [PSR-2: Coding Style Guide](http://www.php-fig.org/psr/psr-2/) 69 | 70 | PSR-2 overview: 71 | ```php 72 | $b) { 86 | $foo->bar($arg1); 87 | } else { 88 | BazClass::bar($arg2, $arg3); 89 | } 90 | } 91 | 92 | final public static function bar() 93 | { 94 | // method body 95 | } 96 | } 97 | ``` 98 | 99 | ### c. PSR-4 100 | Jika menggunakan autoloading, ikuti standard [PSR-4: Autoloading](http://www.php-fig.org/psr/psr-4/) 101 | 102 | ### d. DockBlock (/JavaDoc) 103 | 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](http://docs.phpdoc.org/references/phpdoc/basic-syntax.html) 104 | 105 | Overview: 106 | ```php 107 | khusus untuk `route:cache` tidak boleh ada fungsi closure pada file route 251 | 252 | ### f. Event 253 | Manfaatkan fitur `event` untuk fungsi yang tidak dependen dengan hasil outputnya. Misal: kirim email, logging, push notification. [Dokumentasi event Laravel](https://laravel.com/docs/5.6/events) 254 | 255 | ### g. Eloquent : Eager Loading 256 | Gunakan `eager loading` untuk optimasi penggunaan relationship di eloquent. Baca implementasi [Eager Loading](https://laravel.com/docs/5.6/eloquent-relationships#eager-loading). 257 | 258 | ### h. DB Migration 259 | - Selalu (WAJIB) gunakan `migration` untuk pembuatan atau modifikasi skema database saat development baik itu menambah kolom, edit kolom, hapus kolom, atau modifikasi index. 260 | - Metode ini lebih baik daripada merubah satu file migration lalu menjalankan perintah `php artisan migrate:rollback` lalu `php artisan migrate` lagi. Baca implementasi [migration](https://laravel.com/docs/5.6/migrations) 261 | 262 | ### i. Eloquent Optimization 263 | Dalam kasus tertentu pengambilan data menggunakan `Eloquent` akan memakan terlalu banyak resource. Bentuk optimalisasinya bisa dari salah satu cara berikut: 264 | 265 | + Ganti `relationship` dengan menggunakan operasi `join` sehingga query cukup dijalankan satu kali. 266 | + Ganti operasi menggunakan `Query Builder` 267 | 268 | ### j. Try Catch , Report & Throw 269 | - Gunakan blok `try - catch` untuk handling exception terutama di operasi yang berkaitan dengan I/O seperti database, HTTP request, file, service layer. 270 | - Try & Catch berfungsi untuk menangkap `error exception` yang terjadi & memungkinkan aplikasi melakukan aksi tertentu terkait error tersebut. 271 | 272 | **DONT:** 273 | - Jangan biarkan technical error muncul / terbaca oleh client app/frontend. 274 | 275 | ```php 276 | /** 277 | * This is description of this class 278 | * 279 | * @param Request $request 280 | * @return Response 281 | */ 282 | public function register(Request $request) 283 | { 284 | try { 285 | $service = $this->applicationService->registerUser($user); 286 | return response()->json($service); 287 | } catch(Exception $e) { 288 | return response()->json(['error' => $e->getMessage()]); 289 | } 290 | } 291 | ``` 292 | 293 | **DO:** 294 | - Gunakan fitur `report($exception)` untuk menulis detail exception di file `laravel.log`. 295 | - Dan tampilkan pesan error yang human friendly ke client app / frontend. 296 | 297 | ```php 298 | /** 299 | * This is description of this class 300 | * 301 | * @param Request $request 302 | * @return Response 303 | */ 304 | public function register(Request $request) 305 | { 306 | try { 307 | $service = $this->applicationService->registerUser($user); 308 | return response()->json($service); 309 | } catch(Exception $e) { 310 | report($e); 311 | return response()->json(['error' => "Human Friendly Message"]); 312 | } 313 | } 314 | ``` 315 | 316 | ### k. Service Config 317 | Semua konfigurasi credential dari pihak ketiga harus diset melalui `config/service.php` dan value harus diambil dari file `.env` 318 | 319 | overview: 320 | 321 | ```php 322 | [ 326 | 'userkey' => env('ZENZIVA_USER', ''), 327 | 'passkey' => env('ZENZIVA_PASS', ''), 328 | 'subdomain' => '', 329 | 'masking' => false, 330 | ], 331 | 332 | 'tcast' => [ 333 | 'user' => env('TCAST_USER', ''), 334 | 'password' => env('TCAST_PASSWORD', ''), 335 | 'senderid' => env('TCAST_SENDERID', ''), 336 | ] 337 | ]; 338 | ``` 339 | 340 | ### l. ENV Production 341 | Saat production mode pastikan hal berikut: 342 | 343 | + `APP_ENV=production` 344 | + `APP_DEBUG=false` 345 | + `APP_KEY` harus di generate ulang menggunakan perintah `php artisan key:generate` 346 | 347 | --- 348 | 349 | ## 4. Package & libraries 350 | 351 | Berikut merupakan daftar library / package PHP & Laravel yang biasa digunakan dalam proses development. 352 | 353 | 1. [Laravel Debugbar](https://github.com/barryvdh/laravel-debugbar) - debug & monitor resource laravel 354 | 2. [Laravel Flash](https://github.com/laracasts/flash) - Flash message wrapper 355 | 3. [Laravel CORS](https://github.com/barryvdh/laravel-cors) - Cross Origin Resource Sharing header 356 | 4. [Laravel Excel](https://laravel-excel.maatwebsite.nl/) - Spreadsheet wrapper 357 | 5. [Socialite](https://github.com/laravel/socialite) - OAuth authentication untuk Facebook, Twitter, Google, Linkedin, Github, Bitbucket 358 | 6. [L5 Repository](https://github.com/andersao/l5-repository) - Laravel 5 repository abstraction 359 | 7. [Laravel Horizon](https://horizon.laravel.com/) - Dashboard untuk monitoring Laravel Queue dengan Redis 360 | 8. [Codeception](https://codeception.com/) - Testing suite functional, API, Acceptance, Unit, dll 361 | 9. [Doctrine DBAL](https://github.com/doctrine/dbal) - Doctrine Database Abstraction Layer untuk support laravel migration 362 | 10. [Predis Laravel](https://github.com/nrk/predis) - Redis client untuk PHP 363 | 11. [Laravel Sentry](https://sentry.io/for/laravel/) - Laravel error tracking menggunakan [sentry.io](https://sentry.io/for/laravel/) 364 | 12. [Laravelcollective HTML](https://laravelcollective.com/docs/master/html) - HTML & form laravel wrapper 365 | 13. [Faker](https://github.com/fzaninotto/Faker) - Untuk generate data dummy 366 | 14. [Laravel Datatable](https://github.com/yajra/laravel-datatables) - Laravel JQuery datatable library 367 | 15. [Laravel Tinker](https://github.com/laravel/tinker) - REPL untuk laravel 368 | 16. [Laravel PDF](https://github.com/niklasravnsborg/laravel-pdf), [laravel dompdf](https://github.com/barryvdh/laravel-dompdf) - Wrapper & generate pdf di Laravel 369 | 17. [Laravel Self Diagnosis](https://github.com/beyondcode/laravel-self-diagnosis) - self diagnosis test laravel 370 | 18. [Intervention Image](http://image.intervention.io/) - PHP image handling & manipulation 371 | 19. [JWT auth](https://github.com/tymondesigns/jwt-auth) - JWT wrapper untuk laravel & lumen 372 | 20. [Laravel Passport](https://laravel.com/docs/5.6/passport) - Oauth2 Server Laravel 373 | 21. [Laravel fractal wrapper](https://github.com/spatie/laravel-fractal) - Data transformasi wrapper laravel 374 | 22. [Activity Log](https://github.com/spatie/laravel-activitylog) - Pencatatan aktivitas aplikasi ke dalam log 375 | 23. [LDAP Authentication](https://github.com/pt-dot/ldap-auth) - integrasi auth dengan LDAP 376 | 24. [Laravel Backup](https://github.com/spatie/laravel-backup) - backup direktori laravel & dump database 377 | 25. [Laravel ER Diagram generator](https://github.com/beyondcode/laravel-er-diagram-generator) - Generate Entity Relationship Diagram dari Model Laravel 378 | 379 | --- 380 | 381 | # Kontribusi 382 | 383 | Internal engineer silakan berkontribusi untuk membuat guideline ini bisa lebih lengkap dan lebih baik. Caranya: 384 | 385 | + Fork repository ini 386 | + Buat branch baru di repository hasil fork 387 | + Edit file readme sesuai dengan kebutuhan lalu commit. 388 | + Ajukan pull request 389 | + AVP divisi atau VP of engineering akan melakukan review dan melakukan approval Pull Request. 390 | 391 | Jika ada pertanyaan atau permintaan update silakan untuk mengajukan issue di repository terkait. 392 | --------------------------------------------------------------------------------