Category Archives: PHP

PHPMD and PHPCS Integration

About

Dokumen ini bertujuan untuk memberikan informasi integrasi phpmd dan phpcs ke dalam sublime text 3. Sehingga kita tidak perlu bulak balik ke terminal untuk menjalankan phpcs / phpmd. Integrasi dilakukan dengan cara linting, sehingga kita bisa dengan mudah mengetahui jika terdeteksi pelanggaran standard coding.

Instalasi

  • Install package ‘phpcs’ melalui package control, jika package control belum terinstall, cek dokumen tentang sublime text 3 for PHP development.
    Screen Shot 2015-11-17 at 1.25.33 PM.png
  • Setelah phpcs terinstall, cari preferences > package settings > PHP Code sniffer > settings – user.
    Screen Shot 2015-11-17 at 1.25.56 PM.png
  • Didalam file config, anda perlu menuliskan executeable php, phpmd dan phpcs, berikut dengan rule yang ingin diterapkan. Contohnya sebagai berikut
{
    "phpcs_executable_path": "/Users/libreorca/.composer/vendor/bin/phpcs",
    "phpcs_show_quick_panel": false,
    "phpcs_php_path": "/usr/local/Cellar/php53/5.3.29_4/bin/php",
    "phpmd_run": true,
    "phpmd_executable_path": "/Users/libreorca/.composer/vendor/bin/phpmd",
    "phpmd_additional_args": {
        "codesize,design,unusedcode,naming": ""
    },
}
  • Pada contoh diatas, rule yang digunakan untuk PHPMD adalah codesize,design,unusedcode,naming, untuk PHPCS mengikuti default (PSR2).
  • Setelah menulis file setting, save kemudian restart sublime text.

Contoh

  • Misalkan kita memiliki file test.php
<?php

class Test
{
    public function test_a($a,$b)
    {
        $c = 3 + $a;

        if($c>15)
        {
            $c++;
        }

        $this::test_b();

        echo $c;
    }

    private static function test_b($flag = false)
    {
        if ($flag) {
            echo 'a';
        } else {
            echo 'b';
            exit();
        }

        return;
    }
}

$objA = new Test();
$objA->test_a(1,5);
  • Sublime akan secara automatis melakukan pengecekan setiap kali kita me-save file yang di edit.
  • Jika integrasi phpmd dan phpcs sudah terinstall dengan benar, sublime akan melakukan linting pada baris baris kode yang melanggar aturan / standard kode yang ditentukan. Cek status bar untuk mengetahui pelanggaran apa yang ada di baris kode tersebut.
    Screen-Shot-2015-11-17-at-1.35.02-PM.jpg
  • Hasil perbaikan test.php
<?php
namespace Sublime\test;

class Test
{
    public function testA($varA)
    {
        $varC = 3 + $varA;

        if ($varC>15) {
            $varC++;
        }

        $this::testB();

        echo $varC;
    }

    private static function testB($flag = false)
    {
        if ($flag) {
            echo 'a';
        } else {
            echo 'b';
        }

        return;
    }
}

$objA = new Test();
$objA->testA(1, 5);

Screen Shot 2015-11-17 at 1.39.57 PM.png

Conclusion

Dengan integrasi ini kita dengan mudah bisa mendeteksi jika ada yang tidak sesuai dengan standard code. Tidak hanya membuat coding kita lebih mudah dibaca, tapi kita juga belajar untuk membuat code yang lebih terstruktur. Better programmer = better & cleaner code.

Credit to: Yusuf Irwandi

PHPMD – The mess detector

PHPMD

http://phpmd.org/

This is the project site of PHPMD. It is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD. PHPMD can be seen as an user friendly and easy to configure frontend for the raw metrics measured by PHP Depend.

What PHPMD does is: It takes a given PHP source code base and look for several potential problems within that source. These problems can be things like:

  • Possible bugs
  • Suboptimal code
  • Overcomplicated expressions
  • Unused parameters, methods, properties

Installation

Direkomendasikan install melalui composer karena sangat mudah, dan mudah untuk updatenya.
Add Requirement phpmd/phpmd:”@stable” to your composer project (or global whichever is appropiate).

composer require phpmd/phpmd:"@stable"

Usage

