Pozdravljeni

Na spletu je ogromno zastarelih informacij, ki vodijo nove PHP uporabnike v napačno smer, propagirajo slabe prakse in nezaščiteno kodo. PHP: The Right Way je hitra referenca enostavna za branje popularnih PHP kodnih standardov, povezav k avtoriziranim vodičem po spletu in kar uporabniki, ki prispevajo kodo, smatrajo za najboljšo prakso ta trenutek.

Trenutno ni dogovorjene poti za uporabo PHP-ja. Ta stran teži k predstavitvi nekaterih tem novim PHP razvijalcem, ki jih ne odkrijejo, dokler ni že prepozno, ter nudi izkušenim profesionalcem nove ideje na teh temah, ki so jih uporabljali že leta brez, da bi ponovno premislili. Ta stran vam tudi ne bo narekovala, katera orodja naj uporabljate, vendar namesto tega ponuja predloge za mnoge opcije, ko je možno razložiti razlike v pristopu in primerih uporabe.

Gre za dokument, ki se vedno razvija in bo vedno posodabljan z več uporabnimi informacijami in primeri, ko bodo na voljo.

Prevodi

PHP: The Right Way je preveden v mnoge različne jezike:

Kako prispevati

Pomagajte tej strani narediti najboljši vir za nove PHP programerje! Prispevajte preko GitHub-a

Razširite besedo!

PHP: The Right Way ima na voljo slike pasic, ki jih lahko uporabite na vaši spletni strani. Pokažite vašo podporo in obvestite PHP razvijalce, kje lahko najdejo dobre informacije!

Poglejte si slike pasic

Nazaj na vrh

Pričetek

Uporabite trenutno stabilno verzijo (7.0)

Če pričenjate s PHP-jem, uporabite trenutno stabilno verzijo izdaje PHP 7.0. PHP 7.0 je zelo svež in vsebuje mnoge neverjetne nove lastnosti napram starejšim 5.x verzijam. Motor je bil večinoma napisan ponovno in PHP je sedaj celo hitrejši od starejših verzij.

Najpogosteje boste v bližnji prihodnosti našli uporabljen PHP 5.x in najnovejša 5.x verzija je 5.6. To ni slaba opcija, vendar bi morali poskusiti nadgraditi najnovejšo stabilno različico čimhitreje - PHP 5.6 ne bo vseboval varnostnih popravkov od 2018. Nadgradnja je resnično enostavna, saj ni veliko nazaj nezdružljivih lastnosti. Če niste prepričani, v kateri verziji je funkcija ali lastnost, lahko preverite PHP dokumentacijo na php.net strani.

Vgrajeni spletni strežnik

S PHP 5.4 ali novejšim, se lahko začnete učiti PHP brez namestitve ali konfiguracije celotnega spletnega strežnika. Za zagon strežnika poženite naslednje iz komandne vrstice v vašem vrhnjem spletnem direktoriju:

> php -S localhost:8000

Namestitev v Mac okolju

OS X sicer že vsebuje PHP, vendar ima običajno nekoliko starejšo verzijo za zadnjo stabilno. Mavericks vsebuje PHP 5.4.17, Yosemite 5.5.9, El Capitan 5.5.29 in Sierra 5.6.24, vendar z izzidom PHP 7.0 to pogostokrat ne zadostuje.

Obstoja veliko načinov za namestitev PHP na OS X.

Namestitev PHP preko Homebrew

Homebrew je močan paketni urejevalnik za OS X, ki vam lahko pomaga namestiti PHP in različne razširitve enostavno. Homebrew PHP je repozitorij, ki vsebuje PHP povezane ‘formulae’ za Homebrew, in vam bo omogočil namestiti PHP.

Na tej točki, lahko namestite php53, php54, php55, php56 ali php70 z uporabo ukaza brew install in preklapljanje med njimi s spreminjanjem vaše spremenljivke PATH. Druga možnost je uporaba brew-php-switcher, ki bo preklopil avtomatsko za vas.

Namestitev PHP preko Macports

Projekt MacPorts je pobuda odprto kodne skupnosti načrtovati sistem enostaven za uporabo, za prevajanje, nameščanje in nadgradnjo bodisi ukazne vrstice, X11 ali Aqua osnovane odprto kodne programske opreme na OS X operacijskem sistemu.

MacPorts podpira vnaprej prevedene zagonske datoteke, tako da vam ni potrebno prevajati vsako odvisnost iz izvornih tarball datotek, reši vam življenje tudi če nimate kakršnegakoli paketa nameščenega na vašem sistemu.

Za sedaj lahko namestite php54, php55, php56 ali php70 z uporabo ukaza port install na primer:

sudo port install php56
sudo port install php70

Lahko poženete ukaz select, da preklopite vaš aktiven PHP:

sudo port select --set php php70

Namestitev PHP preko phpbrew

phpbrew je orodje za namestitev in upravljanje različnih PHP verzij. To je lahko res uporabno, če dve različni aplikaciji/projekta zahtevata različni verziji PHP in ne uporabljate virtualne naprave.

Namestitev PHP preko Liip-ovega zagonskega namestitvenega programa

Druga popularna opcija je [php-osx.liip.ch], ki ponuja eno vrstične namestitvene metode za verzije 5.3 do 7.0. Ne prepisuje PHP zagonskih datotek nameščenih s strani Apple-a, vendar namesti vse na ločeno lokacijo (/usr/local/php5).

Prevajanje iz izvorne kode

Druga opcija. ki vam da kontrolo nad verzijo PHP-ja, ki ga nameščate, je da ga sami prevedete. V tem primeru zagotovite, da imate nameščen ali Xcode ali Apple-ov nadomestek “Command Line Tools for XCode”, ki ga je moč prenesti iz Apple Developer Centra.

All-in-One Installers

Rešitve napisane zgoraj v glavnem upravljajo sam PHP in ne podpirajo stvari kot je Apache, Nginx ali SQL server. “Vse-v-enem” rešitve kot je MAMP in XAMPP bodo namestile ostale dele programske opreme za vas in jo skupaj povezale, vendar enostavnost namestitve pride z pomanjkanjem fleksibilnosti.

Namestitev v Windows okolju

Prenesete lahko zagonske datoteke iz windows.php.net/downloads. Po razširitvi datotek PHP-ja je priporočljivo nastaviti PATH na vrhovni direktorij vašega PHP direktorija (kjer se nahaja php.exe), da lahko izvršite PHP iz kjerkoli.

Za učenje in lokalni razvoj lahko uporabite vgrajeni spletni strežnik s PHP 5.4+, tako da vam ni treba skrbeti za njegovo konfiguracijo. Če želite “vse v enem”, ki vključuje celoten spletni strežnik in tudi MySQL, potem orodja, kot so Web Platform Installer, XAMPP, EasyPHP, OpenServer in WAMP, pripomorejo k hitri namestitvi na Windows razvojno okolje. Tako bodo orodja malenkost drugačna od produkcijskih, zato bodite previdni na razlike v razvojnih okoljih, če delate na Windows-u in nalagate na Linux.

Če potrebujete zagnati vaš produkcijski sistem na Windows, potem vam bo IIS7 zagotovil najbolj stabilno in najboljše izvajanje. Lahko uporabite phpmanager (GUI vtičnik za IIS7), ki enostavno skonfigurira in upravlja PHP. IIS7 vsebuje že vgrajen FastCGI in je pripravljen na uporabo, tako da potrebujete samo skonfigurirati PHP kot hendler. Za podporo in dodatne vire je na voljo namensko področje na iis.net za PHP.

V splošnem poganjanje vaše aplikacije v različnih okoljih v razvoju ali produkciji lahko vodi do čudnih hroščev, ko naložite v živo. Če razvijate na Windows in nalagate na Linux (ali na karkoli, ki ni Windows), potem bi morali razmisliti o uporabi virtualne naprave.

Chris Tankersley ima zelo uporabno blog objavo, katera orodja uporablja za PHP razvoj z uporabo Windows-a.

Nazaj na vrh

Vodič kodnega stila

PHP skupnost je velika in raznolika ter sestavljena iz številnih knjižnic, ogrodij in komponent. Za PHP razvijalce je običajno, da izbirajo med mnogimi od le teh in jih kombinirajo v določenem projektu. Pomembno je, da se PHP koda oprijema (kolikor je le mogoče) skupnega stila kodiranja, saj omogoča za razvijalce enostavnejše mešanje in ujemanje različnih knjižnic za njihove projekte.

Framework Interop Group so predlagali in odobrili serijo stilskih priporočil. Vsa niso vezana na kodne stile, vendar tista ki so, so PSR-0, PSR-1, PSR-2 in PSR-4. Ta priporočila so samo skupek pravil, ki jih privzemajo mnogi projekti, kot so Drupal, Zend, Symfony, Laravel, CakePHP, phpBB, AWS SDK, FuelPHP, Lithium itd. Lahko jih uporabite v vaših projektih, ali nadaljujete z uporabo vaših osebnih stilov.

Idealno bi morali pisati PHP kodo, ki se oprijema znanih standardov. To je lahko kakršnakoli kombinacija PSR-jev, ali enega izmed kodnih standardov izdelanih s strani PEAR ali Zend. To pomeni, da ostali razvijalci lahko enostavno berejo in delajo z vašo kodo ter aplikacije, ki implementirajo komponente, imajo lahko konsistentnost celo, ko se uporablja veliko tretje osebne kode.

Lahko uporabite PHP_CodeSniffer, da preverite kodo proti katerimkoli izmed teh priporočil in vtičnike za tekstovne urejevalnike, kot je Sublime Text, ki nudi odziv v realnem času.

Postavitev kode lahko popravite avtomatično z uporabo enega izmed sledečih orodij:

In PHP_CodeSniffer lahko poženete ročno v terminalu:

phpcs -sw --standard=PSR2 file.php

Prikazal bo napake in opisal, kako jih popraviti. Lahko je tudi v pomoč pri vključevanju tega ukaza v git hook. Na ta način se vej, ki vsebujejo kršitve izbranega standards, ne more vnesti v repozitorij dokler se teh kršitev ne odpravi.

Če imate PHP_CodeSniffer, lahko sporočene težave postavitve kode avtomatsko popravite s PHP Code Beautifier and Fixer.

phpcbf -w --standard=PSR2 file.php

Druga opcija je uporaba orodja PHP Coding Standards Fixer. Prikazal bo, katere vrste napak je imela struktura kode pred popravki.

php-cs-fixer fix -v --level=psr2 file.php

Angleščina je priporočljiva za vsa imena simbolov in infrastruktur kode. Komentarji so lahko napisani v kateremkoli jeziku, ki ga lahko enostavno preberejo vse trenutne in bodoče strani, ki bodo delale s kodo.

Nazaj na vrh

Povzetek jezika

Programske paradigme

PHP je fleksibilen, dinamičen jezik, ki podpira celo vrsto programskih tehnik. Tekom let se je izjemno razvijal, še posebej z dodatkom objektno orientiranega modela v PHP 5.0 (2004), anonimnih funkcij in imenskih prostorov (namespaces) v PHP 5.3 (2009) ter t.i. traits-ov v PHP 5.4 (2012).

Objektno orientirano programiranje

PHP ima celoten nabor lastnosti objektnega programiranja, katere vključujejo podporo za razrede (classes), abstraktne razrede, vmesnike (interfaces), dedovanje, konstruktorje, kloniranje, izjeme in še več.

Funkcijsko programiranje

PHP podpira prvo razredne funkcije, kar pomeni, da je lahko funkcija dodeljena spremenljivki. Tako uporabniško definirane ali vgrajene funkcije se lahko sklicujejo na spremenljivko in se jih kliče dinamično. Funkcije se lahko podaja kot argumente drugim funkcijam (lastnost višji red - higher-order funkcije) in funkcije lahko vrnejo tudi drugo funkcije.

Rekurzija, lastnost, ki dovoljuje funkciji, da kliče samo sebe, je podprta v jeziku, vendar večina PHP kode se osredotoča na iteracije.

Nove anonimne funkcije (s podporo za zapiranje - closures) so prisotne od PHP 5.3 (2009).

PHP 5.4 je dodal zmožnost za vezavo zapiranj (bind closures) obsega objekta in tudi izboljšano podporo klicajočih, tako da so lahko uporabljene neodvisno z anonimnimi funkcijami v skoraj vseh primerih.

Meta programiranje

PHP podpira vrsto oblik meta programiranja skozi mehanizme kot so Reflection API in magične metode. Na voljo je veliko magičnih metod kot so __get(), __set(), __clone(), __toString(), __invoke() itd. Te omogočajo razvijalcem, da se povežejo v obnašanje razreda. Ruby razvijalci pogosto pravijo, da v PHP-ju manjka method_missing, vendar je na voljo kot __call() in __callStatic().

Imenski prostori - Namespaces

Kot zgoraj omenjeno, ima PHP skupnost veliko razvijalcev, ki ustvarijo ogromno kode. To pomeni, da določena PHP koda knjižnice lahko uporabi enako ime drugega razreda. Ko sta obe knjižnici uporabljeni v istem imenskem prostoru, lahko sovpadajo in povzročajo težave.

Imenski prostori rešujejo ta problem. Kot je opisano v PHP referenčnem priročniku, lahko primerjamo imenske prostore z direktoriji operacijskega sistema, ki poimenujejo prostor datotek; dve datoteki z enakim imenom lahko obstajata v različnih direktorijih. Enako lahko tudi dva PHP razreda z enakim imenom obstajata v različnih PHP imenskih prostorih. Tako enostavno je.

Pomembno je, da vašo kodo prostorsko poimenujete, da je lahko uporabljena s strani drugih razvijalcev brez strahu pred sovpadanjem z drugimi knjižnicami.

