foreach($item as &$item) içindeki tuzak. foreach'deki tuzak($item as &$item) Final item php

  • 03.11.2019

Birçok önemli ve kurtarılabilir ölümcül hata PHP 7'de istisnalara dönüştürülmüştür. Bu hata istisnaları, kendisi Throwable arabirimini (tüm istisnaların devraldığı yeni temel arabirim) uygulayan Error sınıfından miras alır.

Bu, özel hata işleyicilerin artık tetiklenemeyeceği anlamına gelir, çünkü bunun yerine istisnalar atılabilir (yakalanmamış Hata istisnaları için yeni önemli hatalara neden olur).

PHP 7'de hataların nasıl çalıştığına dair daha kapsamlı bir açıklama PHP 7 hatalar sayfasında bulunabilir. Bu geçiş kılavuzu yalnızca geriye dönük uyumluluğu etkileyen değişiklikleri sıralayacaktır.

// Kırılacak PHP 5 dönemi kodu.
işlev işleyicisi (İstisna $e ) ( ... )
set_exception_handler("işleyici");

// PHP 5 ve 7 uyumlu.
işlev işleyicisi ($e ) ( ... )

// Yalnızca PHP 7.
işlev işleyicisi (Atılabilir $e ) ( ... )
?>

Dahili kurucular her zaman başarısızlık durumunda istisnalar atar

Önceden, bazı dahili sınıflar geri dönerdi BOŞ veya yapıcı başarısız olduğunda kullanılamaz bir nesne. Artık tüm dahili sınıflar, bu durumda, kullanıcı sınıflarının zaten yapmak zorunda olduğu şekilde bir İstisna oluşturacaktır.

E_STRICT önem değişikliklerini fark eder

Tümü E_STRICT bildirimler diğer düzeylerde yeniden sınıflandırılmıştır. E_STRICT sabit tutulur, bu nedenle çağrılar error_reporting(E_ALL|E_STRICT) hataya neden olmaz.

E_STRICT ciddiyet değişikliklerini fark et
Durum Yeni seviye/davranış
Bir kaynağa göre indeksleme E_NOTICE
Soyut statik yöntemler
Bir yapıcıyı "yeniden tanımlama" Bildirim kaldırıldı, herhangi bir hatayı tetiklemez
Devralma sırasında imza uyuşmazlığı E_UYARI
Kullanılan iki özellikte aynı (uyumlu) özellik Bildirim kaldırıldı, herhangi bir hatayı tetiklemez
Statik özelliğe statik olmayan bir şekilde erişme E_NOTICE
Yalnızca değişkenler referansla atanmalıdır E_NOTICE
Yalnızca değişkenler referansla iletilmelidir E_NOTICE
Statik olmayan yöntemleri statik olarak çağırma E_ KULLANIMDAN KALDIRILDI

Değişken işlemedeki değişiklikler

PHP 7 artık kaynak dosyaları ayrıştırırken soyut bir sözdizimi ağacı kullanıyor. Bu, PHP'nin önceki sürümlerinde kullanılan ayrıştırıcıdaki sınırlamalar nedeniyle daha önce imkansız olan dilde birçok iyileştirmeye izin verdi, ancak tutarlılık nedenleriyle birkaç özel durumun kaldırılmasıyla sonuçlandı ve bu da geriye dönük uyumluluk kesintilerine neden oldu. Bu vakalar bu bölümde ayrıntılı olarak açıklanmıştır.

Dolaylı değişkenlerin, özelliklerin ve yöntemlerin işlenmesindeki değişiklikler

Değişkenlere, özelliklere ve yöntemlere dolaylı erişim, önceki özel durum karışımının aksine, artık kesinlikle soldan sağa sırayla değerlendirilecektir. Aşağıdaki tablo, değerlendirme sırasının nasıl değiştiğini göstermektedir.

Dolaylı ifadelerin eski ve yeni değerlendirilmesi
ifade PHP 5 yorumlama PHP 7 yorumlama
$$foo["bar"]["baz"] $($foo["bar"]["baz"]) ($$foo)["bar"]["baz"]
$foo->$bar["baz"] $foo->($bar["baz"]) ($foo->$bar)["baz"]
$foo->$bar["baz"]() $foo->($bar["baz"])() ($foo->$bar)["baz"]()
Foo::$bar["baz"]() Foo::($bar["baz"])() (Foo::$bar)["baz"]()

Eski sağdan sola değerlendirme sırasını kullanan kod, bu değerlendirme sırasını kaşlı ayraçlarla açıkça kullanmak için yeniden yazılmalıdır (yukarıdaki orta sütuna bakın). Bu, kodu PHP 7.x ile hem ileriye hem de PHP 5.x ile geriye doğru uyumlu hale getirecektir.

var_dump (1 >> - 1 );
?>

Önemli hata: Yakalanmayan ArithmeticError: /tmp/test.php:2'de negatif sayı ile bit kaydırma: 2. satırda /tmp/test.php'de #0 (ana) atıldı

Aralık dışı bit kaymaları

bit genişliğinin ötesinde (her iki yönde) bitsel kaydırma tam sayı her zaman 0 ile sonuçlanır. Daha önce, bu tür kaymaların davranışı bağımlı mimariydi.