php vendor/bin/phpmd [php files] [report type] [rules]

PHP files file yang ingin dicek atau folder
Report type bisa menggunakan text atau xml
Rule cek bagian rule untuk lebih detail
Contohnya
php vendor/bin/phpmd test.php text cleancode,unusedcode,naming,design

Rules

cleancode

  • Tidak boleh ada boolean flag sebagai argument – karena melanggar prinsip SOLID
  • Else expression, else expression hampir selalu dihilangkan dengan melakukan refactor code.
  • Static access
  • Personally saya merasa rules ini sangat strict dan sedikit menyebalkan karena terlalu mengikat, terserah pembaca jika ingin phpmd mengecek rule ini, tambahkan cleancode ke list rules.

codesize

  • cyclomatic complexity harus rendah, cyclomatic complexity disebabkan oleh terlalu banyak control statement di dalam sebuah function, if else, while, foreach, do while. Pisahkan kode menjadi method terpisah apabila complexity mencapai lebih dari 10.
  • NPath complexity harus rendah, npath adalah jumlah kemungkinan path di dalam sebuah function. Pisahkan kode menjadi method / class terpisah jika NPath complexity mencapat lebih dari 200.
  • ExcessiveMethodLength, jangan gunakan nama method yang terlalu panjang (mengindikasikan terlalu banyak tanggung jawab).
  • ExcessiveClassLength, jangan gunakan nama class yang terlalu panjang (mengindikasikan terlalu banyak tanggung jawab).
  • ExcessiveParameterList, jangan define suatu method dengan parameter list yang panjang, sederhanakan menjadi lebih compact.
  • ExcessivePublicCount, kurangi kompleksitas sebuah class dengan melakukan refactor pada public method, terlalu banyak public method mengindikasikan terlalu banyak tanggung jawab dan sulit untuk di test.
  • TooManyFields, properties di class bisa disederhakan menjadi lebih compact, misalnya memisahkan menjadi class terpisah, atau melakukan grouping untuk field field yg mirip.
  • TooManyMethods, class yang memiliki terlalu banyak adalah kandidat bagus untuk di refactor untuk tujuan mengurangi kompleksitas.
  • ExcessiveClassComplexity. WMC(Weighted Method Count) dari sebuah class adalah indikator bagus berapa banyak effort dan waktu yang digunakan untuk mengedit dan memaintain class tersebut. Hitungan WMC didefine sebagai jumlah kompleksitas dari semua method yang dideklarasikan di dalam sebuah class.

controversial

  • Superglobal, mengakses superglobal dianggap sebagai bad practice. Variabel ini harus di enkapsulasi di dalam objek yang diberikan oleh framework contohnya.
  • CamelCase untuk class, property, method, parameter dan variable name dianggap sebagai best practice.

design

  • ExitExpression, statement exit di dalam code tidak bisa ditest oleh sebab itu harus dihindari.
  • EvalExpression, statement eval tidak bisa ditest, security risk dan bad practice oleh sebab itu harus dihindari.
  • GotoStatement, statement goto membuat kode lebih sulit dibaca dan sulit dimengerti, oleh sebab itu harus dihindari.
  • NumberofChildren, class dengan jumlah children yang terlalu banyak adalah indikator ketidak seimbangan dalam hierarki class.
  • DepthOfInheritance, class yang memiliki banyak parent  adalah indikator ketidakseimbangan dalam hierarki class.
  • CouplingBetweenObjects. class yang memiliki dependency terlalu banyak memiliki impact buruk dalam beberapa aspek kualitas dari sebuah class.

naming

  • ShortVariable, hindari nama variabel yang terlalu pendek.
  • LongVariable, hindari nama variabel yang terlalu panjang.
  • ShortMethodName, hindari nama method yang terlalu pendek.
  • ConstructorWithNameAsEnclosingClass, constructor sebaikinya menggunakan constructor method.
  • ConstantNamingConventions, konstanta seharusnya selalu uppercase.
  • BooleanGetMethodName, jika sebuah method mengembalikan boolean, refactor method ini menjadi isX atau hasX bukan getX.