Ena izmed priporočenih poti za uporabo imenskih prostorov je poudarjena v PSR-4, ki cilja ponujati standardizirano konvencijo za datoteke, razrede in imenske prostore, da omogoča plug-in-play kodo.

V oktobru 2014 je PHP-FIG opustil prejšnji standard za avtomatsko nalaganje: PSR-0. Tako PSR-0 kot PSR-4 sta še vedno popolnoma uporabna. Slednji zahteva PHP 5.3, tako da mnogi PHP 5.2 projekti vsebujejo PSR-0.

Če nameravate uporabiti standard za avtomatsko nalaganje za novo aplikacijo ali paket, preverite PSR-4.

Standardna PHP knjižnica

Standardna PHP knjižnica (SPL - Standard PHP Library) je zapakirana v PHP in ponuja zbirko razredov in vmesnikov. Izdelana je primarno iz pogoste uporabe potrebnih podatkovno strukturiranih razredov (stack, queue, heap, itd.), in iteratorjev, ki lahko prečkajo te podatkovne strukture ali vaši lastni razredi implementirajo SPL vmesnike (interfaces).

CLI - vmesnik komandne vrstice

PHP je bil narejen za ustvarjanje spletnih aplikacij, vendar je tudi uporaben za skriptiranje programov vmesnika komandne vrstice (CLI - command line interface). PHP programi za ukazno vrstico lahko pomagajo avtomatizirati pogoste naloge, kot so testiranje, nalaganje in administriranje aplikacije.

CLI PHP programi so zmogljivi, ker lahko uporabite kodo vaše aplikacije direktno brez potrebe po ustvarjanju in zavarovanju spletnega GUI-ja zanjo. Bodite samo prepričani, da ne date vaše PHP CLI skripte v vaš javni spletni direktorij!

Poskusite pognati PHP iz komandne vrstice:

> php -i

Opcija -i bo izpisala vašo PHP konfiguracijo tako kot funkcija phpinfo().

Opcija -a ponuja interaktivno lupino, podobno kot Ruby-jev IRB ali Pythonova interaktivna lupina. Na voljo je še mnogo ostalih uporabnih opcij ukazne vrstice.

Napišimo preprost “Hello, $name” CLI program. Da ga preizkusite, ustvarite datoteko poimenovano hello.php, tako kot je prikazano spodaj.

<?php
if ($argc !== 2) {
    echo "Usage: php hello.php [name].\n";
    exit(1);
}
$name = $argv[1];
echo "Hello, $name\n";

PHP priredi dve posebni spremenljivki, ki temeljita na podanih argumentih pri pogonu vaše skripte. $argc je celo številska spremenljivka, ki vsebuje argument count, in $argv je spremenljivka tipa polje, ki vsebuje vrednost vsakega argumenta. Prvi argument je vedno ime vaše PHP skriptne datoteke, v tem primeru hello.php.

Izraz exit() je uporabljen s številko različno od nič, da omogoči lupini vedeti, da je ukaz spodletel. Pogosto uporabljene exit kode je moč najti tu.

Za pogon naše skripte zgoraj iz komandne vrstice:

> php hello.php
Usage: php hello.php [name]
> php hello.php world
Hello, world

Xdebug

Eno najuporabnejših orodij v razvijanju programske opreme je ustrezen iskalnik napak. Omogoča sledenje izvajanja vaše kode in nadzira vsebino skladovnice. Xdebug, PHP-jev iskalnik napak, je lahko izkoriščen s strani različnih IDE-jev, ki ponujajo prekinitvene točke in nadzor skladovnice. Lahko dovoli tudi orodjem kot sta PHPUnit in KCacheGrind, da izvedejo analizo pokritosti kode in profiliranje kode.

Če se vidite v taki navezavi, da se obračate k var_dump()/print_r() in še vedno ne najdete rešitve - morda potrebujete iskalnik napak.

Namestitev Xdebug-a je lahko zahtevna, vendar je ena izmed njegovih najpomembnejših lastnosti t.i. “Remote Debugging” oz. oddaljeno iskanje napak - če razvijate kodo lokalno in jo nato testirate znotraj virtualne naprave ali drugega strežnika, je “Remote Debugging” lastnost, ki jo želite omogočiti takoj.

Običajno boste spremenili vaš Apache VHost ali .htaccess datoteko s sledečimi vrednostmi:

php_value xdebug.remote_host 192.168.?.?
php_value xdebug.remote_port 9000

Lastnosti “remote host” in “remote port” bosta pripadali vašemu lokalnemu računalniku in nastavljenim vratom, ki jih posluša vaš IDE. Nato je samo še stvar nastavitve vašega IDE-ja, da “posluša” povezave in naloži URL:

http://your-website.example.com/index.php?XDEBUG_SESSION_START=1

Vaš IDE bo prestrezal trenutno stanje, ko se skripta izvaja, dovoljuje vam, da ustvarite prekinitvene točke in preveri vrednosti v spominu.

Grafični iskalniki napak omogočajo zelo enostavno prehajanje skozi kodo, preverjanje spremenljivk in ocenjujejo kodo napram živemu zagonu. Mnogi IDE-ji imajo vgrajeno ali na vtičniku osnovano podporo za grafično iskanje napak z Xdebug-om. MacGDBp je brezplačen, odprtokodni, samostojni Xdebug GUI za Mac-a.

Nazaj na vrh

Upravljanje odvisnosti

Na izbiro je ogromno PHP knjižnic, ogrodij in komponent. Vaš projekt bo najverjetneje uporabil več njih - to so t.i. projektne odvisnosti. Do pred kratkim, PHP ni imel dobrega načina za upravljanje teh projektnih odvisnosti. Tudi če ste jih upravljali ročno, ste morali še vedno skrbeti za avtomatske nalagalnike (autoloaders). To ni več težava.

Trenutno sta za PHP na voljo dva glavna paketna upravljalca - Composer in PEAR. Composer je trenutno najpopularnejši upravitelj paketov za PHP, vendar dolgo časa je bil v uporabi glavni upravitelj paketov PEAR. Poznavanje zgodovine PEAR je dobra ideja, saj še vedno najdete sklicevanje nanj, tudi če ga nikoli ne uporabljate.

Composer in Packagist

Composer je briljanten upravljalnik odvisnosti za PHP. Napišite vaše projektne odvisnosti v composer.json datoteko in z nekaj enostavnimi ukazi bo Composer avtomatsko prenesel odvisnosti za vaš projekt in nastavil avtomatsko nalaganje (autoloading) za vas. Composer je analogno NPM v svetu Node.js ali Bundler v Ruby svetu.

Na voljo je že ogromno PHP knjižnic, ki so kompatibilne s Composer-jem in pripravljene za uporabo v vašem projektu. Ti “paketi” so našteti na Packagist-u, uradnem repozitoriju za Composer-kompatibilne PHP knjižnice.

Kako namestiti Composer

Najbolj varen način za namestitev Composer-ja je slediti uradnim navodilom. To preveri, da namestitveni program ni pokvarjen ali ponarejen. Namestitveni program namesti Composer lokalno v vaš trenutni delovni direktorij.

Priporočamo ga namestiti globalno (npr. enojna kopija v /usr/local/bin) - da to naredite, za tem poženite:

mv composer.phar /usr/local/bin/composer

Opomba: Če zgornje ni uspešno zaradi pravic, poženite ponovno s sudo.

Da poženete lokalno nameščen Composer, bi uporabili php composer.phar, globalno pa je enostavno composer.

Namestitev na Windows

Za Windows uporabnike je najenostavnejši način za pričetek uporaba namestitvenega programa ComposerSetup, ki izvede globalno namestitev in nastavi vašo $PATH, da lahko samo pokličete composer iz kateregakoli direktorija v vaši ukazni vrstici.

Kako namestiti Composer (ročno)

Ročna namestitev Composer-ja je napredna tehnika, čeprav obstajajo različni razlogi, zakaj bi razvijalec raje uporabil sledečo metodo proti uporabi interaktivne namestitvene rutine. Interaktivna namestitev preveri vašo PHP namestitev za zagotovitev, da:

Ker ročna namestitev ne izvede nobenih od teh preverjanj, se morate odločiti ali je to ustrezno za vas. Tako je na voljo Composer tudi ročno:

curl -s https://getcomposer.org/composer.phar -o $HOME/local/bin/composer
chmod +x $HOME/local/bin/composer

Pot $HOME/local/bin (ali direktorij po vaši izbiri) bi moral biti v vaši potni $PATH spremenljivki okolja. To bo omogočilo izvajanje ukaza composer.

Ko v dokumentaciji naletite na ukaz, kot je npr. php composer.phar install, ga lahko zamenjate in poženete sledeče:

composer install

Ta sekcija predvideva, da ste namestili Composer globalno.

Kako definirati in namestiti odvisnosti

Composer beleži odvisnosti vašega projekta v datoteki imenovani composer.json. Če želite, jo lahko upravljate ročno, ali uporabite sam Composer. Ukaz composer require doda odvisnost projekta in če nimate composer.json datoteke, bo kreirana. Spodaj je primer, ki doda Twig kot odvisnost v vaš projekt.

composer require twig/twig:~1.8

Alternativno, ukaz composer init vas bo vodil skozi ustvarjanje celotne datoteke composer.json za vaš projekt. Bodisi, ko enkrat ustvarite vašo composer.json datoteko lahko poveste Composer-ju, da prenese in namesti vaše odvisnosti v vendor/ direktorij. To velja tudi za projekte, ki ste jih prenesli in že vsebujejo composer.json datoteko:

composer install

V nadaljevanju dodajte naslednjo vrstico v vašo glavno PHP datoteko aplikacije. To narekuje PHP-ju, da uporabi Composer-jev avtomatski nalagalnik (autoloader) za odvisnosti vašega projekta.

<?php
require 'vendor/autoload.php';

Sedaj lahko uporabite odvisnosti vašega projekta in bodo avtomatsko naložene na zahtevo.

Posodobitev vaših odvisnosti

Composer ustvari datoteko imenovano composer.lock, ki shrani točno verzijo za vsak paket, ki ga je prenesel, ko ste prvič pognali ukaz composer install. Če delite vaš projekt z drugimi, zagotovite, da je datoteka composer.lock vključena, tako da bodo ob ukazu composer install dobili enake verzije kot vi. Za posodobitev vaših odvisnosti poženite ukaz composer update. Ne uporabljajte composer update, ko nalagate aplikacijo na strežnik. Takrat poženite samo composer install, drugače boste lahko imeli drugačne verzije paketov v produkciji.

To je najbolj uporabno, ko definirate vaše verzije zahtev fleksibilno. Na primer zahtevana verzija ~1.8 pomeni “karkoli novejše od 1.8.0, vendar manj kot 2.0.x-dev”. Lahko uporabite tudi nadomestni znak * kot pri 1.8.*. Sedaj bo Composer ukaz php composer.phar update nadgradil vse vaše odvisnosti na najnovejše verzije, ki ustrezajo omejitvam, ki ste jih definirali.

Obvestila posodobitev

Da dobite obvestila o novih verzijah izdaj se lahko naročite na VersionEye, spletno storitev, ki nadzira vaše GitHub in BitBucket račune za composer.json datotekami in pošilja e-pošto z novimi izdajami paketov.

Preverjanje vaših odvisnosti za varnostnimi težavami

Security Advisories Checker je spletni servis in orodje za ukazno vrstico (CLI), ki bo tako preučil vašo datoteko composer.lock kot vam tudi povedal, če potrebujete kakšne posodobitve za vaše odvisnosti.

Upravljanje globalnih odvisnosti s Composer-jem

Composer lahko tudi upravlja globalne odvisnosti in njihove zagonske datoteke. Uporaba je enostavna, vse kar morate narediti je, da dodate predpono global vašim ukazom. Če na primer želite namestiti PHPUnit in ga imeti na voljo globalno, poženite sledeči ukaz:

composer global require phpunit/phpunit

To bo ustvarilo mapo ~/.composer, kjer bodo domovale vaše globalne odvisnosti. Da imate nameščene paketne zagonske datoteke in na voljo kjerkoli, bi potem dodali ~/.composer/vendor/bin k vaši spremenljivki $PATH.

PEAR

Veteranski upravljalnik paketov, ki ga imajo radi nekateri PHP razvijalci, je PEAR. Obnaša se podobno kot Composer, vendar ima nekatere opazne razlike.

PEAR zahteva, da ima vsak paket specifično strukturo, kar pomeni, da mora avtor pripraviti paket za uporabo s PEAR. Uporaba projekta, ki ni bil pripravljen za delo s PEARi, ni možna.

PEAR namesti pakete globalno, kar pomeni, da so po prvi namestitvi na voljo za vse projekte na tem strežniku. To je lahko uporabno, če se veliko projektov zanaša na enak paket z enako verzijo, vendar lahko vodi do problemov, če se verzije med dvema projektoma ne ujemata.

Kako namestiti PEAR

PEAR lahko namestite s prenosom .phar namestitvenega programa in ga poženete. PEAR dokumentacija ima podrobna navodila namestitve za vsak operacijski sistem.

Če uporabljate Linux, lahko tudi pogledate vaš distribucijski upravljalnik paketov. Debian in Ubuntu na primer, imata apt php-pear paket.

Kako namestiti paket

Če je paket napisan na PEAR seznamu paketov, ga lahko namestite z določitvijo uradnega imena:

pear install foo

Če paket gostuje na drugem kanalu, morate najprej odkriti (discover) kanal in ga nato določiti pri namestitvi. Poglejte dokumentacijo uporabe kanalov za več informacij na to temo.

Ravnanje s PEAR odvisnostmi s Composer-jem

Če že uporabljate Composer in lahko prav tako namestite nekatero PEAR kodo, lahko uporabite Composer za ravnanje z vašimi PEAR odvisnostmi. Ta primer bo namestil kodo iz pear2.php.net:

