[2009-04-01] Parametry Debug::enable() a vylepšení profileru

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8227
+
0
-

První parametr metody Debug::enable() se z historických důvodů používal k určení úrovneň sledovaných chyb (např. E_ALL | E_STRICT). Historické důvody jsou přežité, jeho význam se změnil. V tuto chvíli slouží jako přepínač mezi produkčním a vývojovým módem. Pokud je jeho hodnota NULL nebo některá z konstant E_ALL apod, je ignorován.

Místo původního

Debug::$productionMode = TRUE;
Debug::enable();

Lze použít

Debug::enable(TRUE);

Nebo ještě lépe

Debug::enable(Debug::PRODUCTION);

Dále existují konstanty

Debug::enable(Debug::DEVELOPMENT); // totéž jako Debug::$productionMode = FALSE;
Debug::enable(Debug::DETECT); // použije se autodetekce, totéž jako když parametr vynecháme

Zároveň byl vylepšen profiler, má position:static a možnost skrývání.

nAS
Člen | 277
+
0
-

Děkujeme!

phx
Člen | 651
+
0
-

Takze ladenka uz neumi nastavit uvoven sledovani chyb? (E_ALL | E_STRICT)

Patrik Votoček
Člen | 2221
+
0
-

Omlouvám se ale nechtěně jsem měl nahozenu revizi 251 kde to ještě není… http://code.google.com/…/source/diff?…
Něják nestíhám tempo vydávání revizí v posledních dvou dnech… :-(

Editoval vrtak-cz (1. 4. 2009 16:14)

Honza Marek
Člen | 1664
+
0
-

Je to tak i v dokumentaci, ale nechce se mi to opravovat, když jsem tohle neověřil.

romansklenar
Člen | 655
+
0
-

Ale jsou tam … V Environment jsou to jen názvy módů a DETECT tam vůbec není.

Editoval romansklenar (1. 4. 2009 16:00)

David Grudl
Nette Core | 8227
+
0
-

Trošku jsem se obával možné záměny Debug::DEVELOPMENT a Environment::DEVELOPMENT. Jestli kvůli blbuvzdornosti změnit implementaci tak, aby fungovalo obojí. (Environment::DEVELOPMENT je řetězec, Debug::DEVELOPMENT je FALSE).

Jakub Šulák
Člen | 222
+
0
-

Jen se zeptám, k čemu je používáná funkce ini_set v případě, kdy mám v bootstrap.php:

Debug::enable(Debug::DETECT,‚%appDir%/log/php_error.log‘,$emailHeaders);

a v config.ini:
mode.production = true;

vyhodí mi to chybu, jelikož máme zakázaný ini_set(). Když je ale v config.ini:
mode.production = false;
jede to v pohodě.

Můžete mi prosím napsat, k čemu se tam to ini_set používá?
Díky

romansklenar
Člen | 655
+
0
-

Třeba právě k tomu určení souboru do kterého se má logovat a jestli se mají chyby zobrazovat.

Každopádně tobě to myslím padá tady tak si to budeš muset zakomentovat.

Editoval romansklenar (6. 4. 2009 16:53)

Jakub Šulák
Člen | 222
+
0
-

Jo, jen nerumím jak funguje tohle:

bootstrap.php
Environment::loadConfig();
Debug::enable(Debug::DETECT);

config.ini
[production < common]
mode.production = true
mode.debug = no

Myslel jsem si, že pokud v config.ini definuji, že v production mode je debugování vypnuté. Ale asi to takto není, že? Musím mít v bootstrapu nějakou vyjímku, kde budu spouštět Debug::enable() jen pokud budu mít nastaveno mode.debug=yes?

romansklenar
Člen | 655
+
0
-

Když zavoláš Debug::enable() tak se ti prostě zavolá, on ten mode.debug slouží k něčemu jinému, ale teď ti z hlavy neřeknu přesně co ovlivňuje (zkus dokumentaci), takže odpověď no tvoji otázku zní – ano, pokud ho chceš spouštěť v závislosti na mode.debug tak si budeš muset do bootstrapu dát podmínku, něco na způsob

if (Environment::isDebugging()) Debug::enable(...);

Editoval romansklenar (6. 4. 2009 17:23)

Jakub Šulák
Člen | 222
+
0
-

Koukal jsem do dokumentace i do fóra, ale úplně moudrý z toho nejsem:

3 věci:

Envirovment…nastavuje prostředí a to buď manuálně, nebo pomocí autodetekce
Config.ini.....nastavíme pro dané prostředí režim pomocí mode.debug…?
Debug.enable().je na co? Čekal bych, že když mám nastavený Debug.enable(Debug::DETECT), tak když dám, že v případě kdy se Envirovment nastaví autodetekcí na Production vezme se config.ini:
V tom mohu definovat mode.production: true/false (to je k čemu?). Pokud nastavím mode.debug=no, stejně mi v produkčním režimu spadne aplikace na ini_set() – proč ale, když jsem mu řekl, že v produkčním módu nemá debugovat?

Melu asi páté přes deváté, ale fakt mám s tou terminologií a návaznostma velký problém…

díky

EDIT: Ještě praktický dotaz, jde teda nějak rozumně (čti: bez psaní vlastní log class) bez ini_set() logovat chyby do souboru na produkčním serveru?

Editoval Jakub Šulák (7. 4. 2009 19:21)

David Grudl
Nette Core | 8227
+
0
-

mode.debug je něco docela jiného, to sem nepatří.

Nastavuje se režim production. Z toho důvodu, že Nette\Debug lze provozovat i mimo aplikace postavené na zbytku Nette (tedy i bez Nette\Environment) a také proto, že logováníhodné chyby se mohou objevit i při používání Environment a načítání konfigurace z config.ini, je Nette\Debug na Nette\Environment nezávislý a je vhodné ho spouštět jako úplně prvního.

Z toho logicky vyplývá, že ať už nastavíme (později) v config.ini jako mode.production cokoliv, vliv na Debug to mít nemůže. Může klidně dojít k situaci, že Debug beží v jiném režimu než Environment.

Není to ideální situace a pokud najdete řešení, rád jej implementuju. Zatím je nejschůdnější, nechci-li se spoléhat na autodetekci a nastavím-li parameter u Debug::enable() manuálně, tak zároveň manuálně nastavit Environment::setMode('production', ...).

David Grudl
Nette Core | 8227
+
0
-

Jakub Šulák napsal(a):

EDIT: Ještě praktický dotaz, jde teda nějak rozumně (čti: bez psaní vlastní log class) bez ini_set() logovat chyby do souboru na produkčním serveru?

Bez ini_set (nebo ekvivalentního nastavení v .htaccess) nejde logovat chyby do souboru. Nepomůže ani vlastní log class, ta zachytí jen nedostatečný okruh chyb.

Jakub Šulák
Člen | 222
+
0
-

No tak ale nějak to vyřešit musím, ini_set() jen tak nebude, tak lepší nedostatečný okruh chyb než žádný ;-)