unusedcode

  • UnusedPrivateField, jika ada private property tapi tidak digunakan.
  • UnusedLocalVariable, jika ada variable yang dideklarasikan tapi tidak digunakan.
  • UnusedPrivateMethod, jika ada private method tapi tidak digunakan di dalam class.
  • UnusedFormalParameter, hindari passing parameter ke method atau constructor tetapi tidak menggunakannya.

Remark

  • Rules rules tersebut sangat membantu dalam development sehari hari tapi bisa juga menyebalkan.
  • Tapi ingat warning dari phpmd bukan berarti error codenya, direkomendasikan untuk dibetulkan tapi bisa saja diabaikan.
  • Rules yang saya gunakan: codesize,design,naming,unusedcode

Contoh

// file test.php
<?php

class Test
{
    public function test_a($a,$b)
    {
        $c = 3 + $a;

        if($c>15)
        {
            $c++;
        }

        $this::test_b();

        echo $c;
    }

    private static function test_b($flag = false)
    {
        if ($flag) {
            echo 'a';
        } else {
            echo 'b';
            exit();
        }

        return;
    }
}

$objA = new Test();
$objA->test_a(1,5);

Kemudian kita run phpmd menggunakan command berikut

php vendor/bin/phpmd test.php text unusedcode,design,naming,codesize 

/Users/libreorca/Htdocs/test/phpmd/test.php:5	Avoid unused parameters such as '$b'.
/Users/libreorca/Htdocs/test/phpmd/test.php:5	Avoid variables with short names like $a. Configured minimum length is 3.
/Users/libreorca/Htdocs/test/phpmd/test.php:5	Avoid variables with short names like $b. Configured minimum length is 3.
/Users/libreorca/Htdocs/test/phpmd/test.php:7	Avoid variables with short names like $c. Configured minimum length is 3.
/Users/libreorca/Htdocs/test/phpmd/test.php:25	The method test_b() contains an exit expression.

Line 5: ada warning tentang variabel b dideklarasikan tapi tidak digunakan, kemudian ada warning juga kalau nama variabel terlalu pendek dan warning
Line 25: method test_b mengandung statement exit. Maka kita lakukan refactor

// file test.php
<?php

class Test
{
    public function test_a($varA,$varB)
    {
        $varC = 3 + $varA + $varB;

        if($varA>15)
        {
            $varC++;
        }

        $this::test_b();

        echo $varC;
    }

    private static function test_b($flag = false)
    {
        if ($flag) {
            echo 'a';
        } else {
            echo 'b';
        }

        return;
    }
}

$objA = new Test();
$objA->test_a(1,5);

Kemudian kita run ulang phpmd sebagai berikut

php vendor/bin/phpmd test.php text unusedcode,design,naming,codesize

*empty result*

Jika phpmd tidak mengeluarkan output apa apa artinya kode kita memenuhi rules yang didefinisikan (unusuedcode,design,naming,codesize), now your code is much better than the previous one, YAY!!

Lakukan pengecekan phpmd berulang selama development untuk menjaga kualitas kode.

PHPCS – PHP Code Sniffer

https://github.com/squizlabs/PHP_CodeSniffer/wiki

About

PHP Codesniffer adalah set dari dua script PHP: phpcs adalah script yang mendeteksi file PHP, javascript dan CSS dari pelanggaran standard coding yang ditentukan, kemudian yang kedua phpcbf adalah script untuk melakukan perbaikan secara automatis dari standard coding yang ditentukan. PHP Codesniffer adalah tool development esensial yang menjamin kode tetap bersih dan konsisten.

Requirement

PHP Codesniffer membutuhkan PHP versi 5.1.2 atau lebih baru, beberapa aturan sniff mungkin membutuhkan requirement lain.

Installation

Recommended: composer

composer global require "squizlabs/php_codesniffer=*"

pastikan /.composer/vendor/bin ada di PATH

Usage

Untuk mengecek apakah file melanggar standard coding PEAR, execute command berikut di shell.

$ phpcs /path/to/code/myfile.php

FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
  2 | ERROR | Missing file doc comment
 20 | ERROR | PHP keywords must be lowercase; expected "false" but found "FALSE"
 47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
 51 | ERROR | Missing function doc comment
 88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------

 

Atau jika ingin mengecek semua file PHP di dalam direktori, bisa dispesifikasikan direktori saja