{
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear2.php.net"
        }
    ],
    "require": {
        "pear-pear2/PEAR2_Text_Markdown": "*",
        "pear-pear2/PEAR2_HTTP_Request": "*"
    }
}

Prva sekcija "repositories" bo uporabljena, da Composer-ju da vedeti, da mora inicializirati (ali odkriti - “discover” v terminologiji PEAR-a) PEAR repozitorij. Nato bo require sekcija naredila predpone paketom sledeče:

pear-channel/Package

Predpona “pear” je zakodirana, da ne prihaja do konfliktov, saj je PEAR kanal lahko enak kot drugo ime izdelovalca paketov na primer. Takrat je lahko uporabljeno kratko ime kanala (oz. celotni URL) za referenco na katerem kanalu je paket.

Ko je ta koda nameščena, bo na voljo v vašem direktoriju izdelovalcev (vendor) in bo avtomatsko na voljo skozi Composer-jev avtomatski nalagalnik (autoloader).

vendor/pear-pear2.php.net/PEAR2_HTTP_Request/pear2/HTTP/Request.php

Za uporabo tega PEAR paketa se nanj enostavno sklicujete takole:

<?php
$request = new pear2\HTTP\Request();

Nazaj na vrh

Kodne prakse

Osnove

PHP je širok jezik, ki dovoljuje razvijalcem vseh nivojev zmožnost, da sproducirajo kodo ne samo hitro, vendar tudi efektivno. Vendar kljub napredku skozi jezik, pogostokrat pozabimo osnove, ki se jih naučimo na začetku (ali jih spregledamo) zaradi hitrih izrezov in/ali slabih navad. Za pomoč proti tej običajni problematiki ta sekcija cilja k opominjanju razvijalcev o osnovnih kodnih praksah znotraj PHP-ja.

Datum in čas

PHP ima razred DateTime, ki pomaga, ko berete, pišete, primerjate ali računate z datumi in časi. V PHP-ju je na voljo mnogo funkcij, ki se nanašajo na datum in čas poleg DateTime razreda, vendar le-ta ponuja ličen objektno orientiran vmesnik za večino najpogostejših primerov uporabe. Omogoča ravnanje s časovnimi območji, vendar to je izven te kratke predstavitve.

Za pričetek dela z DateTime, pretvorimo izvorni niz datuma in časa v objekt s tovarniško metodo createFromFormat(), ali pa uporabimo new DateTime, da dobimo trenutno datum in čas. Uporabite metodo format() za pretvorbo DateTime nazaj v niz za izpis.

<?php
$raw = '22. 11. 1968';
$start = DateTime::createFromFormat('d. m. Y', $raw);

echo 'Start date: ' . $start->format('Y-m-d') . "\n";

Računanje z DateTime je možno s pomočjo razreda DateInterval. DateTime ima metode, kot so add() in sub(), ki sprejmejo DateInterval kot argument. Ne pišite kode, ki pričakuje enako število sekund v vsakem dnevu, saj bosta tako poletni čas in spreminjanje časovnih območij pokvarila to predpostavko. Namesto tega uporabite intervale datumov. Za izračun sprememb datuma uporabite metodo diff(). Vrnila bo nov DateInterval, ki je izjemno enostaven za prikaz.

<?php
// create a copy of $start and add one month and 6 days
$end = clone $start;
$end->add(new DateInterval('P1M6D'));

$diff = $end->diff($start);
echo 'Difference: ' . $diff->format('%m month, %d days (total: %a days)') . "\n";
// Difference: 1 month, 6 days (total: 37 days)

Na DateTime objektih lahko uporabite standardne primerjave:

<?php
if ($start < $end) {
    echo "Start is before end!\n";
}

Zadnji primer demonstrira razred DatePeriod. Uporabljen je za iteracijo nad ponavljajočimi se dogodki. Vzame lahko dva DateTime objekta, začetek in konec ter interval za katerega vrne vse vmesne dogodke.

<?php
// output all thursdays between $start and $end
$periodInterval = DateInterval::createFromDateString('first thursday');
$periodIterator = new DatePeriod($start, $periodInterval, $end, \DatePeriod::EXCLUDE_START_DATE);
foreach ($periodIterator as $date) {
    // output each date in the period
    echo $date->format('Y-m-d') . ' ';
}

Popularna PHP API razširitev je Carbon. Podeduje vse iz razreda DateTime, tako da vključuje minimalno število sprememb kode, dodatne lastnosti pa vključujejo podporo za lokalizacijo, nadaljnje načine za dodajanje, odštevanje in oblikovanje objekta DateTime ter sredstva za testiranje vaše kode s simuliranjem datuma in časa po izbiri.

Načrtovalski vzorci

Ko gradite vašo aplikacijo, je v pomoč uporabiti pogoste vzorce v vaši kodi in pogoste vzorce za celotno strukturo vašega projekta. Uporaba pogostih vzorcev je v pomoč, ker poenostavi upravljanje vaše kode in omogoča ostalim razvijalcem hitro razumeti, kako se vse skupaj ujema.

Če uporabljate ogrodje, potem bo največ najvišje nivojske kode in projektne strukture osnovane na tem ogrodju, tako da veliko izbir vzorcev je že urejenih namesto vas. Vendar je še vedno na vas, da izberete najboljše vzorce, ki jim boste sledili v kodi, ki jo gradite na osnovi ogrodja. Po drugi strani, če ne uporabljate ogrodja za grajenje vaše aplikacije, potem morate najti vzorce, ki najbolje zadostijo tipu in velikosti aplikacije, ki jo gradite.

Delo z UTF-8

To sekcijo je prvotno napisal Alex Cabal na PHP Best Practices in je uporabljena kot osnova za naš lasten UTF-8 nasvet.

Tu ni ene vrstice. Bodite previdni, pozorni na podrobnosti in skladni.

Trenutno PHP ne podpira Unicode na nižjem nivoju. Obstajajo načini za zagotovitev, da so UTF-8 nizi v redu procesirani, vendar ni enostavno in zahteva posvečanje na skoraj vseh nivojih spletne aplikacije, od HTML do SQL do PHP. Ciljali bomo na kratek, praktičen povzetek.

UTF-8 na PHP nivoju

Osnovne operacije nizov, kot sta združevanje dveh nizov in dodeljevanje nizov spremenljivkam, ne potrebujejo ničesar, posebnega za UTF-8. Vendar večina funkcij nizov, kot sta strpos() in strlen(), ne potrebujeta posebnih premislekov. Te funkcije imajo pogosto mb_* nadomestke: na primer mb_strpos() in mb_strlen(). Ti mb_* nizi so na voljo za vas preko razširitve multibyte niza in so posebej načrtovane za operiranje na Unicode nizih.

Uporabljati morate mb_* funkcije kadarkoli izvajate operacije na Unicode nizih. Na primer, če uporabljate substr() na UTF-8 nizu, je precejšnja verjetnost, da bo rezultat vključeval popačene polovične znake. Pravilna funkcija za uporabo bi bila večbajtni nadomestek, mb_substr().

Težji del si je zapomniti uporabo mb_* funkcij v vseh primerih. Če samo enkrat pozabite, bo vaš Unicode niz zelo verjetno popačen med naslednjim procesiranjem.

Ne vse funkcije nizov imajo mb_* nadomestek. Če določene ni na voljo, za kar želite narediti, potem lahko nimate sreče.

Uporabljati bi morali mb_internal_encoding() funkcijo na vrhu vsake PHP skripte, ki jo napišete (ali na vrhu vaše globalne include skripte), in mb_http_output() funkcijo ravno za njo, če vaša skripta izpisuje brskalniku. Izrecno definiranje kodiranja vašega niza v vsaki skripti vam bo prihranilo veliko glavobolov tekom poti.

Dodatno mnogo PHP funkcij, ki operirajo na nizih imajo opcijske parametre, ki vam omogočajo specifikacijo kodiranja znakov. Vedno bi morali eksplicitno navesti UTF-8, ko imate možnost. Na primer, htmlentites() ima opcijo za kodiranje znakov in bi morali vedno določiti UTF-8, če imate opravka s takimi nizi. Bodite pozorni, da od PHP 5.4.0 je UTF-8 privzeto kodiranje za htmlentities() in htmlspecialchars().

Končno, če gradite distribuirano aplikacijo in ne morete biti prepričani, da bo razširitev mbstring omogočena, potem premislite o uporabi patchwork/utf8 Composer paketa. Ta bo uporabil mbstring, če je na voljo in se vrnil na ne UTF-8 funkcije, če ni.

UTF-8 na nivoju podatkovne baze

Če vaša PHP skripta dostopa do MySQL-a, obstaja verjetnost, da so vaši nizi shranjeni kot ne-UTF-8 nizi v podatkovni bazi, tudi če sledite vsem varnostnim ukrepom zgoraj.

Da zagotovite, da gredo vaši nizi iz PHP-ja v MySQL kot UTF-8, zagotovite, da so vaša podatkovna baza in tabele vse nastavljene na utf8mb4 set znakov in kolacijo in da uporabljate utf8mb4 sete znakov v nizu povezave PDO. Glejte primer kode spodaj. To je kritično pomembno.

Pomnite, da morate uporabiti utf8mb4 set znakov za celotno UTF-8 podporo in ne utf8 seta znakov! Glejte nadaljnje branje spodaj zakaj.

UTF-8 na nivoju brskalnika

Uporabite mb_http_output() funkcijo za zagotovitev, da vaša PHP skripta izpisuje UTF-8 nize v vaš brskalnik. Brskalniku bo nato povedano s strani odziva HTTP, da ta stran bi morala biti smatrana kot UTF-8. Zgodovinski pristop za to je bil vključit charset <meta> značko v značko <head> vaše strani. Ta pristop je povsem veljaven, vendar nastavitev charset-a v Content-Type glavi je dejansko veliko hitrejši.

<?php
// Tell PHP that we're using UTF-8 strings until the end of the script
mb_internal_encoding('UTF-8');

// Tell PHP that we'll be outputting UTF-8 to the browser
mb_http_output('UTF-8');

// Our UTF-8 test string
$string = 'Êl síla erin lû e-govaned vîn.';

// Transform the string in some way with a multibyte function
// Note how we cut the string at a non-Ascii character for demonstration purposes
$string = mb_substr($string, 0, 15);

// Connect to a database to store the transformed string
// See the PDO example in this document for more information
// Note the `charset=utf8mb4` v DSN (Data Source Name)
$link = new PDO(
    'mysql:host=your-hostname;dbname=your-db;charset=utf8mb4',
    'your-username',
    'your-password',
    array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_PERSISTENT => false
    )
);

// Store our transformed string as UTF-8 in our database
// Your DB and tables are in the utf8mb4 character set and collation, right?
$handle = $link->prepare('insert into ElvishSentences (Id, Body) values (?, ?)');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->bindValue(2, $string);
$handle->execute();

// Retrieve the string we just stored to prove it was stored correctly
$handle = $link->prepare('select * from ElvishSentences where Id = ?');
$handle->bindValue(1, 1, PDO::PARAM_INT);
$handle->execute();

// Store the result into an object that we'll output later in our HTML
$result = $handle->fetchAll(\PDO::FETCH_OBJ);

header('Content-Type: text/html; charset=UTF-8');
?><!doctype html>
<html>
    <head>
        <title>UTF-8 test page</title>
    </head>
    <body>
        <?php
        foreach($result as $row){
            print($row->Body);  // This should correctly output our transformed UTF-8 string to the browser
        }
        ?>
    </body>
</html>

Nadaljnje branje

Nazaj na vrh

Injiciranje odvisnosti

Iz Wikipedije:

Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time.

Ta citat naredi koncept veliko bolj zapleten, kot dejansko je. Injiciranje odvisnosti ponuja komponento z njenimi odvisnostmi ali skozi konstruktorjevo injiciranje, klic metode ali nastavitvijo lastnosti. Tako enostavno je.

Osnovni koncept

Koncept lahko demonstriramo z enostavnim in naivnim primerom.

Imamo razred Database, ki zahteva, da adapter komunicira s podatkovno bazo. Instanco adapterja naredimo v konstruktorju in izdelamo zahtevno odvisnost. To naredi testiranje težko in pomeni, da je razred Database zelo tesno povezan v adapter.

<?php
namespace Database;

class Database
{
    protected $adapter;

    public function __construct()
    {
        $this->adapter = new MySqlAdapter;
    }
}

class MysqlAdapter {}

To kodo je mogoče refaktorirati, da uporablja injiciranje odvisnosti in zato naredi odvisnost ohlapnejšo.

<?php
namespace Database;

class Database
{
    protected $adapter;

    public function __construct(MySqlAdapter $adapter)
    {
        $this->adapter = $adapter;
    }
}

class MysqlAdapter {}

Sedaj dajemo razredu Database njegovo odvisnost namesto, da jo naredi sam. Lahko naredimo celo metodo, ki bi sprejela argument odvisnosti in ga nastavila na ta način, ali če bi bila lastnost $adapter public, bi ga lahko nastavili direktno.

Kompleksni problem

Če ste kdarkoli brali o injiciranju odvisnosti, potem ste verjeno videli termine “Inversion of Control” ali “Dependency Inversion Principle”. To so kompleksni problemi, ki jih injiciranje odvisnosti rešuje.

Inverzija kontrole

Inverzija kontrole je, kot pove, “obračanje kontrole” sistema z obdržanjem organizacijske kontrole v celoti ločene od naših objektov. V terminih injiciranja odvisnosti to pomeni rahljanje naših odvisnosti s kontroliranjem in njihovo instantizacijo drugje v sistemu.

