PHP tuhaflıklar ve tuzaklar [kapalı]

14 Cevap

Benim deneyim çoğu PHP uygulamaları yazarken oluşur rağmen, kendimi zaman zaman "acemi hatalar" yapmak bulmak, fark ettik. Bu PHP çok organik olarak yetiştirilen bir dildir ve bu gibi bazı biçimleri, tuhaflıklar ve ben bilmem tuzaklar vardır çünkü.

Bu soru ne inanabilirler kurallar PHP'nin tuzaklar ve istisnalar bilmek isteyenler için bir wiki olmak istiyorum. Ancak, gibi genel cevaplar yazmayın lütfen:

Some functions receive arguments as $needle, $haystack, while some as $haystack, $needle.

Işlev isimlerini söyle. Sen örnek olarak benden birkaç cevap var. Oh, ve cevap başına bir hatadır ekleyin. Bu şekilde biz (oylama ile) hepsini en nefret olduğunu görürsünüz.

Ben, bir alev savaş başlatmak istemiyorum bu konuya devam. Eğer PHP hakkında bazı kötü şeyler yazmak istiyorsanız o zaman ilgili cevap bir açıklama olarak bunu.

Umarım bu wiki bize, yeni başlayanlar ve uzmanlar için tüm yardımcı olacaktır.

Update:

Andrew Moore Yorumlarınız sonra cevap da sıkan bir çözüm veya geçici çözüm içermesi gerektiğini düşünüyorum.

14 Cevap

XML yapılarını işlemek ve sonra bunları unserializing orijinal XML yapısını geri gelmez nesneleri seri:

$dom = new DOMDocument;
$dom->loadXML('<test/>');

$dom = serialize($dom);
$dom = unserialize($dom);

var_dump($dom->saveXML());
// $ Warning: DOMDocument::saveXML(): Couldn't fetch DOMDocument in ...
// $ NULL

Benzer şekilde SimpleXML nesneler için.

Non-sanayi-standart operatör önceliği.

$x = 1;
echo 'foo: ' . $x+1 . ' bar';

Çıktısı: "1 bar", yerine beklenen ve "foo: 2 bar". Çözüm: parantez kullanın.

Tamsayı büyüklüğü platform bağımlıdır. Normalde herhangi bir dış modül olmadan 32bit makinede 64bit tamsayılar kullanamazsınız. Ayrıca, imzasız tamsayıları ilan edemez.

Ben bir ?> kapanış etiketi (etrafında başka bir yol olmalı gibi görünüyor) ile php dosyaları kapatmak eğer sorunları nasıl alabilirim nefret ediyorum. Örneğin, sonra bir boşluk ile bir dosyayı içerir?> Ve sonra da (hayır çıktı tamponlama varsayarak) başlıklarını değiştirmeye çalışın. UGH. Asla ile yakın php dosyaları ?> öğrenmek için uzun bana yol aldı

Gerçek şu ki, testler yapmanın birden çok yolu (not operator, empty(), is_null(), isset()) + zayıf yazarak = this

Bazı disiplin ile çoğunlukla bu tabloya bakın önleyebilirsiniz:

  • Genel hakikat testler için, mantıksal karşılaştırma kullanabilirsiniz if ($) {...} if (!$x) { ... }. Çoğu dilde Boole operatörleri ne şekilde davranır.

  • Eğer (bu yanlış olarak "0" muamelesi) falsy değerleri için form girişi test etmek istiyorsanız her zaman empty() kullanın.

  • Eğer bir değişken ayarlanır Whethere belirlemek istiyorsanız veya her zaman isset() kullanın

  • Sadece NULL kontrol gerekiyorsa is_null() veya $x === NULL kullanın

Ben referansları ile foreach birleştirerek zahmet her türlü yaşadım

$testarray = array(1 => "one", 2 => "two");
$item = "three";
$testarray[3] =& $item;
foreach ($testarray as $key => $item) {
  // do nothing
}
echo $testarray[3]; // outputs "two"