$ phpcs /path/to/code
FILE: /path/to/code/myfile.php
--------------------------------------------------------------------------------
FOUND 5 ERROR(S) AFFECTING 5 LINE(S)
--------------------------------------------------------------------------------
  2 | ERROR | Missing file doc comment
 20 | ERROR | PHP keywords must be lowercase; expected "false" but found "FALSE"
 47 | ERROR | Line not indented correctly; expected 4 spaces but found 1
 51 | ERROR | Missing function doc comment
 88 | ERROR | Line not indented correctly; expected 9 spaces but found 6
--------------------------------------------------------------------------------

FILE: /path/to/code/yourfile.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 1 WARNING(S) AFFECTING 1 LINE(S)
--------------------------------------------------------------------------------
 21 | ERROR   | PHP keywords must be lowercase; expected "false" but found
    |         | "FALSE"
 21 | WARNING | Equals sign not aligned with surrounding assignments
--------------------------------------------------------------------------------

Rekomendasi

  • Gunakan PSR 2 sebagai standard untuk pengecekan code standard violation.
  • Gunakan integrasi dengan IDE atau text editor untuk mempermudah development.

Contoh

Misalkan ada file PHP sebagai berikut

<?php

class Test_My_class
{
    public function index_test()
    {
        $varA = TRUE;

        if($varA) {
            echo 'T';
        }
    }

    private function test_argument($test1,$test2)
    {
        $array = array(1,2);

        if($test1)
        {
            foreach($array as $value){
                echo $value;
            }
        }
    }
}

 

Jika kita jalankan pengecekan phpcs terhadap file tersebut

phpcs --standard=PSR2 test.php 

FILE: /Users/libreorca/Htdocs/test/phpcs/test.php
----------------------------------------------------------------------
FOUND 11 ERRORS AFFECTING 7 LINES
----------------------------------------------------------------------
  3 | ERROR | [ ] Each class must be in a namespace of at least one
    |       |     level (a top-level vendor name)
  3 | ERROR | [ ] Class name "Test_My_class" is not in camel caps
    |       |     format
  5 | ERROR | [ ] Method name "Test_My_class::index_test" is not in
    |       |     camel caps format
  7 | ERROR | [x] TRUE, FALSE and NULL must be lowercase; expected
    |       |     "true" but found "TRUE"
  9 | ERROR | [x] Expected 1 space after IF keyword; 0 found
 14 | ERROR | [ ] Method name "Test_My_class::test_argument" is not
    |       |     in camel caps format
 14 | ERROR | [x] Expected 1 space between comma and argument
    |       |     "$test2"; 0 found
 18 | ERROR | [x] Expected 1 space after IF keyword; 0 found
 18 | ERROR | [x] Expected 1 space after closing parenthesis; found 9
 20 | ERROR | [x] Expected 1 space after FOREACH keyword; 0 found
 20 | ERROR | [x] Expected 1 space after closing parenthesis; found 0
----------------------------------------------------------------------
PHPCBF CAN FIX THE 7 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Time: 19ms; Memory: 3.5Mb

 

Sesuai dengan standard PSR2, kode diatas banyak melanggar standard coding. Ada beberapa pelanggaran yang bisa difix dengan phpcbf secara automatis. Hasilnya bisa dicek dibawah

phpcbf --standard=PSR2 test.php 
Changing into directory /Users/libreorca/Htdocs/test/phpcs
Processing test.php [PHP => 116 tokens in 25 lines]... DONE in 4ms (7 fixable violations)
        => Fixing file: 0/7 violations remaining [made 6 passes]... DONE in 20ms
Patched 1 file
Time: 59ms; Memory: 3.75Mb

phpcs --standard=PSR2 test.php 

FILE: /Users/libreorca/Htdocs/test/phpcs/test.php
----------------------------------------------------------------------
FOUND 4 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
  3 | ERROR | Each class must be in a namespace of at least one level
    |       | (a top-level vendor name)
  3 | ERROR | Class name "Test_My_class" is not in camel caps format
  5 | ERROR | Method name "Test_My_class::index_test" is not in camel
    |       | caps format
 14 | ERROR | Method name "Test_My_class::test_argument" is not in
    |       | camel caps format
