file_get_contents()
Pone do momenta na izlizane na 4.3.0 sa mi poznati 3 nachina za izvlichane sudurzhanieto na fail ot diska
ili vuobshte na fail, kogato se izpolzva pototsi.
Primer 1 |
$content = implode('', file($fname)); |
Komentar :
Tova e edin ot nai-chesto izpolzvanite metodi. Mozhe da go sreshtnete v mnogo skriptove.
Dostatuchno burz. Mozhe da uchastva v izraz.
Nedostatutsi :
V povecheto sluchai tozi kod shte raboti, no ima izklyucheniia. Do versiia 4.3.0 funktsiiata
file() ne e
binary-safe. T.e. za tekstovi failove niama da ima problemi.
Problemite vuznikvat vuv momenta, v koito reshite da otvariate fail, koito sudurzha simvola
na '\0'.
Nachin za izbiagvane : vzh. Primer 2
Primer 2 |
$fd = fopen($fname, 'r');
$content = fread($fd, filesize($fname));
fclose($fd);
$content = implode('', file($fname)); |
Komentar :
Tova e edin ot po-malko izpolzvan metod. Izbiagva problema na predishniiat metod za versii < 4.3.0 .
Skorostta mu e niakude okolo tazi na predishniiat metod, no mislia malko po-baven.
Nedostatutsi :
Mozhe bi edinstveniiat mu nedostatuk e, che se pishe na 3 reda kod i ne mozhe da bude chast ot izraz, kakto
e pri predishniiat metod.
Primer 3 |
ob_start();
readfile($fname);
$content = ob_get_contents();
ob_end_clean();
$content = implode('', file($fname)); |
Komentar :
Tova e edin ot malko izpolzvan metod. Riadkost e da go sreshtnete v skript. Izpolzva se tehnikata
na buferirane na izhoda, koiato ne e mnogo populiarna. Opredeleno nai-burziiat ot vsichki pokazani
do momenta metodi, no za smetka na tova se izpolzvat poveche resursi (glavno pamet).
Nedostatutsi :
Kakto i Primer 2, ne mozhe da uchastva v izraz.
Ne vuv vsichki sluchai e nedostatuk, no ako pametta vi e kut, togava ne Vi go preporuchvam.
Primer 4 : Novata funktsiia |
$content = file_get_contents(); |
Komentar :
Tazi funktsiia se iaviava evolyutsionna, zashtoto vse pak ne e hubavo za skriptov ezik, koito se izpolzva
shiroko za izvlichane sudurzhanieto na fail da se polzvat nakup nai-malko 2 funktsii. Tova shte bude veche
nai-burziiat metod za chetene pri tova e
binary-safe. Kato vutreshnost funktsiiata mnogo napodobiava
readfile(), no vrushta rezultata vmesto da go izkarva na izhoda.
version_compare() i debugvane
Funktsiiata se izpolzva sa sravnenie na dva niza, koito sudurzhat versii po PHP standarta.
Primer 5 |
<?php
$Debug_level = 2|4|8|16|32|1024;
if (($Debug_level & 1024) && version_compare(PHP_VERSION , "4.3.0-dev",'<')) {
$Debug_level -= 1024;
}
define('DEBUG_MODE', $Debug_level);
error_reporting(E_ALL);
...
...
(DEBUG_MODE & 1024) && log_printf("[Elapsed in %s::%s = %2.5fs]\n",
__CLASS__, __FUNCTION__, $timer->elapsed());
?> |
Tozi primer pokazva kak mozhe da zashtitite kod ot izpulnenie na niakoi versii na PHP. V sluchaia na versii, koito
sa predi 4.3.0-dev. Tazi zashtita se nalaga zashtoto predefiniranite konstanti __CLASS__ i __FUNCTION__ se poiaviavat
prez April 2002g. vuv 4.3.0-dev.
Za chast ot chitatelite polovinata kod mozhe da e nerazbiraem. Osobeno posledniia red. Izpolzva se pobitovo sravnenie
(aritmetichen OR). Tova e tehnika shiroko izpolzvana ot programistite na C. Dava vuzmozhnost samo s edna operatsiia da se
proveri dali e triabva da se izpishe dadena debug informatsiia.
Primer 6 |
<?php
(DEBUG_MODE & 5) && printf("Entering parsing and saving mode at : ".microtime()."\n");
?> |
V tozi sluchai se proveriava dali debug nivoto e 1 ili 4
printf() se izpulniava samo kogato e izpulneno da e
"vdignato" nivo i/ili nivo 4. V sluchaia nivo 1 oznachava vsichki suobshteniia, a 4 - informatsiia za vremeto za izpulnenie.
Plyus na tozi metod e che se subira na 1 red.
Primer 7 |
<?php
if ((DEBUG_MODE & 4) || (DEBUG_MODE & 1)) {
printf("Entering parsing and saving mode at : ".microtime()."\n");
}
?> |
Kakto se vizhda ekvivalenten
if operator zaema nai-malko 2 reda. Razbira se mozhe da se zapishe na 1 red, no tozi
zapis shte e protiv vsiakakva konventsiia za zapisvane na tozi operator. Razbira se moga da bude obvinen, che metoda koito
polzvam e nerazbiraem i oburkvasht, dori poniakoga zagroziavasht koda, no opredeleno pesti redove vidim kod v redaktora. A ako
kato sviknesh s nego ne ti pravi vpechatlenie. Podobno da vechniiat disput kude da se pishe otvariashtata liava skoba.
array_shift($ar)
Tazi funktsiia vrushta purviiat element ot masiva
$ar kato go premahva ot tam i prenarezhda
masiva. Ako tursite proizvoditelnost i ne se nuzhdaete ot tova elementite vi v edin
masiv da sa s indeksi zapochvashti ot nula, to ne izpolzvaite tazi funktsiia. Za razlika
ot Perl i Python, tuk PHP e baven. Silno namalenata proizvoditelnost e sledstvie ot fakta,
che vsichki elementi na masiva triabva da budat obhodeni i tehnite indeksi da budat prenomerirani
ot 0. Pochti nikakvo e zabavianeto ot preheshiraneto.
Edno vuzmozhno reshenie samo vednuzh da si podredite masiva po indeksi (posledovatelni), da pravite
unset() na purviiat element ot masiva, kato izpolzvate pomoshtna promenliva.
Primer 7 |
<?php
$ar = array(1,1,2,3,5,8,13,21,34,55);
$first_elem_idx = 0;
$elem = $ar[$firs_elem_idx];
unset($ar[$firs_elem_idx++]);
$elem = $ar[$firs_elem_idx];
unset($ar[$firs_elem_idx++]);
$elem = $ar[$firs_elem_idx];
unset($ar[$firs_elem_idx++]);
?> |
do..while
do..while e tsikul s postuslovie. Toi se izpolzva dosta po-riadko ot
while. Dori dosta chesto se praviat trikove
predi
while za da se emulira na praktika tsikula s postuslovie. Tuk obache shte spomena edna vuzmozhnost, na tazi
konstruktsiia, koiato namiram za mnogo udobna :
Primer 8 |
<?php
do {
if ($i < 5) {
print "i is not big enough";
break;
}
$i *= $factor;
if ($i < $minimum_limit) {
break;
}
print "i is ok";
...process i...
} while(0);
?> |
Primera e vzet ot dokumentatsiiata na PHP. Tozi tsikul se izpulniava samo vednuzh, vsushtnost tova e psevdotsikul, zashtoto se
izpolzva samo zashtoto v nego sa dostupni
break i
continue;. Vsushtnost
continue; ne se izpolzva
zashtoto efekta e ekvivalenten na
break - izlizane ot bloka. Mozhe da se oprilichi na izklyucheniiata poznati na niakoi
ot C++, Java, Object Pascal. Razlikata e, che obrabotkata pri izklyuchitelnata situatsiia v povecheto sluchai se pravi v tialoto
na tsikula predi izpulnenieto na prehoda.
array_map()
Osven obiknovennoto si povedenie, tazi funktsiia ima neshto interesno skrito v neia :
Primer 9 |
<?php
$a = array(1, 2, 3, 4, 5);
$b = array("one", "two", "three", "four", "five");
$c = array("uno", "dos", "tres", "cuatro", "cinco");
$d = array_map(null, $a, $b, $c);
print_r($d);
?> |
Kakto se vizhda, ako purviiat parametur e NULL tazi funktsiia smesva elementite na podadenite i kato parametri masivi v tozi, koito se vrushta.
Purviiat parametur se izpolzva za predavane na ime na "callback" funktsiia.
Malko dumi za proizvoditelnost
Za vseki, koito e reshil da trugne po putia na OOP v PHP e iasno, che koda mu shte bude po-baven. Vse pak ako tolkova silno
zhelaete ili se nuzhdaete ot vsiaka milisekunda to togava ima kakvo da napravite po vuprosa
Primer 10 |
<?php
class CObject {
var $property;
function CObject() {
$this->property = 0;
}
}
class CLongLoop extends CObject {
function CLongLoop() {
parent::CObject();
}
function do_long_loop_slow($how) {
for ($i=0; $i < $how; $i++) {
$this->property++;
}
}
function do_long_loop_fast($how) {
$this_property = &$this->property;
for ($i=0; $i < $how; $i++) {
$this_property++;
}
}
}
$long_loop_obj = new CLongLoop();
echo microtime()."<br>\n";
$long_loop_obj->do_long_loop_slow(100000);
echo microtime()."<br>\n";
$long_loop_obj->do_long_loop_fast(100000);
echo microtime()."<br>\n";
echo microtime()."<br>\n";
$long_loop_obj->do_long_loop_slow(100);
echo microtime()."<br>\n";
$long_loop_obj->do_long_loop_fast(100);
echo microtime()."<br>\n";
?> |
Kakto se vizhda vtoriiat nachin e s okolo 30% po-burz. Vse pak triabva da imate v predvid, che tsikula se izvurta 100 000 puti.
Tova ne e nikak malko. Za tsikli s poriadutsi po-malko na broi iteratsii zabavianeto e neznachitelno. Razbira se, ako v tsikula se
izpolzvat poveche "nelokalni" promenlivi - chlen-promenlivi na klasa skorostta pada proportsionalno na tehniiat broi.
Zashto se poluchava takava razlika? CHetete v sledvashtata tochka.
Navutre v nachina na rabota na Zend Engine
Razlikata se poluchava ot spetsifikata na interpretatsiia na PHP skriptovete. Ako ne izpolzvate "kesh" za kod, to ZendEngine
1)Zarezhda skripta ot diska
2)Pravi analiz
2.1)Sintaktichen
2.2)Semantichen, kato ednovremenno s nego se generira mezhdinen kod
3)Izpulniava generiraniiat mezhdinniiat kod
Mezhdinniiat kompiliraniiat mezhdinen kod e tova, koeto populiarnite produkti kato ZendCache i PHPAccelerator keshirat. V izvestna
stepen mezhdinniiat kod mozhe da se i se optimizira ot tezi produkti. Taka izpulnenieto na skriptove mozhe da se uskori znachitelno.
Vse pak neka da kazha neshto poveche za mezhdinniiat kod. Tova e asemblera na PHP. Instruktsiite sa podobni na tezi v asemblerite za
razlichni protsesori, no suobrazeni sus spetsifikata na "virtualnata mashina". Opkodovete sa nad 110 vuv ZE1 i okolo 140 vuv ZE2.
Kogato edno prisvoiavane se prevrushta v mezhdinen kod to se zamestva s niakolko opkoda. Zarezhda se adresa na promenlivata, na koiato
se prisvoiava stoinost. Tursi se po ime(niz) v hesha na tekushto aktivnata funktsiia (bila tia i main() ). Tozi adres se zarezhda vuv
vremenna promenliva. Sled tova ako na promenlivata se prisvoiava promenliva se zarezhda neiniiat adres, i purvata promenliva
stava referentsiia (da ne se burka s ukazatel) kum vtorata. Ako se prisvoiava izraz, to se izvlicha rezultata ot vremennata promenliva
v koiato predi tova e zapisan. Vsichko tova mozhe da izglezhda malko slozhno, no na praktika ne e taka.
Tazi teoriia pomaga da se obiasneni "Primer 10". Kogato izpolzvat $this->property , se zarezhda adresa na $this ot hesha na
izvestnite promenlivi v tekushtiiat metod, sled tova v hesha sudurzhasht chlen-promenlivite na klasa se izvurshva tursene po niz,
za da se nameri adres na $this->property. Kakto se vizhda razlikata, e che pri chlen promenlivi se izvurshva edno tursene poveche. Vse pak
$this e edna ot purvite deklarirani promenlivi vuv vseki metod i turseneto e po-burzo.
Ako produlzhim s razsuzhdeniiata na baza na gornata teoriia mozhe da se obiasni zashto sa vuzmozhno tova :
Primer 11 |
<?php
$foo = 'bar';
$bar = 'ok we got it';
echo $$foo;
echo $foo();
function bar() {
return "In bar()\n";
}
?> |
Sudurzhanieto na $foo se izpolzva pri turseneto v hesha s promenlivite i se izpisva sudurzhanieto na $bar. Pri funktsiiata e analogichno,
turseneto stava v hesha s deklariranite funktsii. Primera mozhe da se razshiri dori i za suzdavane na instantsiia na klas
Literatura:
- Dokumentatsiiata na PHP
- Razlichni materiali ot Internet
- Dev forumite na PHP
- Statiia na Derick Rethans za tova kak raboti ZE