Bu gerçekten PHP4 döneminde beni attı, ve bunu açık referanslar kullanmak istemiyorsanız aklı başında bir davranış alarak PHP5'ta daha iyi kazanılmış olmasına rağmen, ben hala şimdi ve sonra bu biri tarafından yakalanmak için yönetebilirsiniz.

Yerleşik fonksiyonların tutarsız adlandırma kuralları. Dize işleme fonksiyonları Örneğin bu seti:

 str_shuffle()
 str_split()
 str_word_count()
 strcasecmp()
 strchr()
 strcmp()

Çözüm: Her zaman manuel açık bırakın.

$x = "a string";

if ($x == 142)
{
    echo "lol, of course $x is a number";
}
else
{
    echo "$x is clearly not equal to 142";
}

Çalıştırdığınızda:

lol, of course a string is a number

You must use ===

$x = "a string";

if ($x === 142)
{
    echo "lol, of course $x is a number";
}
else
{
    echo "$x is clearly not equal to 142";
}

Çalıştırdığınızda:

a string is clearly not equal to 142

Having işlevleri farklı OS'es üzerinde farklı davranabilir ve bazı işlevler yalnızca belirli OS'es mevcuttur.

Örneğin, Windows üzerinde mail() function $to parametrede gönderenin adını alamaz. Sadece e-posta adresini içerebilir. Linux üzerinde tüm çalışıyor.

Başka bir örnek, işlevi strptime() Linux üzerinde kullanılabilir, ve Pencereler (bu benim, Windows kutusunu çalıştırmak istedim mevcut projedeki beni).

Tabii, sadece (Win32API fonksiyonlar gibi) bazı OS'es üzerinde mantıklı bazı işlevler vardır, ama aslında öyle değil ne zaman onlar, hepsi OS'es aynı davranması gerektiğini diğerleri gibi görünüyor.

Onlar barındıran ortamlarda varsayılan tarafından desteklenen olacak hiçbir garantisi yoktur çünkü bazı yeni tanıtılan PHP özellikleri düz düşer.

Benim en büyük huysuzlaştırmak <? foobar(); ?> and <?=$var ?> etiketi sözdizimi sağlayan short_tags ayarıdır. Ben PHP yerine opt-in yerine, varsayılan olarak bu özelliği aktif ettik gerektiğini savunuyorlar.

== EDIT ==

Gibi PHP 5.4 ve destekler her hosting ortamında sunulacak PHP> = 5.4 short_tags ayarı artık, steno yankı tablosu için dikkate alınır.

Dizeleri for döngüler ve endeksleri kullanılarak iterated olsa da, onlar foreach döngüler kullanılarak iterated olamaz. Örnek:

$str = 'foo';
$max = strlen($str);

for ($i=0; $i<$max; $i++)  {
    echo $str[$i];
}
// outputs: foo

foreach ($str as $char) {
    echo $char;
}
// Warning: Invalid argument supplied for foreach() ...

benim en sevdiğim:

<?php
$a = 0;
$b = 'x';
var_dump(FALSE == $a);
var_dump($a == $b);
var_dump($b == TRUE);

echo' <br />Conclusion: TRUE equals FALSE (at least in PHP)';

Bazen sadece girdi değişkenleri kabul ettiği, doğrudan başka bir için bir fonksiyon-sonuç geçmek ister.

Örneğin:

array_pop(  explode('\\', get_class($this))  )

... Bir E_STRICT-yanılma "Only variables should be passed by reference" neden olur. Sadece iç etrafında parantez başka bir çifti eklemek çalışma almak almak için (iade) deyimi:

array_pop( (explode('\\', get_class($this))) )

(Senin ad ve genişletilmiş sınıfları kullanıyorsanız, bu hat uzatıldı ve bu işlevi tutabilir çağıran nesne değil üst-sınıf) ad olmadan (sadece sınıf adını döndürür.)

== EDIT == *This is no longer true for PHP >= 5.5!*

What I sometimes run into is the Fatal error: Can't use function return value in write context error when using the empty() construct. For example:

if (!empty(trim($_GET['s']))) {
    // ...
}

empty() bir değişken gerekiyor, başka bir şey hata neden olur.

Çözüm:

$s = trim($_GET['s']);
if (!empty($s)) {
    // ...
}