romansklenar
Člen | 655
+
0
-

Zkus se zeptat na hostingu, jestli by ti ty direktivy, co se nastavují v Debug pomocí ini_set nenastavili. Možná by stačily jen error_log a log_errors.

Editoval romansklenar (9. 4. 2009 11:50)

Honza Marek
Člen | 1664
+
0
-

Tak to nastaví a Debug stejně bude vyhazovat výjimku :-D

romansklenar
Člen | 655
+
0
-

Mám stejně postižený hosting, musí se zakomentovat ten řádek, o kterém jsem psal výše a nebude to vyhazovat žádné výjimky a když nastaví ty direktivy, dosáhne toho čeho chce bez toho aniž by psal nějakou svou logovací class, čemuž se snaží vyhnout.

Jakub Šulák
Člen | 222
+
0
-

Jo to mě napadlo a bylo mi to i schváleno.
Neznám přesně ty direktivy, ale vytáhl jsem si je z nette, na produkčním serveru by to mělo tedy být takto:

ini_set(‚error_log‘, ‚logfile.log‘);
ini_set(‚display_startup_errors‘, FALSE);
ini_set(‚display_errors‘, FALSE);
ini_set(‚html_errors‘, TRUE);
ini_set(‚log_errors‘, TRUE);

?

A další věc, i když mi to nastaví, Nette mi stále bude házet chybu na řádku 352 Debug.php, kde je ini_set() použito, že? Nedělá funkce ini_set() nejdřív ini_get() a teprve pokud je hodnota jiná tak ji přepíše, nebo ano? Nešlo by tohle dodat do Nette? Pokud chci použít ini_set, nejdřív se zeptám, zda ta hodnota už není nastavena…?

romansklenar
Člen | 655
+
0
-

