Shlédnuto: 314x
         

BBcode: Revize


Tento článek se věnuje zásadním úpravám a opravám v BB kódech na Helltrackeru

  Zde nebudeme zmiňovat každý nově přidaný tag BB kódu. Při přidání nového BB kódu bude aktualizován seznam BBcode tagů, který si můžete prohlédnout zde: BBcode
  Pokud Vás nezajímají detaily, ale výsledek, neboli: ''Co to znamená pro mne jako uživatele?'', jděte rovnou na konec článku, kde bude jakési shrnutí.

Revize ke dni 10.1.2018

  Mnoho stránek na internetu se dlouhodobě potýká s problémem zpracování objemných textů pomocí regulárních výrazů (REGEX či PCRE). To se týká i Helltrackeru v případech, kdy uživatelé píší příspěvky a využívají při nich BB kódů. Zpracování textů se realizuje v PHP skriptech především pomocí  regulárních výrazů a to především z důvodu rychlosti. Nalezení BBcode a jeho přepis na HTML tagy se dá realizovat buďto právě pomocí regulárního výrazu, kdy se použije složitý ale jednořádkový příkaz, anebo pomocí samostatných skriptů, kdy se pro každý BB kód musí napsat celá samostatná rutina, čítající v některých případech až několik stovek řádků kódu (příkazů, funkcí, parametrů...).

  Zatímco psát si vlastní skripty pro každý BBcode zvlášť je zdlouhavé, skriptově objemné a při provádění časově náročné, má i své výhody. (1) Především víte, jak vámi vytvořený kód pracuje a máte jistotu že dělá, co dělat má. V případě, že se v budoucnu vyskytne výjimka, lze drobně upravit svůj kód a výjimku ošetřit. (2) Obrovskou výhodou jsou nároky na RAM. Zatímco REGEX klidně zasere 16GB RAM během sekundy, použitá RAM v případě vlastního scriptu nestojí ani za řeč. Nikdy nepřesáhne dvojnásobek objemu zpracovávaného textu. Zasvinit tedy používáním vlastního scriptu 16GB RAM je možné až při zpracování cca pěti knih (románú) najednou, v jednom okamžiku, v jedné proměnné anebo poli.

  Své výhody má i REGEXP. Zejména tedy vše se dá specifikovat do krátkého řetězce.