----------------------------------------------------------------------

Time: 25ms; Memory: 3.5Mb

 

Hasil file setelah difix phpcbf secara automatis

<?php

class Test_My_class
{
    public function index_test()
    {
        $varA = true;

        if ($varA) {
            echo 'T';
        }
    }

    private function test_argument($test1, $test2)
    {
        $array = array(1,2);

        if ($test1) {
            foreach ($array as $value) {
                echo $value;
            }
        }
    }
}

 

Beberapa pelanggaran sudah di fix automatis oleh phpcbf, tapi file tersebut masih ada pelanggaran terhadap standard PSR2, kita perlu melakukan refactor manual.

<?php
namespace Phpcs\Test;

class TestMyClass
{
    public function indexTest()
    {
        $varA = true;

        if ($varA) {
            echo 'T';
        }
    }

    private function testArgument($test1, $test2)
    {
        $array = array(1,2);

        if ($test1) {
            foreach ($array as $value) {
                echo $value;
            }
        }
    }
}

 

Jika kita re-run phpcs dan hasilnya kosong, maka file PHP sudah mengikuti standard yang ditentukan (dalam kasus ini PSR2).

phpcs --standard=PSR2 test.php
*empty string*

Remark

  • Perhatikan kode hasil refactor phpcs tidak mendeteksi unusued code (function testArgument, dan argumen test2), oleh sebab itu phpcs digunakan berdampingan dengan phpmd untuk hasil yang optimum.
  • Lakukan phpcs secara berkala untuk menjaga kualitas koding – atau integrasikan dengan IDE / text editor masing masing.

Credit to: Yusuf Irwandi

PSR 4 – Autoload

http://www.php-fig.org/psr/psr-4/

Perhatikan keyword ‘harus’, ‘tidak boleh’, ‘seharusnya’, ‘disarankan’, ‘dibolehkan’, ‘mungkin’.

1. Overview

Dokumen PSR ini mendeskripsikan spesifikasi untuk autoloading class dari file path. PSR ini bisa digabungkan dengan spesifikasi autoloading yang lain, termasuk PSR0. PSR ini juga mendeskripsikan dimana sebuah file harus disimpan yang akan di autoload sesuai dengan spesifikasinya.

2. Specification

  • Term “class” merefer ke class, interfaces, traits dan struktur mirip lainnya.
  • Nama “fully qualified class” memiliki bentuk sebagai berikut:
    • \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
    • Nama “fully qualified class” harus memiliki namespace top level, yang dikenal juga sebagai “vendor namespace”.
    • Nama “fully qualified class” boleh memiliki satu atau lebih sub namespace.
    • Nama “fully qualified class” harus memiliki akhiran nama class.
    • Underscore tidak memiliki arti khusus di setiap bagian dari nama “fully qualified class”.
    • Karakter alfabet di dalam nama “fully qualified class” boleh mengandung kombinasi huruf kecil dan huruf besar.
    • Semua nama class harus direfer sesuai casenya (case-sensitive).
  • Ketika me-load sebuah file yang berkorespondensi dengan nama “fully qualified class”…
    • Sebuah serial bersambung dari satu atau lebih namespace awal dan sub namespace, tidak termasuk separator namespace awal, di dalam nama “fully qualified class” (namespace prefix) berkorespondensi dengan setidaknya satu “base directory”.
    • Sub namespace yang bersambung setelah “namespace prefix” berkorespondensi dengan sub direktori didalam “base directory”, dimana separator namespace berlaku sebagai separator direktori. Nama sub direktori harus sesuai dengan “case” sub namespace.
    • Nama class berkorespondensi dengan nama file diakhiri dengan .php. Nama file harus sesuai dengan “case” dari nama class.
  • Implementasi autloader tidak boleh menghasilkan exception, tidak boleh menghasilkan error di level apapun, dan seharusnya tidak mengembalikan sebuah value.

3. Examples

Tabel di bawah menampilkan korespondensi file path untuk sebuah nama “fully qualified class”, namespace prefix, dan base directory.