Tam se tomu nevyhneš, já si to tam přímo upravuju tím že tam přidám podmínku, na localu si Nette aktualizuju přes svnko, takže se ty změny co tam udělám nepřepíšou, pak to přes svn vyexportuju (abych se zbavil všech těch meta .svn adresářů) a nahraju na server. Horší je to už s compact verzí…

David Grudl
Nette Core | 8227
+
0
-

Zkusil jsem Debug upravit, můžete to vyzkoušet?

Jakub Šulák
Člen | 222
+
0
-

Bohužel jsem to zatím nestihl ještě vyzkoušet, ale vypadá to, že to takto snad poběží. díky

Přesto bych však udělal změnu. Toto řeší použití ini_set() zde, ale já bych byl pro nějaké kompletnější řešení formou nějaké funkce:

<?php
function ini_set_extended($declaration, $value)
{
  if (ini_get($declaration)!==$value){
    if (function_exists('ini_set')){
      ini_set($declaration, $value);
      return TRUE;
    }else{
      throw new Exception('ini_set() is not allowed');
    }
  }else{
    return TRUE;
  }
}
?>

A nahradil takto všechny výskyty ini_set() v Nette. Tak by bylo možné používat všechny vlastnosti (i do budoucna), které v Nette budou používat ini_set() za předpokladu, že je ini_set() zakázáno, ale je možné konfiguraci navolit jinak (přes podporu hostingu).

romansklenar
Člen | 655
+
0
-

Ve starší revizi na něco podobného byla metoda Tool::iniSet().

Jakub Šulák
Člen | 222
+
0
-

Nejsem si jistý, ale pokud zavolá ini_set() (což dělá jako první), tak to stejně hodí vyjímku, že daná funkce neexistuje, ne? Nebo se to odchytí na vyšší úrovni než je ta metoda?

Byl bych vážně pro jednoduchý způsob, tak jak jsem psal výše. Dá se jen otestovat, co je rychlejší – zda volat ini_get() dříve nebo function_exists().

romansklenar
Člen | 655
+
0
-

Nevyhodí se jen pokud je hodnota co se má nastavit stejná s tím co už je nastaveno, jde to vidět z té podmínky. To je ale jedno, jen jsem tě chtěl navést, můžes si tu metodu z Tool rozšířit podle sebe a přidat do svojí app. Je škoda, že když je ini_set zakázaná, tak ji nejde znovu nadefinovat a volat klasicky, něco ve stylu:

if (!function_exists('ini_get')) {
	function ini_set($varname, $newvalue) {
		Tool:iniSet($varname, $newvalue));
	}
}

ini_set('varname', 'newvalue');

protože by se to obešlo bez jediného zásahu do nette… ale nejde to no :(

Editoval romansklenar (12. 4. 2009 12:51)

Jakub Šulák
Člen | 222
+
0
-

Ale já si myslím, že to zas tak velký zásah do Nette není. Navíc pokud je/byla funkce Tool::iniset() v Nette již implementována.

Domnívám se, že hodně lidí má právě problém s tím, že hosting nepodporuje ini_set() z bezpečnostních důvodů. Řešení typu „změň hosting“ neslyším rád, protože je jako od člověka z jiné planety – firmy mají už mezi sebou různé smlouvy, speciální řešení hostingu, apod. a změna není možná. Pokud se touto jednoduchou úpravou zajistí, že bude nette zase použitelnější, tak je to jenom dobře. Proto taky říkám, aby se to použilo všude, kde je/bude potřeba ini_set().

David Grudl
Nette Core | 8227
+
0
-

Jakub Šulák napsal(a):

Domnívám se, že hodně lidí má právě problém s tím, že hosting nepodporuje ini_set() z bezpečnostních důvodů.

Jenže ještě žádný hostér ty „bezpečnostní“ důvody nedokázal vysvětlit. Hosting nepodporuje ini_set jedine kvůli vlastní hlouposti.

stpnkcrk
Generous Backer | 190
+
0
-

K tomu vysvětlování – před asi dvěma týdny jsem se znovu pokoušel vymáčknout vyjádření z jednoho nejmenovaného hostéra (bíle Č v červeném poli :)), které znělo takto:

povoleni teto funkce neni mozne z bezpecnostnich duvodu. Kdybychom ji povolili, uzivatele by si mohli menit nastaveni PHP na hodnoty, ktere by umoznily ohrozeni bezpecnosti serveru a dat jinych uzivatelu.

Jakub Šulák
Člen | 222
+
0
-

