Skip to content

Instantly share code, notes, and snippets.

@toopay
Last active September 16, 2017 13:59
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save toopay/7086599 to your computer and use it in GitHub Desktop.
Save toopay/7086599 to your computer and use it in GitHub Desktop.
Composer Explained (PHP Indonesia EMagz Draft)

Composer Explained

oleh Taufan Aditya

I. Kenapa Menggunakan Composer

a. Sekilas tentang "native" PHP

Mari kita perhatikan sejenak kode berikut ini :

<?php
$title = 'User Detail';
$data = array();

$con=mysqli_connect("example.com","peter","abc123","my_db");

if (mysqli_connect_errno()) {
  die("Failed to connect to MySQL: " . mysqli_connect_error());
}

$result = mysqli_query($con,"SELECT * FROM users");

while($row = mysqli_fetch_array($result)) {
  $data[] = $row;
}

mysqli_close($con);
?>
<html>
<head>
   <title><?php echo $title?></title>
</head>
<body>
<?php
foreach ($data as $item) {
?>
<h1><?php echo $item["name"];?></h1>
<p><?php echo $item["biodata"];?></p>
<?php
}
?>
</body>
</html>

Potongan kode diatas mungkin tampak familiar bagi anda. Apakah menurut anda, ada yang salah dengan potongan kode diatas? Mayoritas developer PHP akan sepakat bahwa potongan kode diatas bekerja sebagaimana yang diharapkan. Dan jika anda termasuk mereka yang menganggap tidak ada yang salah dengan potongan kode diatas, hal tsb bukan-lah salah anda.

Jika kita bedah lebih lanjut potongan kode diatas, di satu sisi dia melakukan hal yang memang diperlukan. Kita bisa lihat (dengan sedikit usaha ekstra) bahwa program diatas mengambil data user dari database, kemudian secara traversal menampilkan nama dan biodata tiap user. Namun disisi lain, kita juga bisa melihat bahwa potongan kode diatas menempatkan markup SQL, markup HTML dan markup PHP dalam satu file. PHP, secara natural memang memiliki semacam kelebihan (bisa dikatakan bakat) untuk menghasilkan spaghetti code semacam ini. Dan hampir semua tutorial PHP yang beredar di internet (sayangnya) akan mengantarkan para pemula, ke kesalahan fundamental tersebut : kombinasi SQL dengan HTML, di balut dengan markup PHP, yang di-glorifikasi di seluruh bagian aplikasi.

Isu utama pada spaghetti code adalah :

  • Tidak ada modularitas.
  • Kurangnya peng-organisasi-an kode
  • Tidak ada pembagian antara fungsi dan tujuan.
  • Tidak memungkinan penggunaan ulang (mengandalkan Copy-Pasta!).
  • Sulit untuk di-verifikasi.

Kecenderungan ini menjadi problem umum bagi developer PHP, hingga pada tahun 2005-2006 bermunculan apa yang kemudian kita sebut sebagai PHP Framework : Symfony, Zend Framework, Cake PHP, CodeIgniter. Secara umum, sebuah web-framework adalah alat yang menyederhanakan persoalan, dengan menyediakan seperangkat alat yang umum, sehingga developer bisa fokus ke tugas dan tujuan yang spesifik. Web-framework memperkenalkan konsep Separation of Concern. Dengan web-framework, seorang developer PHP bisa menyelesaikan sebuah task lebih cepat daripada sebelumnya. Selain itu, hal-hal penting lainnya yang diperkenalkan oleh web-framework adalah :

  • Organisasi kode.
  • Mempromosikan standard.
  • Mempromosikan reusabilitas kode.

Kita tidak akan membahas lebih detail komparasi antara aplikasi yang ditulis dengan web-framework dengan yang tidak ditulis dengan web-framework, ada banyak resource yang tersebar di internet soal hal tersebut (salah satunya tulisan tentang perbandingan Symfony2 versus Flat PHP)