Regulární výraz sestává z různých operátorů a flagů (vlajek).
Například:
'/\[align=([a-zA-Z]+)\]((\s|.)+?)\[\/align\]/i'
BBcode tag ALIGN má tento REGEX. Význam je částečně zřejmý i pro úplného laika. Z výrazu je vidět, že hledá nějaký [align=,
za ním může následovat slovo sestávající jen z malých a velkých písmen abecedy ([a-zA-Z]+) přičemž ty kulaté závorky znamenají, že jde o množinu znaků, která může být různá, podle pravidel napsaných mezi nimi.
  To jen tak na ukázku. Takovýto výraz se vloží do PHP funkce,
která ve vašem textu najde a nahradí všechny BBcode ALIGN HTML tagem pro ALIGN.

  Samotný REGEX, jak vidíme na příkladu se tváří složitě, ale každý ze znaků je totéž, jako napsat v PHP spoustu řádků příkazů a funkcí. PHP samo pak těmto výrazům rozumí a umí je zpracovat tak, jako kdybychom skutečně psali celý skript, ale má to úžasné bonusy. Za prvé PHP REGEX zkompiluje do strojového kódu. Za druhé si PHP ponechá kompilovaný kód nějakou dobu v RAM, pak jej přesune do CACHE na harrdisk, a až když dlouhou dobu není stejný REGEX použit, vymaže i tuto zálohu a uvolní tak CACHE na harddisku.

  Tím, že je regulární výraz ve skutečnosti prováděn rutinou ve strojovém kódu, je zpracování REGEX-u neuvěřitelně rychlé oproti řešení skriptem. Také při použití stejného REGEX-u v dohledné době se tento REGEX znovu nekompiluje a dochází k dalšímu zrychlení. A zde je tedy zapotřebí přiznat, že tyto výhody mají přednost před úsporou RAM či procesorového času. Proto také používáme REGEX řešení. Jenže, jak bylo zmíněno výše, používání REGEX-ů má omezení.
  Pokud je zakázána kompilace REGEX do strojového kódu, dokáže REGEX a potažmo PHP zpracovat text do teoretické velikosti 64 kB (65536 znaků). Jenomže ne každý znak má jeden Bajt (Byte), většina obsahuje dva Bajty, některé znaky jsou reprezentovány i čtymi Bajty. To výrazně redukuje objem textu, který může být zpracován. Finálně je reálná délka textu cca poloviční, tedy 32-tis. znaků. Zdá se to hodně, ale nenechte se mýlit. Zvláště zde na HellWIKi na tento limit narazíme běžně. Pak se musí WIKi článek rozdělit na několik samostatných článků.
  Pokud je kompilace REGEX povolena, pak se limit velikosti zmenšuje doslova drasticky. Podle různých testů - a teď se podržte - na 4096 znaků (4 kB) !!! A z tohoto množství se ještě odečte délka REGEX-u.
  REGEX-y při zapnuté i vypnuté kompilaci způsobují chyby, při překročení těchto limitů. Při vypnuté kompilaci dojde k chybě, kdy se příkaz pro převod z BBcode na HTML nějakou dobu provádí a pak spadne PHP, což se u Vás, jako uživatelů projeví tím, že se vůbec nenačte stránka, koukáte na bílou plochu, na které je napsáno něco o CHYBĚ SERVERU 500 a v logu APACHE2 se bjeví jen hlášení: ''[core:notice] [pid 6973] AH00051: child pid 8244 exit signal Segmentation fault (11), possible coredump in /etc/apache2'', bez jakéhokoliv náznaku, kde ve skriptech vlastně k této chybě došlo. (ta chyba znamená porušení segmentace - způsobena je nedostatkem prostředků - v tomto specifickém případě nedostatkem RAM). Při zapnuté kompilaci REGEXU a překročení limitu se zpracovávaný text zahodí a na Vás vyskočí normální stránka Helltrackeru, na které ovšem není žádný obsah. Ani v logu chyb se nezobrazí žádné chybové hlášení.

  Další problém REGEXU je syntaktika posloupnosti zpracování textu. Regulární výraz prohledává text a hledá například BBcode tag: ALIGN. Když jej najde, hledá kde je koncová značka tagu. Když ji najde, obsah mezi těmito dvěma tagy vystředí, nebo šoupne doleva či doprava. Až potud dobrý. Co když máte ale text, který je celý vystředěný na stránce a v něm potřebujete určitou část šoupnout doleva? Nu, vrazíte tam další ALIGN. Máme tak situaci    ALIGN=CENTER - nějaký text - ALIGN=LEFT - nějaký text - /ALIGN - nějaký text - /ALIGN. V tomto případě najde REGEX prní ALIGN a propojí s prvním /ALIGN, stejně to udělá s druhými ALIGN-y. Výsledkem je překrývání tagů místo vnořování tagů. V lepším případě vůbec nebude fungovat tag ALIGN, v horším může dojít až ke kolapsu stránky. Nechci sem psát přímo danou situaci, tato hrubka v PHP a REGEX není na Helltrackeru doposud zcela ochráněna.

  Takže poslední dva týdny se snažím. Dělám na pitomém BBcode a vcelku úspěšně. Po odlaborování s ''php.ini'' runtime proměnnými pcre.backtrack_limit, pcre.recursion_limit  a pcre.jit, po pokusech o nastavení paměťových limitů a dalších zrůdnostech, po mnoha bezesných nocí se v samotném PHP, kde chyba vzniká, nepodařilo dojít k úspěšnému řešení. Nezbývalo, než si vybrat, jakým způsobem se díry v programátorské práci jiných budou řešit. Řešením je REVIZE SKRIPTŮ, o čemž je tento článek. Já vím, to nebylo směšné. Řešením je předělat kód a při každé jednotlivé situaci u každého jednotlivého tagu využít REGEX, využít REGEX částečně, nevyužít REGEX vůbec. Následkem ovšem bude veliký nárůst času při strojovém zpracování. Až se Vám jednoho dne začnou stránky Helltrackeru sekat, možná to bude následkem REVIZE BBCODE č.2. Zatím máme za sebou revizi č.1, která řeší nejpovážlivější problémy a přináší minimum problémů následných.


Co pro nás všechny znamená proběhnuvší REVIZE BBcode č.1 ze dne 10.1.2018

  Z toho, jak byla změněna struktura algoritmu vzešly tyto výsledky:
  • Neznatelně se zpomalilo načítání stránky.
  • Znatelně se zvýšila bezpečnost uživatelských příspěvků. Nedochází už k ''zahození'' textů (viz. výše).
  • Nedojde ke zobrazení prázdné bílé stránky v prohlížeči s hlášením: Internal Server Error 500.
  • Pokud dojde ke kritické situaci, právě jen a jen ten jeden jediný BBcode, který chybu vyvolal se neprovede, ale zobrazí se v textu v RAW tvaru, tedy např. [ align=center ].

  •  Kód byl dále přepracován tak, aby i posledně jmenovaná situace měla řešení. Pokud k takové události dojde, uživatel jen vstoupí do EDITACE příspěvku a jmenovaný tag (a jeho koncovou část) smaže. Případně, pokud nechce přijít o tu funkcionalitu, kterou měl BBcode tag provést, použije stejný tag několikrát tak, že jakoby rozdělí příspěvek. Řekněme, že jsme měli sáhodlouhý příspěvek, kde úplně na začátku byl tag ALIGN=CENTER a na konci /ALIGN. Vložíme někam doprostřed nový konec centrování /ALIGN a hned za něj opět začátek centrování ALIGN=CENTER. Tak se to provede i s dalšími tagy, které by případně vykazovaly stejné chování.

    Ještě tabulka jako příklad:
    Princip obnovení stylování dlouhých příspěvků, ve kterých selže některý tag
    Původní příspěvekUpravený příspěvekNebo upravený jinak
    [ align=center ]
         200 řádků textu
         30 řádků textu
         100 řádků textu
         50 řádků textu
         20 řádků textu
    [ /align ]
    [ align=center ]
         200 řádků textu
         30 řádků textu
    [ /align ]
    [ align=center ]
         100 řádků textu
         50 řádků textu
         20 řádků textu
    [ /align ]
    [ align=center ]
         200 řádků textu
    [ /align ]
    [ align=center ]
         30 řádků textu
      100 řádků textu
    [ /align ]
    [ align=center ]
         50 řádků textu
    [ /align ]
    [ align=center ]
         20 řádků textu
    [ /align ]



    Zdroje:
      -  php.net
      - Zdrojový kód Helltrackeru
      - Programátorské úpravy na Helltrackeru
      - 2 miliony stránek internetu prohlédnuté za posledních 14 dní
      - Ownerova prastará palice


    Přidal(a): 10-01-2018 14:05:31 anon
    Upraveno: 1x, naposledy: 10-01-2018 15:25:34 anon



    x
    Vygenerováno za: 1.2678 seckund, dotazů: 10
    Uživatel: nick-neprihlaseny, IP-54.163.42.154, země-US
    První návštěva: 2018-12-10 18:20:58, celkem: 18
    Posledně navštíveno: article|name=FAQ a article|name=Bezpečné barvy
    Powered by U-232 V5
    Using Valid CSS3 & HTML5
    Klikněte pro podporu ve fóru zde