PHP triky

Weblog o elegantním programování v PHP pro mírně pokročilé

Adminer 5.5.1

Claude Fable jsem pustil i na závislosti Admineru. Opravil řadu chyb v PhpShrink a JsShrink. Admineru se netýkaly, ale i tak jsem za jejich opravu vděčný. Admineru se týká aktualizace zvýrazňování syntaxe v JUSH. Nechal jsem napsat i aktualizátory jazyků z oficiálních dokumentací.

Změny přímo v Admineru:

  • Hlavička X-Forwarded-Prefix se použila jen pro prefix /[^/]. Tomu bohužel vyhovuje i /\evil.com, což prohlížeče pořád vyhodnotí jako https://evil.com. (GHSA-fr74-9mf9-gf44)
  • V přihlašovacím formuláři lze opět používat znaky :/_, které jsem v minulé verzi zakázal. (bug #1305)
  • Kvůli minimalizaci velikosti byl zkompilovaný adminer.php binární soubor, s čímž uživatelé měli problém při všelijakém ručním kopírování (bug #1113, #1213). Jednoduchým řešením by bylo binární řetězce prohnat base64_encode, jenže to je zvětší o 33 %. Hospodárnější řešení je každých 13 bitů binárního výstupu zakódovat jako dva znaky z rozsahu [!-~], což přidá jen 23 %. Tady jsem si ověřil, jak moc modely pokročily – stejnou úlohu jsem zadal AI asi před půl rokem, dost jsem se s tím natrápil a výsledku jsem se stejně nedobral. Teď to bylo na první dobrou.
  • Toto navýšení jsem vyvážil změnou kompresního algoritmu z LZW na účinnější gzdeflate. Pro dekompresi se používá gzinflate. Jen pokud není k dispozici, tak se použije vlastní implementace – to by se mi ručně fakt psát nechtělo.
  • Claude Fable jsem použil i na doplnění chybějících překladů, ale jen v případech, kdy si byla překladem jistá. Model k tomu využil i obraty ze stávajících překladů. Přeskočil jazyky, kterými si nebyl jist. Našel u toho i několik chyb v původních překladech. Nové překlady jsou označené komentářem // Claud Fable 5, který můžou rodilí mluvčí po kontrole smazat. Doplnění překladů paradoxně snížilo velikost zkompilovaného souboru – každý jazyk se komprimuje zvlášť a místo chybějících překladů se používá angličtina. Míchání jazyků komprimaci zhoršuje.
  • Adminer v PHP 8 opět funguje i se zakázanou funkcí ini_set. Starší verze PHP dokázaly funkce zakázané pomocí disable_functions pořád zavolat, jen vyvolaly chybu, kterou Adminer potlačil. Od PHP 8 už takto zakázaná funkce nejde zavolat vůbec, proto jsem pro ni do Admineru musel přidat wrapper. Přidal jsem i kontrolu dostupnosti funkce set_time_limit. (bug #1288)
  • V PostgreSQL se jde opět přihlásit i s prázdným serverem. (bug #1304, regrese z 5.5.0)

Také jsem aktualizoval PHPCS a PHPStan.

Jakub Vrána, Adminer, 21.7.2026

Adminer 5.5.0

Z nástupu AI jsem byl trochu rozčarovaný. Model udělal třeba 80 % požadované kvality práce, ale donutit ho dodělat ten zbytek nebo to dodělávat sám nakonec často zabralo víc času, než když bych si to udělal sám celé od začátku. Často mi to připadalo jako hádat se s blbcem. Když přišel model Fable 5 a David Grudl kvůli němu zrušil návštěvu festivalů, tak jsem se rozhodl tomu dát šanci znovu.

A jsem nadšen! Model kódu rozumí kolikrát líp než já. Zeptal jsem se ho třeba „Jak to, že se v Admineru pro SQLite zobrazuje struktura tabulky sqlite_schema?“ A on mi to správně vysvětlil – sám bych to musel v kódu hledat a vymýšlet to. Spoustu práce mi ušetřil hlavně dotaz „Podívej se na poslední verze MySQL/PostgreSQL/SQLite a navrhni novinky, které by šly do Admineru zahrnout.“ Pak už jen stačilo zaškrtnout, které z těch novinek chci, a bylo hotovo. Tohle procházení novinek se mi nikdy dělat nechce, protože většina z nich se Admineru nijak netýká. Při práci se model jen tak mimochodem zmínil, že v process listu došlo v PostgreSQL 9.2 k přejmenování jednoho sloupce, a opravil to taky.

Nebo jsem chtěl v SQLite podporovat tabulky STRICT bez toho, aniž bych tím zaplevelil uživatelské rozhraní. Navrhl použít mechanizmus engine, který se v MySQL používá pro výběr typu tabulky. Jde skutečně o elegantní řešení, ke kterému je UI už navíc hotové. Časem bych k němu nejspíš dospěl i sám.

Pomohl mi i se zvýrazňovačem syntaxe. Třeba při přidávání podpory pro VECTOR do Admineru nejprve do submodulu jush commitnul zvýraznění syntaxe a pak do Admineru přidal samotnou podporu. Ještě mi připomněl, ať submodul pushnu jako první.

S tímhle už mě baví pracovat, je to rovnocenný parťák. Část novinek v Admineru je tedy ve spolupráci s Fable.

  • Zakázal jsem neplatné porty a sockety. (GHSA-58cq-mgw2-38m5)
  • Ignoruje se neplatný X-Forwarded-Prefix. (GHSA-8478-xrj3-h9c2)
  • Do process listu jsem přidal odkaz pro zkopírování do schránky. Dávno existuje možnost ho i naklonovat, ale pokud je moc dlouhý, tak se nevejde do URL.
  • Odkazy pro zkopírování dotazů do schránky nefungují v nebezpečných kotextech (např. na HTTP), takže se nově ani nezobrazují.
  • V editaci se zalamují zobrazené hodnoty. To se hodí hlavně u needitovatelných položek na více řádků.
  • Zrychlil jsem zvýrazňování syntaxe, hlavně při editaci dlouhých textů a při velkém množství zvýrazňovaných položek (typicky JSON v datech tabulky).
  • Dá se připojit k socketu bez serveru pomocí :/tmp/mysql.sock. (bug #1199, regrese z 5.4.0)
  • MySQL: V parametrech funkcí se neexportuje příznak IN.
  • MySQL: Sloupce typu vector se ve výpisu a editaci zobrazují jako text.
  • MySQL: Odstranil jsem podporu MySQL 5.0 (z roku 2005) a starší.
  • MySQL, SQLite: Ve změně tabulky jde sloupce přesouvat pomocí drag and drop.
  • MariaDB: Podpora typů inet4 a inet6.
  • MariaDB: Podpora password validation pluginů při správě uživatele – Adminer volal odděleně PASSWORD(), aby se nezahešované heslo neukládalo do historie. To se těmto pluginům nelíbilo. (bug SF-814)
  • MariaDB 11.7+: Podpora typu a indexů vector.
  • PostgreSQL 9.2+: Zvýraznění dotazu v process listu.
  • SQLite: Podpora typu ANY.
  • SQLite: Podpora možností STRICT a WITHOUT ROWID.
  • SQLite: Samotné integer PRIMARY KEY už se nebere jako AUTOINCREMENT.
  • SQLite: Zakázání editace sqlite_schema.
  • MS SQL: Oprava dotazů s více výsledky. (bug #1180)

Přidal jsem taky jednoduchý ovladač pro Redis a plugin pro přihlášení za reverzní proxy. Samotný Adminer totiž nevěří hlavičce X-Forwarded-For, takže neplatné pokusy o přihlášení za reverzní proxy znemožní přihlášení z jakékoliv IP adresy.

Jakub Vrána, Dobře míněné rady, 17.7.2026

Zastaralé $http_response_header

PHP 8.5 zastaralo proměnnou $http_response_header, která obsahuje hlavičky posledního HTTP požadavku. Místo ní je k dispozici funkce http_get_last_response_headers(). Co když potřebujeme zpětně kompatibilní kód? Tímhle si nepomůžeme, protože zastaralost $http_response_header se zjišťuje už při kompilaci:

<?php
$headers = (function_exists('http_get_last_response_headers') ? http_get_last_response_headers() : $http_response_header);
?>

Tohle varování o zastaralosti vyřeší, ale kód ve starších verzích nefunguje, proměnná se nenaplní:

<?php
$var = 'http_response_header';
$headers = (function_exists('http_get_last_response_headers') ? http_get_last_response_headers() : $$var);
?>

Jedině tohle je řešení, které ve starších verzích funguje a v nové nezpůsobí varování:

<?php
if (function_exists('http_get_last_response_headers')) {
    $http_response_header = http_get_last_response_headers();
}
?>
Jakub Vrána, Řešení problému, 12.7.2026

Novinky PHP 8.5

Novinky v PHP 8.5:

  • Operátor pro řetězení funkcí |> (nepříliš praktický).
  • Anonymní funkce lze použít na místě konstant: const FN = strlen(...);
  • Předdefinovaný atribut #[\NoDiscard] pro vynucení použití návratové hodnoty funkce. S ním související přetypování (void) pro zahození návratové hodnoty.
  • Globálním konstantám lze přiřadit atribut: #[Deprecated] const A = 1;
  • Atribut #[\DelayedTargetValidation] pro odložení kontroly nepodporovaných atributů.
  • Atribut #[\Override] lze použít i u vlastností.
  • Statické vlastnosti můžu mít také asymetrickou viditelnost.
  • Fatální chyby (jako překročení maximálního času) mají backtrace.
  • Property promotion lze použít s final.
  • V hodnotách konstant lze použít přetypování: const T1 = (int) 0.3;
  • Operátor clone lze používat jako funkci s druhým parametrem, který určí novou hodnotu vlastností: $b = clone($a, ['x' => 2]);
  • Třídy ve jmenném prostoru Uri pro práci s URL podle RFC 3986 a WHATWG.
  • Chybové handlery lze získat funkcemi get_error_handler a get_exception_handler.
  • Metodou Closure::getCurrent lze získat vlastní closure.
  • Funkcí curl_share_init_persistent lze vytvořit cURL handle, který nezanikne po skončení aktuálního požadavku.
  • Funkce array_first a array_last jako obdoba reset a end nepotřebující referenci.
  • Zaniklo nastavení disable_classes.
  • Zastaralé obraty: operátor `, __sleep() a __wakeup(), $http_response_header.
Jakub Vrána, Seznámení s oblastí, 10.7.2026

Adminer 5.4.3

Vyšel Adminer 5.4.3. Opravuje několik nepříliš vážných bezpečnostních chyb:

Ostatní změny jsou starší, ale dřív jsem je nevydal.

  • Tabulky v přehledu lze třídit. (bug #1231)
  • Inline editace pomocí Ctrl+klik je deaktivovaná, pokud uživatel nemá právo UPDATE.
  • Ve výpisu tabulky se v bublině názvu sloupce zobrazuje typ, teď jsem přidal i informaci o NULL.
  • V exportu se pamatují nevybrané položky. (regrese z 5.0.6)
  • U cizího klíče se v případě chyby zobrazí nová hodnota.
  • Adminer Editor: Sloupec typu tinyint(1) se zobrazí jako checkbox. (bug #1246, regrese z 5.4.2)
  • Přibyl chorvatský překlad.

Další změny se týkají PostgreSQL:

  • NULL se řadí na konec.
  • Zobrazí se všechna SQL varování a pouze jednou.
  • Typ serial se exportuje jako serial, ne nextval().
  • Opraven export GENERATED AS IDENTITY. (bug #1260)
  • U nextval() a REFERENCES se exportuje schéma.
  • Přidal jsem operátor ~*. (bug #1271)
Jakub Vrána, Adminer, 9.7.2026

Starší články naleznete v archivu.

avatar © 2005-2026 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.