b. Apakah Framework sudah menjawab semua persoalan?

Hingga tulisan ini dibuat, PHP adalah bahasa yang memiliki web-framework terbanyak. Setiap hari, di suatu tempat, seseorang mungkin sedang menulis "Yet Another PHP Framework". Anda mungkin telah mengenal dan menggunakan web-framework dalam kehidupan sehari-hari anda. Dan, kalau anda seperti saya, anda akan mulai melihat problem utama pada (semua) web-framework : interopabilitas.

Kenapa kita peduli tentang interopabilitas? Bukankah web-framework sudah memberikan kita fondasi yang solid untuk mengembangkan aplikasi yang mudah di-maintain?

Pernahkan, pada satu waktu, anda memerlukan fungsionalitas yang tidak disediakan web-framework yang anda gunakan? Misalnya, fungsionalitas untuk mengirim payload data ke message-queue broker. Atau fungsionalitas untuk melakukan autentifikasi berbasis protokol oAuth misalnya. Anda akan dihadapkan ke dua pilihan yang tidak mudah :

  • Mengimport external library.
  • Menulis library sendiri.

Pilihan pertama mungkin tampak mudah. Kita tinggal melakukan riset untuk mencari library yang sesuai dengan kebutuhan kita. Setiap framework memiliki repository untuk library mereka masing-masing :

  • Symfony -> Bundle
  • CodeIgniter -> Spark
  • Zend Framework -> Modules
  • CakePHP -> Bakery

Anda mungkin akan mendapat salah satu dari hasil berikut :

  • Menemukan library yang (tampaknya) sesuai, tapi dia berada di repository framework lain.
  • Menemukan library yang (sekali lagi, tampaknya) sesuai, tapi dia berada di PEAR repository (atau situs sejenis PHPClasses?)
  • Tidak menemukan library yang sesuai dengan kebutuhan anda di manapun.

Jika anda tidak menemukan apapun yang cocok, maka hanya tersisa satu pilihan untuk anda : menulis sendiri library tersebut. Meskipun tampaknya hal tersebut menyeramkan, mungkin itu adalah pilihan terbaik anda. Kenapa? Jika anda menemukan library yang sesuai dengan kebutuhan anda, tapi dia tidak berada di repository web-framework yang anda gunakan, maka kemungkinan besar anda akan mengalami masalah saat mengintegrasikan library tersebut ke framework anda. Pernahkah anda menggunakan library yang dikembangkan untuk web-framework lain di web-framework anda? Jika anda pernah mengalami hal tersebut, saya yakin anda memahami maksud saya. Yap. Setiap web-framework memiliki standard dan konvensi mereka sendiri. Kecil kemungkinan anda dapat menggunakan library yang dikembangkan untuk web-framework lain, untuk di-integrasikan ke web-framework anda tanpa menambahkan boilerplate ke dalam aplikasi anda. Technical debt semacam ini, jika tidak di-manage dengan baik, bisa membawa aplikasi anda ke arah yang tidak pernah anda harapkan : kode yang tidak terurus, kotor dan tidak fleksibel. Bayangkan jika anda perlu memperbarui eksternal library tersebut dengan patch terbaru : chaos!

Dalam situasi tersebut, anda mungkin berpendapat bahwa ada yang salah dengan web-framework yang anda pakai. Anda mungkin akan mengambil langkah drastis : berpindah ke web-framework lain. Percayalah, hal ini pun bukan pilihan yang ideal. Berpindah ke web-framework lain berarti membuang semua yang sudah anda bangun (termasuk konvensi dan standard-standard anda sudah terbiasa dengannya), dan memulai semuanya dari nol. Anda (dan tim anda) akan memerlukan waktu yang cukup banyak, untuk mempelajari dan terbiasa dengan konvensi dan standard web-framework baru tersebut, yang tentunya, mempengaruhi waktu pengembangan. Dan meskipun pihak manajemen perusahaan anda, setuju untuk membuang semua hasil kerja beberapa bulan (atau tahun) terakhir, dan memulai semuanya dari awal, tidak ada jaminan anda tidak akan berakhir di tempat yang sama.