Fully Qualified Class Name Namespace Prefix Base Directory Resulting File
\Acme\Log\Writer\File_Writer Acme\Log\Writer ./acme-log-writer/lib ./acme-log-writer/lib/File_Writer.php
\Aura\Web\Response\Status Aura\Web /path/to/aura-web/src/ /path/to/aura-web/src/Response/Status.php
\Symfony\Core\Request Symfony\Core ./vendor/Symfony/Core/ ./vendor/Symfony/Core/Request.php
\Zend\Acl Zend /usr/includes/Zend/ /usr/includes/Zend/Acl.php

Sebagai contoh implementasi dari autoloader yang mengikuti spesifikasi, lihat contoh file. https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md

Contoh implementasi tidak boleh dianggap sebagai bagian dari spesifikasi dan mungkin berubah kapan saja.

 

Credit to: Yusuf Irwandi

PSR 2 – Coding Style Guide

http://www.php-fig.org/psr/psr-2/

Guide ini melanjutkan dan melengkapi PSR1 the basic coding standard.

Tujuan dari guide ini adalah untuk mengurangi coginitive friction ketika membaca kode dari pembuat yang berbeda. Caranya adalah dengan memiliki aturan dan ekspektasi umum tentang bagaimana menulis kode PHP.

Aturan aturan disini diambil dari kebiasaan kebiasaan para anggota project. Ketika authors berkolaborasi dengan multiple project, akan membantu jika kita memiliki satu set guideline yang bisa digunakan untuk project project tersebut.

Perhatikan keyword ‘harus’, ‘tidak boleh’, ‘seharusnya’, ‘disarankan’, ‘dibolehkan’, ‘mungkin’.

1. Overview

  • Kode harus mengikuti “coding style guide” PSR1.
  • Kode harus menggunakan 4 spasi untuk indentasi, bukan tab.
  • Tidak boleh ada hard limit untuk panjang kode dalam satu baris, soft limitnya adalah 120 karakter, satu line seharusnya 80 karakter atau kurang.
  • Harus ada satu line kosong setelah deklarasi namespace, dan harus ada satu line kosong setelah deklarasi block use.
  • Kurung kurawal buka untuk class harus ditempatkan di baris selanjutnya, dan kurung kurawal tutup harus ditempatkan di baris setelah isi.
  • Kurung kurawal buka untuk method harus ditempatkan di baris selanjutnya, dan kurung kurawal tutup harus ditempatkan di baris setelah isi.
  • Visibility (public protected private), harus dideklarasikan untuk setiap properties dan methods. Abstran dan final harus dideklarasikan sebelum visibility; static harus dideklarasikan setelah visibility.
  • Control structure keywords harus memiliki satu spasi setelahnya, sedangkan pemanggilan method dan function tidak boleh.
  • Kurung kurawal buka untuk control structure harus ditempatkan di line yang sama, dan kurung kurawal tutup harus ditempatkan di baris setelah isi.
  • Kurung buka untuk control structure tidak boleh ada spaci setelahnya, dan kurung tutup untuk control structure tidak boleh ada spasi sebelumnya.

1.1 Example

Contoh berikut menampilkan beberapa aturan untuk overview singkat.

<?php
namespace Vendor\Package;

use FooInterface;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class Foo extends Bar implements FooInterface
{
    public function sampleFunction($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
    }
}

2. General

2.1 Basic Coding Standard

Kode harus mengikuti aturan yang ditulis di PSR1

2.2 Files

Semua file PHP harus menggunakan line ending Unix LF (linefeed)
Semua file PHP harus diakhiri dengan satu baris kosong.
Tag penutup ?> tidak boleh ada di file yang hanya mengandung PHP.

2.3 Lines

Tidak boleh ada hard limit untuk panjang baris.

Soft limitnya adalah 120 karakter, pengecekan automatis harus memberi warning tapi tidak boleh menampilkan error untuk soft limit.

Panjang baris seharusnya tidak lebih dari 80 karakter, baris yang lebih dari itu harus di split menjadi multiple line yang panjangnya tidak lebih dari 80 karaketer masing masing.

Tidak boleh ada spasi di akhir baris yang tidak kosong.

Baris kosong boeh ditambahkan untuk mengingkatkan readibility atau menampilkan block kode.

2.4 Indenting

Kode harus menggunakan identasi 4 spasi, tidak boleh menggunakan tab.

