Co je PHP-FIG? Entita „framework“ pro PHP z jedné třídy Anemic group php

16.09.2016

Pokusme se zjistit, jak zvýšit výkon aplikačního serveru založeného na php-fpm, a také vytvořit kontrolní seznam pro kontrolu konfigurace procesu fpm.

Nejprve byste měli určit umístění konfiguračního souboru fondu. Pokud jste nainstalovali php-fpm ze systémového úložiště, pak konfigurace fondu www bude umístěn přibližně zde /etc/php5/fpm/pool.d/www.conf . Pokud používáte vlastní sestavení nebo jiný OS (ne debian), měli byste hledat umístění souboru v dokumentaci nebo jej zadat ručně.

Zkusme se na konfiguraci podívat podrobněji.

Přechod na UNIX sockety

Pravděpodobně první věc, kterou byste měli věnovat pozornost, je to, jak data proudí z webového serveru do vašich PHP procesů. To se odráží v direktivě listen:

poslech = 127.0.0.1:9000

Pokud je nastavena adresa:port, pak data procházejí zásobníkem TCP a to pravděpodobně není příliš dobré. Pokud existuje cesta k soketu, například:

listen = /var/run/php5-fpm.sock

pak data procházejí unixovým socketem a tuto sekci můžete přeskočit.

Proč se stále vyplatí přejít na unixovou patici? UDS (unix domain socket), na rozdíl od komunikace přes TCP stack, má významné výhody:

  • nevyžadují přepínání kontextu, UDS používá netisr)
  • Datagram UDS je zapsán přímo do cílového soketu
  • odeslání datagramu UDS vyžaduje méně operací (žádné kontrolní součty, žádné hlavičky TCP, žádné směrování)

Průměrná latence TCP: 6 us UDS průměrná latence: 2 us Průměrná latence PIPE: 2 us Průměrná propustnost TCP: 253702 msg/s Průměrná propustnost UDS: 1733874 msg/s Průměrná propustnost PIPE: 1682796 msg/s

UDS má tedy zpoždění ~66% méně a propustnost v 7krát více TCP. Proto se s největší pravděpodobností vyplatí přejít na UDS. V mém případě bude soket umístěn na /var/run/php5-fpm.sock.

; Pojďme to okomentovat – listen = 127.0.0.1:9000 listen = /var/run/php5-fpm.sock

Měli byste se také ujistit, že webový server (nebo jakýkoli jiný proces, který potřebuje komunikovat) má přístup pro čtení/zápis do vašeho soketu. K tomu existují nastavení poslouchat.skupina A režim poslechu Nejjednodušší způsob je spustit oba procesy od stejného uživatele nebo skupiny, v našem případě php-fpm a webový server se spustí se skupinou www-data:

listen.owner = www-data listen.group = www-data listen.mode = 0660

Kontrola vybraného mechanismu zpracování událostí

Pro efektivní práci s I/O (vstup/výstup, soubor/zařízení/socket deskriptory) se vyplatí zkontrolovat, zda je nastavení zadáno správně události.mechanismus. Pokud je php-fpm nainstalováno ze systémového úložiště, s největší pravděpodobností je tam vše v pořádku - buď není zadáno (nainstalováno automaticky), nebo zadáno správně.

Jeho význam závisí na OS, pro který je v dokumentaci nápověda:

; - epoll (linux >= 2.5.44); - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0) ; - /dev/poll (Solaris >= 7) ; - port (Solaris >= 10)

Pokud například pracujeme na moderní distribuci Linuxu, potřebujeme epool:

události.mechanismus = epoll

Výběr typu fondu - dynamický / statický / na vyžádání

Rovněž stojí za to věnovat pozornost nastavení správce procesů (pm). V podstatě se jedná o hlavní proces, který bude spravovat všechny své potomky (které spouštějí kód aplikace) podle určité logiky, která je ve skutečnosti popsána v konfiguračním souboru.

K dispozici jsou celkem 3 schémata řízení procesů:

  • dynamický
  • statický
  • na požádání

Nejjednodušší je statický. Funguje to následovně: spusťte pevný počet podřízených procesů a udržujte je v provozuschopném stavu. Toto operační schéma není příliš efektivní, protože počet požadavků a jejich zatížení se může čas od času měnit, ale počet podřízených procesů nikoli - vždy zabírají určité množství paměti RAM a nemohou zpracovat špičkové zatížení ve frontě.

dynamický tento problém vyřeší fond, který reguluje počet podřízených procesů na základě hodnot konfiguračního souboru a mění je nahoru nebo dolů v závislosti na zatížení. Tento fond je nejvhodnější pro aplikační server, který vyžaduje rychlou reakci na požadavky, práci se špičkovým zatížením a vyžaduje úsporu prostředků (snížením počtu podřízených procesů při nečinnosti).

na požádání bazén je velmi podobný statický, ale při spuštění hlavního procesu nespustí podřízené procesy. Teprve když přijde první požadavek, vytvoří se první podřízený proces a po určité době čekání (zadané v konfiguraci) bude zničen. Proto je relevantní pro servery s omezenými prostředky nebo pro logiku, která nevyžaduje rychlou odezvu.

Úniky paměti a zabiják OOM

Měli byste věnovat pozornost kvalitě aplikací, které budou spouštěny podřízenými procesy. Pokud kvalita aplikace není příliš vysoká nebo se používá mnoho knihoven třetích stran, musíte přemýšlet o možných únikech paměti a nastavit hodnoty těchto proměnných:

  • pm.max_requests
  • request_terminate_timeout

pm.max_requests toto je maximální počet požadavků, které podřízený proces zpracuje, než bude zabit. Vynucená destrukce procesu vám umožní vyhnout se situaci, kdy paměť podřízeného procesu „nabobtná“ kvůli únikům (protože proces pokračuje v práci po vyžádání po vyžádání). Na druhou stranu příliš malá hodnota bude mít za následek časté restarty, což povede ke ztrátám výkonu. Vyplatí se začít s hodnotou 1000 a poté tuto hodnotu snížit nebo zvýšit.

request_terminate_timeout nastavuje maximální dobu, po kterou může podřízený proces běžet, než bude zabit. To vám umožní vyhnout se dlouhým dotazům, pokud byla z nějakého důvodu změněna hodnota max_execution_time v nastavení interpretu. Hodnota by měla být nastavena na základě logiky zpracovávaných aplikací, řekněme 60. léta(1 minuta).

Nastavení dynamického fondu

Pro hlavní aplikační server se kvůli zjevným výhodám často volí dynamický fond. Jeho činnost je popsána následujícími nastaveními:

  • pm.max_children- maximální počet podřízených procesů
  • pm.start_servers- počet procesů při spuštění
  • pm.min_spare_servers- minimální počet procesů čekajících na připojení (požadavek na zpracování)
  • pm.max_spare_servers- maximální počet procesů čekajících na připojení (požadavky ke zpracování)

Pro správné nastavení těchto hodnot je nutné zvážit:

  • kolik paměti průměrně spotřebuje dětský proces?
  • množství dostupné paměti RAM

Průměrnou hodnotu paměti na jeden proces php-fpm na již běžící aplikaci můžete zjistit pomocí plánovače:

# ps -ylC php-fpm --sort:rss S UID PID PPID C PRI NI RSS SZ WCHAN TTY TIME CMD S 0 1445 1 0 80 0 9552 42588 ep_pol ? 00:00:00 php5-fpm

Potřebujeme průměrnou hodnotu ve sloupci RSS (velikost rezidentní paměti v kilobajtech). V mém případě je to ~ 20 MB. Pokud nedochází k žádnému zatížení aplikací, můžete použít Apache Benchmark k vytvoření jednoduchého zatížení php-fpm.

Množství celkové / dostupné / použité paměti lze zobrazit pomocí volný, uvolnit:

# free -m celkem využito zdarma ... Paměť: 4096 600 3496

Celkový maximální počet procesů = (celkem RAM - (použitá RAM + vyrovnávací paměť)) / (paměť na proces php) Celková RAM: 4 GB Použitá RAM: 1000 MB Bezpečnostní vyrovnávací paměť: 400 MB Paměť na podřízený proces php-fpm (v průměru): 30 MB Maximální možný počet procesů = (4096 - (1000 + 400)) / 30 = 89 Sudé číslo: 89 zaokrouhleno dolů na 80

Hodnotu zbývajících direktiv lze nastavit na základě očekávaného zatížení aplikace a také vzít v úvahu, co dalšího server dělá kromě běhu php-fpm (například DBMS také vyžaduje zdroje). Pokud je na serveru mnoho úloh, vyplatí se snížit počet počátečních / maximálních procesů.

Vezměme například v úvahu, že na serveru jsou 2 fondy www1 a www2 (například 2 webové zdroje), konfigurace každého z nich pak může vypadat takto:

pm.max_children = 40 ; 80 / 14 pm.start_servers = 15 pm.min_spare_servers = 15 pm.max_spare_servers = 25

Vzhledem k tomu, že vývoj technologií vedl k tomu, že každý programátor má nyní svůj vlastní počítač, jako vedlejší efekt máme tisíce různých knihoven, frameworků, služeb, API atd. pro všechny příležitosti. Ale když přijde tento případ života, vyvstává problém - co použít a co dělat, když to úplně nesedí - přepište to, napište vlastní od začátku nebo připojte několik řešení pro různé případy použití.

Myslím, že mnoho lidí si všimlo, že vytváření projektu často nespočívá ani tak v programování, jako spíše v psaní kódu pro integraci několika hotových řešení. Někdy se takové kombinace promění v nová řešení, která lze opakovaně použít v následných problémech.

Přejděme ke konkrétní „běžící“ úloze – objektové vrstvě pro práci s databázemi v PHP. Existuje velké množství různých řešení, od PDO po víceúrovňové (a podle mého názoru ne zcela vhodné v PHP) ORM motory.

Většina těchto řešení migrovala na PHP z jiných platforem. Často ale autoři neberou v úvahu vlastnosti PHP, což by značně zjednodušilo jak psaní, tak používání portovaných konstrukcí.
Jednou z běžných architektur pro tuto třídu úloh je vzor Active Record. Tato šablona se používá zejména k vytváření takzvaných entit, které se v té či oné podobě používají na řadě platforem, od perzistentních beanů v EJB3 po EF v .NET.

Vytvořme tedy podobnou konstrukci pro PHP. Spojme dvě super věci – hotovou knihovnu ADODB a slabě typované a dynamické vlastnosti objektů jazyka PHP.
Jednou z mnoha funkcí ADODB je tzv. automatické generování SQL dotazů pro vkládání (INSERT) a aktualizaci (UPDATE) záznamů na základě asociativních polí s daty.
Ve skutečnosti není nic vojenského, co by si vzalo pole, kde klíče jsou názvy polí a hodnoty jsou data a generují řetězec dotazu SQL. Ale ADODB to dělá chytřeji. Dotaz je založen na struktuře tabulky, která je předtím načtena z databázového schématu. Výsledkem je, že za prvé jsou v sql zahrnuta pouze existující pole a ne vše v řadě, za druhé je zohledněn typ pole - u řetězců jsou přidány uvozovky, formáty data mohou být tvořeny na základě časového razítka, pokud jej ADODB vidí místo řetězec v přenášené hodnotě atd. .

Nyní pojďme ze strany PHP.
Představme si takovou třídu (zjednodušeně).

Entita třídy( chráněné $pole = pole(); veřejná konečná funkce __set($jméno, $hodnota) ( ​​$this->pole[$jméno] = $hodnota; ) veřejná konečná funkce __get($jméno) ( return $ this- >fields[$name]; ) )

Předáním interního pole do knihovny ADODB můžeme automaticky generovat SQL dotazy pro aktualizaci záznamu v databázi s daným objektem.Zároveň odpadá těžkopádné návrhy mapování polí databázových tabulek na entitu založenou na XML objektová pole a podobně. Je pouze nutné, aby název pole odpovídal vlastnosti objektu. Protože na tom, jak jsou pole v databázi a pole objektu pojmenována, nezáleží na počítači, není důvod, aby se neshodovaly.

Pojďme si ukázat, jak to funguje ve finální verzi.
Kód pro dokončenou třídu se nachází na Gist. Jedná se o abstraktní třídu obsahující minimum nutné pro práci s databází. Podotýkám, že tato třída je zjednodušenou verzí řešení, které bylo testováno na několika desítkách projektů.

Představme si, že máme takové znamení:

CREATE TABLE `users` (`username` varchar(255) , `created` date , `user_id` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`user_id`))
Na typu databáze nezáleží - ADODB poskytuje přenositelnost na všechny běžné databázové servery.

Vytvořme třídu entity User na základě třídy Entity

/** * @table=users * @keyfield=user_id */ class User extends Entity()

To je vše.
Snadné použití:

$user = nový uživatel(); $user->username="Vasya Pupkin"; $user->created=time(); $user->save(); //uložit do úložiště //načíst znovu $thesameuser = User::load($user->user_id); echo $thesameuser ->uživatelské jméno;

Tabulku a pole klíče označujeme v pseudoanotacích.
Můžeme také určit pohled (například view =usersview), pokud, jak je tomu často, je entita vybrána na základě její tabulky s připojenými nebo vypočítanými poli. V tomto případě budou data vybrána z pohledu a tabulka bude aktualizována. Ti, kterým se takové poznámky nelíbí, mohou přepsat metodu getMetatada() a zadat parametry tabulky ve vráceném poli.

Co dalšího je užitečné na třídě Entity v této implementaci?

Můžeme například přepsat metodu init(), která se volá po vytvoření instance entity, a inicializovat výchozí datum vytvoření.
Nebo přetížit metodu afterLoad(), která je automaticky volána po načtení entity z databáze, a převést tak datum na časové razítko pro další pohodlnější použití.
Ve výsledku tak získáme ne o moc složitější strukturu.

/** * @table=users * @view=usersview * @keyfield=user_id */ class Uživatel rozšiřuje Entitu( chráněná funkce init() ( $this->created = time(); ) chráněná funkce afterLoad() ( $this ->created = strtotime($this->created); ) )

Můžete také přetížit metody beforeSave a beforeDelete a další události životního cyklu, kde můžete například provést ověření před uložením nebo některé další akce - například odstranit obrázky z nahrávání při mazání uživatele.

Načteme seznam entit podle kritéria (v podstatě podmínka pro WHERE).
$users = User::load("uživatelské jméno jako "Pupkin" ");
Třída Entity vám také umožňuje provádět libovolný, „nativní“ SQL dotaz, abych tak řekl. Chceme například vrátit seznam uživatelů s některými seskupeními na základě statistik. Nezáleží na tom, která konkrétní pole budou vrácena (hlavní je, že by tam mělo být user_id, pokud je potřeba s entitou dále manipulovat), stačí znát jejich jména, abyste měli přístup k vybraným polím. Při ukládání entity, jak je z výše uvedeného zřejmé, také nemusíte vyplňovat všechna pole, která budou v objektu entity přítomna, ta půjdou do databáze. To znamená, že nepotřebujeme vytvářet další třídy pro náhodné vzorky. Podobně jako anonymní struktury při načítání v EF, pouze zde se jedná o stejnou třídu entity se všemi metodami obchodní logiky.

Přísně vzato, výše uvedené metody získávání seznamů jsou poněkud mimo vzor AR. V podstatě se jedná o tovární metody. Ale jak Occamův starý muž odkázal, nevytvářejme entity nad rámec toho, co je nutné, a vytvářejme samostatného Správce entit nebo něco podobného.

Všimněte si, že výše uvedené jsou pouze třídy PHP a lze je rozšířit a upravit podle potřeby přidáním vlastností a metod obchodní logiky do entity (nebo do základní třídy Entity). To znamená, že obdržíme nejen kopii řádku databázové tabulky, ale obchodní entitu jako součást objektové architektury aplikace.

Kdo by z toho mohl mít prospěch? Samozřejmě ne pro ostřílené vývojáře, kteří věří, že používat něco jednoduššího, než je doktrína, není úctyhodné, a ani pro perfekcionisty, kteří jsou přesvědčeni, že pokud řešení nevytáhne miliardu volání do databáze za sekundu, pak to řešení není. . Soudě podle fór, mnoho běžných vývojářů pracujících na běžných (99,9 %) projektech dříve či později čelí problému najít jednoduchý a pohodlný objektový způsob přístupu k databázi. Potýkají se ale s tím, že většina řešení je buď nepřiměřeně sofistikovaná, nebo je součástí nějakého rámce.

P.S. Řešení z frameworku bylo vytvořeno jako samostatný projekt

1. GROUP BY one key

Tato funkce funguje jako GROUP BY pro pole, ale s jedním důležitým omezením: Je možný pouze jeden seskupovací "sloupec" ($identifikátor) ​​.

Funkce arrayUniqueByIdentifier(pole $pole, řetězec $identifikátor) ​​( $ids = pole_column($pole, $identifikátor); $ids = pole_unique($ids); $array = pole_filter($pole, funkce ($klíč, $hodnota ) use ($ids) ( return in_array($value, array_keys($ids)); ), ARRAY_FILTER_USE_BOTH); return $array; )

2. Detekce jedinečných řádků pro tabulku (dvourozměrné pole)

Tato funkce slouží k filtrování „řádků“. Řekneme-li, že dvourozměrné pole je tabulka, pak každý jeho prvek je řádek. Pomocí této funkce tedy můžeme odstranit duplicitní řádky. Dva řádky (prvky prvního rozměru) jsou stejné, pokud jsou všechny jejich sloupce (prvky druhého rozměru) stejné. Pro porovnávání hodnot "sloupců" platí: Pokud je hodnota jednoduchého typu, použije se při porovnávání samotná hodnota; jinak bude použit jeho typ (pole , objekt , zdroj , neznámý typ).

Strategie je jednoduchá: Vytvořte z původního pole mělké pole, kde prvky jsou implodovány do "sloupců" původního pole; pak na něj aplikujte array_unique(...); a jako poslední použít zjištěná ID pro filtrování původního pole.

Funkce arrayUniqueByRow(pole $table = , řetězec $implodeSeparator) ( $elementStrings = ; foreach ($table as $row) ( // Chcete-li se vyhnout upozorněním jako "Převod pole na řetězec". $elementPreparedForImplode = array_map(funkce ($pole) ( $valueType = gettype($field); $simpleTypes = ["boolean", "integer", "double", "float", "string", "NULL"]; $field = in_array($valueType, $simpleTypes) ? $field: $valueType; return $field; ), $row); return $table; )

Je také možné zlepšit porovnávání, detekovat třídu hodnoty "sloupce", pokud je jejím typem objekt.

$implodeSeparator by měl být víceméně komplexní, z.B. spl_object_hash($this) .

3. Detekce řádků se sloupci s jedinečným identifikátorem pro tabulku (dvourozměrné pole)

Toto řešení se opírá o 2. Nyní nemusí být celý „řádek“ jedinečný. Dva „řádky“ (prvky první dimenze) jsou nyní stejné, pokud všechny relevantní"pole" (prvky druhé dimenze) jednoho "řádku" se rovnají odpovídajícím "polím" (prvkům se stejným klíčem).

"Relevantní" "pole" jsou "pole" (prvky druhé dimenze), které mají klíč, který se rovná jednomu z prvků předávaných "identifikátorů".

Funkce arrayUniqueByMultipleIdentifiers(pole $tabulka, pole $identifikátory, řetězec $implodeSeparator = null) ( $arrayForMakingUniqueByRow = $removeArrayColumns($table, $identifiers, true); $arrayUniqueByRow = $arrayUniqueByarrayRowRowSeparow($); ByMultipleI identifiers = array_intersect_key ($table, $arrayUniqueByRow); return $arrayUniqueByMultipleIdentifiers; ) funkce removeArrayColumns(pole $table, pole $columnNames, bool $isWhitelist = false) (foreach ($table jako $rowKey => $array) ( if (is row )) ( if ($isWhitelist) ( foreach ($row as $fieldName => $fieldValue) (neif (!in_array($fieldName, $columnNames)) ( unset($table[$rowKey][$fieldName] ); ) ) ) else ( foreach ($row as $fieldName => $fieldValue) ( ​​​if (in_array($fieldName, $columnNames)) ( unset($table[$rowKey][$fieldName]); ) ) ) ) vrátit $ tabulku; )

PHP lze plnohodnotně nazvat „lidovým jazykem webového programování“, jen velmi těžko se hledá jiný jazyk, který by mu co do oblíbenosti mohl rovnocenně konkurovat. Rozhodl jsem se poznat lidi, kteří stojí za jeho vývojem, odpovídat na naléhavé otázky, diskutovat o nejnovějších inovacích a dokonce se pokusit nahlédnout do budoucnosti internetu. K tomu jsme se setkali s legendárními účastníky Základní tým PHP, kteří na vývoj tohoto jazyka přímo dohlížejí a vysloužili si pověst uznávaných světových odborníků v oblasti webových technologií.

Takže dnes přední vývojáři z Základní tým PHP— (Andrei Zmievski), (Stas Malyshev), (Ilia Alshanetsky).

Pro začátek nám prosím řekněte něco o sobě – co teď děláte a kde pracujete. Vzpomeňte si na příběh, jak jste se dostali do světa programování.

SM: Nyní žiji v USA a pracuji ve firmě, pracuji na infrastruktuře tohoto produktu - tzn. ty části systému, které poskytují základ pro obecnou funkčnost a poskytují rozhraní pro vývoj specifických modulů.

Pokud mluvíme o historii mého příchodu do programování, pak jsem začal zpátky ve škole, s programy publikovanými v časopise az nich“ Technologie - Mládež" I když se to zpočátku nedalo nazvat programováním – v podstatě jsem jen zadával programy vytištěné v časopise do paměti stroje a viděl, co se stalo. Ale pak jsem se chtěl sám naučit, jak přimět tento složitý (v té době) stroj, aby dělal, co jsem chtěl, a začal jsem zjišťovat – sám as pomocí starších – jak to celé funguje. Účastnil se kroužků, trávil hodiny v knihovně čtením zahraničních časopisů, psal programy pro své potěšení a pak pro peníze. Ukázalo se, že mě baví dělat počítače užitečné a k mému velkému štěstí je dnes taková dovednost na trhu práce žádaná.

Bylo by těžké vyjmenovat, co všechno mě na této cestě ovlivnilo, ale asi nejvíce na mě zapůsobily knihy, zejména díla (Mýtický muž-měsíc) a (Vězni běží v azylu – v ruském překladu „Psychiatrická léčebna v rukou pacientů“).

AZ: V San Franciscu žiji už 5 let a je to podle mě nejkrásnější město v Americe. Pracuji pro společnost. Přestože se jedná o relativně mladý startup, máme již zhruba 110-120 zaměstnanců. Široká škála společností po celém světě používá náš produkt k monitorování svých obchodních systémů a rychlému nalezení problémů. Máme také velké klienty, například Netflix, Priceline a další.

Pokud jde o můj milostný vztah k programování... Myslím, že je pravděpodobnější, že si tato profese vybere vás, než vy ji. Pamatuji si, že když mi bylo 9 let, dostal jsem svou první programovatelnou kalkulačku, ale už předtím jsem měl znatelné sklony k matematice, logice a technickým věcem - pokud si pamatuji, tyto schopnosti mi byly vlastní.

Jako názorný příklad toho, jak to všechno začalo, vám poskytnu příběh z dětství. Pak jsem jako většina sovětských dětí neměl doma vlastní počítač, takže jsem pravidelně docházel do počítačového centra, kde jsem si mohl na hodinu pronajmout stroj a pracovat na BASICu a Pascalu. Chodil jsem tam několikrát týdně, ale jednoho dne, když jsem přijel velmi brzy ráno, nechal jsem se tak unést, že jsem bezhlavě spadl do programu, který mě zaujal, a přitom úplně ztratil pojem o čase a zapomněl. že je čas jít domů.

Probudil jsem se, až když už se toto centrum zavíralo, ve 22 hodin. V té době už moji rodiče obvolali všechny mé přátele, učitele atd. hledali mě, ale naštěstí narazili na mě vracející se z centra. Tehdy jsem za to dostal tvrdou ránu, ale když se ohlédnu zpět, chápu to: odjakživa jsem psal programy a žil v tomto částečně virtuálním světě, takže moje současná profese je prostě pokračováním vzrušující cesty, která začalo v dětství.

IA:Žiji a pracuji v kanadském Torontu.

Co se týče mého vstupu do programování, je to pro mě stále překvapivé. Na úplném začátku mé cesty bylo programování spíše koníčkem, až na jednu zvláštní práci, kterou jsem na léto nějak sehnal, související s vývojem na nízké úrovni v C. Když jsem byl mladý, nikdy jsem si vědomě nedával cíle a neplánoval jsem to dělat profesionálně. Zatímco jsem si amatérsky šťoural se svými C programy, jednou jsem se podílel na svém prvním vlastním vývoji webu, který probíhal v Perlu. Tady začíná moje cesta k internetu a moje specializace na programování webu.

Bohužel, jak se tento projekt v Perlu rozrůstal, nejednotnost tohoto jazyka se mi stále více nelíbila a hostingová společnost, která mi v té době sloužila, mnou „mučená“, se jednoho dne sama nabídla, že vyzkouší PHP, které bylo pro to nové. čas. Tento jazyk se mi okamžitě zalíbil, protože byl lépe strukturovaný a svou syntaxí se blížil mému milovanému C. Vynikající online dokumentace – dokončila jsem na ni rychlou a konečnou migraci.


Ilja Alshanetsky

PHP 3 jsem začal používat tak aktivně, že se postupně začaly objevovat mé vlastní vývoje rozšiřující jeho možnosti, které jsem začal pravidelně nabízet na IRC kanálu jeho tvůrci Rasmusovi. Bylo ode mě tolik záplat a oprav, že ho to rychle omrzelo a dal mi přímý CVS přístup do repozitáře projektu. Od té doby se toho hodně napsalo a udělalo, dokonce jsem měl možnost být release managerem (PHP release master) pro jeho oblíbené verze 4.3, 5.1 a 5.2.

Mimochodem, paralelně s touto činností probíhala i spousta konzultační práce pro externí komerční zákazníky, pro které se soukromě řešily někdy velmi mimořádné problémy s výkonem, škálovatelností a bezpečností vlastních projektů vytvořených v PHP. Na jedné z těchto konzultací jsem se tak hluboce ponořil do jejich projektu, že jsem se nakonec stal partnerem této společnosti (Centah Inc.) a získal pozici CIO, kde v současnosti pracuji.

Jak jsi se dostal do PHP Core Teamu, jakou cestou jsi se tam dostal?

AZ: Dovolte mi odpovědět vlastním příkladem, ale nejprve trochu historie. S PHP jsem začal pracovat kolem roku 1998, tehdy to bylo PHP 3, jedna z dřívějších verzí. Přepisovali jsme velký projekt z jiného jazyka do PHP a potřeboval jsem najít podporu pro dnes už téměř zapomenutý . Takovou knihovnu jsem nenašel, ale moc se mi líbilo, že PHP má výbornou dokumentaci a API, tak jsem se rozhodl napsat vlastní rozšíření. Když jsem skončil, okamžitě jsem to poslal do PHP mailing listu. A pro mě nečekaně se rozhodli přidat to do dalšího vydání jazyka.

Následně jsem dostal přístup k CVS a začal jsem opravovat chyby, psát více různých funkcí atd. Koncem roku 1999 jsem byl jedním z nejaktivnějších členů skupiny a poté jsem navrhl uspořádat první setkání vývojářů PHP v Izraeli, kde by se diskutovalo o budoucnosti jazyka, a zařadil mě do tohoto mailing listu. Takže se nehlasovalo, náhodou jsem se do toho hned pustil Základní tým PHP.


Rasmus Lerdorf, tvůrce PHP

Tento druh důvěry a otevřenosti mě motivoval k tomu, abych stále více pracoval na kódu PHP. Po WDDX jsem pracoval na modulu session, pak jsem napsal spoustu funkcí pro práci s poli, pak jsem se rozhodl, že PHP potřebuje mít regulární výrazy podobné Perlu, tak jsem vytvořil modul PCRE. V té době už bylo PHP 4 dávno vydáno, ale velmi mě štvaly některé problémy s tím, jak objekty a třídy fungovaly (nebo spíše nefungovaly). Při této příležitosti jsem měl dlouhou korespondenci s Andim a Zeevem, kteří vytvořili , a výsledkem byla zásadně nová podpora Objektově orientované programování v tehdy novém PHP 5.

Poté jsem pracoval hlavně na kódu pro samotný Zend Engine a také jsem vytvořil nový modul tokenizeru. Od roku 2003 jsem společně s Rasmusem a tam rozjel projekt na podporu Unicode v PHP, ale to až jindy...

Co si myslíte, že je PHP tak populární?

AZ: Stává se, že v tuto chvíli píšu projekt v C++ a Pythonu, takže odpovím na základě této srovnávací zkušenosti a vypadám jako z této „jiné zvonice“.

Hlavní pro mě je, že PHP má bohaté a rozsáhlé API, pomocí kterého můžete jazyk rozšířit mnoha, i někdy nečekanými směry. Na druhou stranu od lidí často slyším, jak snadné pro ně bylo začít používat PHP a jak moc milují, že můžete napsat web nebo program během několika hodin. To je podstata PHP: je složité i jednoduché, staromódní i moderní, originální a vypůjčené nápady zvenčí – je prostě velmi všestranné.

Chyby zabezpečení jsou velkým bolehlavem webových programátorů a mnoha uživatelů jejich produktů. Když se podíváte zpět na své rozsáhlé zkušenosti, jaké jsou nejdůležitější a typické bezpečnostní problémy s PHP a jeho vývojáři? Můžete dát nějakou radu pro výchovu mladých PHP programátorů?

SM: Jednou z hlavních lekcí je, myslím, to, že zabezpečení kódu není vlastnost, kterou lze vštípit externě, nezávisle na zbytku kódu. Bezpečnost by měla být každodenní součástí práce od první minuty, od návrhu až po vydání hotového výrobku. Bylo učiněno několik pokusů přidat do PHP bezpečnostní prvky "zvenčí" - ale zkušenost ukazuje, že tyto pokusy jsou bez neustálé bdělosti ze strany programátora odsouzeny k neúspěchu. Platforma mu může pouze pomoci monitorovat zabezpečení kódu, ale nemůže toto zabezpečení zaručit bez úsilí z jeho strany.

Hlavní rada by tedy byla následující – nikdy nevěřte žádným externím datům, nebo datům, nad kterými je možná kontrola zvenčí. K 99 % bezpečnostních problémů dochází proto, že předpoklady o vstupních datech se ukážou jako nesprávné, a když následně dojde k útoku, kód se chová jinak, než vývojář zamýšlel. Vypěstujte si proto zvyk se vždy ptát – „co když se tento parametr nečekaně změní? Co když tento argument není použit tak, jak bylo zamýšleno? A podle toho svůj kód otestujte.

Moje další doporučení je, že místo kontroly „jestli v datech není něco nezákonného“ proaktivně transformujte data tak, aby bylo zaručeno, že budou tak, jak mají být. Tím se mnohem snáze vyvarujete chyb. Také se nespoléhejte na to, že se o zabezpečení postarají jiné části kódu – například pokud vytváříte dynamický databázový dotaz, vždy se ujistěte, že parametry a dotaz jsou generovány a filtrovány tak, aby sql injekce je nemožné - i když jste si jisti, že data jsou filtrována někde jinde (například na úrovni rámce). Pokud se pak externí kód změní tak, že se do vaší procedury náhle dostanou nefiltrovaná data, zranitelnost stále nevznikne.

Explozivní růst mobilních aplikací bude pravděpodobně pokračovat, ale mnoho z nich přejde na HTML5 jako univerzální platformu. V tomto ohledu bude potřeba vyvinout protokoly pro synchronizaci dat a také vyvinout modely, které umožní souběžnou práci jak s tradičními prohlížeči, tak s různými mobilními klienty, často s různými schopnostmi.

Obecně platí, že prohlížeč se konečně stane plnohodnotnou součástí webové infrastruktury, a proto některé povinnosti, které v současné době vykonává server, přejdou na stranu klienta. Proto bych doporučil lidem, kteří v současné době pracují s PHP, aby také drželi krok s nejnovějším vývojem v Javascriptu, HTML5, CSS3 atd.

Děkuji členům Základní tým PHP, který si, i když byl velmi zaneprázdněn, laskavě našel čas a zodpověděl dotazy našim čtenářům.

Postavy:


Andrej Zmievskij, jeden z kurátorů Projekt PHP, vývojář Zend Engine, tvůrce projektu a spoluautor populární učebnice, autor implementací Unicode a OOP v PHP. Ve volném čase se věnuje sportu, vaření piva a vaření. Rád čte a hodně cestuje.

Stas Malyshev, účastník Projekt PHP od roku 2000, správce verzí PHP 5.4, účastník mnoha projektů OpenSource. Ve volném čase intelektuální hry (sportovní verze „Co? Kde? Kdy?“, „Brain Ring“) a aikido.

Ilja Alshanetsky, bezpečnostní expert a jeden z nejstarších vývojářů PHP, vedoucí, správce verzí PHP 4.3, 5.1, 5.2, tvůrce enginu fóra, aktivní účastník mnoha projektů OpenSource. a na téma zabezpečení webového programování.

p.s.: Slibuji, že v novém roce 2013 zveřejním mnohem více mých VIP rozhovorů s předními světovými vývojáři - některá specifika nechť zatím zůstanou v tajnosti.