Category Archives: Programming

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

PSR 1 – Basic Coding Standard

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

Rekomendasi ini disarankan agar tingkat interopability antar kode tetap tinggi.

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

1. Overview

  • File harus menggunakan hanya tag <?php dan <?=.
  • File PHP harus hanya menggunakan UTF-8 tanpa BOM.
  • File seharusnya deklarasi simbol (class, functions, constants) saja atau menghasilkan efek samping (menghasilkan output, merubah setting .ini) saja tapi tidak boleh keduanya.
  • Namespace harus mengikuti aturan “autoloading” PSR0 atau PSR4.
  • Nama class harus di deklarasikan dalam StudlyCaps.
  • Konstanta dalam class harus dideklarasikan dengan kapital semua dan underscore untuk separator.
  • Nama method harus di deklarasikan dalam camelCase.

2. Files

2.1 PHP Tags

File PHP harus menggunakan tag <?php ?> atau tag short-echo <?= ?>, tidak boleh menggunakan variasi tag lain

2.2 Character Encoding

File PHP harus hanya menggunakan UTF-8 tanpa BOM.

2.3 Side Effects

Kata “side effects” berarti eksekusi logic yang tidak berhubungan dengan deklarasi class, function, constants dll.

Side effects termasuk tapi tidak terbatas pada: menghasilkan output (contoh: echo), penggunaan require atau include, koneksi ke service eksternal, menghubah setting .ini, menampilkan error atau exception, mengubah variabel global atau static, membaca atau menulis ke file, dan sebagainya.

Berikut adalah contoh file PHP dengan deklarasi dan side effect (contoh yang harus dihindari).

<?php 
//side effect: change ini settings
ini_set('error_reporting', E_ALL);

//side effect: loads a file
include "file.php";

//side effect: generates output
echo "<html>\n";

//declaration
function foo()
{
   // function body
}

Berikut adalah contoh file yang hanya mengandung deklarasi tanpa side effect (contoh yang direkomendasikan).

<?php
//declaration
function foo()
{
    function body
}

//conditional declaration is *not* a side effect
if (! function_exists('bar')) {
    function bar()
    {
        function body
    }
}

3. Namespace and Class Names

Namespace dan nama class harus mengikuti “autoloading” PSR0 atau PSR4.

Ini artinya setiap file mengandung satu class (dirinya sendiri), dan didalam namespace yang setidaknya 1 level: top level vendor name.

Nama class harus dideklarasikan dalam StudlyCaps.

Kode yang ditulis untuk PHP versi 5.3 dan selanjutnya harus menggunakan namespace formal.
Contoh

<?php
//PHP 5.3 and later:
namespace Vendor\Model;

class Foo
{
}

Kode yang ditulis untuk PHP versi 5.2.x dan sebelumnya harus menggunakan aturan pseudo-namespacing dengan menambahkan Vendor_ di nama class.

<?php
//PHP 5.2.x and earlier:
class Vendor_Model_Foo
{
}

4. Class Constants, Properties, and Methods

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

4.1 Constants

Konstanta harus di deklarasikan dengan huruf kapital semua dengan underscore sebagai separator. Contoh:

<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}

4.2 Properties

Guide ini tidak menyarankan salah satu dari $StudlyCaps, $camelCase, atau $under_score untuk nama properties.

Apapun aturan yang digunakan, harus digunakan secara konsisten dalam suatu scope. Scope tersebut bisa vendor level, package level, class level, atau method level.

4.3 Methods

Nama method harus dideklarasikan dalam camelCase().

Credit to: Yusuf Irwandi