Menggunakan hanya spasi, dan tidak campur dengan tab, membantu menghindari masalah dengan diff, patches, history dan annotation. Penggunaan spasi juga memudahkan untuk melakukan alignment.

2.5 Keywords and True/False/Null

PHP Keywords harus ditulis dengan huruf kecil. Konstanta PHP true, false, dan null semua harus lowercase.

 

3. Namespace and use declarations

Jika menggunakan, harus ada satu baris kosong setelah deklarasi namespace.

Jika menggunakan namespace, deklarasi use harus setelah deklarasi namespace.

Harus ada satu keyword user per deklarasi.

Harus ada satu baris kosong setelah block user.

Contoh.

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...

4. Classes, Properties, and methods

Term “class” merefer ke semua class, interfaces, dan traits.

4.1 Extends and Implements

Keyword extends dan implements harus dideklarasikan di baris yang sama dengan nama class.

Kurung kurawal buka untuk class harus ditempatkan di baris sendiri, kurung kurawal tutup harus ditempatkan di baris setelah isi.

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}

List implements boleh di split sebagai multiple line, dimana setiap baris di identasikan sekali. Jika melakukan ini, item pertama di list harus berada di baris selanjutnya, dan perbaris hanya boleh satu interface.

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // constants, properties, methods
}

4.2 Properties

Visibility harus dideklarasikan di semua properties.

Keyword var tidak boleh digunakan untuk mendeklarasikan property.

Per satu statement tidak boleh lebih dari satu property yang dideklarasikan.

Nama property seharusnya tidak di tambahkan underscore untuk mengindikasikan visibilitynya sebagai private atau protected.

Contoh deklarasi property:

<?php
namespace Vendor\Package;

class ClassName
{
    public $foo = null;
}

4.3 Methods

Visibility harus dideklarasikan di semua method.

Nama method seharusnya tidak ditambahkan underscore untuk mengindikasikan visibilitynya sebagai protected atau private.

Nama method tidak boleh dideklarasikan dengan spasi setelah nama method. Kurung kurawal buka harus berada di baris sendiri, dan kurung kurawal tutup harus berada di line setelah isi. Tidak boleh ada spasi setelah kurung buka, dan tidak boleh ada spasi sebelum kurung tutup.

Contoh Deklarasi method, perhatikan penempatan kurung, koma, spasi dan kurung kurawal:

<?php
namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

4.4 Method Argument

Di dalam list argumen, tidak boleh ada spasi sebelum koma, dan harus ada satu spasi setelah setiap koma.

Argumen method dengan nilai default harus ditempatkan di akhir list argument.

<?php
namespace Vendor\Package;

class ClassName
{
    public function foo($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

List argument boleh di split menjadi multiple line, dimana setiap line di identasikan sekali. Jika melakukan ini, item pertama harus ditempatkan di baris selanjutnya, dan per baris hanya boleh ada satu argument.

Ketika list argument di split menjadi multiple line, kurung tutup dan kurung kurawal buka harus ditempatkan di baris baru yang sama dengan satu spasi di antaranya.

<?php
namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // method body
    }
}

 

4.5 Abstract final and static

Jika ada, deklarasi abstract dan final harus sebelum deklarasi visibility.

Jika ada, deklarasi static harus sesudah deklarasi visibility.

<?php
namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

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

4.6 Method and function calls

Ketika memanggil method atau function, tidak boleh ada spasi di antara method atau nama function dan kurung buka, tidak boleh ada spasi setelah kurung buka dan tidak boleh ada spasi sebelum kurung tutup. Di dalam list argument tidak boleh ada spasi sebelum setiap koma, dan harus ada satu spasi setelah setiap koma.

<?php
bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

List argument boleh di split menjadi multiple line, dimana setiap line diidentasikan sekali. Jika melakukan ini, item pertama di dalam list harus ditempatkan di baris selanjutya, dan hanya boleh ada satu argument per satu baris.

<?php
$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);

5. Control Structures

Aturan umum untuk control structures adalah sebagai berikut

  • Harus ada satu spasi setelah keyword control structure.
  • Tidak boleh ada spasi setelah kurung buka.
  • Tidak boleh ada spasi sebelum kurung tutup.
  • Harus ada satu spasi antara kurung tutup dengan kurung kurawal buka.
  • Isi dari control structure harus diidentasikan sekali.
  • Kurung kurawal tutup harus ditempatkan di baris setelah isi.

