Bu bölüm, PHP betiklerini yazarken karşılaşabileceğiniz hatalarla ilgili sıkça sorulan sorulardan oluşturulmuştur.
Bir formdan gelen veriyi işleyebileceğim genel amaçlı bir PHP betiği yazmak istiyorum. Hangi POST değişkenlerinin kullanılabilir olduğunu nasıl bileceğim?
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.
Benim bütün tek tırnakları bir tersbölü ile öncelemem lazım. Bunu bir düzenli ifade ile nasıl yapabilirim? Ayrıca, " imlerini \" ve \ imlerini de \\ biçimine çevirmek istiyorum.
The function addslashes() işlevi istediğiniz işlemi yapar. Ayrıca, mysql_escape_string() işlevine de bakınız. Eğer bu tersbölüleri tekrar temizlemek isterseniz stripslashes() işlevine de bakınız.
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.
Benim bütün " imlerim \" dizgelerine ve ' imlerim de \' dizgelerine dönüşmüş. Bu istenmeyen tersbölülerden nasıl kurtulurum? Bunlar neden ve nasıl ortaya çıktılar?
PHP'nin stripslashes() işlevi string türündeki tersbölülerden sizi kurtarır. PHP'nin magic_quotes_gpc yönergesi etkin olduğu sürece tersbölüler sihirli bir biçimde ortaya çıkacaklardı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 register_globals yönergesi beni nasıl etkiler?
Ö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. PHP 6'dan itibaren 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.
Aşağıdakini gerçeklerken çıktı yanlış sırada basılıyor:
<?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);
?>
Neyi yanlış yapıyorum?
İş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.
Hey, satırsonu karakterleri nereye gitti?
<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ı.
Şöyle bir ileti alıyorum: 'Warning: Cannot send session cookie - headers already sent...' veya 'Cannot add header information - headers already sent...'. (Tercümesi: 'Uyarı: Oturum çerezleri gönderilemiyor - başlıklar zaten gönderilmişti...' veya 'Başlık bilgisi eklenemiyor - başlıklar zaten gönderilmişti...')
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.
İstek başlığındaki bilgiye doğrudan erişmem gerekiyor. Bunu nasıl yapabilirim?
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 ile kimlik doğrulaması yapmaya çalışırken şunu alıyorum: 'No Input file specified' (Türkçesi: 'Girdi dosyası belirtilmemiş').
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.
Windows: IIS kullanarak diğer bilgisayardaki paylaşımlı dosyalara erişemiyorum.
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.
PHP betiğim IE ve Lynx üzerinde düzgün çalışıyor, fakat Netscape üzerinde çıktının bir kısmı kayboluyor. "Sayfa kaynağını göster" seçeneğini kullandığımda ise içeriği IE ile görebiliyorum ama Netscape ile göremiyorum.
Netscape HTML etiketlerine IE'den daha duyarlıdır. HTML çıktısını » validator.w3.org gibi bir HTML doğrulayıcısında çalıştırmak bu konuda size yardımcı olabilir. Örneğin eksik bir </table> etiketi böyle bir soruna yol açabilir.
IE ve Lynx, Netscape'in aksine HTML akımlarda NULL (\0) değerleri yoksayar. Bunu sınamanın en iyi yolu PHP'nin komut satırı sürümünü (CGI sürümü diye de bilinir) derlemek ve betiğinizi komut satırında çalıştırmaktır. *n*x'lerde od -c üzerinden borulamak suretiyle \0 karakterlerinin varlığına bakabilirsiniz. Windows üzerindeyseniz, ikil dosyalara bakmanızı sağlayacak bir metin düzenleyici veya başka bir programa ihtiyacınız olacaktır. Netscape bir \0 karakterine rastladığında IE ve Lynx'in aksine o satırda başka hiçbir şey çıktılamaz.
PHP betiklerinde nasıl XML kullanabilirim? <?xml etiketlerinde sorun çıkarıyor!
<?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 1'dir.
Kodlarımı devre dışı bırakmakta inat eden FrontPage'de ve bazı HTML düzenleyicilerde PHP'yi nasıl kullanabilirim?
En kolayı PHP kodunuzda ASP etiketlerini etkin kılmaktır. Böylece ASP tarzı <% ve %> etiketlerini kullanabilirsiniz. Günümüz HTML düzenleyicilerinin bazıları bunları (şimdilik) daha akıllıca ele almaktadır. ASP tarzı etiketleri etkin kılmak için php.ini asp_tags yönergesini veya buna uygun Apache yönergesini kullanabilirsiniz.
PHP'de kullanabileceğim değişkenlerin tam listesini nerede bulabilirim?
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.
PDFLib gibi ticari ve özgür olmayan kütüphaneleri kullanmaksızın PDF dosyaları nasıl üretebilirim?
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.
Kullanıcı tanımlı bir işlevden standard CGI değişkenlerinden birine ($DOCUMENT_ROOT veya $HTTP_REFERER gibi) erişmeye çalışıyorum ama beceremiyorum. Neyi yanlış yapıyorum?
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.
Bazı PHP yönergeleri büyük bayt değerleri için Kilobayt, Megabayt birimlerin kısaltmalarını kabul edebiliyor. Bu birimlerin tam listesini nerede bulabilirim ve bunları php.inidışında da kullanabilir miyim?
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.