Jo už to v tom vidím (asi jsem měl slabší den) :-)

Jo, je fakt, že je škoda, že to nejde.
Ale co je důležité – dotaz – Davide uděláš převod všech ini_set() na Tool:iniset()?

David Grudl
Nette Core | 8227
+
0
-

skocourek napsal(a):

povoleni teto funkce neni mozne z bezpecnostnich duvodu. Kdybychom ji povolili, uzivatele by si mohli menit nastaveni PHP na hodnoty, ktere by umoznily ohrozeni bezpecnosti serveru a dat jinych uzivatelu.

A ještě vymáčkni: kterou direktivu konkrétně a jak by to přesně ohrozilo bezpečnost serveru, pane hostére? ;)

Pokud Český hosting neumí dosud logovat chyby, tak je použitelný pouze na statické prezentace. Hostovat v něm aplikace Nette vám způsobí spoustu starostí, vezme spoustu času a stejně dřív nebo později odejdete jinam a budete si říkat „že já vůl to neudělal hned."

Jakub Šulák
Člen | 222
+
0
-

Nemluvím o tom, zda je nebo není ini_set() bezpečnostní problém. Každopádně ale tímto přístupem vedeš firmy k tomu, aby používali jiný framework než Nette. Souhlasím s tebou, že absence ini_set() je nešvar, ale ne všichni jednodušše mohou ze dne na den změnit hosting. Dost často totiž o tom rozhodují nekompetentní lidé, kterým je opravdu zvysoka ___, že nejde logovat chyby. Takže pak tyto firmy (vývojáře) stavíš do pozice, kdy si protlačí Nette ačkoliv vedení koukalo po Zendu (jediné co kdy slyšeli). A kdo myslíš, že vyhraje, když jim ten vývojář ještě řekne, že se musí přepsat smlouvy o hostingu a převést stovka prezentací k firmě, se kterou nemá vedení zkušenosti. Zkus se zamyslet i nad touto, řekl bych, marketingovou otázkou.

David Grudl
Nette Core | 8227
+
0
-

Já lidi vedu k tomu, aby se naučili dát sbohem hostingu, který jim nevyhovuje. Souvisí to s naší národní „zaprcaností“, my pokud dostaneme v restauraci nedobré jídlo, tak si sice řekneme „sem už nepůjdem“, ale personálu nedáme vědět nic, aby jsme je neurazili. Tak se to nedělá.

Tohle nesouvisí s frameworkem (nebo alespoň ne s Nette, u Zendu bude stejná nemožnost logovat chyby).

Argumenty o nákladech a smlouvách neberu. Roční hosting stojí totéž, co 3 hodiny práce programátora. Pokud nejdou logovat chyby, firma utratí za zbytečné debugování víc už při výskytu první chyby. Také pokud má někdo někde 100 prezentací, hostér mu milerád vyjde vstříc, není blázen, aby o takového klienta přišel kvůli ptákovině.

Takže ačkoliv jsem Debug::enable() před týdnem upravil, budu dál a stále víc brojit proti nekvalitním restauracím a hostérům ;) Proto vznikl Requirements Checker.

romansklenar
Člen | 655
+
0
-

Ikdyž mám taky hosting, který trpí tímto nešvarem, souhlasím s tebou. Pokud jde jen o logování, tak požebrám o nastavení direktiv případně zkusím nastavit přes .htaccess, upravím část Nette a netrápí mě to. Na větší prezentace je to časovaná bomba a porozhlédnu se raději někde jinde, a že je z čeho vybírat.

Jakub Šulák
Člen | 222
+
0
-

Hádat se nebudu, tvé argumenty chápu – jen si dovolím vyvrátit tvůj argument – roční hosting stojí 3 hodiny práce programátora.

  1. převod hostingu – hrubá kalkulace nákladů

Změna systému importu faktur za hosting pro přefakturování svým klientům od firmy dodávající ekonomický systém – 15–20 000,–

Převod jednoho hostingu (pouze fyzické překopírování dat a kontrola nastavení a funkčnosti) á 200,– = 100*200=20 000,–

Nastavení e-mailových adres a v 30% případů půl hodinový telefon zákazníkovi – á 100,– = 10 000,–

Změna smluv – poplatky za právní služby = 10 000,–

Jednorázové platby za převod SSL a zřízení IP = 10 000,–

CELKEM: 55–60 000,–
na zákazníka: 5 500 – 6 000 Kč

