Tag Archives: PHP

URL Dinamik untuk Framework Laravel dan Code Igniter

Framework PHP Laravel dan Code Igniter menggunakan URL aplikasi yang didefinisikan pada file konfigurasi masing-masing framework. Konfigurasi alamat aplikasi ini akan dipakai oleh framework untuk menghasilkan alamat URL seperti pada form, link, dan kebutuhan framwork lainnya.

Pada framework Laravel, konfigurasi ini bisa dilihat pada file app/config/app.php dengan baris kode seperti di bawah ini

'url' => 'http://localhost',

sedangkan pada framework Code Igniter, konfigurasi bisa dilihat pada file application/config/config.php dengan baris kode seperti di bawah

$config['base_url']	= 'http://localhost/';

Aplikasi umumnya didevelop di komputer dengan URL localhost dan akan dipindahkan ke hosting yang berbeda URL nya dengan komputer pada saat developing. Ketika memindahkan aplikasi ke web server, terpaksa kita harus mengganti alamat URL. Jika mengganti secara manual, akan sangat merepotkan terutama jika sering memindah-mindahkan file. Dengan variabel spesial PHP, alamat URL bisa diganti agar lebih dinamis menyesuaikan dengan alamat URL aplikasi.

Untuk Laravel, potongan kode di atas bisa diganti menjadi

'url' => 'http://'.$_SERVER['SERVER_NAME'],

sedangkan untuk Code Igniter menggunakan konfigurasi di bawah ini

$config['base_url']	= 'http://'.$_SERVER['SERVER_NAME'];

Debug WordPress untuk Fungsi yang Deprecated

Sehari kemaren saya berusaha mengupdate WordPress saya dari versi 3.4 ke versi 3.5. Sayangnya sejak WordPress versi 3.3 yang lalu, saya tidak bisa mengupdate secara otomatis. Saya hanya memperoleh error dengan kode 500 (Internal Error) ketika saya membuka tautan untuk update otomatis. Terpaksa pada beberapa versi kemaren termasuk update ke versi 3.5, saya melakukan update manual (download lalu timpa pada file WordPress yang lama).

Karena penasaran link update masih belum jalan juga, saya berniat melakukan analisis untuk mencari tau penyebab erornya WordPress saya. Untuk memulai proses analisis (debug), kita perlu mengaktifkan WordPress agar mengeluarkan eror yang dihasilkan oleh php. Tambahkan baris berikut pada wp-config.php.

1
2
3
4
5
6
/** File: wp-config.php **/
/** Debug **/
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', true);
@ini_set('display_errors',1);

Ternyata dari hasil debug, banyak eror yang dihasilkan oleh plugin dan themes yang saya pakai. Kebetulan themes dan plugin tersebut banyak yang tidak ada update terbarunya. Seiring dengan perkembangan WordPress, banyak fungsi-fungsi yang deprecated atau sudah tidak dipakai lagi dan digantikan oleh fungsi lain. Satu-satunya cara untuk memperbaiki plugin dan themes tersebut adalah dengan mengganti fungsi-fungsi tersebut dengan fungsi yang lebih baru.

Namun sayangnya, konsep WordPress dalam menjebak eror (error catch) sangat tidak memudahkan user dalam mencari tau letak error yang sebenarnya. Ketika Wordpres menampilkan eror, maka baris eror yang ditunjukkan adalah baris untuk menampilkan eror tersebut, bukan baris error yang sesungguhnya.

Screenshot from 2012-12-12 15:11:11 1

Akhirnya saya menemukan sebuah cara untuk mengakali WordPress menampikan baris eror yang sebenarnya.

Langkah pertama yang kita lakukan adalah mengingat atau menuliskan fungsi yang deprecated yang ditunjukkan pada layar browser. Contoh pada gambar di atas adalah fungsi get_current_theme() yang sudah tidak dipakai lagi dan harus digantikan dengan fungsi wp_get_theme().

Lalu buka file wp-includes/deprecated.php dan cari baris dengan nama fungsi tersebut. Lalu rename fungsi tersebut, cukup dengan menambahkan beberapa string di depan atau di belakang nama fungsi tersebut. Pada contoh di bawah ini, saya merename fungsi get_current_theme menjadi test_get_current_theme. Setelah itu simpan perubahan yang sudah dilakukan.