Že leta so PHP ogrodja dosegala inverzijo kontrole, vendar vprašanje je postalo, kateri del kontrole obračate in kam? Na primer, MVC ogrodja bi običajno podala super objekt ali osnovni krmilnik, ki ga morajo ostali krmilniki razširiti, da pridobijo dostop do svojih odvisnosti. To je inverzija kontrole, čeprav namesto rahljanja odvisnosti, jih ta metoda enostavno premakne.

Injiciranje odvisnosti nam omogoča bolj elegantno rešiti ta problem s samo injiciranjem odvisnosti, ki jih potrebujemo, ko jih potrebujemo, brez potrebe za kakršnekoli vkodirane odvisnosti.

Princip inverzije odvisnosti

Princip inverzije odvisnosti (dependency Injection Principle) je “D” v S.O.L.I.D. skupku objekta orientiranih načrtovalskih principov, ki pravijo, da bi moralo biti “odvisno od abstrakcije. Ne zanašano na konkretizacijo.” Dano enostavno to pomeni, da naše odvisnosti bi morale biti vmesniki/vezave ali abstraktni razredi namesto konkretne implementacije. Lahko enostavno refkatoriramo zgornji primer, da sledi temu principu.

<?php
namespace Database;

class Database
{
    protected $adapter;

    public function __construct(AdapterInterface $adapter)
    {
        $this->adapter = $adapter;
    }
}

interface AdapterInterface {}

class MysqlAdapter implements AdapterInterface {}

Na voljo je nekaj koristi od razreda Database, ki je sedaj odvisen od vmesnika namesto od konkretizacije.

Zamislite si, da delate v ekipi in na adapterju dela kolega. V našem prvem primeru, bi morali čakati omenjenega kolega, da konča adapter preden ga lahko ustrezno preizkusimo za naše teste enot. Sedaj, ko je odvisnost vmesnik/vezava lahko veselo preizkusimo ta vmesnik in vemo, da bo naš kolega zgradil adapter na osnovi te vezave.

Še večja korist te metode je, da je sedaj naša koda bolj skalabilna. Če se leto dni kasneje odličimo, da se želimo preseliti na drug tip podatkovne baze, lahko napišemo adapter, ki implementira originalni vmesnik in namesto tega to injicira, nič več refaktoringa ne bi bilo potrebnega, saj lahko zagotovimo, da adapter sledi vezavi nastavljeni s strani vmesnika.

Kontejnerji

Prva stvar, ki bi jo morali razumeti o kontejnerjih injiciranja odvisnosti je, da niso enaka stvar kot injiciranje odvisnosti. Kontejner je pomožna prikladnost, ki nam pomaga implementirati injiciranje odvisnosti, vendar so lahko pogostokrat napačno uporabljeni, da implementirajo anti-vzorec, storitveno lokacijo. Injiciranje DI (dependency injection) kontejnerja kot storitvena lokacija v naših razredih verjetno naredi težje odvisnosti na kontejnerju kot odvisnost, ki jo zamenjujete. Tudi naredi kodo veliko bolj transparentno in konec koncev težjo za testiranje.

Veliko modernih ogrodij ima svoje lastne kontejnerje injiciranja odvisnosti, ki vam omogočajo povezati odvisnosti skupaj skozi nastavitve. Kaj to pomeni v praksi, je, da lahko pišete kodo aplikacije, ki je čista in ločena kot ogrodje na katerem je zgrajena.

Nadaljnje branje

Nazaj na vrh

Podatkovne baze

Mnogokrat bo vaša PHP koda uporabila podatkovno bazo za pridobivanje informacij. Na voljo imate nekaj opcij za povezavo in interakcijo z vašo podatkovno bazo. Priporočena opcija do PHP 5.1.0 je bila uporaba originalnih gonilnikov kot so mysqli, pgsql, mssql itd.

Originalni gonilniki so odlični, če uporabljate samo eno podatkovno bazo v vaši aplikaciji, vendar če na primer uporabljate MySQL in nekaj MSSQL hkrati, ali se potrebujete povezati na Oracle podatkovno bazo, potem ne boste mogli uporabiti istih gonilnikov. Naučiti se boste morali popolnoma nov API za vsako podatkovno bazo — in to lahko postane neumno.

Razširitev MySQL

Razširitev mysql za PHP je izjemno stara in je bila nadomeščena z dvema drugima razširitvima:

Ne samo, da se je razvoj na mysql ustavil dolgo nazaj, razširitev je opuščena od PHP 5.5.0 in je uradno odstranjena v PHP 7.0.

Da si prihranite čas s poglabljanjem v vaše nastavitve php.ini, da vidite, katere module uporabljate, je ena opcija za iskanje mysql_* v vašem priljubljenem urejevalniku. Če se pojavi katerakoli izmed funkcij, kot je mysql_connect in mysql_query, potem je v uporabi mysql.

Tudi če še ne uporabljate PHP 7.0, izpustitev te nadgradnje kakor hitro je mogoče, bo vodilo k še večjim težavam, ko boste prišli do nadgradnje PHP 7.0. Najboljša opcija je zamenjati uporabo mysql z mysqli ali PDO v vaši aplikacijah znotraj vašega razvojnega razporeda, tako da se vam ne bo kasneje mudilo.

Če nadgrajujete iz mysql k mysqli, bodite pozorni o lenobnih vodičih nadgradnje, ki enostavno predlagajo najti in zamenjati mysql_* z mysqli_*. Ne samo, da je to prevelika posplošitev, pozablja tudi prednosti, ki jih mysqli ponuja, kot je vezava parametrov, ki je ponujena tudi v PDO.

Razširitev PDO

PDO je abstraktna knjižnica povezovanja podatkovne baze — vgrajen v PHP od 5.1.0 —, ki ponuja enoten vmesnik za komunikacijo z mnogimi različnimi podatkovnimi bazami. Na primer lahko uporabite v osnovi identično kodo za vmesnik z MySQL ali SQLite:

<?php
// PDO + MySQL
$pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password');
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);

// PDO + SQLite
$pdo = new PDO('sqlite:/path/db/foo.sqlite');
$statement = $pdo->query("SELECT some_field FROM some_table");
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo htmlentities($row['some_field']);

PDO ne bo prevajal vaših SQL poizvedb ali emuliral manjkajočih lastnosti. Je izključno za povezovanje večih tipov podatkovnih baz z istim API-jem.

Bolj pomembno, PDO vam dovoljuje varno vstavljanje tujih vhodov (npr. ID-ji) v vaše SQL poizvedbe brez skrbi pred podatkovno baznimi SQL vstavljenimi napadi. To je mogoče z uporabo PDO stavkov in vezanih parametrov.

Predpostavimo, da PHP skripa dobi numeričen ID, kot parameter poizvedbe. Ta ID bi moral biti uporabljen za pridobitev zapisa iz baze. To je napačen način:

<?php
$pdo = new PDO('sqlite:/path/db/users.db');
$pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO!

To je grozna koda. Vstavljate izvorni parameter poizvedbe v SQL poizvedbo. Tako dopustite možen izjemno hiter napad z uporabo prakse imenovane SQL injiciranje. Samo predstavljajte si, če bi napadalec poslal sledeči iznajdljivi id parameter s klicom preko URL-ja kot je http://domain.com/?id=1%3BDELETE+FROM+users. To bo nastavil $_GET['id'] spremenljivko na 1;DELETE FROM users kar bo izbrisalo vse vaše uporabnike! Namesto tega bi morali očistiti ID vnos z uporabo PDO veznih parametrov.

<?php
$pdo = new PDO('sqlite:/path/db/users.db');
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT); // <-- filter your data first (see [Data Filtering](#data_filtering)), especially important for INSERT, UPDATE, etc.
$stmt->bindParam(':id', $id, PDO::PARAM_INT); // <-- Automatically sanitized for SQL by PDO
$stmt->execute();

To je pravilna koda. Uporablja vezni parameter na PDO stavku. To počisti tuj vnosni ID preden se ga predstavi podatkovni bazi, kar preprečuje potencialne SQL vstavljene napade.

Za pisanja, kot sta INSERT ali UPDATE, je poseben kritično, da še vedno najprej filtrirate vaše podatke in jih počistite za drugimi stvarmi (odstranitev HTML značk, JavaScript-a itd.). PDO ga bo samo počistil za SQL, vendar ne pa za vašo aplikacijo.

Morate se tudi zavedati, da povezave podatkovne baze uporabljajo vire in se je že pogosto zgodilo, da so bili vsi viri zasedeni, če povezave niso bile implicitno zaprte, čeprav je to bolj običajno v drugih jezikih. Z uporabo PDO, lahko implicitno zaprete vaše povezave z uničenjem objekta in zagotovite, da so vse preostale reference nanj izbrisane, t.j. nastavljene na NULL. Če ne naredite tega eksplicitno, bo PHP avtomatsko zaprl povezavo, ko se skripta konča - razen seveda, če uporabljate trajne povezave.

Interakcija s podatkovnimi bazami

Ko se razvijalci prvič pričnejo učiti PHP, pogosto končajo z mešanjem njihovih interakcij s podatkovnimi bazami z njihovo predstavitveno logiko, z uporabo kode, ki izgleda nekako tako:

<ul>
<?php
foreach ($db->query('SELECT * FROM table') as $row) {
    echo "<li>".$row['field1']." - ".$row['field1']."</li>";
}
?>
</ul>

To je slaba praksa zaradi vseh vrst razlogov, v glavnem ker je težko razhroščevati, težko testirati, težko brati in izpisalo bo veliko polj, če tam ne postavite omejitve.

Medtem ko obstoja veliko ostalih rešitev za to - odvisno od tega, če imate raje OOP ali funkcijsko programiranje - mora biti nek element ločitve.

Premislite o najbolj osnovnem koraku:

<?php
function getAllFoos($db) {
    return $db->query('SELECT * FROM table');
}

foreach (getAllFoos($db) as $row) {
    echo "<li>".$row['field1']." - ".$row['field1']."</li>"; // BAD!!
}

To je dober začetek. Dajte ta dva elementa v dve različni datoteki in imate nekoliko čisto ločitev.

Izdelajte razred, kamor date to metodo in imate “Model”. Izdelajte enostavno .php datoteko, kamor date predstavitveno logiko in imate “View”, kar je zelo blizu MVC - skupni OOP arhitekturi za večino ogrodij.

foo.php

<?php
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');

// Make your model available
include 'models/FooModel.php';

// Create an instance
$fooModel = new FooModel($db);
// Get the list of Foos
$fooList = $fooModel->getAllFoos();

// Show the view
include 'views/foo-list.php';

models/FooModel.php

<?php
class FooModel
{
    protected $db;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    public function getAllFoos() {
        return $this->db->query('SELECT * FROM table');
    }
}

views/foo-list.php

<?php foreach ($fooList as $row): ?>
    <?= $row['field1'] ?> - <?= $row['field1'] ?>
<?php endforeach ?>

To je v bistvu enako, kar počne večina modernih ogrodij, vse to bolj ročno. Lahko ne boste potrebovali narediti vsega tega vsakokrat, vendar mešanje skupaj preveč predstavitvene logike in interakcij s podatkovno bazo je lahko pravi problem, če kadarkoli želite narediti teste enot za vašo aplikacijo.

PHPBridge ima odličen vir imenovan Izdelava podatkovnega razreda - Data Class, ki pokriva precej podobno temo in je odličen za razvijalce, ki so se ravnokar navadili na koncept interakcije s podatkovno bazo.

Plasti abstrakcije

Mnoga ogrodja ponujajo svojo lastno plast abstrakcije, ki lahko ali pa ne sedi na vrhu PDO. Te bodo pogosto posnemale lastnosti za sistem ene podatkovne baze, ki manjka iz druge z ovitjem poizvedb v PHP metodah, kar vam da dejansko abstrakcijo podatkovne baze namesto samo abstrakcije povezave, ki jo PDO ponuja.

To bo seveda dodalo nekaj prekomernosti, vendar če gradite prenosno aplikacijo, ki potrebuje delovati z MySQL, PostgreSQL in SQLite, potem bo nekaj prekomernosti vredno zaradi čistosti kode.

Nekatere plasti abstrakcije so bile zgrajene z uporabo PSR-0 ali PSR-4 standardov imenskih prostorov, tako da se jih lahko namesti v katerokoli aplikacijo, ki želite:

Nazaj na vrh

Predloge

Predloge ponujajo priročen način ločitve logike vašega krmilnika in domene iz vaše logike prezentacije. Predloge običajno vsebujejo HTML vaše aplikacije, vendar so lahko uporabljene tudi za ostale oblike kot je XML. Na predloge se pogosto sklicuje kot “pogledi”, ki naredijo del druge komponente model–view–controller (MVC) vzorca arhitekture programske opreme.

Koristi

Glavna korist uporabe predlog je jasna ločitev, ki jo naredijo med logiko predstavitve in ostalo vašo aplikacijo. Predloge imajo izključno odgovornost prikaza vsebine oblike. Niso odgovorne za iskanje podatkov, pridobivanje in ostala bolj kompleksna opravila. To vodi v čistejšo bolj bralno kodo, ki je posebej priročna v okolju ekip, kjer razvijalci delajo na kodi strežniške strani (krmilniki, modeli) in oblikvalci delajo na kodi klientne strani (oblikovanje).

Predloge tudi izboljšajo organizacijo kode predstavitve. Predloge so običajno postavljene v folder “views”, vsaka definirana znotraj ene datoteke. Ta pristop spodbuja ponovno uporabo kode, kjer so večji bloki kode razbiti v manjše ponovno uporabne dele, pogosto imenovani partials - deli. Na primer, glava in noga vaše strani sta lahko definirani vsaka kot predloga, ki je nato vključena pred in za vsako predlogo strani.

Končno, odvisno od knjižnice, ki jo uporabljate, predloge lahko ponujajo več varnosti z avtomatičnim čiščenjem uporabniško generirane vsebine. Nekatere knjižnice celo ponujajo peskovnik, kjer oblikovalci predlog dobijo samo dostop do dovoljenega seznama spremenljivk in funkcij.