Sıfıra Göre Bölme'deki Değişiklikler

Önceden, bölme (/) veya modül (%) operatörleri için bölen olarak 0 kullanıldığında, bir E_WARNING yayınlanır ve YANLIŞ iade edilecekti. Şimdi, bölme operatörü, IEEE 754 tarafından belirtildiği gibi bir kayan noktayı +INF, -INF veya NAN olarak döndürür. Modül operatörü E_WARNING kaldırılmıştır ve bir DivisionByZeroError istisnası atar.

var_dump(3/0);
var_dump(0 / 0 );
var_dump(0 % 0 );
?>

PHP 5'te yukarıdaki örneğin çıktısı:

Uyarı: %s satırında sıfıra bölme %d satırında bool(yanlış) Uyarı: %s satırında %d satırında sıfıra bölme bool(false) Uyarı: %d satırında %s satırında sıfıra bölme bool(yanlış)

PHP 7'deki yukarıdaki örneğin çıktısı:

Uyarı: %s satırında sıfıra bölme, %d satırında float(INF) Uyarı: %s satırında %d satırında sıfıra bölme float(NAN) PHP Önemli hata: Yakalanmamış DivisionByZeroError: Modulo %s satırında sıfıra

$str = "0xffff" ;
$int = filter_var ($str , FILTER_VALIDATE_INT , FILTER_FLAG_ALLOW_HEX );
if (yanlış === $int ) (
yeni Exception("Geçersiz tamsayı!");
}
var_dump($int ); // int(65535)
?>