Screenshot from 2012-12-12 15:12:40

Selanjutnya kita harus mereload halaman yang tadi menunjukkan eror tersebut. Kali ini, WordPress tidak lagi menampilkan pesan eror bahwa fungsi pada wordpress sudah deprecated, namun WordPress akan menujukkan eror yang sebenarnya, yaitu baris yang memakai fungsi deprecated tersebut.

Screenshot from 2012-12-12 15:16:59 1

Langkah selanjutnya adalah membuka file yang ditunjukkan pada error tersebut dan mengganti fungsi lama dengan fungsi yang baru. Dalam kasus di atas, fungsi get_current_theme diganti dengan fungsi wp_get_theme pada file themes/core/tools/theme-options.php baris ke 9.

Screenshot from 2012-12-12 15:18:56

Setelah selesai memperbaiki banyak plugin dan themes yang eror, akhirnya saya bisa membuka halaman update WordPress tanpa ada masalah sedikitpun. Jangan lupa untuk menonaktifkan debug pada file wp-config.php dengan mengganti nilai true menjadi false.

Ekstraksi File PHAR (PHP Archive)

Pagi ini saya hendak menginstall dan mencoba PHPUnit, framework untuk mengetest kode PHP yang kita buat ketika masa development. Ada 3 cara untuk menginstall PHPUnit, pertama menggunakan PEAR, kedua dengan menggunakan composer, dan ketiga adalah menggunakan format PHAR.

Saya rasa saya dulu pernah menggunakan metode PEAR, tinggal jalankan beberapa baris perintah, maka semua file akan terdownload secara otomatis. Namun entah mengapa ketika saya mencoba PHPUnit dengan Pear, instalasinya berlangsung agak lama, jadi saya skip dan saya langsung mencoba cara lain. Saya lebih memilih mendownload format PHAR daripada menggunakan composer. Hal ini saya lakukan karena saya sendiri belum menginstall Composer itu sendiri dan saya belum pernah mencobanya 🙂

Format PHAR ternyata adalah text biasa dengan potongan kode-kode PHP yang ditulis dalam 1 file. Ini dilakukan agar semua paket berada dalam 1 file saja. Masalahnya adalah bagaimana mengekstrak paket Phar ini agar kembali seperti paket biasa, baik itu dalam format php ataupun direktori-direktori yang ada dalam file phar tersebut.

