PHP

2015-09-22

PHP'nin neresinin kötü olduğunu söyleyemem bile, çünkü... Düşünün bir alet kutunuz var. Bir takım araçlardan oluşuyor. Standart şeyler var içerisinde, normal gözüküyor.

İçerisinden bir tornavida çıkardınız ve bir bakıyorsunuz garip 3 kafalı vidalar için kullanılan şeylerden biri. Tamam, peki bu sizin işinize yaramayabilir, fakat ileride işe yarayabileceğini varsayıyorsunuz.

İçerisinden çekici çıkardınız, dehşete kapıldınız, iki ucu da tırnaklı. Fakat hâlâ iş görebilir, yani yan tutarak ortasındaki yüzey sayesinde çivi çakabilirsiniz.

İçerisinden penseyi çıkardınız, fakat ucu tırtırlı değil dümdüz. Daha az kullanışlı ama yine de civataları döndürmek için yeterli, yani herneyse.

Devam ediyorsunuz. Kutuda ki her şey bir garip ve değişik, tamamen işe yaramaz diyecek kadar değiller. Üstelik kutunuz da her şey var.

Şimdi düşünün sizinkiyle aynı aletleri kullanan milyonlarca marangozla tanıştınız ve size "Bu aletlerin sorunu ne? Hepsi kullandığım şeyler ve çalışıyorlar!" diyorlar. Ardından marangozlar size yaptığı evi gösteriyor, her oda beşgen ve çatı ters. Giriş kapısını çalıyorsunuz kapı içeri devriliyor ve hepsi sana kapılarını kırdınız diye bağırıyor.

İşte PHP'nin burası kötü.

PHP: a fractal of bad design


Table of Contents

PHP tutarsızdır ve öngörülemez

Her C ailesi dilinde yer alan == operatörü, PHP'de tam anlamıyla patır patır dökülmektedir. == her şeyi sayıya çevirmeye çalışır. Ama bunu yaparken bile saçmalar:

Örnek 1:

<?php

if ("6 portakal" + "4 elma" == "10 armut") {
    echo "Çok dogru!";
} else {
    echo "Hayır olamaz!";
}

Çıktı 1:

Çok dogru!

Örnek 2:

<?php
var_dump(123 == "123foo");
var_dump("123" != "123foo");

Çıktı 2:

bool(true)
bool(true)

Killer Örnek 3:

<?php
var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
var_dump('0010e2' == '1e3');
var_dump('0x1234Ab' == '1193131');
var_dump('0xABCdef' == '     0xABCdef');

Killer Çıktı 3:

bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

Bunun yerine PHP'de C apisini kullanan ve kendi standartı olan tip kontrolü de yapan === operatörü vardır. Ama < ve > operatörlerinin bir alternatifi yoktur. Aynı zamanda switch de == kullanır.

Örnek 4:

<?php
$option = 2;

switch($option) {
  case "2 belli ki doğru seçenek değil";
    echo "İlk seçenek seçildi!";
    break;
  case 2:
    echo "İkinci seçenek seçildi!";
    break;
}

Çıktı 4:

İlk şecenek seçildi!

Eğer geliştirici dikkatsizlikten dolayı veya daha önceki alışkanlıklarından dolayı === yerine == kullanırsa, ruhunu ve kaderini PHP'ye teslim etmiş olur.


PHP'de aynı perl'de ki gibi false, "" ve 0 olmayan her şey true dir. Ama PHP'de "foo" == 0 da "0" == 0 da true dir. 0 da false dir (beyin eridi).

Örnek 5::

<?php
var_dump("foo" == TRUE);
var_dump("foo" == 0);
var_dump(TRUE != 0);

Çıktı 5:

bool(true)
bool(true)
bool(true)

== operatörü beyin yakan tablolar oluşturulmasına vesile olmuştur.