II. Apa itu Composer?

a. Composer : Depedency Manager untuk PHP

Berikut bisa kita lihat, perbandingan arsitektur package antar bahasa pemrograman :

  • Perl -> CPAN
  • Ruby -> Gem
  • Java -> Maven
  • Python -> pip
  • C#(.net) -> NuGet
  • Node.JS-> npm
  • PHP -> Composer

Yap. Composer adalah depedency manager. Artinya :

  • Composer bisa menginstall package yang dibutuhkan
  • Composer bisa mengupdate package yang memiliki release terbaru
  • Composer bisa menghapus package yang sudah tidak diperlukan

Lalu, masalah apa yang coba diselesaikan oleh Composer? Coba kita lihat kembali point sebelumnya : integrasi eksternal library kedalam web-framework bukanlah hal mudah. Ambil contoh nyata. Misal anda ingin mengintegrasikan PHPActiveRecord ORM ke dalam project anda. Ada berbagai cara untuk melakukannya, semuanya tergantung framework apa yang anda gunakan.

Bagaimana dengan composer? Hanya diperlukan 3 langkah mudah :

  • Buat deskripsi depedency. Misalnya, kita hendak menggunakan Monolog, maka kita perlu membuat file bernama composer.json dengan isi sebagai berikut :
{
    "require": {
        "monolog/monolog": "~1.6"
    }
}
  • Install depedency menggunakan composer. Buka terminal dan jalankan perintah berikut :
curl -s http://getcomposer.org/installer | php
php composer.phar install

Composer akan membuat direktori vendor yang berisi semua depedency project anda.

  • Import autoloader yang dihasilkan composer pada project anda :
require 'vendor/autoload.php';

Dan libray eksternal tersebut sudah siap dipakai! Tak peduli library eksternal apapun yang anda perlukan, hanya perlu satu cara untuk menggunakannya, jika anda memilih Composer sebagai depedency manager untuk project PHP anda. Dan jika library tersebut juga memiliki depedency terhadap library lain? Selama depedency tersebut memiliki repository composer, maka Composer akan me-resolusi depedensi tersebut untuk anda.

Cara Composer dalam me-resolusi depedensi yang anda perlukan sangat reliable. Hal ini dikarenakan Composer mengadopsi SAT solver sebagai algoritma untuk me-resolusi depedensi. Semua package pertama-tama di kumpulkan dalam pool. Depedency antar package kemudian diterjemahkan menjadi boolean. Berikut contoh terjemahan depedensi di Composer dalam anotasi boolean :

StatementAnotasi
Install B (versi 1 atau 2)(B1|B2)
A require B (versi 1 atau 2)(-A|B1|B2)
A conflict B (versi 1 atau 2)(-A|-B1), (-A|-B2)
C dan D provide E(-E|C|D)
B2 update B1(-B1|-B2)

Sehingga, misalnya dalam suatu contoh kasus, kita memiliki depedensi seperti berikut :

(-A|B1|B2) (-B2|C) (A) (-B1|-B2) (-A|-C)

SAT solver akan mengevaluasi boolean untuk A, B1, B2 dan C sehingga semua kondisi menjadi TRUE. Jika nilai akhirnya TRUE, dia akan diinstall.

b. Composer Quick Start

Menggunakan Composer untuk mengimport atau menyediakan dependensi sangat sederhana dan mudah. Untuk mendefinisikan dependensi, buat file composer.json berisi :

{
    "require": {
        "vendor/package": "1.3.2",
        "vendor/package2": "1.*",
        "vendor/package3": ">=2.0.3"
    }
}