Dari beberapa sumber di internet, ternyata ada konverter online untuk mengubah format .phar menjadi format .zip atau .tar (http://unphar.com/). Namun jika tidak ada koneksi internet, maka konversi harus dilakukan secara offline. Konversi offline sebenarnya bisa dilakukan dengan membuat skrip php agar bisa mengekstrak file tersebut, namun karena saya pikir akan memakan waktu agak lama, lebih baik mencari tools yang siap pakai saja. Saya mendapatkan info bahwa kita bisa mengekstrak file phar dengan menggunakan bantuan Empir (http://empir.sourceforge.net/). Empir adalah file php yang bisa mengubah file php menjadi phar atau sebaliknya.

Download file Empir dan ekstrak ke dalam sebuah direktori. Hasil ekstrak akan menghasilkan sebuah file bernama empir. Lalu file dengan format .phar yang akan diekstrak ditempatkan dalam 1 folder dengan file yang Empir yang diekstrak tadi. Kamu harus memastikan bahwa perintah ‘php’ bisa dijalankan melalui terminal atau command-line. Lalu jalankan perintah berikut:

#format perintah
php -dphar.readonly=0 empir extract <phar_file> [extract_path]
 
D:\Empir>php -dphar.readonly=0 empir extract phpunit.phar phpunit

Nanti file akan diekstrak ke dalam direktori yang telah kita tentukan.

Kecepatan Eksekusi PHP

Uji coba ini cuma estimasi saja dan tidak menyimpulkan apapun, cuma pengen tau kecepatan kalkulasi dengan menggunakan PHP itu seperti apa.

1
2
3
4
5
6
7
8
9
10
<?php
    $result=0;
    $loop=100000000; 
	$start = microtime(true);
	for($i=0; $i<$loop; $i++){
		$result=$result+$i;
	}
	$end = microtime(true);
    echo "Pengulangan sebanyak ".$loop." kali<br />";
	echo "Durasi: ".($end-$start)." detik";

Hasil

Pengulangan sebanyak 100000000 kali
Durasi: 26.762096881866 detik

Dengan jumlah pengulangan sebanyak 100 juta kali, PHP menghasilkan sebuah nilai dengan durasi 26 detik.

Saya berencana melakukan kalkulasi matriks yang membutuhkan pengulangan yang sangat banyak. Namun dengan jumlah pengulangan yang lebih sedikit, mungkin saya bisa memperkirakan estimasi waktu yang dibutuhkan oleh PHP untuk mengolah data tersebut 🙂

suPHP untuk Server Multidomain

Server dengan multidomain sering digunakan pada usaha-usaha hosting atau bisa saja untuk perusahaan skala kecil untuk menyimpan data-data mereka. Maksud dari multidomain di sini adalah sebuah server dengan 1 IP bisa digunakan untuk menyimpan banyak web dengan domainnya masing-masing di dalamnya. Isitilah yang digunakan oleh Apache untuk menggambarkan multidomain ini adalah dengan virtual host.

Kadang kala, dalam menggunakan multidomain, kita ingin agar setiap direktori web dikelola secara mandiri oleh user yang bertanggung jawab pada web mereka. Oleh karena itu, kita harus membuat user untuk tiap direktori web. Misalnya saja domain unit.itb.ac.id akan memiliki user unit dan domain ubg.unit.itb.ac.id akan memiliki user ubg, demikian juga dengan domain-domain lainnya. Hal ini kita lakukan demi alasan keamanan. Defaultnya, jika pengelolaan dilakukan terpusat oleh seorang admin, maka kita cukup membuat direktori-direktori tersebut dimiliki oleh user www,yaitu user yang menjalankan service apache. Namun jika masing-masing dikelola terpisah, kita membuat user masing-masing agar user yang satu tidak bisa melihat apalagi mengedit file-file direktori web lainnya.

Masalah yang sering terjadi ketika kita membuat user-user tersebut dalam tiap direktori, mereka akan kesulitan dalam mengupload file dan sering mengeluarkan pesan error : access denied for upload. Hal ini terjadi karena user-user tersebut bukanlah bagian group dari www. Kita bisa saja membuat mode 777 pada direktori-direktori tersebut, namun ini sangat tidak disarankan karena sangat berbahaya.

Untuk mengatasi hal ini, kita menggunakan suPHP, sebagai tool yang membantu apache. suPHP mirip dengan suexec dalam default apache, namun suexec sangat lambat dibandingkan dengan suPHP. suPHP bertugas agar file-file yang dijalankan oleh apache dieksekusi menggunakan user yang memiliki file tersebut. Misalnya saja, file index.php dalam domain unit.itb.ac.id dimiliki oleh user unit, maka ketika browser meminta file index.php, maka index.php akan dijalankan dengan menggunakan user itu sendiri, yaitu user unit, bukan lagi dengan user www.

Untuk menginstall suPHP, ikuti langkah-langkah berikut ini (FreeBSD):

root# cd /usr/ports/www/suphp
root# make install clean
root# cd /usr/local/etc/
root# cp suphp.conf-example suphp.conf
root# vim suphp.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[global]
;Path to logfile
logfile=/var/log/suphp.log
 
;Loglevel
loglevel=info
 
;User Apache is running as
webserver_user=www
 
;Path all scripts have to be in
docroot=/usr/local/www
 
;Path to chroot() to before executing script
;chroot=/mychroot
 
; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false
 
;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true
 
;Send minor error messages to browser
errors_to_browser=false
 
;PATH environment variable
env_path=/bin:/usr/bin
 
;Umask to set, specify in octal notation
;umask=0077
umask=0022
 
; Minimum UID
min_uid=80
 
; Minimum GID
min_gid=80
 
 
[handlers]
;Handler for php-scripts
application/x-httpd-php="php:/usr/local/bin/php-cgi"
 
;Handler for CGI-scripts
x-suphp-cgi="execute:!self"
root# cd /usr/local/etc/apache22/
root# vim httpd.conf
#################
# suPHP
#################
# Tambahkan baris di bawah ini pada file httpd.conf
 
suPHP_Engine on
suPHP_AddHandler application/x-httpd-php .php

Cari file di bawah ini lalu nonaktifkan dengan memberi tanda komentar:

#LoadModule php5_module        libexec/apache22/libphp5.so

Setelah itu tambahkan baris seperti di bawah ini:

LoadModule suphp_module        libexec/apache22/mod_suphp.so

Hasil akhirnya :

#LoadModule php5_module        libexec/apache22/libphp5.so
LoadModule suphp_module        libexec/apache22/mod_suphp.so

Di sini, kita tidak lagi menggunakan modul php dan digantikan dengan modul suPHP.

root# apachectl restart
root# cd /usr/home/local/www/unit/
root# chown -R ubg:ubg ubg/
root# cd  ubg

Perintah di bawah ini digunakan untuk mengubah semua direktori menjadi 755

root# find . -type -d -exec chmod 755 {}\;
root# find . -type -f -exec chmod 644 {}\;
root# cd .. ; ls -l
drwxr-xr-x  4 ubg     ubg     512 Jan 31 12:06 ubg/

Sekarang, coba lihat web tersebut dari browser, pastikan bahwa web tersebut bisa diakses dengan baik. Masalah yang sering terjadi adalah pesan 503 (Error 503 Service unavailable! : 503, error, service, unavailable). Hal ini terjadi karena direktori web tersebut belum memiliki user tertentu atau mungkin saja masih dimiliki oleh root. Segera tambahkan user dan berikan perintah chown pada direktori tersebut.
Untuk web-web tertentu, kamu masih bisa menggunakan user www pada direktori tersebut.

Alkitab Online

Sebenarnya ide pembuatan Alkitab ini sudah lama saya buat. Namun banyaknya kegiatan dan pekerjaan-pekerjaan lain tidak sempat membuat saya menyelesaikan aplikasi web Alkitab ini. Seminggu kemaren, dengan berbekal semangat dan sebuah alasan yang tidak bisa saya sebutkan di sini, saya akhirnya mengerjakan aplikasi ini hingga selesai. Aplikasi ini menggunakan PHP dan library Jquery dan memanfaatkan ajax dalam mengambil isi alkitab ke database. Pengembangan fitur-fitur lainnya akan terus dilakukan.

Jika kamu mempunyai saran, kritik, atau komentar tentang isi Alkitab yang salah (databasenya saya peroleh dari internet), kamu bisa memberitahu saya agar saya bisa memperbaikinya.

Alamat Alkitab online bisa diakses di : http://duken.info/alkitab/

Sistem Login yang Aman dengan PHP

Saya pertama kali belajar PHP, saya bingung dengan bagaimana sistem login di web. Saya mencari-cari artikel di internet dan banyak sekali variasi kode untuk halaman dan verifikasi login agar bisa masuk ke halaman tertentu, baik itu halaman admin atau halaman yang dilindungi oleh pembuatnya. Skema login sebenarnya sederhana dan pada tulisan ini saya juga hanya memberikan skema yang sederhana. Urutan autentikasi login ada 4:

  1. User melihat halaman dengan form untuk mengisi username dan password disertai dengan tombol untuk login, bisa juga ditambahkan dengan form lain misalnya Captcha berupa gambar. Kadang kala, form login tidak harus username dan password, bisa saja hanya form password saja yang ditampilkan.
  2. User memasukkan data dan memberikan data ke server untuk diproses.
  3. Data input username dan password diproses. Data ini dicocokan dengan database yang ada, misalnya database MySQL. Jika username dan password yang diberikan dari input user sama dengan username dan password pada database, maka login berhasil. Jika tidak ada data yang  cocok, maka login tidak berhasil.
  4. Buat session untuk akses file yang diproteksi. Session digunakan untuk keperluan yang kita inginkan. Session adalah variabel global yang bisa menyimpan data penanda bahwa seorang user telah berhasil login sehingga file yang diproteksi bisa diakses.

Skema login yang lebih kompeks bisa ditambahkan sesuai dengan kebutuhan, misalnya saja memeriksa IP, membatasi jumlah user yang login, dll. Pertama, kita harus membuat halaman login, kode-kode html di bawah ini adalah bagian dari keseluruhan html yang ada.

login.php

1
2
3
4
5
<form action="auth.php" method="post">
	<label for="username">Username</label><input type="text" name="username"  class="input" size="10" autocomplete="off" /><br /><br />
	<label for="password">Password</label><input type="text" name="password" class="input" size="20" autocomplete="off" /><br />
	<input type="submit" value="Login" class="btn" />
</form>

auth.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
	session_start();
	$user       = mysql_real_escape_string($_POST["user"]);
	$user       = substr($user, 0, 10);
	$password   = mysql_real_escape_string($_POST["password"]);
	$password   = substr($password, 0, 20);
	$q          = "SELECT * FROM user WHERE user='$user'";
	$r          = mysql_query($q);
	$d          = mysql_fetch_object($r);
 
	if($d->user == $user AND $d->password == md5($password))
	{
		$_SESSION["user"] = $data->user;
		$_SESSION["nama"] = $data->nama;
	}
	else
	{
		header("location: login.php");
	}
?>

Jika dilihat kode di atas, ada beberapa isu keamanan yang perlu diperhatikan.

  1. Gunakan $_POST, bukan $_GET, atau $_REQUEST. Metoda ini digunakan agar data dikirim lewat metoda POST yang tidak kelihatan lewat browser. REQUEST dicegah karena metoda ini masih menerima data dari GET.
  2. Gunakan fungsi mysql_real_escape_string(). Fungsi ini berguna untuk mengilangka tanda quote pada data input username dan password yang bisa membahayakan fungsi login kita dengan serangan sql injection. SQL injection adalah metode serangan pada halaman login dengan memasukkan inputan data yang salah sehingga sql kita menjadi tidak logis sesuai dengan tujuan awal, hasilnya bisa saja user mendapatkan akses admin tanpa harus mengetahui password admin tersebut.
  3. Ambil data username dari database terlebih dahulu. Pengecekan passwor dilakukan setelah mengambil data username terlebih dahulu. Sebisa mungkin hindari penggunaan perintah sql :
    1
    
    "SELECT * FROM user WHERE user='$user' and password='$password'";

    Kode sql di atas bisa rentan terhadap serangan sql injection.

  4. Batasi penggunaan input karakter pada form login. Form input bisa dibatasi dengan penggunaan tag size=”10″ pada kode html. Lakukan proteksi juga di sisi server dengan fungsi substr()
  5. Jangan simpan password pada $_SESSION. Session bisa saja disalahgunakan, oleh karena itu simpanlah data yang memang pentin pada session dan jangan menyimpan password.

Selamat mengamankan halaman login 🙂

Mendeteksi Perangkat Mobile dengan PHP

Ketika user membuka sebuah web, ada 2 kemungkinan yaitu user membuka halaman web dari desktop atau dari perangkat mobile. Saat ini banyak layanan web yang menyediakan tampilan web yang sesuai dengan ukuran layar perangkat mobile sehingga lebih mudah dibaca dan dilihat. Berikut cara mendeteksi perangkat mobile menggunakan php, anda bisa mengembangkannya atau menambahkan jenis-jenis perangkat mobile lainnya.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
 
	/*Detect mobile device*/
 
	$ismobile = 0;
	$container = $_SERVER['HTTP_USER_AGENT'];
 
	/*List of mobile devices*/
	$useragents = array(
	'Blazer',
	'Palm',
	'Handspring',
	'Nokia',
	'Kyocera',
	'Samsung',
	'Motorola',
	'Smartphone',
	'Windows CE',
	'Blackberry',
	'WAP',
	'SonyEricsson',
	'PlayStation Portable',
	'LG',
	'MMP',
	'OPWV',
	'Symbian',
	'EPOC'
	);
 
	foreach($useragents as $useragents)
	{
		if(strstr($container,$useragents))
		{
			$ismobile = 1;
		}
	}
	if($ismobile)
	{
		echo "<p>Anda menggunakan perangkat mobile.</p>";
	}
 
	echo $_SERVER['HTTP_USER_AGENT'];
 
?>