Dil tutarlılığı, geliştirici verimliliği için çok önemlidir. Her bir tutarsızlık geliştiricinin hatırlaması gereken yeni bir özellik, dökümantasyonu okuma gerekliliği veya konsantrasyon kaybına neden olur. PHP standart kütüphanesinde bazı fonksiyonlarda _ vardır bazılarında yoktur, bazılarnda to kullanılmıştır bazılarında 2. PHP standart kütüphanesinde yer alan fonksiyon isimlerindeki tutarsızlıklar saymakla bitmez, bunlardan bazıları:

Örnek 6: Alt-cizgi kullanan fonksiyonlar:

get: gettype get_class
str: str_ireplace str_pad str_repeat str_replace str_shuffle str_split str_word_count strcasecmp strchr strcmp strcoll strcspn
encode: base64_encode quoted_printable_encode session_encode rawurlencode urlencode gzencode
php: php_uname php_sapi_name php_logo_guid phpinfo phpcredits phpversion
htmlentites: htmlentities html_entity_decode[/code]

Örnek 7: to ve 2 kullanan fonksiyonlar:

to: stream_copy_to_stream strtolower strtotime strtoupper unixtojd
2: bin2hex deg2rad hex2bin ip2long long2ip nl2br rad2deg

PHP evrendeki tek sol çağrışımlı ternary operatörüne sahiptir

Örnek 8:

$ perl -le 'print 1 ? 2 : 3 ? 4 : 5'
2
$ ruby -e 'print 1 ? 2 : 3 ? 4 : 5'
2
$ php -r 'print 1 ? 2 : 3 ? 4 : 5;'
4

PHP geliştiricileri...

Buna ben de katıla katıla gülmekten başka bir şey yazamıyorum. Rasmus (PHP dilinin yaratıcısı)'un da fonksiyon adlarını seçerken bir dahi gibi düşündüğünü görebilirsiniz.

Diğer dillerde yer alan strtotime implementasyonları, 00-00-00'a hata döner. Fakat bu PHP'de normal bir tarihtir, aynı zamanda 2000-00-00'a eşittir, o da aynı zamanda 1999-12-00'a eşittir o da aynı zamanda 1999-11-30'a eşittir ve bu da aynı zamanda birer dahi olan PHP geliştiricilerine göre: No bug, perfectly normal.

PHP geliştiricileri fonksiyon adı seçiminde çok iyidir. parse_str fonksiyonu URL sorgusunda yer alan anahtar ve değerleri döner.


PHP parseri buglarla doludur

PHP kendi standartlarını da yoksayar. Örneğin her dilde olduğu gibi PHP'de de || operatörünün = operatörüne göre işlem önceliği vardır. Hiç bir dilde: a || a = 1; yapamazsınız. Ama PHP'de yapabilirsiniz.

|| operatörü çalışır. Aslında çalışmaz da. Örneğin 4 || 5, 1 (true) döner, 0 || 6 da 1 (true) döner. Gerzekçe olmayan her dilde || operatörü sol değeri döner ve insanlar || operatörünü varsayılan değer atamak için kullanırken PHP'de $foo = $bar || "varsayılan değer"; yapılamaz.

Parser buglarına başka bir örnek 8 tabanındaki sayılar için verilebilir. Örneğin 8 tabanında yazılan 08 her dilde hatalıdır. Elbette PHP hariç:

Örnek 9:

$ perl -le 'print 07'
7
$ perl -le 'print 08'
Illegal octal digit '8' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

$ python -c 'print 07'
7
$ python -c 'print 08'
  File "", line 1
    print 08
           ^
SyntaxError: invalid token

$ php -r 'print 07;'
7
$ php -r 'print 08;'
0

Üstelik en ukalâ (pedantic) hata raporunu açsanız dahi sizi hiç uyarmaz:

<?php
error_reporting(E_ALL);
eval("print 028;");  # hiç bir uyarı olmadan 2 yazar

Diğer irili ufaklı özellikleri:

Zamanında rast gelince gülüp not aldıklarım bunlar. Sonuçta PHP, geliştiriciler arasında birbirlerini trollemek için yaygın olarak kullanılan bir araç.