Osnovne PHP predloge

Osnovne PHP predloge so enostavno predloge, ki uporabljajo prvotno PHP kodo. So naravna izbira, ker je PHP dejansko jezik predlog sam po sebi. To enostavno pomeni, da lahko kombinirate PHP kodo znotraj druge kode, kot je HTML. To je koristno za PHP razvijalce, saj ni nobene nove sintakse za naučiti, poznajo funkcije, ki so jim na voljo in njihovi urejevalniki kode že imajo vgrajeno označevanje sintakse PHP in avtomatsko zaključevanje. Dalje, osnovne PHP predloge se nagibajo, da so kakor hitre možno, saj ni potrebne nobene faze prevajanja.

Vsako moderno PHP ogrodje vključuje neko vrsto sistema predlog, večina od teh uporabljajo privzeto osnovni PHP. Zunaj ogrodij, knjižnice kot je Plates ali Aura.View delujejo z osnovnimi PHP predlogami enostavnejše s ponujanjem moderne funkcionalnosti predlog, kot je dedovanje, postavitve in razširitve.

Enostaven primer osnovne PHP predloge

Uporaba knjižnice Plates:

<?php // user_profile.php ?>

<?php $this->insert('header', ['title' => 'User Profile']) ?>

<h1>User Profile</h1>
<p>Hello, <?=$this->escape($name)?></p>

<?php $this->insert('footer'i) ?>

Primer osnovne PHP predloge z uporabo dedovanja

Uporaba knjižnice Plates.

<?php // template.php ?>

<html>
<head>
    <title><?=$title?></title>
</head>
<body>

<main>
    <?=$this->section('content')?>
</main>

</body>
</html>
<?php // user_profile.php ?>

<?php $this->layout('template', ['title' => 'User Profile']) ?>

<h1>User Profile</h1>
<p>Hello, <?=$this->escape($name)?></p>

Prevedene predloge

Medtem ko se je PHP razvil v zrel, objektno orientiran jezik, se ni veliko izboljšal kot jezik predlog. Prevedene predloge, kot so Twig, Brainy, ali Smarty*, zapolnjujejo to praznino s ponujanjem nove sintakse, ki je bila sestavljena posebej za predloge. Od avtomatskega čiščenja, do dedovanja in poenostavljenih krmilnih struktur, so prevedene predloge načrtovane za enostavnejše pisanje, čistejše branje in varnejše za uporabo. Prevedene predloge so lahko celo deljene med različnimi jeziki, Mustache je dober primer tega. Ker morajo biti te predloge prevedene, prihaja do manjšega udarca na zmogljivost, vendar je ta zelo minimalen, ko je uporabljeno ustrezno predpomnjenje.

*Medtem ko Smarty ponuja avtomatsko čiščenje, ta lastnosti NI omogočena privzeto.

Enostaven primer prevedene predloge

Uporaba knjižnice Twig.

{% include 'header.html' with {'title': 'User Profile'} %}

<h1>User Profile</h1>
<p>Hello, {{ name }}</p>

{% include 'footer.html' %}

Primer prevedenih predlog z uporabo dedovanja

Uporaba knjižnice Twig.

// template.html

<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>

<main>
    {% block content %}{% endblock %}
</main>

</body>
</html>
// user_profile.html

{% extends "template.html" %}

{% block title %}User Profile{% endblock %}
{% block content %}
    <h1>User Profile</h1>
    <p>Hello, {{ name }}</p>
{% endblock %}

Nadaljnje branje

Članki in vodiči

Knjižnice

Nazaj na vrh

Napake in izjeme

Napake

V mnogih “polnih izjem” programskih jezikov, kadarkoli gre kaj narobe bo vržena izjema. To je zagotovo izvedljiv način za urejanje stvari, vendar PHP je jezik, ki ni poln izjem. Medtem ko ima izjeme in več jedra jih pričenja uporabljati, ko se dela za objekti, bo večina samega PHP-ja poskušala nadaljevati s pocesiranjem ne glede na to kaj se zgodi, razen v primeru usodnih napak.

Na primer:

$ php -a
php > echo $foo;
Notice: Undefined variable: foo in php shell code on line 1

To je samo napaka z obvestilom in PHP se bo veselo poganjal napej. To je lahko zmedeno za tiste, ki prihajajo iz jezikov polnih izjem, ker sklicevanje na manjkajoče spremenljivke v Python-u na primer bo vrglo izjemo:

$ python
>>> print foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

Edina prava razlika je, da bo Python ponorel ob vsaki manjši stvari, da so lahko razvijalci prepričani, da katerakoli potencialna težava ali če je ujet redek primer, kjer bo pa PHP nadaljeval s procesiranjem razen, če se zgodi kaj ekstremnega, na kateri točki bo vrglo napako in se o njej poročalo.

Resnost napake

PHP ima nekaj nivojev resnosti napak. Tri najbolj pogosti tipi sporočil so napake, obvestila in opozorila. Ta imajo različne nivoje resnosti; E_ERROR, E_NOTICE in E_WARNING. Napake so usodne napake pri poganjanju in so običajno povzročene zaradi napak v vaši kodi in jih je potrebno popraviti saj bodo povzročile, da se PHP ne bo več poganjal. Obvestila so svetovalna sporočila povzročena s strani kode, ki lahko ali pa ne povzročajo probleme med izvajanjem skripte, izvajanje ni ustavljeno. Opozorila so ne-usodne napake, izvajanje skripte ne bo ustavljeno.

Drug tip sporočila napake poročan med časom priprave so E_STRICT sporočila. Ta sporočila so uporavljena za predlaganje sprememb vaše kode, da pomagajo zagotoviti najboljšo interoperabilnost in nadaljnjo združljivost s prihajajočimi verzijami PHP-ja.

Sprememba PHP obnašanja poročanja napak

Poročanje napak je možno spremeniti z uporabo PHP nastavitev in/ali klicev PHP funkcij. Z uporabo vgrajene PHP funkcije error_reporting() lahko nastavite nivo napak za trajanje izvajanja skripte s podajanjem ene izmed vnaprej definirane konstante nivoja napak, kar pomeni, če želite samo videti napake in opozorila - vendar ne obvestil - potem lahko to nastavite:

<?php
error_reporting(E_ERROR | E_WARNING);

Lahko tudi krmilite ali so ali ne napake prikazane na zaslonu (dobro za razvoj) ali skrite in beležene (dobro za produkcijo). Za več informacij na to temo preverite sekcijo Poročanje napak.

Medvrstično zatiranje napak

PHP-ju lahko tudi poveste, da zatre določene napake z operatorjem kontrole napak @. Ta operator dodate na začetek izraza in katerakoli napaka, ki je direktni rezultat izraza je utišana.

<?php
echo @$foo['bar'];

To bo izpisalo $foo['bar'], če obstaja, vendar bo enostavno vrnilo null in nič izpisalo, če je spremenljivka $foo ali 'bar' ključ ne obstajata. Brez operatorja kontrole napak lahko ta izraz ustvari PHP Notice: Undefined variable: foo ali PHP Notice: Undefined index: bar napako.

To lahko zgleda kot dobra ideja, vendar pride do nekaterih nezaželjenih kompromisov. PHP upravlja izraze, ki uporabljajo @ v manj zmogljivem načinu kot tiste brez @. Prezgodnja optimizacija je lahko izhodišče vseh programerskih argumentov, vendar če je zmogljivost posebej pomembna za vašo aplikacijo/knjižnico, je pomembno razumeti posledice zmogljivosti operatorja kontrole napak.

V nadaljevanju operator kontrole napak popolnoma pogoltne napako. Napaka ni izpisana in napaka ni poslana v dnevnik napak. Tudi celotni/produkcijski PHP sistemi nimajo načina izključitve operatorja napak. Medtem ko imate lahko prav, da napaka, ki jo vidite, je neškodljiva bo druga manj škodljiva napaka tudi utišana.

Če je način, kako se izogniti operatorju zatiranja napak, premislite o njem. Na primer naša koda zgoraj je lahko prepisana sledeče

<?php
echo isset($foo['bar']) ? $foo['bar'] : '';

Primer, kjer je zatiranje napak lahko smiseln, je, kjer fopen() ne uspe najti datoteke za nalaganje. Lahko preverite obstoj datoteke preden jo poskušate naložiti, vendar če je datoteka zbrisana po preverjanju in pred fopen() (kar zveni nemogoče, vendar se lahko zgodi) potem bo fopen() vrnil false in vrgel napako. To je potencialno nekaj, kar bi moral PHP razrešiti, vendar gre za en primer, kjer je zatiranje napak edina veljavna rešitev.

Prej smo omenili, da ni načina v celotnem PHP sistemu, da se izključi operator kontrole napak. Vendar ima xDebug ima xdebug.scream ini nastavitev, ki onemogoči operator kontrole napak. To lahko nastavite preko vaše php.ini datoteke s sledečim.

xdebug.scream = On

Lahko tudi nastavite to vrednost na začetku poganjanja z ìni_set funkcijo

<?php
ini_set('xdebug.scream', '1')

PHP razširitev “Scream” ponuja podobno funkcionalnost napram xDebug, vendar Scream-ova ini nastavitev je imenovana scream.enabled.

To je najbolj uporabno, ko razhroščujete kodo in sumite, da bo informativna napaka zatrta. Uporabite scream previdno in kot začasno razhroščevalno orodje. Je na voljo ogromno PHP knjižnične kode, ki lahko ne dela z onemogočenim operatorjem kontrole napak.

ErrorException

PHP je odlično sposoben biti programski jezik “polen izjem” in samo zahteva nekaj vrstic kode za pretvorbo. V osnovi lahko vržete vaše “napake” kot “izjeme” z uporabo razreda ErrorException, ki razširi Exception razred.

To je pogosta praksa implementirana s strani velikega števila modernih ogrodij, ko sta Symfony in Laravel. Privzeto Laravel bo prikazal vse napake kot izjeme z uporabo Whoops! paketa, če je app.debug stikalo vklopljeno in jih skril, če je stikalo izklopljeno.

Z vrženjem napak kot izjeme jih v razvoju lahko upravljate bolje kot običajne rezultate in če vidite izjemo med razvojem, jo lahko ovijete v catch stavek z določenimi navodili, kako upravljati v tej situaciji. Vsaka izjema, ki jo ujamete bo takoj naredila vašo aplikacijo malenkost bolj robustno.

Več infomacij na to temo in podrobnosti kako uporabljati ErrorException pri upravljanju napak, se lahko najde na ErrorException Class.

Izjeme

Izjeme (Exceptions) so standardni deli najbolj popularnih programskih jezikov, vendar so pogosto spregledani s strani PHP programerjev. Jeziki kot je Ruby so izjemno zapolnjeni z izjemami, tako da kadarkoli gre kaj narobe, kot npr. okvara zahtevka HTTP, ali okvara pri poizvedbi podatkovne baze, ali celo ko slikovnega stredstva ni mogoče najti, Ruby (ali uporabljeni gemi) bodo izpisali izjemo na zaslon, kar pomeni, da takoj veste, kje se nahaja napaka.

PHP sam po sebi ima precej pomanjkanja glede tega in klic file_get_contents() vam bo ponavadi vrnil FALSE in opozorilo. Mnoga starejša ogrodja, kot je na primer CodeIgniter, bodo vrnila samo false vrednost, zapis sporočila v dnevnik in mogoče vam omogočila uporabo metode, kot je $this->upload->get_error(), da lahko vidite, kaj je šlo narobe. Problem tu je, da morate iskati napako in preverjati dokumentacijo, za katero napako metode gre za določen razred, namesto da se to naredi izjemno očitno.

Naslednji problem je, ko razredi avtomatsko vržejo napako na zaslon in zapustijo proces. Ko naredite to, ustavite drugega razvijalca, da bi lahko dinamično ravnal s to napako. Izjeme bi morale biti zagnane, da opozorijo razvijalca pred napako. Nato le-ta lahko izbere, kako bo ravnal v tem primeru. Primer:

<?php
$email = new Fuel\Email;
$email->subject('My Subject');
$email->body('How the heck are you?');
$email->to('guy@example.com', 'Some Guy');

try
{
    $email->send();
}
catch(Fuel\Email\ValidationFailedException $e)
{
    // The validation failed
}
catch(Fuel\Email\SendingFailedException $e)
{
    // The driver could not send the email
}
finally
{
    // Use this to let user know email was sent
}

SPL izjeme

Generični Exception razred ponuja zelo malo konteksta razhroščevanja za razvijalca, čeprav za odpravo tega je mogoče narediti specializiran Exception tip s pomočjo pod-razreda generičnega Exception razreda:

<?php
class ValidationException extends Exception {}

To pomeni, da lahko dodate več catch blokov in upravljate z različnimi izjemami različno. To lahko vodi v ustvarjanje veliko izjem po meri, nekaterim med njimi se lahko izognete z uporabo SPL izjem, ki so na voljo v SPL razširitvi.

Če na primer uporabite __call() magično metodo in je nato zahtevana napačna metoda, se namesto zagona standardne izjeme Exception, ki je nejasna, ali ustvarjanja izjeme po meri samo za to, lahko samo zaženete throw new BadMethodCallException;.

Nazaj na vrh

Varnost

Varnost spletnih aplikacij

Obstajajo slabi ljudje pripravljeni in voljni izkoristiti vašo spletno aplikacijo. Pomembno je, da naredite ustrezne varnostne ukrepe za izboljšanje varnosti vaše spletne aplikacije. Na srečo so dobri ljudje pri The Open Web Application Security Project (OWASP) prevedli zgoščen seznam znanih varnostnih težav in metod, da se lahko zaščitite pred napadalci. To je obvezno branje za varnostno ozaveščenega razvijalca. Drug dober vodič za varnost spletnih PHP aplikacij je tudi Survive The Deep End: PHP Security avtorja Padraic Brady.