Dalam resep composer.json diatas, kita menggunakan keyword require untuk memberi informasi Composer tentang daftar package yang diperlukan oleh project kita. Semua package/library dalam composer memiliki format vendor/package. Sehingga jika anda memutuskan untuk membuat sebuah library untuk didistribusikan melalui composer, anda juga perlu mengikuti format tersebut. Misalnya, saya ingin membuat sebuah library untuk mengambil data dari kaskus, saya mungkin akan memiliki composer.json sebagai berikut dalam root project saya :

{
    "name": "toopay/kaskus",
    "require": {
        "php": ">=5.3.0",
        "another-vendor/package": "1.*"
    }
}

Jika kita perhatikan, dua contoh composer.json diatas, menjadi jelas bahwa perbedaan antara provider dan consumer terletak hanya di eksistensi atribut name. Hanya dengan menambahkan atribut name pada composer.json project kita, maka project kita sendiri telah menjadi sebuah package yang bisa di-install oleh project lain sebagai depedensi!

Hal ini sangat membantu bagi banyak pihak yang hendak mengadopsi Composer sebagai dependensi manager, untuk kemudian misalnya, mengekstrak project mereka menjadi bagian-bagian yang lebih kecil dan di-distribusikan sebagai package yang independen. Symfony2 menjadi pioner dalam hal ini. Seluruh komponen yang membentuk Symfony2, sebagai sebuah full-stack framework, adalah komponen-komponen yang bersifat independen dan didistribusikan melalui Composer. Artinya, kita dapat menggunakan satu atau dua komponen Symfony (seperti HttpFoundation - library yang menyediakan Object-Oriented layer untuk HTTP - atau Console - library yang menyediakan komponen komponen standard I/O - misalnya) tanpa perlu menginstall keseluruhan web-framework. Ini sungguh sebuah kemajuan, bukan hanya bagi Symfony sebagai sebuah open-source project, melainkan juga, PHP sebagai web-platform. Dan tidak berhenti disitu, saat ini sudah cukup banyak open-source project yang mengikuti langkah tersebut (dan saling berkolaborasi dalam perjalannya) : Zend, Laravel, Drupal, Joomla. Dan daftar ini hanya bisa terus bertambah.

Composer mendukung beberapa terms dependensi, selain statemen require yang sudah sering kita pakai dalam contoh-contoh deklarasi dependensi diatas. Beberapa istilah dependensi yang ada di Composer adalah sebagai berikut :

  • Require : daftar package yang diperlukan oleh project.
  • Require-dev : daftar package yang diperlukan oleh project, ketika project berposisi sebagai root project. Jika project di-install sebagai dependensi, maka daftar ini akan diabaikan. Daftar ini sangat berguna dalam proses development package.
  • Provide : daftar package yang disediakan oleh project.
  • Replace : daftar package yang digantikan oleh project ini. Daftar ini berguna jika kita, di kemudian hari, mengubah nama project/package kita.
  • Conflict : daftar package yang tidak bisa ko-eksis dengan package kita.
  • Recommend : daftar package yang direkomendasikan oleh package kita.
  • Suggest : daftar package yang disarankan oleh package kita.

Sebagai infrastruktur distribusi library/package, Composer memiliki sentral repository bernama Packagist, yang merupakan agregasi semua open-source package. Untuk closed-source package, Composer juga mendukung private repository via Satis. Jika anda menggunakan Github, tersedia service-hook Depending yang akan memudahkan anda dalam memonitor kesehatan dependensi project anda.

c. Peran Lain Composer

Selain sebagai dependensi manager, Composer memiliki dua peran penting lain :

  • Memungkinkan kita me-reproduksi environment aplikasi yang sama di semua mesin yang kita pakai
  • Memungkinkan kita melakukan automatisasi dalam lifecycle development