Náklady jsou orientační, ale vycházejí z mé nedávné zkušenosti, kdy partnerská firma přecházela na jiný hosting. Tyto náklady není možné fakturovat zákazníkovi, jelikož mu nelze říci: "Váš předchozí hosting byl v pořádku, ale jelikož XYZ (nerozumí proč, ani nemůže) zaplaťte šesti násobek ročního poplatku.

Takže ačkoliv si jindy velice vážím tvého tlaku na lidi, v tomto případě dáváš firmám jasný signál, že mohou mít příště strach „co přijde příště“ :).

PS: V restauracích se rád ozvu – naposledy jsem dělal ostudu v Brně u Pandura, kde neumí (skutečně neumí) načepovat půl litr.;-)

David Grudl
Nette Core | 8227
+
0
-

Musím se bránit, aby nevznikla fáma ;)

  • Nette Framework jsem s velkým úsilím naučil fungovat na mizerné verzi PHP 5.2.0, protože se (z hloupých důvodů) drží na řadě VPN hostingů
  • na základě požadavku jsem do jedné hodiny (!) upravil Debug tak, aby fungoval bez ini_set
  • třída Configurátor nebo Session přes půl roku umí chybějící ini_set mapovat na jiné funkce
  • žádné další závislosti na ini_set (tuším) nejsou
  • díky své architektuře nejsou aplikace pod Nette závislé ani na pravidlech mod_rewrite

Tohle je jasný signál. A schválně se pokus podobné úpravy prosadit třeba ve třídě Zend_Session.

Říkat, že je to Nette, kdo nutí firmy měnit hosting nebo používat jiný framework, mi připadá jako chucpe.

Jakub Šulák
Člen | 222
+
0
-

Tady se ta debata na konci převedla spíše do úrovně, zda „vést“ firmy k tomu, aby měnili hosting, nebyla tu už ani tak řeč o samotné podstatě problému, který je jak jsi uvedl již vyřešen.

Šlo mi o to vývratit tvoji větu Já lidi vedu k tomu, aby se naučili dát sbohem hostingu, který jim nevyhovuje. a nahradit ji právě větou Říkat, že je to Nette, kdo nutí firmy měnit hosting nebo používat jiný framework, mi připadá jako chucpe.

Howgh.

stpnkcrk
Generous Backer | 190
+
0
-

David Grudl napsal(a):

A ještě vymáčkni: kterou direktivu konkrétně a jak by to přesně ohrozilo bezpečnost serveru, pane hostére? ;)

Žádané vymáčknutí. ;)

pomoci ini_set() lze menit temer vsechny hodnoty a to libovolne (vice viz dokumentace PHP). Jedna se napriklad o open_basedir – tu je mozne pomoci ini_set() zmenit ci uplne zrusit – uzivatel by pak diky tomu mohl prochazet vsechny soubory na serveru (tedy i soubory jinych uzivatelu a systemove soubory). Nebo by treba mohl libovolne menit nastaveni limitu PHP (memory_limit, time_limit…), coz nechceme z duvodu zachovani moznosti rovneho pristupu k systemovym prostredkum pro vsechny uzivatele sdilenych sluzeb.

Pokud pozadujete vetsi moznosti individualniho nastaveni PHP, muzete vyuzit nejakou nasi vyhrazenou sluzbu – tedy virtualni ci dedikovany server. Blizsi informace pripadne najdete na nasich strankach – http://www.cesky-hosting.cz/…lni-servery/ resp. http://www.cesky-hosting.cz/…ane-servery/ .

David Grudl
Nette Core | 8227
+
0
-

skocourek napsal(a):

Žádané vymáčknutí. ;)

Jé, tichá pošta. Tak se jich zeptej na php_admin_value a php_admin_flag. Cituji:

php_admin_value: Sets the value of the specified directive. This can not be used in .htaccess files. Any directive type set with php_admin_value can not be overridden by .htaccess or ini_set(). To clear a previously set value use none as the value.

Wosonj
Člen | 36
+
0
-

S tím ale afaik nemá pravdu, protože tyto hodnoty může nastavit už httpd.conf pomocí php_admin_value nebo php_admin_flag. Hodnoty nastavené zde už nejde později měnit.

Jiná věc je, že z pohledu webhostingu je řádově jednodušší, stabilnější a tím i bezpečnější prostě zakázat nastavování všeho.

Edit: sakra, David to napsal rychleji a i s odkazem :-)

Editoval Wosonj (20. 4. 2009 13:10)