Zgoščevanje gesel

Eventuelno vsakdo zgradi PHP aplikacijo, ki uporablja uporabniško prijavo. Uporabniška imena in gesla so lahko shranjena v podatkovni bazi in potem uporabljena za potrjevanje uporabnikov pri prijavi.

Pomembno je, da se ustrezno zgosti gesla, preden se jih shrani. Zgoščevanje gesel je nepovratna, enosmerna funkcija izvedena nad uporabnikovim geslom. To naredi določeno dolg niz, ki se ga ne da enostavno povrniti. To pomeni, da lahko primerjate zgostitev z drugo, da ugotovite, če obe prihajata iz istega vira niza, vendar pa ne morete določiti osnovnega niza. Če gesla niso zgoščena in je vaša podatkovna baza dostopna s strani neavtorizirane tretje strani, so vsi uporabniški računi ogroženi.

Gesla bi morala biti posamezno soljena z dodajanjem naključnega niza za vsako geslo pred zgoščevanjem. To preprečuje napade s slovarji in z uporabo “mavričnih tabel” (obratni seznam kriptografskih zgostitev za pogosta gesla).

Zgoščevanje in soljenje sta izjemnega pomena, saj uporabniki pogostokrat uporabljajo enako geslo za več storitev in kvaliteta gesla je lahko slaba.

Na srečo, dandanes PHP to naredi enostavno.

Zgoščevanje gesel s password_hash

V PHP 5.5 je bila izdana funkcija password_hash(). Trenutno uporablja BCrypt, najmočnejši algoritem trenutno podprt s strani PHP-ja. Bo pa tudi posodobljena v prihodnosti za podporo večih algoritmov, kakor bo potrebno. Ustvarjena je bila knjižnica password_compat, ki ponuja vnaprejšnjo kompatibilnost za PHP >= 5.3.7.

Spodaj bomo zgostili niz in nato preverili zgostitev proti novemu nizu. Ker sta naša dva vira nizov različna (‘secret-password’ proti ‘bad-password’), ta prijava ne bo uspela.

<?php
require 'password.php';

$passwordHash = password_hash('secret-password', PASSWORD_DEFAULT);

if (password_verify('bad-password', $passwordHash)) {
    // Correct Password
} else {
    // Wrong password
}

password_hash() poskrbi za soljenje gesel. Sol je shranjena skupaj z algoritmom in “ceno” kot del zgostitve. password_verify() to izloči, da določi, kako preveriti geslo, tako da vam ni potrebno uporabiti ločenega polja v podatkovni bazi, da shranite vaše soli.

Filtriranje podatkov

Nikoli, nikoli ne zaupajte tujemu vnosu predstavljenemu vaši PHP kodi. Vedno počistite in preverite tuj vnos, preden ga uporabljate v kodi. Funkciji filter_var() in filter_input() lahko počistita tekst in preverita obliko teksta (npr. e-poštni naslov).

Tuj vnos je lahko karkoli: $_GET in $_POST podatki obrazcev, nekatere vrednosti v $_SERVER superglobalni spremenljivki in telo (body) HTTP zahtevka preko fopen('php://input', 'r'). Dobro je vedeti, da tuj vnos ni omejen na poslane podatke iz obrazca s strani uporabnika. Naložene in prenesene datoteke, vrednosti sej, podatki piškotkov in podatki s tretjih strani spletnih servisev so tudi tuji vnosi.

Medtem ko se tuje podatke lahko shrani, kombinira in do njih dostopa kasneje, gre še vedno za tuj vnos. Vsakič, ko procesirate, izpisujete, spojite ali vključite podatke v vašo kodo, se vprašajte, če so bili podatki ustrezno filtrirani in jim lahko zaupate.

Podatki so lahko filtrirani različno na osnovi njihovega namena. Na primer, ko je nefiltriran tuj vnos podan v izpis HTML strani, lahko izvede HTML in JavaScript na vaši strani! To je poznano kot Cross-Site Scripting (XSS) in je lahko zelo nevaren napad. En način, da se izognete XSS, je čiščenje vseh uporabnikovih generiranih podatkov, preden jih izpišete v vašo stran, z odstranitvijo HTML značke s funkcijo strip_tags() ali čiščenje znakov s posebnim pomenom (escaping) v njihove ustrezne HTML entitete s funkcijama htmlentites() ali htmlspecialchars().

Drug primer je podajanje opcij, ki se bodo izvedle v komandni vrstici. To je lahko izjemno nevarno (in je ponavadi slaba ideja), vendar lahko uporabite vgrajeno funkcijo escapeshellarg() za čiščenje izvedenih ukaznih argumentov.

Zadnji primer je sprejemanje tujega vnosa za ugotovitev, katero datoteko naložiti iz datotečnega sistema. To je lahko izkoriščeno s spremembo imena datoteke v pot datoteke. Odstraniti morate /, ../, null bajte, ali ostale znake iz poti datoteke, da ne uspe naložiti skritih, nejavnih ali občutljivih datotek.

Čiščenje

Čiščenje odstrani (ali spremeni - escaping) nedovoljene ali nevarne znake iz tujega vnosa.

Na primer, morali bi počistiti tuj vnos preden vključujete vnos v HTML ali ga vnašate v izvorno SQL poizvedbo. Ko uporabljate vezanje parametrov s PDO, bo vnos počistilo za vas.

Včasih je potrebno dovoliti nekatere varne HTML značke v vnosu, ko se ga vključuje v HTML stran. To je zelo težko izvesti in mnogi se tega izogibajo z uporabo ostalih bolj omejenih oblikovanj kot sta Markdown ali BBCode, čeprav s tem namenom obstajajo čistilne knjižnice kot je HTML Purifier.

Poglejte si čistilne filtre

Deserijalizacija

Nevarno je uporabiti unserialize() za podatke od uporabnikov ali drugih nezaupljivih virov. To lahko omogoči zlonamernim uporabnikom, da sprožijo objekte (z uporabniško definiranimi lastnostmi), katerih destruktorji bodo izvršeni, tudi če objekti sami niso uporabljeni. Zato bi se morali izogibati deserializaciji nezaupljivih podatkov.

Če absolutno morate deserializirati podatke iz nezaupljivih virov, uporabite PHP 7 allowed_classes opcijo za omejitev, kateri tipi objektov so dovoljeni za deserializacijo.

Preverjanje

Preverjanje zagotavlja, da je tuj vnos to, kar pričakujete. Na primer, lahko boste želeli preveriti e-poštni naslov, telefonsko številko ali starost pri procesiranju registracijske oddaje.

Poglejte si filtre preverjanja

Konfiguracijske datoteke

Pri ustvarjanju konfiguracijskih datotek za vaše aplikacije, najboljše prakse priporočajo, da se upošteva eno izmed naslednjih metod:

Registracija globalnih spremenljivk

UPOŠTEVAJTE: Od PHP 5.4.0 je bila nastavitev register_globals odstranjena in je ni več možno uporabljati. To je samo vključeno kot opozorilo za kogarkoli v procesu nadgradnje stare aplikacije.

Ko je omogočeno, register_globals nastavitev naredi nekaj tipov spremenljivk (vključno tiste iz $_POST, $_GET in $_REQUEST) na voljo globalnemu področju vaše aplikacije. To lahko hitro vodi v varnostne težave, saj vaša aplikacija ne more efektivno povedati, od kod podatki prihajajo.

Na primer: $_GET['foo'] je tako na voljo preko $foo, kar lahko prepiše spremenljivke, ki niso bile opredeljene. Če uporabljate PHP < 5.4.0 se prepričajte da je register_globals izključen - off.

Poročanje o napakah

Beleženje napak je lahko uporabno v tem, da najdete problematične točke v vaši aplikaciji, vendar lahko tudi razkrije informacije o strukturi aplikacije zunanjemu svetu. Za efektivno zaščito vaše aplikacije pred težavami, ki jih lahko povzroči izpis teh sporočil, morate nastaviti vaš razvojni strežnik drugače od produkcijske različice (v živo).

Razvoj

Za prikaz vsake možne napake med razvojem, nastavite sledeče v vaši php.ini datoteki:

display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On

Podajanje vrednosti -1 bo prikazalo vsako možno napako, tudi če so novi nivoji ali konstante dodani v prihodnjih PHP verzijah. E_ALL konstanta se tudi obnaša na tak način od PHP 5.4. - php.net

E_STRICT konstanta nivoja napak je bila predstavljena v 5.3.0 in ni del E_ALL, čeprav je postala del E_ALL v 5.4.0. Kaj to pomeni? V smislu poročanja vsake možne napake v verziji 5.3 pomeni, da morate uporabiti ali -1 ali E_ALL | E_STRICT.

Poročanje vsake možne napake po PHP verzijah

Produkcija

Da skrijete napake v vašem produkcijskem okolju, nastavite vašo php.ini datoteko kot:

display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On

S temi nastavitvami v produkciji, bodo napake še vedno zabeležene v dnevnike napak za spletni strežnik, vendar ne bodo prikazane uporabniku. Za več informacij na teh nastavitvah, si oglejte PHP priročnik:

Nazaj na vrh

Testiranje

Pisanje avtomatizacijskih testov za vašo PHP kodo se smatra za najboljšo prakso in lahko vodi k dobro zgrajenim aplikacijam. Avtomatizirani testi so odlično orodje za zagotovitev, da se vaša aplikacija ne zlomi, ko delate spremembe ali dodajate nove funkcionalnosti in ne bi smelo biti ignorirano.

Obstaja več različnih tipov testnih orodij (ali ogrodij), ki so na voljo za PHP, ki uporabljajo različne pristope - vsa stremijo k izogibanju ročnega testiranja in potrebi po velikih ekipah za zagotavljanje kvalitete, samo da zagotovijo, da zadnje spremembe niso pokvarile trenutne funkcionalnosti.

Testno gnani razvoj

Vir Wikipedia:

Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or ‘rediscovered’ the technique, stated in 2003 that TDD encourages simple designs and inspires confidence

Obstaja več različnih tipov testiranja, ki ga lahko izvedete za vašo aplikacijo.

Testiranje enot

Testiranje enot (Unit Testing) je programerski pristop, da se zagotovi funkcijam, razredom in metodam, da delujejo kot pričakovano od trenutka, ko jih zgradite skozi celotno pot razvojnega cikla. S preverjanjem vrednosti, ki vstopajo in izstopajo, različnih funkcij in metod lahko zagotovite, da notranja logika deluje pravilno. Z uporabo injiciranja odvisnosti in gradnjo modelnih razredov in nastavkov lahko preverite, da so odvisnosti pravilno uporabljene za še boljšo pokritost testiranja.

Ko izdelate razred ali funkcijo, bi morali narediti test enote za vsako obnašanje, ki ga mora imeti. Na zelo osnovnem nivoju bi se morali prepričati, da pride do napake, ko pošljete napačne argumente, in se prepričati, da deluje, če pošljete pravilne. To bo pomagalo, da ko naredite spremembe temu razredu ali funkciji kasneje v razvojnem ciklu, bo stara funkcionalnost še vedno delovala kot pričakovano. Edina alternativa temu bi bila var_dump() v test.php, kar ni nikoli v redu za gradnjo aplikacije - male ali velike.

Drug primer uporabe za teste enot je prispevanje odprti kodi. Če lahko napišete test, ki pokaže nedelujočo funkcionalnost (t.j. napako), potemo jo popravite in pokažite, da gre test skozi, saj bodo popravki tako veliko bolj sprejeti. Če poganjate projekt, ki sprejema poteg zahtevkov, potem bi morali predlagati to kot zahtevo.

PHPUnit je defakto testno ogrodje za pisanje testov enot za PHP aplikacije, vendar je na voljo tudi precej alternativ:

Integracijsko testiranje

Vir Wikipedia:

Integration testing (sometimes called Integration and Testing, abbreviated “I&T”) is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.

Mnogo enakih orodij, ki so lahko uporabljena za testiranje enot, je lahko uporabljenih za integracijsko testiranje, saj so uporabljeni mnogi enaki principi.

Testiranje funkcionalnosti

Včasih je poznano tudi kot testiranje sprejemljivosti, testiranje funkcionalnosti sestoji iz uporabe orodij za izdelavo avtomatskih testov, ki dejansko uporabljajo vašo aplikacijo namesto samo preverjanja, da se individualne enote kode obnašajo pravilno in da lahko individualne enote pravilno komunicirajo med seboj. Ta orodja običajno delujejo z uporabo pravih podatkov in simulirajo dejanske uporabnike aplikacije.

Orodja za testiranje funkcionalnosti

Vedenjsko usmerjen razvoj

Na voljo sta dva različna tipa vedenjsko usmerjenega razvoja (BDD): SpecBDD in StoryBDD. SpecBDD se osredotoča na tehnično obnašanje kode, medtem ko se StoryBdd osredotoča na poslovna ali lastnostna vedenja ali interakcije. PHP ima ogrodja za oba BDD tipa.

Pri StoryBDD pišete zgodbe, ki upisujejo vedenje vaše aplikacije. Te zgodbe se nato lahko požene kot dejanske teste napram vaši aplikaciji. Uporabljeno ogrodje v PHP aplikacijah za StoryBDD je Behat, ki je bil navdihnjen od Ruby-jevega Cucumber projekta in implementira Gherkin DSL za opisovanje lastnosti vedenja.

Pri SpecBDD pišete specifikacije, ki opisujejo, kako bi se vaša dejanska koda morala vesti. Namesto testiranja funkcije ali metode, opisujete, kako bi se funkcija ali metoda morala vesti. PHP ponuja PHPSpec ogrodje za ta namen. To ogrodje je navdihnjeno od Rspec projekta za Ruby.

Dopolnilna testna orodja

Poleg individualnega testiranja in vedenjsko gnanih ogrodij, je na voljo tudi precejšnje število generičnih ogrodij in pomagalnih knjižnic uporabnih za kateregakoli izbranih prednostnih pristopov.

Povezave orodij

Nazaj na vrh

Strežniki in postavitev

PHP aplikacije so lahko postavljene in pognane na produkcijskih spletnih strežnikih na mnoge načine.

Platforma kot storitev (PaaS)

PaaS ponuja sistem in omrežje arhitekture potrebne za poganjanje PHP aplikacij na spletu. To pomeni malo ali nič nastavitev za zagon PHP aplikacij ali PHP ogrodij.

Nedavno je PaaS postala popularna metoda za postavitev, gostovanje in skaliranje PHP aplikacij vseh velikosti. Lahko najdete seznam PHP PaaS “Platform as a Service” ponudnikov v naši sekciji virov.

Virtualni ali namenski strežniki

Če se počutite domače s sistemsko administracijo, ali ste zainteresirani za učenje, virtualni ali namenski strežniki ponujajo celotno kontrolo vašega aplikacijskega produkcijskega okolja.

nginx in PHP-FPM

PHP preko PHP-jevega vgrajenega FastCGI procesnega upravljalnika (FPM), gre res lepo skupaj z nginx strežnikom, ki je lahek, dobro zmogljiv spletni strežnik. Uporabi manj spomina kot Apache in boljše ravna s trenutni zahtevki. To je še posebej pomembno na virtualnih strežnikih, ki nimajo na voljo veliko spomina.

Apache in PHP

PHP in Apache imata za sabo dolgo zgodovino. Apache je divje nastavljiv in ima na voljo mnogo modulov za razširitev funkcionalnosti. Je popularna izbira za skupne strežnike in enostavna namestitev za PHP ogrodja in odprtokodne aplikacije kot je WordPress. Na žalost Apache privzeto uporabi več virov kot nginx in ne more ravnati z mnogimi uporabniki istočasno.

Apache ima nekaj možnih nastavitev za poganjanje PHP. Najbolj pogosta in enostavna za namestitev je prefork MPM z mod_php5. Medtem ko ni najbolj spominsko učinkovit, je pa najbolj enostaven za delo in uporabo. To je verjetno najboljša izbira, če se ne želite poglabljati preveč globoko v aspekte strežniške administracije. Upoštevajte, da če uporabljate mod_php5, morate uporabiti prefork MPM.

Alternativno, če želite stisniti več zmogljivosti in stabilnosti iz Apache-ja, potem lahko izkoristite enak FPM sistem kot nginx in pognati worker MPM ali event MPM z mod_fastcgi ali mod_fcgid. Ta nastavitev bo bistveno bolj spominsko učinkovita in bolj hitra, vendar je potrebno več dela za vzpostavitev.

Če poganjate Apache 2.4 ali novejši, lahko uporabite mod_proxy_fcgi, da dobite enostavno nastavljivo zmogljivost.

Skupni strežniki

PHP se lahko zahvali skupnim strežnikom za njegovo popularnost. Težko je najti gostitelja brez nameščenega PHP, vendar bodite prepričani, da je zadnja verzija. Skupni strežniki dovoljujejo vam ali ostalim razvijalcem, da se postavi spletno stran na eno napravo. Prednost tega je, da je to postalo poceni blago. Slabost pa je, da nikoli ne veste, kakšno navlako bodo vaši sosedje ustvarili; nalagalni čas strežnika in odprte varnostne luknje so glavna zaskrbljenost. Če si proračun vašega strežnika lahko privošči izogib skupnih strežnikov, je to dobro.

Da se prepričate, če vaši deljeni strežniki ponujajo zadnje verzije PHP, preverite stran PHP Versions.

Gradnja in postavitev vaše aplikacije

Če ugotovite, da delate ročne spremembe podatkovne baze ali poganjate vaše teste ročno, preden posodabljate vaše datoteke (ročno), ponovno premislite! Z vsakim dodatnim ročnim opravilom potrebnim za postavitev nove verzije vaše aplikacije, se možnosti za potencialno usodno napako povečajo. Ali če imate opravka z enostavno posodobitvijo, podrobnim procesom gradnje ali celo strategijo zvezne integracije, je avtomatizacija gradnje vaš prijatelj.

Med opravili, ki jih želite avtomatizirati so:

Orodja za namestitev

Orodja za namestitev lahko opišemo kot zbirko skript, ki opravljajo pogosta opravila namestitve programske opreme. Orodje za namesitev ni del vaše aplikacije, vendar deluje na vaši aplikaciji od ‘zunaj’.

Na voljo je ogromno odprtokodnih orodij, ki so na voljo za pomoč pri avtomatizirani gradnji in namestitvi. Nekatera so napisana v PHP, nekatera ne. To vas ne bi smelo ovirati pri njihovi uporabi, če so bolj primerna za določeno nalogo. Tu je nekaj primerov:

Phing lahko krmili vaše procese pakiranja, postavitve ali testiranja iz XML postavitvene datoteke. Phing (ki je osnovan na Apache Ant) ponuja bogat nabor opravil, ki so ponavadi potrebna za namestitev ali posodobitev spletne aplikacije, in se ga lahko razširi z dodatnimi opravili po meri, napisanimi v PHP. Je stabilno in močno orodje, ki je na voljo že dolgo časa, vendar se ga lahko dojema za nekoliko staromodno zaradi načina obravnave konfiguracije (XML datoteke).

Capistrano je sistem za programerje z nadaljevalnim do naprednim znanjem, da lahko izvajajo ukaze na strukturiran, ponovljiv način na eni ali več oddaljenih naprav. Je prednastavljen za namestitev aplikacij Ruby on Rails, čeprav z njim lahko uspešno nameščate PHP sisteme. Uspešna uporaba Capistrana zavisi na praktičnem znanju Ruby-ja in Rake-a. Dave Gardner-jeva objava na blogu PHP Deployment with Capistrano je dobro izhodišče za PHP razvijalce, ki jih zanima Capistrano.

Rocketeer je dobil inspiracijo in filozofijo iz ogrodja Laravel. Cilj je hitrost, elegantnost in enostavna uporaba s smiselnimi privzetimi nastavitvami. Vsebuje več strežnikov, več razvojnih stopenj, atomske namestitve in vzporedno izvedene namestitve. Vse v orodju se lahko zamenja ali razširi med delovanjem in vse je napisano v PHP.

Deployer je orodje za namestitev napisano v PHP, je enostavno in funkcionalno. Opravila poganja vzporedno, opravlja atomske namestitve in obdrži konsistentnost med strežniki. Na voljo so recepti pogostih opravil za Symfony, Laravel, Zend Framework in Yii. Younes Rafie-jev članek Easy Deployment of PHP Applications with Deployer je odličen vodič za namestiev vaše aplikacije s tem orodjem.

Magallanes je drugo orodje napisano v PHP z enostavno konfiguracijo v YAML datotekah. Podpira več strežnikov in okolij, atomske namestitve in ima vgrajena opravila, ki jih lahko uporabite pri pogostih orodjih in ogrodjih.

Nadaljnje branje

Strežniške provizije

Upravljanje in konfiguracija strežnikov je lahko zastrašujoče opravilo pri večih strežnikih. Na voljo so orodja za ravnanje s tem, tako da lahko avtomatizirate vašo infrastrukturo in zagotovite, da imate pravilno nastavljene strežnike. Pogosto se integrirajo z večjimi ponudniki oblačnega gostovanja (Amazon Web Services, Heroku, DigitalOcean itd.) za upravljanje instanc, kar naredi skaliranje aplikacije veliko enostavnejše.

Ansible je orodje, ki upravlja vašo infrastrukturo preko YAML datotek. Je enostaven za začeti in lahko upravlja kompleksne in večje apllikacije. Na voljo je API za upravljanje oblačnih instanc in lahko jih upravlja preko dinamičnega inventarja z uporabo določenih orodij.

Puppet je orodje, ki ima svoj lasten jezik in vrste datotek za upravljanje strežnikov in konfiguracij. Lahko se ga uporabi v namestitvi master/klient ali pa se ga uporablja v “master-less” načinu. V načinu master/klient, bodo klienti raziskali osrednje master-je za novo konfiguracijo po nastavljenih intervalih in se posodobili, če je potrebno. V načinu master-less, lahko pošljete spremembe vašim vozliščem.

Chef je močno, na Ruby-ju osnovano, sistemsko ogrodje za integracijo, s katerim lahko zgradite vaše celotno strežniško okolje ali virtualne naprave. Dobro se integrira z Amazon Web Services preko njihove storitve imenovane OpsWorks.

Nadaljnje branje:

Zvezna integracija

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily — leading to multiple integrations per day. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.

– Martin Fowler

Obstaja več različnih poti za implementacijo zvezne integracije za PHP. Travis CI je naredil odlično delo zvezne integracije, zaradi česar je realnost tudi za manjše projekte. Travis CI je gostovan servis zvezne integracije za odprto kodno skupnost. Integriran je z GitHub-om in ponuja prvo razredno podporo za mnoge jezike, tudi PHP.

Nadaljnje branje:

Nazaj na vrh

Virtualizacija

Poganjanje vaše aplikacije v različnih okoljih v razvoju in produkciji lahko pripelje do pojavljanja čudnih hroščev, ko greste v produkcijo. Tudi zapleteno je imeti posodobljena različna razvojna okolja z enakimi verzijami za vsemi uporabljenimi knjižnicami, ko delate z ekipo razvijalcev.

Če razvijate na Windows in nalagate na Linux (ali na karkoli ne-Windows) ali razvijate v ekipi, bi morali premisliti o uporabi virtualne naprave. Zveni zapleteno, vendar poleg znanih virtualizacijskih okolj kot sta VMware ali VirtualBox, so na voljo dodatna oroja, ki vam lahko pomagajo naložiti virtualno okolje v nekaj enostavnih korakih.

Vagrant

Vagrant vam pomaga zgraditi vaše virtualne naprave na vrhu znanih virtualnih okolj in bo nastavil ta okolja na osnovi ene nastavitvene datoteke. Te naprave se lahko nastavi ročno ali pa lahko uporabite “provisioning” (rezervacijsko) programsko opremo, kot je Puppet ali Chef, ki to naredi za vas. Rezerviranje osnovne škatle je odličen način za zagotovitev, da je več škatel nameščenih v identični obliki in odstrani potrebo po vzdrževanju komplicirane namestitve seznama komand. Lahko tudi odstranite vašo osnovno škatlo in jo ponovno kreirate brez mnogih ročnih korakov, kar omogoča enostavno novo namestitev.

Vagrant naredi skupne mape, ki se uporabljajo za deljenje vaše kode med vašim gostiteljem in vašo virtualno napravo, kar pomeni, da lahko naredite in uredite vaše datoteke na vaši gostiteljski napravi in nato poženete kodo znotraj virtualne naprave.

Malo pomoči

Če potrebujete malo pomoči za začetek uporabe Vagranta, je na voljo nekaj storitev, ki so lahko uporabne:

Docker

Docker - lahka alternativa polni virtualni napravi - se tako imenuje, ker gre za “kontejnerje”. Kontejner je gradnik, ki v najenostavnejšem primeru opravlja posamezno specifično nalogo, npr. poganja spletni strežnik. Slika je paket, ki jo uporabite za gradnjo kontejnerja - Docker ima repozitorij poln slik.

Običajna LAMP aplikacija ima lahko tri kontejnerje: spletni strežnik, PHP-FPM proces in MySQL. Kot pri deljenih mapah pri Vagrantu, lahko pustite datoteke vaše aplikacije, kjer so in poveste Docker-ju, kje jih najde.

Kontejnerje lahko generirate iz ukazne vrstice (glejte primer spodaj) ali zaradi enostavnosti vzdrževanja, zgradite datoteko docker-compose.yml za vaš projekt, kjer se določi katere ustvariti in kako komunicirajo eden z drugim.

Docker lahko pomaga, če razvijate več spletnih strani in želite ločitev, ki pride z namestitvijo vsakega na svoji lastni virtualni napravi, vendar nimate potrebnega prostora na disku ali časa, da imate vse posodobljeno. Je učinkovito: namestitev in prenosi so hitrejši, shraniti morate edino eno kopijo vsake slike ne glede na to koliko pogostokrat je uporabljena. Kontejnerji potrebujejo manj RAM-a in si delijo isto jedro operacijskega sistema, tako da lahko poganjate več strežnikov istočasno, kjer zaustavitev in zagon vzame nekaj sekund in ni potrebno čakati, da se strežnik ponovno zažene.

Primer: Poganjanje vaše PHP aplikacije v Docker-ju

Po namestitvi Docker-ja na vašo napravo lahko poženete spletni strežnik z enim ukazom. Sledeče bo preneslo polno funkcionalno namestitev Apache z zadnjo verzijo PHP, preslikalo /path/to/your/php/files v vrhnjo mapo, kar lahko pogledate na http://localhost:8080:

docker run -d --name my-php-webserver -p 8080:80 -v /path/to/your/php/files:/var/www/html/ php:apache

To bo inicializiralo in pognalo vaš kontejner. -d ga požene v ozadju. Da ga zaustavite in zaženete, enostavno poženite docker stop my-php-webserver in docker start my-php-webserver (drugi parametri niso ponovno potrebni).

Izvedite več o Docker-ju

Ukaz zgoraj prikazuje hiter način pogona osnovnega strežnika. Obstaja še več, kar lahko naredite (in tisoče vnaprej zgrajenih slik v Docker Hub-u). Vzamite si čas, da spoznate terminologijo in preberite Docker User Guide, da ga bolje spoznate in ne poganjate naključne kode, ki ste jo prenesli brez preverjanja, če je varna - neuradne slike lahko nimajo najnovejših varnostnih popravkov. Če ste v dvomih, se držite uradnih repozitorijev.