\u( hatalara neden olabilir

Yeni Unicode kod noktası kaçış sözdiziminin eklenmesi nedeniyle, bir hazır bilgi içeren dizeler \u( ardından geçersiz bir sıra önemli bir hataya neden olur. Bunu önlemek için, baştaki ters eğik çizgiden kaçınılmalıdır.

Kaldırılan işlevler

Kaldırılan INI yönergeleri

xsl.security_prefs

xsl.security_prefs yönergesi kaldırıldı. Bunun yerine, XsltProcessor::setSecurityPrefs() güvenlik tercihlerini işlemci bazında denetlemek için yöntem çağrılmalıdır.

Diğer geriye dönük uyumsuz değişiklikler

Yeni nesneler referansla atanamaz

sonucu yeni ifade artık referans yoluyla bir değişkene atanamaz:

C sınıfı()
$c =& yeni C ;
?>

PHP 5'te yukarıdaki örneğin çıktısı:

Kullanımdan kaldırıldı: Yeni dönüş değerinin referansa göre atanması, 3. satırdaki /tmp/test.php'de kullanımdan kaldırılmıştır.

PHP 7'deki yukarıdaki örneğin çıktısı:

Ayrıştırma hatası: sözdizimi hatası, 3. satırda /tmp/test.php dosyasında beklenmeyen "yeni" (T_NEW)

Geçersiz sınıf, arayüz ve özellik adları

Aşağıdaki adlar sınıfları, arabirimleri veya özellikleri adlandırmak için kullanılamaz:

  • bool
  • int
  • batmadan yüzmek
  • sicim
  • BOŞ
  • DOĞRU
  • YANLIŞ

Ayrıca aşağıdaki isimler kullanılmamalıdır. PHP 7.0'da bir hata oluşturmasalar da, ileride kullanılmak üzere ayrılmıştır ve kullanımdan kaldırılmış olarak kabul edilmelidirler.

  • nesne
  • karışık
  • sayısal

ASP ve komut dosyası PHP etiketleri kaldırıldı

PHP kodunu sınırlamak için ASP ve komut dosyası etiketlerini kullanma desteği kaldırıldı. Etkilenen etiketler şunlardır:

ASP ve komut dosyası etiketleri kaldırıldı
açılış etiketi kapanış etiketi
<% %>
<%= %>

Uyumsuz bağlamdan gelen aramalar kaldırıldı

Daha önce PHP 5.6'da kullanımdan kaldırılmış olan, uyumsuz bir bağlama sahip statik olmayan bir yönteme yapılan statik çağrılar, artık çağrılan yöntemin tanımsız bir değere sahip olmasına neden olacaktır. $bu değişken ve bir kullanımdan kaldırma uyarısı veriliyor.

a sınıfı (
genel işlev testi() ( var_dump($this); )
}

// Not: A'yı GENİŞLETMEZ
B sınıfı (
genel işlev callNonStaticMethodOfA() ( A::test(); )
}

(yeni B)-> callNonStaticMethodOfA();
?>

PHP 5.6'daki yukarıdaki örneğin çıktısı:

Kullanımdan kaldırıldı: Statik olmayan yöntem A::test(), $this öğesinin 8. satırdaki /tmp/test.php içindeki uyumsuz bağlamdan geldiği varsayılarak statik olarak çağrılmamalıdır object(B)#1 (0) ( )

PHP 7'deki yukarıdaki örneğin çıktısı:

Kullanımdan kaldırıldı: Statik olmayan yöntem A::test(), 8. satırda /tmp/test.php içinde statik olarak çağrılmamalıdır. Uyarı: Tanımsız değişken: bu, 3. satırda /tmp/test.php'de NULL

verim artık doğru bir ilişkisel operatördür

Getiri yapısı artık parantez gerektirmez ve önceliğe sahip bir doğru ilişkisel işleç olarak değiştirilmiştir. Yazdır ve => . Bu, davranış değişikliğine neden olabilir:

yankı verimi - 1 ;
yankı (verim) - 1;
// Ve şimdi olarak yorumlanır
yankı verimi (- 1 );

$foo ver ya da öl;
// Daha önce şu şekilde yorumlanmıştı:
verim($foo veya öl);
// Ve şimdi olarak yorumlanır
(verim $foo ) veya öl;
?>

Bu durumların belirsizliğini gidermek için parantezler kullanılabilir.

Fonksiyonların aynı ada sahip birden fazla parametresi olamaz

Aynı ada sahip iki veya daha fazla fonksiyon parametresi tanımlamak artık mümkün değil. Örneğin, aşağıdaki işlev bir E_COMPILE_ERROR:

foo işlevi ($a , $b , $kullanılmayan , $kullanılmayan ) (
}
?>

Bağımsız değişkenleri inceleyen işlevler, akım parametre değeri

func_get_arg(), func_get_args(), debug_backtrace() ve istisna geri izlemeleri artık bir parametreye iletilen orijinal değeri rapor etmeyecek, bunun yerine geçerli değeri sağlayacaktır (değiştirilmiş olabilir).

foo işlevi ($x ) (
$x++;
var_dump(func_get_arg(0));
}
foo(1); ?>

PHP 5'te yukarıdaki örneğin çıktısı:

PHP 7'deki yukarıdaki örneğin çıktısı:

Switch deyimlerinin birden çok varsayılan bloğu olamaz

Bir switch ifadesinde iki veya daha fazla varsayılan blok tanımlamak artık mümkün değildir. Örneğin, aşağıdaki switch ifadesi bir E_COMPILE_ERROR:

anahtar(1 ) {
varsayılan:
kırmak;
varsayılan:
kırmak;
}
?>

JSON uzantısı JSOND ile değiştirildi

JSON uzantısı, JSOND ile değiştirildi ve üç küçük BC kesintisine neden oldu. İlk olarak, bir sayı ondalık nokta ile bitmemelidir (ör. 34. ikisinden birine değiştirilmelidir 34.0 veya 34 ). İkincisi, bilimsel gösterimi kullanırken, eüs hemen bir ondalık noktayı takip etmemelidir (ör. 3.e3 ikisinden birine değiştirilmelidir 3.0e3 veya 3e3). Son olarak, boş bir dize artık geçerli JSON olarak kabul edilmez.

Taşmada dahili fonksiyon hatası

Önceden, dahili işlevler, kayan nokta bir tamsayı olarak temsil edilemeyecek kadar büyük olduğunda, kayan nokta-tamsayı zorlamalarından üretilen sayıları sessizce keserdi. Şimdi, bir E_WARNING yayınlanacak ve BOŞ iade edilecek.

Özel oturum işleyici dönüş değerlerine yönelik düzeltmeler

Dönen özel oturum işleyicileri tarafından uygulanan tüm yüklem işlevleri YANLIŞ veya -1 ölümcül hatalar olacaktır. Bu işlevlerden bir boole dışında herhangi bir değer varsa, -1 , veya 0 döndürülürse başarısız olur ve bir E_WARNING verilir.

Eşit öğelerin sıralama düzeni

Dahili sıralama algoritması iyileştirildi; bu durum, eskisinden daha eşit olarak karşılaştırılan öğelerin farklı sıralama düzenine neden olabilir.

Eşit olarak karşılaştırılan öğelerin sırasına güvenmeyin; her an değişebilir.

Yanlış yerleştirilmiş break ve switch ifadeleri

kırmak ve devam et bir döngü dışındaki ifadeler veya değiştirmek kontrol yapısı artık daha önce olduğu gibi çalışma zamanı yerine derleme zamanında algılanıyor ve bir E_COMPILE_ERROR.

Birçok insan bu tür yapıları bir biçimde yazmayı sever, herkes karşılaştı:
foreach ($item &$item olarak) ( $item += 2; )
Ancak pek çoğu burada gizlenen tehlikenin farkında değil.
Bir örnek düşünün.

Vasya Pupkin bir dizi aldı, içinden geçerek tüm öğeleri iki katına çıkardı:
$items = dizi("a" => 10, "b" => 20, "c" => 30,); foreach ($item &$item olarak) ( $item += 2; ) print_r($item);
Çöplüğe baktım, görevin çözüldüğünü gördüm ve memnun ayrıldım:
Dizi([a] => 12[b] => 22[c] => 32)
Bir süre sonra Petrovich, kodun bu bölümünü başka bir numaralandırma ile tamamlamaya karar verdi ve aşağıdakileri ekledi:
$yeni öğeler = dizi("a" => 10, "b" => 20, "c" => 30,); foreach ($yeni öğeler olarak $anahtar=>$öğe) ( $yeni öğeler[$anahtar] += 5; ) print_r($yeni öğeler);
Görevinin de çözüldüğüne baktı ve bir başarı duygusuyla dosyayı kapattı:
Dizi ([a] => 15 [b] => 25 [c] => 35)
Bir süre sonra anlaşılmaz hatalar çıkmaya başladı. Niye ya?
Kodun sonuna var_dump($items) yapalım:
dizi(3) ( ["a"]=> int(12) ["b"]=> int(22) ["c"]=> &int(30) )
otuz! Vasya Pupkin kontrol ettiğine yemin ediyor. Neden 32 ve Petrovich'in kodu 30'dan sonra?

Nedeni ve işareti yatıyor. İşaretlenen verilere başka biri tarafından başvurulduğunu bildirir. Vasya ayrılırken, arkasındaki numaralandırma ($item) için kullandığı geçici değişkeni silmedi. Değişken, "referansla atama" olarak da adlandırılan kaynağı ("&") değiştirme izniyle kullanıldı. Değişkenin yalnızca döngü içinde kullanılacağından emindi. Petrovich, aynı isimde bir değişken kullanarak, sayımı sırasında değerini değiştirdi ve her seferinde bu değişkenin saklandığı yer değişti. Ve Pupkin dizisinin son öğesiyle aynı yerde saklandı.

Tabii ki, makalede abartılı durumda. Uygulamada, özellikle proje ucuzsa ve deneyimsiz ve farklı web geliştiricileri içeriyorsa, bu bağlantılar çok karmaşık olabilir.

Bunu nasıl aşabilirsin?

  • Özellikle kullanılan verilerle herhangi bir bağlantıları varsa, kullanımdan sonra geçici değişkenleri yok edin:
    foreach ($item &$item olarak) $item += 2; unset($item);
  • Birisi tarafından zaten kullanılmış olan değişkenlere dikkat edin.
  • Eylemlerinizi ayrı işlevler, yöntemler veya ad alanlarında kapsülleyin.
  • print_r yerine var_dump kullanın ve ve işaretine dikkat edin. Tarayıcı yerine bir dosyaya döküm yapmak için print_r($var,true) alternatifi şu olabilir:
    function dump() ( ob_start(); foreach(func_get_args() as $var) var_dump($var); return ob_get_clean(); )
Sonuç olarak linklerle ilgili bugların sadece foreach içinde olamayacağını söyleyeceğim. Ve hepsi bir zamanlar tartışıldı. Ancak, deneyimlerime bakılırsa, bu dava pratikte o kadar yaygın ki özel bir ilgiyi hak ediyor.

İstemsizce görün ... Rusça eş anlamlılar ve anlam bakımından benzer ifadeler sözlüğü. altında. ed. N. Abramova, M.: Rusça Sözlükler, 1999. Bilinçsizce, farkında olmadan, kendiliğinden, panikle, içgüdüsel olarak, farkında olmadan, farkında olmadan, ... ... eşanlamlı sözlük

Açıklanamaz bir şekilde, içgüdüsel olarak, otomatik olarak, kendiliğinden, körü körüne. Santimetre … eşanlamlı sözlük

İstemsiz, bilinçsiz, bilinçsiz, içgüdüsel, mekanik, mekanik, körü körüne, kendiliğinden; yanlışlıkla, istemeden; Willy-nilly, beğen ya da beğenme (volens nolens), zorunlu olarak, elinde olmayan şeyler yüzünden bunu yapmak zorunda kaldı... ... eşanlamlı sözlük

Kör, bilinçsiz, içten, farkında olmadan, farkında olmadan, kendiliğinden, bilinçsizce, farkında olmadan, bilinçsiz, mekanik, bilinçsiz, bilinçsiz, sezgisel, bilinçsiz, altıncı his, içgüdüsel olarak Rusça Sözlüğü ... ... eşanlamlı sözlük

İstemsizce görün ... Rusça eş anlamlılar ve anlam bakımından benzer ifadeler sözlüğü. altında. ed. N. Abramova, M.: Rusça sözlükler, 1999. körü körüne, bilinçsizce, istemsizce; belli belirsiz, pervasızca, bilinçsizce, kendiliğinden, içgüdüsel olarak, kölece, bilinçsizce, belirsizce, ... ... eşanlamlı sözlük

adv. hesap sorulamayana. [Anne] geri dönmek istedi ama bilinçsizce tekrar ileri gitti. M. Gorki, anne. [Judushka] iyi arkadaşı annesine mülkünü dolaylı olarak yönetmesi için yalvardı. Saltykov Shchedrin, Beyler Golovlevs ... Küçük Akademik Sözlük

RAPORLANMAZ, hesap verilemez, hesap verilemez; (kısa eril kullanılmamış) sorumsuz, sorumsuz. 1. Herhangi bir kontrole tabi değildir, rapor vermek zorunda değildir. Dükkanda dolaylı olarak (zarf) elden çıkardı. 2. Makul düşüncelere bağlı olmayan, ... ... Ushakov'un Açıklayıcı Sözlüğü

- (Yunanca). Başkasının hesabına hesap sorulmaksızın ticaret yapmakla görevlendirilen kişi. Rus diline dahil olan yabancı kelimelerin sözlüğü. Chudinov A.N., 1910. ANAGALİST Başka birinin hesabına hesap vermeksizin ticaret yapmakla görevlendirilen kişi. Açıklama… … Rus dilinin yabancı kelimeler sözlüğü

Hesapsız, bilinçsiz, mekanik, istemsiz, otomatik, mekanik, otomatik, mekanik olarak, otomatik pilot Rusça eşanlamlılar sözlüğü. otomatik olarak Rus dilinin eşanlamlı sözlüğünü otomatik olarak görün. Pratik rehber. M.: Rusça ... eşanlamlı sözlük

İstemsizce görün ... Rusça eş anlamlılar ve anlam bakımından benzer ifadeler sözlüğü. altında. ed. N. Abramova, M.: Rusça sözlükler, 1999. içgüdüsel, bilinçsiz, istemsiz olarak; istemsizce, bilinçsizce, içten içe, kendiliğinden, kendiliğinden, bilinçsizce, körü körüne, ... ... eşanlamlı sözlük

Kitabın

  • Çekoslovakya'da Yolculuk, J. Marko, M. Peterka, Prag, 1959. Artia. Birçok fotoğraf illüstrasyonu ile. Yayıncının bağlayıcılığı. Güvenlik iyi. Dünyanın herhangi bir ülkesinin büyülü gezgini, bu güzel kitaba dalarak, ... Kategori: Gezginlerin notları, hatıralar, araştırma Yayımcı: Artia,
  • Yönetim Kurulu veya Sennaya, Gennady Grigoriev, Sergey Nosov'da Toplantılar, St. Petersburg'da sadece fantazmojenik olan yerler var. Sennaya Meydanı bunlardan biri. "Sennaya - fantazmagorinin beşiği". Yazarlar, Sennaya'da başlarına gelenlere şaşırmış görünüyorlar. Evet ve... Kategori: Klasik ve modern nesir Seri: Zamanımızın Petersburg yüzleri Yayımcı:

PHP'yi ne kadar kullanırsak kullanalım, hala adını bile duymadığımız bazı özellikler ortaya çıkıyor. Bazıları bizim için çok yararlı olacaktır. Her PHP programcısının cephaneliğinde olması gereken kullanışlı özelliklerin kısa bir listesini oluşturdum.

1. Değişken sayıda argüman içeren işlevler oluşturma

Muhtemelen PHP'nin isteğe bağlı argümanlarla işlevler oluşturmamıza izin verdiğini zaten biliyorsunuzdur. Şimdi, argüman sayısının büyük/küçük harfe değişebileceği bir fonksiyon göstereceğim.

Ama önce, fonksiyonları her zamanki gibi nasıl yarattığımızı hatırlayalım:

// iki isteğe bağlı parametreli fonksiyon function foo($arg1 = "", $arg2 = "") ( echo "arg1: $arg1\n"; echo "arg2: $arg2\n"; ) foo("merhaba", "Dünya"); /* çıktı: arg1: merhaba arg2: dünya */ foo(); /* çıktı: arg1: arg2: */

Şimdi sınırsız sayıda argüman içeren bir fonksiyonu nasıl yazabileceğinize bakalım. Bunun için func_get_args() yöntemi kullanılacaktır:

// argümanları belirtme function foo() ( // geçirilen argümanların bir dizisini döndürür $args = func_get_args(); foreach ($args as $k => $v) ( echo "arg".($k+1) ." : $v\n"; ) ) foo(); /* çıktı çıktısı */ foo("merhaba"); /* çıktı arg1: merhaba */ foo("merhaba", "dünya", "tekrar"); /* çıktı arg1: merhaba arg2: dünya arg3: tekrar */

2. Dosyaları Bulmak için Glob() kullanın

Genellikle işlev adları kendileri için konuşur. Aynı şey glob() işlevi için söylenemez.

Ayrıntılara girmeden, işlevi scandir() yöntemine benzer. Desene göre gerekli dosyayı bulmanızı sağlar:

// tüm php dosyalarını bul $files = glob("*.php"); print_r($dosya); /* çıktı: Dizi ( => phptest.php => pi.php => post_output.php => test.php) */

Birkaç türde dosya bulmak için şöyle yazmanız gerekir:

// tüm php ve txt dosyalarını bul $files = glob("*.(php,txt)", GLOB_BRACE); print_r($dosya); /* çıktı: Dizi ( => phptest.php => pi.php => post_output.php => test.php => log.txt => test.txt) */

Şablonda yolu da belirtebilirsiniz:

$dosyalar = glob("../images/a*.jpg"); print_r($dosya); /* çıktı: Dizi ( => ../images/apple.jpg => ../images/art.jpg) */

Bir belgenin tam yolunu almak için realpath() yöntemini kullanın:

$dosyalar = glob("../images/a*.jpg"); // "realpath" işlevini dizinin her bir öğesine uygulayın $files = array_map("realpath",$files); print_r($dosya); /* çıktı: Dizi ( => C:\wamp\www\images\apple.jpg => C:\wamp\www\images\art.jpg) */

3. Kullanılan hafıza hakkında bilgi

Komut dosyalarınız tarafından tüketilen bellek miktarını takip ederseniz, muhtemelen onları daha sık optimize edeceksiniz.

PHP'nin güçlü bir bellek izleme aracı vardır. Komut dosyasının farklı bölümlerinde yükler farklı olabilir. Halihazırda kullanılan belleğin değerini almak için memory_get_usage() yöntemini kullanmalıyız. Kullanılan maksimum bellek miktarını düzeltmek için memory_get_peak_usage() işlevini kullanın.

echo "Başlangıç: ".memory_get_usage()." bayt \n"; /* Başlangıç: 361400 bayt */ // ($i = 0; $i) için küçük bir yük verin< 100000; $i++) { $array = md5($i); } // и ещё for ($i = 0; $i < 100000; $i++) { unset($array[$i]); } echo "Final: ".memory_get_usage()." bytes \n"; /* Final: 885912 bytes */ echo "Peak: ".memory_get_peak_usage()." bytes \n"; /* Peak: 13687072 bytes */

4. İşlemci Bilgileri

Bunu yapmak için getrusage() yöntemini kullanmanız gerekir. Ancak bu özelliğin Windows'ta çalışmayacağını unutmayın.

Print_r(getrusage()); /* Dizi yazdırır ( => 0 => 0 => 2 => 3 => 12692 => 764 => 3864 => 94 => 0 => 1 => 67 => 4 => 0 => 0 => 0 => 6269 => 0) */

Yukarıda özetlenen resim, sistem yönetiminde deneyimi olanlar için net olacaktır. Diğer herkes için bir şifre çözme sunuyoruz:

  • ru_oublock: blok yazma sayısı
  • ru_inblock: blok okuma sayısı
  • ru_msgsnd: gönderilen mesaj sayısı
  • ru_msgrcv: alınan mesaj sayısı
  • ru_maxrss: disk belleği olmayan kümenin maksimum boyutu
  • ru_ixrss: toplam paylaşılan bellek
  • ru_idrss: paylaşılmayan toplam veri miktarı
  • ru_minflt: kullanılan bellek sayfası sayısı
  • ru_majflt: sayfa hatası sayısı
  • ru_nsignals: alınan sinyal sayısı
  • ru_nvcsw: sürece göre bağlam değiştirme sayısı
  • ru_nivcsw: zorunlu bağlam anahtarlarının sayısı
  • ru_nswap: sayfalama sırasında disk erişimlerinin sayısı
  • ru_utime.tv_usec: kullanıcı modunda harcanan süre (mikrosaniye)
  • ru_utime.tv_sec: kullanıcı modunda geçirilen süre (saniye)
  • ru_stime.tv_usec: ayrıcalıklı mod süresi (mikrosaniye)
  • ru_stime.tv_sec: ayrıcalıklı mod süresi (saniye)

İşlemcinizin hangi kaynaklarının komut dosyası tarafından kullanıldığını bulmak için, 'kullanıcı zamanı' (kullanıcı modundaki zaman) ve 'sistem zamanı' (ayrıcalıklı moddaki zaman) değerine ihtiyacınız vardır. Sonucu hem saniye hem de mikro saniye olarak alabilirsiniz. Toplam saniye sayısını ondalık sayıya dönüştürmek için mikrosaniye değerini 1 milyona bölmeniz ve değere saniye eklemeniz gerekir.

Nedense kafa karıştırıcı. İşte bir örnek:

// 3 saniye dinlenme uyku(3); $veri = getrusage(); echo "Kullanıcı saati: ". ($veri["ru_utime.tv_sec"] + $veri["ru_utime.tv_usec"] / 1000000); echo "Sistem saati: ". ($veri["ru_stime.tv_sec"] + $veri["ru_stime.tv_usec"] / 1000000); /* yazdırır Kullanıcı zamanı: 0.011552 Sistem zamanı: 0 */

Komut dosyasının tamamlanması yaklaşık 3 saniye sürse de, işlemci yoğun bir şekilde yüklenmedi. Mesele şu ki, bir çağrıda (uykuda) komut dosyası pratik olarak işlemcinin kaynaklarını tüketmez. Genel olarak, önemli miktarda zaman alan ancak işlemciyi kullanmayan birçok görev vardır. Örneğin, diskle ilgili işlemleri beklemek. Yani betiklerinizde her zaman CPU zamanı kullanmazsınız.

İşte başka bir örnek:

// for($i=0;$i) için 10 milyon kez yürü<10000000;$i++) { } $data = getrusage(); echo "User time: ". ($data["ru_utime.tv_sec"] + $data["ru_utime.tv_usec"] / 1000000); echo "System time: ". ($data["ru_stime.tv_sec"] + $data["ru_stime.tv_usec"] / 1000000); /* выводит User time: 1.424592 System time: 0.004204 */

Komut dosyası 1.4 saniye CPU süresi aldı. Bu durumda, sistem çağrı süreleri genellikle düşüktür.

Ayrıcalıklı mod zamanı (Sistem Zamanı), işlemcinin program adına çekirdeğe sistem isteklerini yürütmek için harcadığı zamandır. Örnek vermek:

$başlangıç ​​= mikrozaman(doğru); // microtime'ı her 3 saniyede bir çağır while(microtime(true) - $start< 3) { } $data = getrusage(); echo "User time: ". ($data["ru_utime.tv_sec"] + $data["ru_utime.tv_usec"] / 1000000); echo "System time: ". ($data["ru_stime.tv_sec"] + $data["ru_stime.tv_usec"] / 1000000); /* выводит User time: 1.088171 System time: 1.675315 */

Şimdi sistem zamanı önceki örnekte olduğundan çok daha fazla harcandı. Hepsi sistem kaynaklarını kullanan microtime () yöntemi sayesinde.

Ancak, gösterilen zamanın doğru olmayabileceğine dikkat edilmelidir, çünkü. bu noktada, işlemci kaynakları diğer programlar tarafından da kullanılıyor ve bu da küçük bir hataya neden olabilir.

5. Büyü sabitleri

PHP'de geçerli satır numarası (__LINE__), dosya yolu (__FILE__), dizin yolu (__DIR__), işlev adı (__FUNCTION__), sınıf adı (__CLASS__), yöntem adı (__METHOD__) ve ad alanları (__NAMESPACE__) gibi birçok sihirli sabit vardır. .

Hepsini dikkate almayacağız. Sadece bir çifte bakalım:

// bu betik dosyanın o anki konumuna bağlıdır ve // ​​farklı dizinlerden kullanıldığında sorunlara neden olabilir require_once("config/database.php"); // bu betik soruna neden olmaz request_once(dirname(__FILE__) . "/config/database.php");

Komut dosyalarında hata ayıklarken __LINE__ kullanın:

// kod // ... my_debug("bazı hata ayıklama mesajları", __LINE__); /* çıktı Satır 4: bazı hata ayıklama mesajları */ // daha fazla kod // ... my_debug("başka bir hata ayıklama mesajı", __LINE__); /* çıktı Satır 11: başka bir hata ayıklama mesajı */ function my_debug($msg, $satır) ( echo "Satır $satır: $msg\n"; )

6. Benzersiz kimliklerin oluşturulması

Benzersiz bir dize oluşturmanız gereken zamanlar vardır. Çoğu zaman bu sorunu çözmek için md5() işlevinin kullanıldığını gördüm:

// rastgele bir dize oluştur echo md5(time() .mt_rand(1,1000000));

Ama aslında PHP'nin bu amaç için özel bir uniqid() işlevi vardır.

// rastgele bir dizi oluştur echo uniqid(); /* 4bd67c947233e çıktısı */ // bir kez daha echo uniqid(); /* 4bd67c9472340 yazdırır */

Çıplak gözle, ilk karakterlerin en az söylemek gerekirse benzer olduğunu görebilirsiniz ... Bunun nedeni, bu yöntemin karakter oluşturmak için sunucu zamanını kullanmasıdır. Hatta faydalı çünkü. oluşturulan tüm değerler alfabetik sırayla elde edilir, bu da onları hızlı bir şekilde sıralamayı mümkün kılar.

Kopya alma olasılığını azaltmak için bir önek ekleyebilir veya ikinci bir parametre kullanabiliriz (karakter sayısını artırabilirsiniz):

// ön eki echo uniqid("foo_"); /* çıktı foo_4bd67d6cd8b8f */ // ikinci parametre ile echo uniqid("",true); /* çıktılar 4bd67d6cd8b926.12135106 */ // her ikisi de echo uniqid("bar_",true); /* bar_4bd67da367b650.43684647 yazdırır */

Bu yöntem, md5'ten daha küçük dizeler oluşturur, böylece yerden tasarruf edebilirsiniz.

7. Serileştirme

Hiç karmaşık verileri bir veritabanında veya dosyada depolamak zorunda kaldınız mı? Bir nesneyi bir dizgeye dönüştürmek için PHP özel bir işlev sağlar.

Genel olarak konuşursak, bu yöntemler 2: serialize() ve unserialize() şeklindedir.

// karmaşık dizi $myvar = dizi("merhaba", 42, dizi(1,"iki"), "elma"); // dizgeye dönüştür $string = serialize($myvar); yankı $dizi; /* çıktı a:4:(i:0;s:5:"merhaba";i:1;i:42;i:2;a:2:(i:0;i:1;i:1;s :3:"two";)i:3;s:5:"elma";) */ // orijinal değeri al $newvar = unserialize($string); print_r($newvar); /* Dizi yazdırır ( => merhaba => 42 => Dizi ( => 1 => iki) => elma) */

Bu işlevler bu şekilde çalışır. Ancak, JSON'un popülaritesindeki hızlı artış nedeniyle, PHP 5.2'ye json_encode() ve json_decode() olmak üzere 2 yöntem eklendi. Çalışmaları serialize() işlevine benzer:

// karmaşık dizi $myvar = dizi("merhaba", 42, dizi(1,"iki"), "elma"); // dizgeye dönüştür $string = json_encode($myvar); yankı $dizi; /* ["merhaba",42,"elma"] yazdırır */ // orijinal değeri geri yükler $newvar = json_decode($string); print_r($newvar); /* Dizi yazdırır ( => merhaba => 42 => Dizi ( => 1 => iki) => elma) */

Bu seçenek daha kompakttır ve JavaScript gibi diğer dillerle uyumludur. Ancak, çok karmaşık nesnelerle çalışırken veri kaybı meydana gelebilir.

8. Dize Sıkıştırma

Sıkıştırma denilince akla hemen ZIP formatındaki arşiv dosyaları gelir. PHP, uzun dizeleri herhangi bir dosya olmadan sıkıştırma yeteneği sağlar.

Aşağıdaki örnekte, gzcompress() ve gzuncompress() işlevlerinin çalışmasını göstereceğiz:

$string = "Lorem ipsum dolor sit amet, conectetur adipiscing elit. Unc ut elit id mi ultricies adipiscing. Nulla facilisi. Praesent pulvinar, sapien vel feugiat vestibulum, nulla dui pretium orci, non ultricies elit ve lacus domet quis. , consectetur adipiscing elit. Aliquam pretium ullamcorper urna quis iaculis. metus, lacinia augue'de. Sed magna nisi, mollis içinde ornare, mollis sed nunc. Etiam, leo congue mollis'te justo. ; $sıkıştırılmış = gzcompress($dizi); echo "Orijinal boyut: ". strlen($dize)."\n"; /* yazdırır Orijinal boyut: 800 */ echo "Sıkıştırılmış boyut: ". strlen($sıkıştırılmış)."\n"; /* çıktı Sıkıştırılmış boyut: 418 */ // dönüş $orijinal = gzuncompress($sıkıştırılmış);

Metin miktarını %50 oranında azaltabiliriz. Aynı amaçla, farklı bir sıkıştırma algoritması kullanan gzencode() ve gzdecode() yöntemlerini kullanabilirsiniz.

9. Tamamlanmadan önce çalıştırın

PHP, komut dosyası çıkmadan önce bazı kodları çalıştırmanıza izin veren bir register_shutdown_function() işlevine sahiptir.

Diyelim ki biraz bilgi edinmek istiyorsunuz... Script çalışma süresi:

// başlangıç ​​zamanını al $start_time = microtime(true); // bazı işlemler // ... // çalışma süresini yazdır yankı "yürütme: ". (mikrozaman(doğru) - $başlangıç_zamanı). "saniye.";

İlk bakışta, bu önemsiz bir görev gibi görünebilir. Bu amaçlar için, kodu dosyanın sonuna koyabilirsiniz. Ancak, çıkış() işlevi daha önce bir yerde yürütülürse, bu kod hiçbir zaman çalışmayacaktır. Ayrıca, sayfada bir hata varsa veya kullanıcı sayfa yüklemesini durdurursa (tarayıcısındaki uygun düğmeye tıklayarak) çalışmayacaktır;

register_shutdown_function() yöntemini kullanırken, kod yine de yürütülür:

$start_time = mikrozaman(doğru); register_shutdown_function("my_shutdown"); function my_shutdown() ( global $start_time; echo "yürütme sürdü: ". (microtime(true) - $start_time). " saniye."; )

Çıktı

PHP, içeriğiyle bizi şaşırtmaktan asla vazgeçmeyen bir gezegendir. Bu özellikler hakkında ne düşünüyorsunuz?

Kontrolünde bir web sitesinin oluşturulması ve tanıtımıyla uğraşıyorsunuz. İYS Joomla ve aniden zevkinize ve ruh halinize göre yeniden yapma ihtiyacı duyuyorsunuz com_content bileşeninin standart şablonlarını düzenleyerek materyali tasarlama? Bileşen, içerik oluşturmaktan sorumludur. Şimdi bileşenin yapısına bir göz atalım.

Standart malzeme şablonunun konumu

Orijinal bileşen dosyaları com_content component\com_content\views\View\tmpl içinde bulunur. Bileşen dosyaları, kullandığınız \templates\template\html\com_content\ dizinine kopyalanırsa, malzeme şablonu bu klasörün dosyalarından alınacaktır.

Şablon dizinleri ve dosyaları

Şablon konumu dizini, görünümler oluşturmak için beş klasör içerir.

dosya Arşiv

  • Arşiv çıktı şablonu klasörü. Bu makale dikkate alınmaz, nadiren kimse tarafından kullanılır. Yapı, aşağıda açıklanan klasörlere benzer;

dosya makale - Malzeme

dosya ön Sayfa - Ana Sayfa

  • default.php kategori\blog.php ile aynı prensip;
  • default_item.php kategori\blog_item.php ile aynı prensip;
  • default_links.php kategori\blog_links.php ile aynı ilke;

dosya Bölüm - Bölüm

  • blog.php Bölüm blog şablonu. kategori\blog.php ile aynı prensip;
  • blog_item.php Blog bölümünden ayrı bir makale için bir şablon. kategori\blog_item.php ile aynı prensip;
  • blog_links.php Bölüm blogunun altındaki bağlantıları sunmak için şablon. kategori\blog_links.php ile aynı ilke;
  • default.php Standart bölüm şablonu. Kategori başlığını, açıklamasını, öğe sayısını görüntüler. Kategori başlığına tıkladıktan sonra sayfa, Category\default.php ile işlenir;

Şablon düzenlemeye bir örnek. Malzemenin görünüm sayısını görüntüler.

Diyelim ki istiyoruz isabet sayısını yazdır ayırmak malzeme kategori blogundan. Bunu yapmak için kategori\blog_item.php şablonunu düzenleyin. İsabetler hakkında bilgi ekleme kodu aşağıdaki gibi olacaktır:

item->isabet ?>

Şimdi kategori\blog_item.php şablon dosyasında bu kodu nereye ekleyeceğinizi bulmanız gerekiyor. Örneğin, materyalin son düzenleme tarihini görüntülemeden önce. Hattı arıyorum:

item->modified) !=0 && $this->item->params->get("show_modify_date")) : ?>

Ve ondan önce, kodu içeren bir satır ekleyin.

Örnek vermek kategorileri birden çok sütunda listeleme .