Ketika kita menggunakan composer untuk menginstall dependensi, sebuah file bernama composer.lock akan dihasilkan. Saya rekomendasikan anda untuk memasukkan file ini dalam SVN yang anda gunakan. Composer akan menginstall package berdasarkan composer.lock, dan bukan berdasarkan composer.json, jika file tersebut ditemukan. Dengan begitu, tidak ada lagi statemen klise developer yang sering terdengar : "Semuanya baik-baik saja di komputerku" ketika program memuntahkan error. Dengan menyertakan composer.lock dalam SVN, semua developer dalam team bisa bekerja dengan versi package yang sama. Artinya, tidak ada developer yang menggunakan versi yang belum kita verifikasi. Semua mesin (target deploy) juga akan menggunakan versi package yang sama.

Composer memiliki Hooks, sebagai entri point bagi penyedia library untuk mengintersep dan berinteraksi dengan life-cycle composer. Bayangkan jika anda menyediakan sebuah library yang memerlukan pengecekan kondisi environment di komputer target. Dengan hooks, anda bisa meletakan proses pengecekan tersebut atau hal-hal lain yang diperlukan sebagai pre-requirement agar library anda bekerja, misalnya, menginstall keseluruhan schema database yang diperlukan, sebelum (atau sesudah) composer menginstall package anda. Tentu ini menambahkan fleksibilitas, dan mengurangi kerja manual yang biasa kita lakukan saat menginstall sebuah package/library. Hal ini juga sangat membantu kita dalam, misalnya, automatisasi workflow development kita atau dalam proses provisioning di Continuous-Integration server yang kita gunakan.

III. Penutup

Composer, sebagai arsitektur depedency package, jelas sebuah kemajuan bagi PHP. Bahasa lain seperti Ruby, telah menunjukkan betapa mudah untuk menggunakan package dalam project sehingga masalan yang umum bisa segera dipecahkan, dan kita bisa berhenti menghabiskan waktu sebagai developer untuk terus-menerus "reinvent the wheel".

Dan seperti yang sudah disinggung diatas, sudah banyak open-source project yang telah mengadopsi Composer. Hingga tulisan ini dibuat, Composer telah melakukan 7 kali release (sejak 2011), memiliki 244 contributor, menyediakan 16.586 packages (di packagist) dalam 55.071 versi dan total instalasi keseluruhan mencapai 68.718 940. Composer sudah dipakai oleh developer di 182 negara (hanya menyisakan beberapa negara afrika, green-land dan korea utara untuk mengcover seluruh dunia!). Sebagai seorang PHP developer, Composer akan menjadi teman baik anda, dan seiring dengan meningkatnya penggunaan Composer, dia akan menjadi bagian penting dalam keseharian anda.

Composer telah memecahkan problem besar yang selama ini menaungi PHP sebagai bahasa pemrograman, dan benar-benar tidak ada alasan bagi anda untuk tidak segera mengadopsinya, hari ini.

@23Pstars
Copy link

23Pstars commented Jan 9, 2014

mantap :D

@rizals8
Copy link

rizals8 commented Jul 7, 2014

mantap

@sancoLgates
Copy link

mantab gan,

@aginanjar
Copy link

Thanks for sharing. Mantap (y)

@sandhi
Copy link

sandhi commented Dec 4, 2014

paket komplit ini gan..mantap 😄

@nmfzone
Copy link

nmfzone commented Jan 10, 2015

masih belum paham gan, hahaha, hadeehhh

@agengr
Copy link

agengr commented May 21, 2015

josss
ijin mempelajari.

@Helwieahmad
Copy link

joss. ijin nyimak

@bleeloe
Copy link

bleeloe commented Feb 26, 2016

terima kasih infonya bro

@balqqi
Copy link

balqqi commented Jun 16, 2017

mau nanya,
kalo memindahkan project dari pc lama ke pc baru, didalam project tersebut sudah terinstall composer berikut autoloader nya. Ketika di PC lama semua source code berjalan lancar. Ketika di running di PC baru ada error seperti ini
PHP fatal error : class 'fMessaging' not found in ..........

apakah harus ada settingan / konfigurasi lagi di PC baru agar project tersebut bisa berjalan lancar seperti di PC lama ?

Note : fMessaging adalah salah satu class yang dimiliki library Flourish

Terima Kasih

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment