PHP 5.3 je stále nejpoužívanější
verzí PHP. Nicméně jde o verzi nepodporovanou, nevycházejí už ani záplaty
na závažné bezpečnostní díry. Podle trendů se
zdá, že verze 5.4 by ji mohla vystřídat po prázdninách. Ironií je, že
v ten moment i jí skončí podpora.
Jisté je, že v době vydání další verze Nette bude PHP 5.3 dávno
passé, tudíž jsem v masteru změnil minimální požadovanou verzi z PHP
5.3.1 na PHP 5.4.4.
Právě tohle setinkové číslo jsem zvolil s ohledem na Debian 7.0 Wheezy.
Opuštění větve 5.3 znamenalo řadu spíš kosmetických změn (DI,
Tracy),
odstranění drobného počtu workaroundů (magic quotes u Http,
Reflection,
Utils)
a výjimečně i užití nových tříd (Finder
nebo Component-Model).
Což potvrzuje, že verze PHP 5.3 byla skutečně hodně dobrá.
PHP 5.4 zároveň skýtá nové možnosti, první implementovanou byla
žádaná serializace objektu DateTime do
JSON. Dále se nabízí možnost nahradit Nette\Object
za
trait atd.
Na co jsem se ale hodně těšil byla normální syntax pro zápis polí
pomocí []
namísto šíleného array()
. A také
možnost používat v šablonách <?=
místo dlouhého
<?php echo
.
S jejich nasazením v masteru jsem ale váhal, protože by to udělalo
z cherry-pickování do starších větví peklo. Nicméně verze Nette 2.1 a
od května i 2.2 jsou ve stádiu, kdy se opravují jen závažné chyby,
které se v Nette objevují jen zřídkakdy, a v aktuální verzi 2.3 se
nové komity objevují jen svátečně, tudíž jsem si řekl, že netřeba to
odkládat a všechny repozitáře převedl na hezčí
syntax.
(Rebasování větví byl docela oříšek, rozepsal jsem se o tom včera.
Takový převod tabulátorů na mezery by musel být hotové peklo.)
Nástroj Code Checker
nyní kontroluje, aby se v repozitářích používala výhradně nová syntax
a nedocházelo k míchání obou zápisů polí.
Přechod na PHP 5.5 by přinesl taky jednu byť drobnou syntaktickou změnu:
konstantu
::class. A mohly by se použít nové funkce v
Nette\Utils\Image
a případně
Nette\Security\Password
, typ DateTime
by se
v typehintech nahradil za DateTimeInterface.
Přechod na PHP 5.6 by přinesl zejména nahrazení většiny
func_get_args()
& call_user_func_array()
za trojtečky
(včetně operátoru (expand)
v Latte). V pár případech by se
dalo využít i konstant obsahujících pole.
A přechod na PHP 7 by byla revoluce.
Jak jsem v projektech, které používají PHP 5.4 a
vyšší, převáděl starou syntaxi pro zápis polí array()
na
novou []
.
Samotný převod PHP souborů je úplně jednoduchý. Stačí použít PHP 5.4 Short Arrays Converter a
v repozitáři zavolat:
php /php54-arrays/convert.php .
Nástroj zamění syntax ve všech souborech *.php
a
*.phpt
v aktuálním adresáři a také ve všech
podadresářích. Změněné soubory jsem pak komitnul (příklad).
Oříšek je ale rebasování dalších větví na takto změněný
master.
Nakonec jsem na to šel přes filtry. Ale
plně zautomatizovat se mi to nepovedlo.
Nejprve je vhodné všechny větve rebasovat na master těsně před samotnou
změnou syntaxe.
Poté jsem si vytvořil filtr nazvaný phparray
, který bude
on-the-fly překládat v PHP souborech []
na array()
při checkoutu a obráceně při komitování. Tedy aby slučování probíhalo
při použití staré syntaxe, ale komitnulo se s novou.
Filtr se vytvoří v souboru .git/config
, v mém případě to
vypadalo takto:
[filter "phparray"]
clean = c:/php/php.exe w:/php54-arrays/convert.php
smudge = c:/php/php.exe w:/php54-arrays/convert.php -r
required
Aby se filtr při slučování používal (ale i při každém checkoutu,
cherry-picku atd), je nutné doplnit do .git/config
ještě
následující:
[merge]
renormalize = true
Filtr se bude aplikovat na soubory *.php
a *.phpt
,
což se definuje v souboru .git/info/attributes
(nepoužívejte
.gitattributes
, protože jde o dočasnou záležitost a nechceme
ji komitovat):
*.php filter=phparray
*.phpt filter=phparray
Teď by ve větvi mělo fungovat git rebase master
. Bez
konfliktů, které by bylo nutné ručně řešit. Jenže ouha, konflikty se mi
vytvářely (na Windows; je možné, že na Linuxu to půjde) a když jsem je
chtěl řešit v TortoiseGit, objevovala se hláška, že na souboru
.git/index.lock
je zámek atd. Zkoušel jsem experimentovat
s dalšími nastaveními pro merge, ale bez výsledku.
Zkusil jsem dělat rebase ručně: což znamená nejprve větev resetnout na
master (git reset master --hard
) a pak jednotlivé komity
přidávat pomocí git cherry-pick <hash>
. Nedělal jsem to
z příkazové řádky, ale pomocí TortoiseGit. I nadále mi hlásil, že
některé soubory neumí automaticky sloučit a je vyžadován ruční zásah,
ale vždy stačilo soubor rozkliknout do TortoiseGitMerge a rovnou stisknout
Mark as resolved.
Bylo to otravné, ale fungovalo to a postupně jsem „rebasoval“ všechny
větve. Poté jsem filtr z .git/config
a
.git/info/attributes
smazal.
Proč to nešlo úplně automaticky, nemám páru, nicméně bylo snazší
hodinu klikat, než dva dny studovat Git.
Command-line script to convert between array()
and
PHP 5.4's short syntax []
. It uses native PHP tokenizer, so
conversion is safe. The script was successfully tested against thousands of
PHP files.
Download from GitHub
To convert all *.php
and *.phpt
files in whole
directory recursively or to convert a single file use:
php convert.php <directory | file>
To convert source code from STDIN and print the output to STDOUT use:
php convert.php < input.php > output.php
To convert short syntax []
to older long syntax
array()
use option --reverse
:
php convert.php --reverse [<directory | file>]
Způsob, jak se vyvíjejí aplikace v PHP, se v posledních
5 letech dramaticky proměnil. Nejprve jsme opouštěli čisté PHP a učili se
používat frameworky, později přišel Composer a s ním instalace knihoven
z příkazové řádky a nyní nastává konec frameworků, jak je známe.
Monolitické frameworky se postupně rozpadají do samostatných (decoupled)
komponent. A to přináší řadu výhod. Zatímco dříve bylo použití jen
jedné části frameworku obtížné až nemožné, dnes si prostě
nainstalujete jeho komponentu. Vývojový cyklus jednotlivých komponent může
mít různé tempo. Mají vlastní repozitáře, issue trackery, mohou mít
vlastní vývojářské týmy.
Komponenty můžete aktualizovat na nové verze průběžně, bez čekání,
než vyjde další verze celého frameworku. Nebo naopak se můžete rozhodnout
určitou komponentu neaktualizovat, třeba kvůli BC breaku.
Význam slova framework se tak posouvá, o verzích už takřka nelze
hovořit. Místo frameworku XYZ ve verzi 2.3.1 používáte sadu komponent
v různých verzích, které spolu fungují.
Rozdělení frameworku na komponenty je dost složité. Nette to trvalo
2 roky a hotovo bylo loni. Naprostou nutností bylo prosazení se Composeru a
také důsledné používání dependency injection. Nette dnes tvoří přes
20 samostatných repozitářů a v tom původním zbyla jen jediná
třída.
Všechny významné frameworky, jako Symfony, Zend, Laravel nebo CakePHP,
jsou rozčleněné do komponent, byť k dotažení chybí ještě jeden krok:
rozdělení do samostatných repozitářů (namísto náhražky v podobě Git
subtree split). Zend slibuje, že s tím přijde ve verzi 2.5, uvidíme, co
Symfony.
Komponování Nette
Dlouhým úvodem jsem se vás snažil přivést na myšlenku, že dívat se
na Nette jako na framework v nějaké konkrétní verzi je překonané. Že
šikovnější je k němu přistupovat jako k sadě komponent.
Tj. namísto uvádění závislosti na nette/nette
uvádět
závislosti na konkrétních komponentách. Tak to nyní dělá
i Sandbox. Jako základ budoucí aplikace může posloužit i Nette Web Project, což je
úplně minimalistická obdoba Sandboxu. Stáhněte jej pomocí
composer create-project nette/web-project
a vyhoďte z composer.json
komponenty, které nepotřebujete.
Zrychlíte tak operace Composeru.
Rychleji se k vám dostanou i bugfixy. Po opravení chyby lze hned
u příslušné komponenty tagnout novou verzi, zatímco cyklus uvolňování
verzí celého frameworku je mnohem pomalejší.
Pokud tvoříte doplňky pro Nette, tak vůbec neváhejte a hned nahraďte
závislost na nette/nette
výčtem skutečně požadovaných
komponent.
Samozřejmě i nadále budou vycházet nové verze frameworku jako doposud,
bude fungovat require nette/nette
a pro verzi 2.3 budou vycházet
i distribuce v archivech ZIP. Ale jejich význam bude pomalu upadat.
Nette se v anketě Best
PHP Framework for 2015 pořádané magazínem SitePoint umístilo na
úžasném 3. místě. Moc děkuji všem za hlasy, tak skvělý výsledek
jsem opravdu nečekal.
Těší mě na tom, že uživatelé jsou s Nette nejspíš spokojení, jinak
by asi hlasy neposílali. A také samozřejmě fakt, že Nette tím na sebe
upozornilo ve světě, kde se o něm kvůli jazykové bariéře
tolik neví.
Na výsledcích je zajímavé i to, že si člověk uvědomí, jak velké
množství PHP frameworků se reálně používá, že existují i další
populární „lokální frameworky“ a že je tu stále dost těch, kteří
žádný framework nepoužívají.
Jednou z nejzajímavějších částí Nette, kterou
vychvalují i uživatelé jiných frameworků, je Dependency Injection Container (dále
Nette DI). Podívejte se, jak snadno jej můžete použít kdekoliv,
i mimo Nette.
Mějme aplikaci pro rozesílání newsletterů. Kód jednotlivých tříd
jsem zjednodušil na dřeň. Máme tu objekt představující email:
class Mail
{
public $subject;
public $message;
}
Někoho, kdo ho umí odeslat:
interface Mailer
{
function send(Mail $mail, $to);
}
Přidáme podporu pro logování:
interface Logger
{
function log($message);
}
A nakonec třídu, která rozesílání newsletterů zajišťuje:
class NewsletterManager
{
private $mailer;
private $logger;
function __construct(Mailer $mailer, Logger $logger)
{
$this->mailer = $mailer;
$this->logger = $logger;
}
function distribute(array $recipients)
{
$mail = new Mail;
...
foreach ($recipients as $recipient) {
$this->mailer->send($mail, $recipient);
}
$this->logger->log(...);
}
}
Kód respektuje Dependency Injection, tj. že každá třída pracuje
pouze s proměnnými, které jsme jí předali. Také máme možnost si
Mailer
i Logger
implementovat po svém,
třeba takto:
class SendMailMailer implements Mailer
{
function send(Mail $mail, $to)
{
mail($to, $mail->subject, $mail->message);
}
}
class FileLogger implements Logger
{
private $file;
function __construct($file)
{
$this->file = $file;
}
function log($message)
{
file_put_contents($this->file, $message . "\n", FILE_APPEND);
}
}
DI kontejner je nejvyšší architekt, který umí stvořit
jednotlivé objekty (v terminologii DI označované jako služby) a poskládat
a nakonfigurovat je přesně podle naší potřeby.
Kontejner pro naši aplikaci by mohl vypadat třeba takto:
class Container
{
private $logger;
private $mailer;
function getLogger()
{
if (!$this->logger) {
$this->logger = new FileLogger('log.txt');
}
return $this->logger;
}
function getMailer()
{
if (!$this->mailer) {
$this->mailer = new SendMailMailer;
}
return $this->mailer;
}
function createNewsletterManager()
{
return new NewsletterManager($this->getMailer(), $this->getLogger());
}
}
Implementace vypadá takto, aby:
- se jednotlivé služby vytvářely, až když je potřeba (lazy)
- dvojí volání
createNewsletterManager
využívalo stále
stejný objekt loggeru a maileru
Vytvoříme instanci Container
, necháme ji vyrobit managera a
můžeme se pustit do spamování uživatelů newslettery:
$container = new Container;
$manager = $container->createNewsletterManager();
$manager->distribute(...);
Podstatné na Dependency Injection je, že žádná třída nemá závislost
na kontejneru. Tudíž jej můžeme klidně nahradit za jiný. Třeba za
kontejner, který nám vygeneruje Nette DI.
Nette DI
Nette DI je totiž generátor kontejnerů. Instruujeme ho (zpravidla) pomocí
konfiguračních souborů a třeba tato konfigurace vygeneruje cca totéž, jako
byla třída Container
:
services:
- FileLogger( log.txt )
- SendMailMailer
- NewsletterManager
Zásadní výhodou je stručnost zápisu. Navíc jednotlivým třídám
můžeme přidávat další a další závislosti často bez nutnosti do
konfigurace zasahovat.
Nette DI vygeneruje skutečně PHP kód kontejneru. Ten je proto extrémně
rychlý, programátor přesně ví, co dělá, a může ho třeba
i krokovat.
Kontejner může mít v případě velkých aplikací desetitisíce
řádků a udržovat něco takového ručně by už nejspíš ani
nebylo možné.
Nasazení Nette DI do naší aplikace je velmi snadné. Nejprve jej
nainstalujeme Composerem (protože stahování zipů je tááák
zastaralé):
composer require nette/di
Výše uvedenou konfiguraci uložíme do souboru config.neon
a
pomocí třídy Nette\DI\ContainerLoader
vytvoříme kontejner:
$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function($compiler) {
$compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
a pak jej opět necháme vytvořit objekt NewsletterManager
a
můžeme rozesílat emaily:
$manager = $container->getByType('NewsletterManager');
$manager->distribute(['john@example.com', ...]);
Ale ještě na chvíli zpět ke ContainerLoader
. Uvedený zápis
je podřízen jediné věci: rychlosti. Kontejner se vygeneruje jednou, jeho
kód se zapíše do cache (adresář __DIR__ . '/temp'
) a při
dalších požadavcích se už jen odsud načítá. Proto je načítání
konfigurace umístěno do closure v metodě
$loader->load()
.
Během vývoje je užitečné aktivovat auto-refresh mód, kdy se kontejner
automaticky přegeneruje, pokud dojde ke změně jakékoliv třídy nebo
konfiguračního souboru. Stačí v konstruktoru ContainerLoader
uvést jako druhý argument true
.
Jak vidíte, použití Nette DI rozhodně není limitované na aplikace
psané v Nette, můžete jej pomocí pouhých 3 řádků kódu nasadit
kdekoliv. Zkuste si s ním pohrát, celý příklad je dostupný na GitHubu.
V Nette je k dispozici nástroj LinkGenerator
pro vytváření odkazů bez nutnosti použití presenterů a přitom stejně
pohodlně. Jak ho použít?
Ukážeme si to na příkladu třídy, která odesílá emaily. Kód emailu
může vypadat nějak takto: (všechny příklady jsou pro Nette
2.4 nebo vyšší)
<title>Subject of message</title>
<p>Hello {$name} <a n:href="Homepage:">click here</a></p>
Třídě předám
LinkGenerator a ta si jej uloží do proměnné
$this->linkGenerator
.
class MailSender
{
/** @var Nette\Application\LinkGenerator */
private $linkGenerator;
function __construct(Nette\Application\LinkGenerator $generator)
{
$this->linkGenerator = $generator;
}
Samotné odesílání emailů bude provádět metoda sendEmail
,
která si vytvoří objekt Latte:
function sendEmail()
{
$latte = new Latte\Engine;
$latte->setTempDirectory(...);
...
}
U Latte je vhodné nastavit temp directory , aby se šablona s každým
emailem nemusela znovu kompilovat, nicméně pokud jich posíláte jen několik
denně, nebo třeba hodně, ale v jednom requestu (tj. pomocí jednoho objektu
$latte
), není to nutné, kompilace je blesková. Kde cestu k temp
složce vzít? Můžeme si ji opět předat, ale chytřejší řešení je
místo toho si předat objekt (tzv. továrničku), který dovede
nakonfigurované Latte vyrobit:
/** @var Nette\Bridges\ApplicationLatte\ILatteFactory */
private $latteFactory;
// $latteFactory opět předáme přes konstruktor
function sendEmail()
{
$latte = $this->latteFactory->create();
// nainstalujeme do $latte makra {link} a n:href
Nette\Bridges\ApplicationLatte\UIMacros::install($latte->getCompiler());
$params = [ // proměnné do šablony
'name' => $order->getName(),
...
];
// a vygenerujeme HTML email
$html = $latte->renderToString(__DIR__ . '/email.latte', $params);
// a odešleme jej, viz dále
}
Tady ještě jednou přeruším, protože musím zmínit ještě jednu
alternativu, a to nechat si vygenerovat přímo známý objekt
$template
, který bude obsahovat například proměnné
$basePath
apod, už s nakonfigurovaným Latte. Vyměním tedy
latteFactory
za templateFactory
:
/** @var Nette\Application\UI\ITemplateFactory */
private $templateFactory;
// $templateFactory si opět předáme přes konstruktor
function sendEmail()
{
$template = $this->templateFactory->createTemplate();
$template->name = $order->getName();
$template->setFile(__DIR__ . '/email.latte');
}
Jde o obdobu použití $this->createTemplate()
uvnitř
presenteru či komponenty.
Zbytek metody sendEmail
bude vypadat takto:
...
$mail = new Nette\Mail\Message;
$mail->addTo($order->email);
$mail->setHtmlBody($html); // nebo setHtmlBody($template)
$this->mailer->send($mail); // $mailer si opět předáme konstruktorem
}
A teď zbývá poslední krok! Zapojit do toho LinkGenerator, ke kterému se
konečně dostávám. Je to snadné:
Tedy buď (pokud si předáváme latteFactory
):
$latte->addProvider('uiControl', $this->linkGenerator);
nebo (pokud jdeme cestou templateFactory
):
$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
O té chvíle můžete používat makro {link}
nebo
n:href
.
LinkGenerator generuje všechny URL absolutní, tedy včetně
http://example.com
. Taktéž na moduly pohlíží absolutně,
tudíž v odkazech neuvádějte na začátku dvojtečku ani //
,
není to potřeba a vlastně tomu ani nebude rozumět.
Pokud v routeru používáte relativní cesty, což je velmi časné,
generátor bere doménu z aktuálního HTTP requestu. Ale v CLI žádný HTTP
request pochopitelně neexistuje. Lze jej však podstrčit třeba
v config.neon:
services:
application.linkGenerator:
arguments:
refUrl: Nette\Http\UrlScript('http://example.com')
Celý kód by vypadal tedy nějak takto:
<?php
use Nette\Application\LinkGenerator;
use Nette\Bridges\ApplicationLatte\ILatteFactory;
use Nette\Mail\IMailer;
class MailSender
{
/** @var LinkGenerator */
private $linkGenerator;
/** @var ILatteFactory */
private $latteFactory;
/** @var IMailer */
private $mailer;
function __construct(LinkGenerator $generator, ILatteFactory $latteFactory, IMailer $mailer)
{
$this->linkGenerator = $generator;
$this->latteFactory = $latteFactory;
$this->mailer = $mailer;
}
function sendEmail()
{
$latte = $this->latteFactory->create();
// nainstalujeme do $latte makra {link} a n:href
Nette\Bridges\ApplicationLatte\UIMacros::install($latte->getCompiler());
$latte->addProvider('uiControl', $this->linkGenerator);
//$order = ...;
$params = [
'name' => $order->getName(),
// ...
];
$html = $latte->renderToString(__DIR__ . '/email.latte', $params);
$mail = new Nette\Mail\Message;
$mail->addTo($order->email);
$mail->setHtmlBody($html);
$this->mailer->send($mail);
}
}
Jak zprovoznit CSS Flexbox na
iOS zařízeních aneb pár poznámek pro sebe, až zase příště budu zoufat,
proč to neflexí, a tápat v paměti, jak jsem to minule vyřešil.
Prefixy
Safari stále ještě, i ve verzi 8.1, vyžaduje pro Flexible Box prefixy.
Jsi opět překvapený, že? Takže tam hezky doplň
display: -webkit-flex
nebo
-webkit-flex-wrap: wrap
atd.
Pořadí
Záleží na pořadí deklarací! Tohle funguje:
-webkit-flex-wrap: wrap;
-webkit-justify-content: space-between;
flex-wrap: wrap;
justify-content: space-between;
display: -webkit-flex;
display: flex;
Zatímco tohle pořadí, které se ti líbí více, na iPhone a iPadu vůbec
neflexí:
display: -webkit-flex;
-webkit-flex-wrap: wrap;
-webkit-justify-content: space-between;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
Jak udělat mezeru mezi prvky?
Řešíš, jak zajistit minimální mezeru mezi prvky v natahovacím
kontejneru s justify-content: space-between
? Vždycky nad tím
dlouze dumáš, googlíš to a nikdy jsi nic nevygooglil.
Mezera má být natahovací, ale nesmí jít pod určité minimum. A krajní
prvky musí přiléhat ke kraji.
Můžeš prvkům nastavit margin-right: x
a kontejneru
margin-right: -x
, ale to trošku rozhodí layout a na mobilu půjde
stránku horizontálně posouvat. Třeba ti někdo poradí něco
lepšího… Řešením je obalit kontejner do prvku s
overflow: hidden
.
Nette ve verzi 2.3 bude case sensitive. Proč a co to
konkrétně znamená?
Case sensitivity, anglicky „citlivost na velikost písmen“, znamená, že
například Homepage
a homepage
jsou dva naprosto
rozdílné řetězce. PHP je citlivé na velikost písmen u proměnných,
ignoruje ji u tříd a metod. JavaScript, C#, Ruby nebo XML jsou citlivé
u všech identifikátorů, naopak HTML je case insensitive. Souborový systém
na Linuxu je case sensitive, zatímco na Windows a Macu nikoliv. Atd.
Začínal jsem na jazycích, které nebyly na velikost písmen citlivé, a
připadalo mi šílené, že některé jiné jsou. „To si jako u každého
identifikátoru musím pamatovat, které písmenko je malé a které velké?“.
Tohle byla lichá obava, funguje to stejně jako v přirozeném jazyce, prostě
stačí znát, že vlastní jména se píší s velkým počátečním
písmenem, nikoliv to, že jeden konkrétní člověk se jmenuje
Franta
a ne franta
.
Nicméně mám rád pravidlo „buď velkorysý v tom, co přijímáš, a
striktní v tom, co odesíláš“ a protože striktní lpění na citlivosti
může být až
komické (Nabla je automat), Nette bylo vůči velikosti písmen
tolerantní.
Konkrétně šlo o
- jména presenterů
- některé parametry v cestě URL
- názvy tříd u autoloadingu a DI kontejneru
Být tolerantní v prostředí, které je na velikost písmen citlivé, ba
co hůř, které je citlivé v závislosti na operačním systému apod,
přináší řadu úskalí. Například URL lišící se jen velikostí písmen
mohou mít zcela odlišný
obsah, atd. A přitom vlastně jen tolerujete, že někdo píše jak motejlek.
Proto od verze 2.3 bude Nette na velikost písmen citlivé.
A protože se Nette vždy snaží o co nejbezproblémovější přechod,
bude chyby ve velikosti písmen detekovat a upozorní na ně.
Občas dostávám otázky, proč Nette nemá přesný
harmonogram vydávání verzí, kde by bylo uvedeno, kdy přesně vyjde
příští verze a jak dlouho bude podporovaná. Pokusím se vysvětlit, jak to
v Nette funguje.
Podle mého je ideální vydávat ročně jednu až dvě nové větší
verze. Rychlejší a zejména pomalejší vydávání způsobuje různé
komplikace, a ony 1–2 verze ročně se ukázaly jako ideál.
Zároveň přibližně každých 6 týdnů vydávám opravné setinkové
verze. Někdy je interval kratší, protože se objeví chyba, kterou je třeba
opravit co nejdřív, jindy je delší, protože k vydání verze
není důvod.
Podporu pro každou verzi se snažím držet dlouho:
- Nette 0.9 vyšlo 8/2009, poslední 0.9.7 vyšla 1/2012 (2,5 roku)
- Nette 2.0 vyšlo 2/2012, poslední 2.0.18 vyšla 12/2014 (2,5 roku)
- Nette 2.1 vyšlo 12/2013, aktuální 2.1.9 uvádí, že
podpora bude trvat do 1/2016 (2,1 roku)
Podpora tedy vždy trvá minimálně 2 roky. Pravdou je, že tato
informace nebyla explicitně na webu zmíněna, proto jsem ji doplnil na
stránku download.
Související otázkou je i podpora konkrétní verze PHP. Před nějakou
dobou jsem sliboval,
že PHP 5.3 bude podporované ještě pár let, a skutečně nadcházející
Nette 2.3 (vyjde asi na přelomu února a března) je stále s PHP
5.3 kompatibilní, tedy minimálně dva roky ještě bude 5.3 podporované.
(Nicméně téměř jistě příští verze Nette už 5.3 opustí.)
Zpátky k harmonogramu vydávání nových verzí. Předvídatelné a
pravidelné vydání nových verzí je z mého pohledu ideální, na rozdíl od
kalendáře s přesnými daty, kdy která verze v budoucnu vyjde. Koneckonců
ho téměř žádný jiný podobný open source projekt nemá.
Samozřejmě chápu, že je prima pocit vědět, kdy která verze vyjde,
také bych rád věděl, kdy třeba vyjde PHP 7.0, ale zároveň rozumím, že
nikdo z PHP mi přesné datum nedá.
Vydávání nové verze je poměrně náročný proces, do kterého zasahuje
hodně faktorů, a tím hlavním je být s výsledkem spokojený a stát si za
ním. Kdyby měl do toho ještě zasahovat faktor pevného data, tak to bude jen
na úkor něčeho jiného. A to nechci.
Dovedu si představit typy projektů, kde naopak přesný harmonogram je
výhodou, ale co funguje jinde, není nutně vhodné i pro Nette.
Doplnění: aby nedošlo k nedorozumění, je samozřejmě potřebné,
aby se tým vývojářů domluvil na harmonogramu vydání příští verze,
buď mezi sebou interně, nebo veřejně jako v případě PHP timeline, což je při
koordinaci velkého počtu vývojářů nutnost. Článek se týkal něčeho
jiného, tedy veřejných příslibů, kdy přesně v následujících letech
vyjde která verze.)