PHP Kullanımı

Bu bölüm, PHP betiklerini yazarken karşılaşabileceğiniz hatalarla ilgili sıkça sorulan sorulardan oluşturulmuştur.

  1. PHP'deki değiştirgelerin sırasını hatırlayamadıh, rasgele midir?
  2. 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?
  3. 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.
  4. 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?
  5. PHP'nin register_globals yönergesi beni nasıl etkiler?
  6. 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?
  7. 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>
  8. Şö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...')
  9. İstek başlığındaki bilgiye doğrudan erişmem gerekiyor. Bunu nasıl yapabilirim?
  10. IIS ile kimlik doğrulaması yapmaya çalışırken şunu alıyorum: 'No Input file specified' (Türkçesi: 'Girdi dosyası belirtilmemiş').
  11. Windows: IIS kullanarak diğer bilgisayardaki paylaşımlı dosyalara erişemiyorum.
  12. PHP betiklerinde nasıl XML kullanabilirim? <?xml etiketlerinde sorun çıkarıyor!
  13. PHP'de kullanabileceğim değişkenlerin tam listesini nerede bulabilirim?
  14. PDFLib gibi ticari ve özgür olmayan kütüphaneleri kullanmaksızın PDF dosyaları nasıl üretebilirim?
  15. 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?
  16. 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?
  17. Windows: localhost kullanırken bağlantı sürekli zaman aşımına uğruyor, halbuki "127.0.0.1" çalışıyor. Ne yapmalıyım?
PHP'deki değiştirgelerin sırasını hatırlayamadıh, rasgele midir?

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.

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;
}
?>

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.

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.

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 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.

PHP'nin register_globals yönergesi beni nasıl etkiler?
Uyarı

Bu özelliğin kullanımı PHP 5.3.0 itibariyle ÖNERİLMEMEKTE olup PHP 5.4.0'da tamamen KALDIRILMIŞTIR.

Ö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. Ç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 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 On'dur.

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.

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.

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.

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.

Windows: localhost kullanırken bağlantı sürekli zaman aşımına uğruyor, halbuki "127.0.0.1" çalışıyor. Ne yapmalıyım?

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.