Stran PHPDocker.io bo avtomatsko zgenerirala vse datoteke, ki jih potrebujete za polni LAMP/LEMP sklad, vključno z vašo izbiro verzije PHP in razširitev.

Nazaj na vrh

Predpomnjenje

PHP je precej hiter sam po sebi, vendar ozko grlo se lahko pojavi, ko delate oddaljene povezave, nalagate datoteke itd. Na srečo so na voljo različna orodja, ki pohitrijo določene dele vaše aplikacije ali zreducirajo število časa, ki jih ta različna časovno potratna opravila potrebujejo za izvajanje.

Predpomnilnik ukazne kode

Ko se PHP datoteka izvede, mora biti naprej prevesti v ukazno kodo - opcodes (navodila strojnega jezika za CPU). Če je izvorna koda nespremenjena, bo ukazna koda enaka, tako da ta korak sestavljanja postane odvečen vir za CPU.

Predpomnilnik ukazne kode (opcode cache) preprečuje odvečno sestavljanje s shranjevanjem ukazne kode v spomin in jo ponovno uporabi pri zaporednih klicih. Običajno se najprej preveri podpis ali čas spremembe datoteke, če je prišlo do kakšnih sprememb.

Verjetno je, da bo predpomnilnik ukazne kode naredil opazno izboljšanje hitrosti vaše aplikacije. Od PHP 5.5 je na voljo vgrajeni Zend OPCache. Odvisno od vašega PHP paketa/distribucije je običajno privzeto vključen - preverite opcache.enable in izpis phpinfo(), da se prepričate. Za prejšnje verzije je na voljo PECL razširitev.

Preberite več o predpomnilnikih ukazne kode:

Predpomnjenje objektov

Pride čas, ko je koristno predpomniti individualne objekte v vašo kodo, kot so podatki, ki so prepomembni, da bi jih dobili iz ali klicali v podatkovno bazo, kjer se rezultat verjetno ne bo spremenil. Lahko uporabite programsko opremo za predpomnjenje objektov, da shrani te dele podatkov v spomin pri izjemno hitrih kasnejših klicih. Če shranite te elemente v podatkovno shrambo, ko naredite poizvedbo zanje, potem jih potegnite direktno iz predpomnilnika za le-te zahtevke. Dobite lahko izjemno izboljšavo v zmogljivosti kot tudi zmanjšanje obremenitve na vaše strežnike podatkovne baze.

Mnoge popularne rešitve predpomnilnikov ukazne kode, vam omogočajo tudi predpomnjenje podatkov po meri. Tako, da je še večji razlog, da jih izkoristite. APCu, XCache in WinCache vsi ponujajo API-je, da shranite podatke iz vaše PHP kode v njihov spomin predpomnilnika.

Najobičajnejši uporabljani sistemi spominsko objektnega predpomnjenja sta APCu in memcached. APCu je odlična izbira za objektno predpomnjenje, vključuje enostaven API za dodajanje vaših podatkov v njihov spomin predpomnilnika in je zelo enostaven za nastaviti in uporabiti. Ena realna omejitev APCu-ja je, da je vezan na strežnik, na katerega je nameščen. Memcached po drugi strani je nameščen kot ločena storitev in se do nje lahko dostopa čez omrežje, kar pomeni, da lahko shranite objekte v hiper-hitro podatkovno shrambo v centralni lokaciji in mnoge različne sisteme lahko potegnete iz nje.

Upoštevajte, da ko poganjate PHP kot (Fast-)CGI aplikacijo znotraj vašega spletnega strežnika, bo imel vsak PHP proces namesto tega svoj predpomnilnik, to pomeni, da APCu podatki ne bodo deljeni med vašimi delovnimi procesi. V teh primerih je namesto tega dobro premisliti o uporabi memcached predpomnilnika, saj ni vezan na PHP procese.

V omrežnih nastavitvah APCu bo običajno prekašal memcached, kar se tiče dostopne hitrosti, vendar memcached bo sposoben hitrejšega in širšega skaliranja. Če ne pričakujete, da boste imeli mnoge strežnike za poganjanje vaše aplikacije ali ne potrebujete dodatnih lastnosti, ki jih memcached ponuja, potem je APCu verjetno najboljša izbira za predpomnjenje objektov.

Primer logike z uporabo APCu:

<?php
// check if there is data saved as 'expensive_data' in cache
$data = apc_fetch('expensive_data');
if ($data === false) {
    // data is not in cache; save result of expensive call for later use
    apc_add('expensive_data', $data = get_expensive_data());
}

print_r($data);

Upoštevajte, da pred PHP 5.5, APC ponuja tako predpomnilnik objektov kot tudi predpomnilnik ukazne kode. APCu je projekt, ki je prinesel APC-jev predpomnilnik objektov v PHP 5.5+, odkar ima PHP sedaj vgrajeni predpomnilnik ukazne kode (OPcache).

Naučite se več o popularnih sistemih predpomnilnikov objektov:

Nazaj na vrh

Dokumentiranje vaše kode

PHPDoc

PHPDoc je neformalni standard za komentiranje PHP kode. Na voljo je veliko različnih značk. Celoten seznam značk in primerov se lahko najde v PHPDoc navodilih.

Spodaj je primer, kako lahko dokumentirate razred z nekaj metodami;

<?php
/**
 * @author A Name <a.name@example.com>
 * @link http://www.phpdoc.org/docs/latest/index.html
 */
class DateTimeHelper
{
    /**
     * @param mixed $anything Anything that we can convert to a \DateTime object
     *
     * @throws \InvalidArgumentException
     *
     * @return \DateTime
     */
    public function dateTimeFromAnything($anything)
    {
        $type = gettype($anything);

        switch ($type) {
            // Some code that tries to return a \DateTime object
        }

        throw new \InvalidArgumentException(
            "Failed Converting param of type '{$type}' to DateTime object"
        );
    }

    /**
     * @param mixed $date Anything that we can convert to a \DateTime object
     *
     * @return void
     */
    public function printISO8601Date($date)
    {
        echo $this->dateTimeFromAnything($date)->format('c');
    }

    /**
     * @param mixed $date Anything that we can convert to a \DateTime object
     */
    public function printRFC2822Date($date)
    {
        echo $this->dateTimeFromAnything($date)->format('r');
    }
}

Dokumentacija za razred kot celoto ima najprej značko @author in značko @link. Značka @author je uporabljena za dokumentiranje avtorja kode in je lahko ponovljena za dokumentiranje večih avtorjev. Značka @link je uporabljena za povezavo na stran, ki označuje zvezo med spletno stranjo in kodo.

Znotraj razreda ima prva metoda značko @param, ki dokumentira tip, ime in opis parametra, ki je bil podan metodi. Dodatno ima znački @return in @throws za dokumentiranje vrnjenega tipa in katerekoli izjeme, ki jih lahko vrže.

Druga in tretja metoda sta zelo podobni in imata eno značko @param, kot jo ima prva metoda. Pomembna razlika med blokom dokumentacije druge in tretje metode, je vključevanje/izključevanje značke @return. @return void nas eksplicitno informira, da nič ne vrne, zgodovinska izpustitev @return void stavka ima tudi rezultate v isti akciji, ki ne vrne ničesar.

Nazaj na vrh

Viri

Iz izvora

Sledite ljudem

Ko začenjate, je težko najti zanimive in izobražene člane, PHP skupnosti. Podroben seznam članov PHP skupnosti in njihove povezave Twitter profilov lahko najdete na:

Mentorstvo

PHP PaaS ponudniki

Katere verzije poganjajo gostitelji PaaS, preverite na strani PHP Versions.

Ogrodja

Namesto ponovnega odkrivanja kolesa, mnogi PHP razvijalci uporabljajo ogrodja, da zgradijo spletne aplikacije. Ogrodja abstraktirajo mnoge nizko nivojske skrbi in ponujajo ustrežljive vmesnike enostavne za uporabo, da se dokonča pogosta opravila.

Ne potrebujete uporabljati ogrodja za vsak projekt. Včasih je preprosti PHP pravilen način, vendar če pa potrebujete ogrodje potem so na voljo trije glavni tipi:

Mikro ogrodja so v osnovi ovoj za usmeritev HTTP zahtevka v povratni klic, kontroler, metodo itd. kot hitro je mogoče in včasih pridejo z nekaj dodatnimi knjižnicami, da pomagajo razvijanju, kot so osnovna ovijanja podatkovne baze in podobno. Uporabljeni so očitno za gradnjo oddaljenih HTTP storitev.

Mnoga ogrodja dodajo veliko število lastnosti na tisto, kar je na voljo v mikro ogrodju in ta so znana kot celotna ogrodja. Ta pogosto pridejo v paketu z ORM-ji, paketi za preverjanje pristnosti itd.

Komponentno osnovana ogrodja so zbirka specializiranih in samonamenskih knjižnic. Raznolika komponentno osnovana ogrodja se lahko uporabljajo skupaj, da se tvori mikro ali celotno ogrodje.

Komponente

Kot že omenjeno zgoraj, so komponente še en pristop k skupnemu cilju izdelave, distribucije in implementacije skupno deljene kode. Obstajajo različni komponenti repozitoriji, glavna med njimi sta dva:

Oba od teh repozitorijev imata orodja za ukazno vrstico povezano z njimi, da pomagata namestiti in nadgraditi procese in sta bolj podrobno razložena v sekciji upravljanja paketov.

So na voljo tudi komponentno osnovana ogrodja, ki vam dovoljujejo uporabiti njihove komponente z minimalnimi ali nič zahtevami. Na primer lahko uporabite FuelPHP paket preverjanje, brez potrebe po uporabi samega FuelPHP ogrodja. Te projekti so v bistvu samo dodaten repozitorij za ponovno uporabne komponente:

Laravelove Illuminate komponente bodo postale bolj nevezane v ogrodju Laravel. Za sedaj so tu zabeležene samo komponente, ki so lahko najboljše nevezne.

Ostali uporabni viri

Plonk listki

Več najboljših praks

Novice skupnosti PHP in spletnega razvoja

Lahko se naročite na tedenske e-novice, da ste obveščeni o novih knjižnicah, najnovejših novicah, dogodkih in splošnih obvestilih, kot tudi dodatnih virih, ki so objavljeni vsake toliko časa:

PHP vesolje

Video vodiči

Kanali YouTube

Plačljivi vodiči

Knjige

Na voljo je mnogo knjig za PHP; na žalost so nekatere sedaj precej stare in niso več točne. Posebej se izogibajte knjig na temo “PHP 6”, verzija, ki sedaj ne bo nikoli obstajala. Naslednja večja verzija PHP po 5.6 je bila “PHP 7”, delno zaradi tega.

Ta sekcija ima cilj biti posodobljen dokument za priporočene knjige o PHP razvoju na splošno. Če želite, da se doda vašo knjigo, pošljite PR in bo pregledana za relevantnost.

Brezplačne knjige

Plačljive knjige

Nazaj na vrh

Skupnost

PHP skupnost je tako raznolika, kot je tudi velika in njeni člani so pripravljeni podpirati nove PHP programerje. Premislite o pridružitvi vaši lokalni PHP uporabniški skupini (PHP User Group - PUG) ali obiščite večje PHP konference, da se naučite več o najboljših praksah prikazanih tu. Lahko se priklopite tudi na IRC na #phpc kanal irc.freenode.com in sledite @phpc twitter računu. Pojdite tja, spoznajte nove razvijalce, naučite se nove teme in predvsem si naredite nove prijatelje! Ostali viri skupnosti vključujejo Google+ PHP programersko skupnost in StackOverflow.

Preberite uraden koledar PHP dogodkov

PHP uporabniške skupine

Če živite v večjem mestu, je verjetnost, da blizu obstaja PHP uporabniška skupina. Enostavno lahko najdete vašo lokalno PUG skupino na seznamu uporabniških skupin na php.net, ki je osnovan na PHP.ug. Alternativni viri so lahko Meetup.com ali iščite php user groups near me z uporabo vašega priljubljenega iskalnika (t.j. Google PHP.ug. Če živite v manjšem mestu, lahko da lokalna PUG ne obstaja. V tem primeru jo kar pričnite!

Posebna omemba je potrebna dvema globalnima uporabniškima skupinama: NomadPHP in PHPWomen. NomadPHP ponuja dvakrat mesečeno online srečanje uporabnikov s predstavitvami nekaterih najboljših govornikov v PHP skupnosti. PHPWomen je ne-eksluzivna uporabniška skupina prvotno targetirana ženskam v svetu PHP. Članstvo je odprto za vsakogar, ki podpira bolj raznoliko skupnost. PHPWomen ponuja omrežje za podporo, mentorstvo in izobraževanje ter v splošnem promovira izdelavo “ženskam prijazne” in profesionalne atomsfere.

Preberite o uporabniških skupinah na PHP Wiki

PHP konference

PHP skupnost gosti tudi večje regionalne in nacionalne konference v mnogih državah po svetu. Dobro znani člani PHP skupnosti običajno govorijo na teh večjih dogodkih, tako da je to odlična priložnost, da se naučite direktno od vodilnih v industriji.

Najdite PHP konferenco

ElePHPant-i

ElePHPant je tista lepa maskota projekta PHP s slončkom v njeni obliki. Prvotno jo je za projekt PHP oblikoval v 1998 Vincent Pontier - spiritualni oče tisočih elePHPant-ov po svetu in 10 let kasneje se je rodila tudi prikupna plišasta elephant igračka. Sedaj so elePHPant-i prisotni na mnogih PHP konferencah in pri mnogih PHP razvijalcih za njihovimi računalniki za zabavo in inispiracijo.

Intervju Vincent Pontier