Bu bölüm, PHP betiklerini yazarken karşılaşabileceğiniz hatalarla ilgili sıkça sorulan sorulardan oluşturulmuştur.
PHP yüzlerce harici kütüphaneyi bir araya getiren bir yapıştırıcıdır, dolayısıyla bu bazı düzensizlikleri yol açar. Böyle düzensizlikler için basit bir kural uygulanır:
Dizi işlevlerinin değiştirgeleri "iğne, samanlık" diye dizilirken dizge işlevlerinin değiştirgeleri tersine "samanlık, iğne" diye dizilir.
PHP, $_POST süper küreseli gibi bir çok öntanımlı değişkene sahiptir. POST yöntemi ile gönderilmiş değerleri bir ilişkisel dizi olarak $_POST üzerinden döngüye sokabilirsiniz. Örnek olarak, foreach ile basit bir döngü oluşturup boş değerleri empty() ile tespit edip bütün değerleri basalım:
<?php
$empty = $post = array();
foreach ($_POST as $varname => $varvalue) {
if (empty($varvalue)) {
$empty[$varname] = $varvalue;
} else {
$post[$varname] = $varvalue;
}
}
print "<pre>";
if (empty($empty)) {
print "POST ile gönderilen boş değer yok; değerler:\n";
var_dump($post);
} else {
print count($empty) . " boş değer var.\n";
print "Boş olmayanlar:\n"; var_dump($post);
print "Boş olanlar:\n"; var_dump($empty);
exit;
}
?>
Bilginize: Süper Küreseller Kullanılabilirlik Bilgisi
$_GET, $_POST, $_SERVER, vs. gibi süper küreseller PHP 4.1.0 sürümünden beri kullanılabilmektedir. Bu konuda daha ayrıntılı bilgi edinmek için süper küreseller bölümüne bakınız.
Bunun bir veritabanı için yapıldığını varsayarak, veritabanı ile gelen önceleme mekaizması kullanılabilir. Örneğin, MySQL ile mysql_real_escape_string(), PostgreSQL ile pg_escape_string() işlevi kullanılır. Ayrıca, PHP kodu için daha genel amaçlı olarak addslashes() ve stripslashes() işlevleri de vardır.
Bilginize: magic_quotes_gpc yönergesi hakkında
magic_quotes_gpc yönergesinin değeri öntanımlı olarak on' olup tüm GET, POST ve COOKIE verisi üzerinde addslashes() çalıştırılmasına sebep olur. Bunun etkisini ortadan kaldırmak için stripslashes() kullanılabilir.
PHP'nin magic_quotes_gpc yönergesi etkin olduğu sürece tersbölüler sihirli bir biçimde ortaya çıkacaklardır. Bu PHP'nin eski bir özelliği olup iptal edilmesi ve kullanılmaması gerekir. Ayrıca, stripslashes() adlı PHP işlevi de bir dizgeden tersbölüleri ayıklamak için kullanılabilir.
Bilginize: magic_quotes_gpc yönergesi hakkında
magic_quotes_gpc yönergesinin değeri öntanımlı olarak on' olup tüm GET, POST ve COOKIE verisi üzerinde addslashes() çalıştırılmasına sebep olur. Bunun etkisini ortadan kaldırmak için stripslashes() kullanılabilir.
Önce, bu ini ayarının ne işe yaradığından bahsedelim. Şöyle bir URL'miz olsun: http://gen.tr/fan.php?hayvan=kedi. Ayrıca, fan.php içinde şu PHP kodu bulunsun:
<?php
// Burada $_GET tercih ediyoruz
echo $_GET['hayvan'];
// $hayvan'ın mevcut olması için, register_globals on olmalı
// BUNU YAPMAYIN
echo $animal;
// Bu, tüm değişkenlere uygulanır, tabii $_SERVER'a da
echo $_SERVER['PHP_SELF'];
// Tekrar, $PHP_SELF'in mevcut olması için, register_globals on olmalı
// BUNU YAPMAYIN
echo $PHP_SELF;
?>
Yukarıdaki kod register_globals'in çok sayıda değişkeni nasıl oluşturduğunu göstermektedir. Yıllardır böyle bir kodlama uygun görülmediği gibi yıllardır öntanımlı olarak register_globals off'tur. Bu kullanımı önerilmeyen özelliğin tamamen kaldırılacağını aklınızdan çıkarmayın. Çoğu sitede register_globals kapalı olsa da hala güncellenmemiş makaleler, öğreticiler ve kitaplar değerenin 'on' olması gerektiğini belirtip durmaktalar. Bunlar bir an önce düzeltilmelidir.
Daha fazla bilgi için aşağıdaki belgelere de bakınız:
Bilginize:
Yukarıdaki örnekte bir sorgu dizgesi içeren bir URL kullanılmıştır. Bu tür bilgiler aktarılırken bir GET HTTP isteği yapılır. Dolayısıyla, $_GET süper küreselinin kullanılma nedeni de budur.
<?php
function işlevim($değiştirge)
{
echo $değiştirge + 10;
}
$değişken = 10;
echo "işlevim($değişken) = " . işlevim($değişken);
?>
İşlevinizin sonucunu bir ifadede kullanmak istiyorsanız (yukarıdaki örnekte yapıldığı gibi dizgeleri ardarda eklemek gibi), işlevinizin sonucu return ile döndürmesi echo ile çıktılamaması gerekir.
<pre>
<?php echo "Bu ilk satır olmalı."; ?>
<?php echo "Bu da ilk satırın altındaki satır olmalı."; ?>
</pre>
PHP'de, bir kod bloğu ya "?>" ya da "?>\n" (burada \n satırsonu karakteridir) ile biter. PHP blokların sonundaki satırsonu karakterlerini yoksaydığından yukarıdaki örnekte çıktılanan iki satır aynı satıra basılacaktır. Yani, her bloktan sonra bir satırsonu karakteri basılmasını istiyorsanız fazladan bir satırsonu karakteri yerleştirmeniz (bloklar arasına boş bir satır girmek) gerekir.
PHP bunu neden yapıyor? Normal HTML biçemlerken bloklardan sonra satırsonu karakterlerinin bulunması genelde istenmeyen bir durumdur ve PHP buna göre davranır. Bu böyle yapılmasaydı gereğinden fazla uzun satırlardan oluşan kodlar yazmak zorunda kalırdınız ve bu da kodlarınızın okunaklılığını azaltırdı.
Başlıkları çıktı akımına eklemek için header(), setcookie() ve oturum işlevleri kullanmak gerekir. Bu işlevleri kullanmadan önce hiçbir çıktılama (HTML gibi) yapılmamış olması gerekir. headers_sent() işlevi betiğinizin evvelce başlıkları gönderip göndermediğinize bakacaktır. Ayrıca, Çıktı Denetim İşlevleri'ne de bakınız.
PHP'yi bir Apache modülü olarak çalıştırıyorsanız getallheaders() işlevi istediğiniz şeyi yapacaktır. Aşağıdaki küçük kod tüm istek başlıklarını gösterecektir:
<?php
$başlıklar = getallheaders();
foreach ($başlıklar as $isim => $içerik) {
echo "başlıklar[$isim] = $içerik<br />\n";
}
?>
Ayrıca bakınız: apache_lookup_uri(), apache_response_headers() ve fsockopen()
IIS'nin güvenlik modeli bu noktada hata verecektir. Bu, IIS altında çalışan bütün CGI programlarının ortak sorunudur. Bu sorundan kurtulmanın tek yolu erişim için kimlik doğrulaması yapılacak dizinde girdi sayfası olarak (PHP ile çözümlenmeyecek) düz bir HTML sayfası oluşturmaktır. Ya bir META etiketi ile PHP dosyaya yönlendirme yaparsınız ya da sayfaya PHP dosya için bir bağlantı koyarsınız. Böylelikle PHP kimlik doğrulamasını doğru olarak yapacaktır. ISAPI modülü kullanıldığında böyle bir sorun ortaya çıkmaz. Bunun diğer NT HTTP sunucularını etkilememesi gerekir. Daha fazla bilgi için » http://support.microsoft.com/kb/q160422/ adresine ve bu kılavuzun HTTP Kimlik Doğrulaması bölümüne bakınız.
Internet Information Services Yöneticisini açın. PHP dosyanızı bulup özelliklerine gidin. Dosya Güvenliği sekmesine geçip, Anonim erişim ve kimlik doğrulama denetimi bölümlerini düzenleyin.
Anonim Erişim'i işaretsiz, Tümleşik Windows Kimlik Doğrulaması'nı işaretli bırakarak veya Anonim Erişim'i işaretleyip erişim izni vermek istediğiniz kullanıcıyı düzenleyerek sorunu çözümleyebilirsiniz.
<?xml etiketlerini PHP kodu içinde doğrudan kullanmak isterseniz, PHP'nin kısa etiketlerini, short_open_tags yönergesine 0 değerini atamak suretiyle devre dışı bırakmanız gerekir. Bu yönergeye ini_set() işleviyle değer atayamazsınız. short_open_tags yönergesinin değerinin ne olduğuna bakmaksızın bu etiketi şöyle de kullanabilirsiniz: <?php echo '<?xml'; ?>. Bu yönergenin öntanımlı değeri On'dur.
Betiğinizde kullanılabilecek öntanımlı değişkenlerin bir kısmını içeren Öntanımlı Değişkenler bölümünü okuyunuz. Kullanılabilecek değişkenlerin ve daha pek çok şeyin tam bir listesini elde etmek için phpinfo() işlevini kullanabilirsiniz. HTML formları, çerezler ve URL'ler gibi kaynaklardan elde edilen harici değişkenlerle ilgili senaryoların açıklandığı Dış Kaynaklı Değişkenler bölümünü de okumayı unutmayın.
Bilginize: register_globals için önemli bilgi
PHP 4.2.0'dan itibaren, register_globals yönergesinin öntanımlı değeri off olup PHP 6.0.0'dan itibaren tamamen kaldırılmıştır. PHP topluluğu, geliştiricilere, bu yönergeyi kullanmaktan vazgeçmelerini ve yerine süper küreselleri tercih etmelerini önermektedir.
PHP ile yazılmış bir kaç seçenek var: » FPDF ve » TCPDF.
Bundan başka, özgür libHaru harici kütüphanesini kullanan Haru eklentisi diye bir eklenti daha vardır.
PHP'nin register_globals
yönergesinin sunucu ve ortam değişkenlerini nasıl etkilediğini bilmek
önemlidir. register_globals = off
olduğunda (PHP 4.2.0'den
beri öntanımlı olarak böyledir), $DOCUMENT_ROOT
değişkeni mevcut olmayacaktır. Yerine $_SERVER['DOCUMENT_ROOT']
kullanmalısınız. register_globals = on
olduğunda ise $DOCUMENT_ROOT ve
$GLOBALS['DOCUMENT_ROOT'] değişkenlerinin ikisi de
mevcut olacaktır.
register_globals = on
olduğunda
$DOCUMENT_ROOT değişkeninin işlevlerin içinde neden
geçerli olmadığını merak ediyor olabilirsiniz. Bunun sebebi, diğer
değişkenler gibi bunun için de global $DOCUMENT_ROOT
gerekmesidir. Ayrıca, Değişken
etki alanı bölümüne de bakınız. Ancak, kodlarınızı
register_globals = off
olduğu duruma uygun olarak yazmayı
tercih etmelisiniz.
Bilginize: Süper Küreseller Kullanılabilirlik Bilgisi
$_GET, $_POST, $_SERVER, vs. gibi süper küreseller PHP 4.1.0 sürümünden beri kullanılabilmektedir. Bu konuda daha ayrıntılı bilgi edinmek için süper küreseller bölümüne bakınız.
Kilobaytlar için K, Megabaytlar için M ve PHP 5.1.0'dan beri Gigabaytlar için G kullanılabilmektedir. Bunlar harf büyüklüğüne duyarlıdır. Belirtilmedikleri takdirde değerin bayt sayısını gösterdiği varsayılır. 1K bir Kilobayta veya 1024 bayta, 1M ise bir Megabayta veya 1048576 bayta eşittir. Bu birimlerin kısa gösterimlerini php.ini dışında da kullanabilirsiniz. Bu değerler arasındaki dönüşümlerin nasıl yapıldığı ini_get() belgesinde açıklanmıştır.
Bilginize: kilobayt mı, kibibayt mı?
PHP gösteriminde bir kilobayt 1024 bayta eşittir. IEC standardı bunu kibibayt olarak adlandırır. Özetle: k veya K = 1024 bayt.
PHP'nin ağ çözümleme kodunda, PHP 5.3.4 öncesinde, IPv6 etkinken, akımlarla ilgili tüm durumlarda localhost'un başarısız olmasına sebep olan bir yazılım hatası vardı. Bu sorundan kurtulmak için ya hosts dosyasına IPv6 çözümlemesini iptal edin ya da localhost yerine "127.0.0.1" kullanın.