Isi dari setiap struktur harus di dalam kurung kurawal. Ini menstandardisasikan bagaimana struktur terlihat, dan mengurangi kemungkinan error ketika baris baru ditambahkan di dalam isi.

5.1 If, elseif, else

Tampilan struktur If seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal, dan else dan elseif berada dalam baris yang sama dengan isi sebelumnya.

<?php
if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}

Keyword elseif seharusnya digunakan alih alih else if sehingga semua control keyword terlihat seperti satu kata.

5.2 Switch, case

Tampilan struktur switch seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal. Statement case harus di identasikan sekali dari switch, dan keyword break (atau terminating keyword yang lainnya) harus diidentasikan di level yang sama dengan isi case. Harus ada komentar  no break ketika memang disengajakan fall-through di dalam isi case yang tidak kosong.

<?php
switch ($expr) {
    case 0:
        echo 'First case, with a break';
        break;
    case 1:
        echo 'Second case, which falls through';
        // no break
    case 2:
    case 3:
    case 4:
        echo 'Third case, return instead of break';
        return;
    default:
        echo 'Default case';
        break;
}

5.3 While, do while

Tampilan statement while seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal.

<?php
while ($expr) {
    // structure body
}

Mirip dengan while, statement do while tampilannya seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal.

<?php
do {
    // structure body;
} while ($expr);

5.4 For

Tampilan statement for seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal.

<?php
for ($i = 0; $i < 10; $i++) {
    // for body
}

5.5 Foreach

Tampilan statement foreach seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal.

<?php
foreach ($iterable as $key => $value) {
    // foreach body
}

5.6 Try, catch

Tampilan block try catch seperti berikut. Perhatikan penempatan kurung, spasi dan kurung kurawal.

<?php
try {
    // try body
} catch (FirstExceptionType $e) {
    // catch body
} catch (OtherExceptionType $e) {
    // catch body
}

 

6. Closures

Closures harus dideklarasikan dengan satu spasi setelah keyword function, dan satu spasi sebelum dan sesudah keyword use.

Kurung kurawal buka harus ditempatkan di baris yang sama, dan kurung kurawal tutup harus ditempatkan di baris setelah isi.

Tidak boleh ada spasi setelah kurung buka dari list argument atau list variabel, dan tidak boleh ada spasi sebelum kurung tutup dari list argument atau list variabel.

Di dalam list argument dan list variabel, tidak boleh ada spasi sebelum setiap koma, dan harus ada satu spasi setelah setiap koma.

Argument closure dengan nilai default harus ditempatkan di akhir list argument.

Deklarasi closure seperti berikut. Perhatikan penempatan kurung, koma, spasi, dan kurung kurawal.

<?php
$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};

List argument dan variabel boleh di split menjadi multiple line dimana setiap baris diidentasikan sekali. Jika melakukan ini, item pertama harus ditempatkan di baris baru, dan hanya boleh ada satu argument atau variabel per satu baris.

Ketika list akhir (argument atau variabel) di split menjadi multiple line, kurung tutup dan kurung kurawal buka harus ditempatkan di baris baru dengan spasi di antara mereka.

Berikut adalah contoh closures dengan atau tidak dengan list argument dan list variabel yang di split menjadi multiple line

<?php
$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
   // body
};

$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // body
};

$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // body
};

$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
   // body
};

$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // body
}; 

 

Perhatikan aturan penulisan juga digunakan ketika closure dipanggil di function atau method sebagai argument.

<?php
$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);

7. Conclusion

Banyak aturan dan practice yang sengaja tidak ditulis di guide ini. Termasuk tapi tidak terbatas pada:

  • Deklarasi variabel global dan konstanta global.
  • Deklarasi functions
  • Operator dan assignment
  • Inter-line alignment
  • Comments and documentation blocks
  • Class name prefixes and suffixes
  • Best practices

Rekomendasi selanjutnya mungkin merevisi dan melengkapi guide ini untuk bagian bagian tersebut.

Credit to: Yusuf Irwandi