PHP triky
Weblog o elegantním programování v PHP pro mírně pokročilé
Adminer 5.4.2
Adminer 5.4.2 opravuje bezpečnostní chybu DoS: útočník může Admineru podstrčit nesprávně formátovanou verzi a Adminer se pak všem uživatelům na tomto serveru odmítne nahrát. Chyba postihuje verze 4.6.2 až 5.4.1. Pokud nemůžete Adminer aktualizovat, dá se chyba potlačit tak, že souboru adminer.version v dočasném adresáři (obvykle hodnota upload_tmp_dir) seberete práva zápisu.
Způsob kontroly nové verze byl dříve dost komplikovaný – z adminer.org se nahrál <iframe>, ten pomocí postMessage poslal informaci zpátky Admineru, který ji uložil do cookie a také do souboru na serveru. Tento soubor se vytvářel kvůli uživatelům s vypnutými cookies, kteří jinak server Admineru bombardují žádostí o novou verzi při každém požadavku. Aby soubor nemohl nikdo podstrčit, tak byl podepsaný – a právě při ověřování podpisu mohlo dojít k DoS.
Kontrolu nové verze jsem teď díky CORS dramaticky zjednodušil – Adminer se ptá adminer.org rovnou přes fetch a novou verzi ukládá jen do cookie. Snad mi to nesloží server. Připomínám, že kontrola nové verze se pomocí pluginu dá přepnout na GitHub, nebo úplně vypnout.
Další změny
- V editačním formuláři se JSON vypisuje hezky.
- Při změně tabulky lze upravovat víceřádkové generované hodnoty.
- Z textů, které začínají
//a vypadají jako URL, se nyní vytváří odkaz stejně jako když začínajíhttps://. - Některé ovladače v pluginech vracejí jako hodnoty tabulky pole. Toto pole se teď vykresluje jako vnořená tabulka.
- Některé databáze mají právo pro řazení podle sloupce. Adminer ho nyní respektuje při vytváření odkazů v záhlaví tabulky.
- V editačním formuláři se nyní zobrazují i hodnoty, které se nedají upravit. To jsou jednak generované sloupce a jednak sloupce bez práva modifikace (u některých databází např. auto increment).
- Při výpisu dat se zkracují textové sloupce. Ale typů, které se zkracovaly, postupně přibývalo, tak jsem podmínku znegoval – nyní se zkracuje vše kromě čísel a datumů.
- Pro ošetření hodnot cookie se používalo
urlencode. To asi někdy může způsobit nějaké komplikace, tak jsem to přehodil narawurlencode. (bug #1208) - V TSV exportu se do uvozovek zavíraly i hodnoty s čárkou. To sice ničemu nevadilo, ale nebylo to pěkné. (bug #1238)
- V MariaDB není název checků unikátní, takže se mohly zobrazit i checky z jiné tabulky. (bug #1135)
PostgreSQL
- Při vytváření tabulky se podle názvu sloupce nabízí vytvoření cizího klíče stejně jako to už 16 let dělá Adminer v MySQL. Změna přitom byla na pár řádek. Těch člověko-hodin, co jsem tím mohl ostatním ušetřit…
- V exportu checků chyběly závorky.
- … a naopak se duplikovalo
DEFERRABLEu cizích klíčů. - Lze vytvářet
NOT DEFERRABLEcizí klíče. - V exportu sekvencí a pohledů se nyní uvádí schéma stejně jako u tabulek.
- Opravil jsem zobrazování složitých generovaných sloupců.
- Unikátní částečné klíče se nyní označují jako unikátní. (bug #1172)
- U zděděných tabulek se správně zobrazují tabulky z jiných schémat. (bug #1221)
- Naopak všude kromě PostgreSQL se zobrazují explicitně vytvořené
NOT NULLchecky. (bug #1237)
Pluginy dostaly metody showVariables() a showStatus() (bug #1157). Také mohou být v jakémkoliv jmenném prostoru, pokud dědí z Adminer\Plugin.
Sponzoři
Mezi sponzory Admineru chci po první vlaštovce PikaPods přivítat také AI-Text-Humanizer.com.
Adminer 5.4.0
Delší dobu se v Admineru neobjevila žádná závažná chyba, tak jsem nemusel vydávat novou verzi, až počet změn hodně nabobtnal.
- Při vyhledávání ve všech tabulkách se dá nově zadat jakýkoliv operátor. Dřív se vždy používalo
=. - Při
GROUP BYselectu (např. vybrání sloupce a k tomu nějaké agregační funkce) se výsledky už neřadí sestupně. - V SQL příkazu lze nově exportovat i zadaný příkaz (bug #1092).
- V přehledu databáze jsem přidal odkazy na sekce (např. na rutiny), což se hodí, když je toho v databázi hodně.
- Při importu se zobrazí varování v případě překročení
max_file_uploads. - V seznamu existujících přihlášení v menu přihlašovací stránky se za uživatelským jménem zobrazuje
@, i pokud je server prázdný. - V přehledu databáze se u materializovaných pohledů zobrazuje velikost dat a indexů.
- Při zvýrazňování syntaxe se nově kromě tabulek odkazují i rutiny.
- Ve změně struktury tabulky se přesune focus na nově přidaný sloupec.
- Do hlášek o provedených SQL příkazech jsem přidal tlačítko na jejich zkopírování.
- Po nahrání více řádek ve výpisu se spouští zvýrazňování syntaxe, hlavně kvůli JSON sloupcům.
- Je možné se připojit k serveru pomocí IPv6 adresy (bug #1095). Dřív se chápala jako server s portem.
- V MySQL jsem opravil ukládání
enums prázdnou hodnotou (bug #1152). - V MySQL 5.0- se nenahrávají informace o rozdělených tabulkách (bug #1099).
- V MariaDB se parsuje
COLLATEv definici rutiny (bug #1104). - V Elasticsearch lze smazat alias.
Další spousta změn je pro PostgreSQL, který jsem začal více používat:
- U zděděných tabulek se zobrazuje struktura.
- Zobrazují se výrazy indexů, např.
lower(filename). - K operátorům jsem přidal
SQL, který dovoluje hledat podle libovolného SQL výrazu. - V menu se skrývají jen oddíly, ne všechny zděděné tabulky.
- Lze porovnávat JSON sloupce (bug #1107).
- Kromě textových sloupců se při výpisu zkracují i hodnoty ve sloupcích
hstore. - S operátorem
intervalse hodnoty předávají jako řetězce. - Opravil jsem volání funkcí s bezejmennými parametry.
- Opravil jsem volání funkcí vracejících tabulky.
- Uživatelské typy obsahující
fileuž se neberou jakoblob(bug #1118). - Při exportu databáze se respektuje požadavek na její
DROPaCREATE(bug #1140). - Ve verzi 11 a nižší jsem opravil duplicitní
oidpři získávání informací o tabulce (bug #1089).
Pluginy:
- Přidal jsem metody
afterConnect(),processList()akillProcess(). - Vytvořil jsem plugin pro zobrazení čísla řádku ve výpisu (bug #1106).
- Vytvořil jsem plugin pro nastavení timeoutu dotazů.
Php-Wasm
WebAssembly je pozoruhodná technologie. Umožňuje běh binárních programů v různých prostředích, především pak v prohlížečích. Do Wasm se dá kompilovat z různých programovacích jazyků, pro PHP existuje Php-Wasm. To umožňuje spouštět PHP kód v prohlížeči na počítači klienta. Výhoda je mnohem rychlejší odezva, než když se data pro zpracování posílají na server a zpátky, dále pak nezatěžování serveru. Další využití je, pokud spouštěnému kódu nevěříte a nechcete si ho pouštět na server.
Php-Wasm jsem si vyzkoušel na demu PhpShrink:
let highlightShrink;
(async function () {
// momentálně je potřeba použít alfa verzi, vydaná 0.0.8 toto nepodporuje
const { PhpWeb } = await import('https://cdn.jsdelivr.net/npm/php-wasm@0.0.9-alpha-29/PhpWeb.mjs');
const php = new PhpWeb({files: [
// namapujeme URL jako soubor v prostředí Wasm; URL musí vrátit PHP kód nezpracovaný serverem
{name: 'phpShrink.php', url: 'https://raw.githubusercontent.com/vrana/PhpShrink/refs/heads/main/phpShrink.php'}
]});
// výstup a chybový výstup nepoužíváme, tak ho jen pošleme do konzole
php.addEventListener('output', event => console.log(event.detail));
php.addEventListener('error', event => console.error(event.detail));
// zpracuje PHP kód z URL zadaného výše
await php.run('<?php include "./phpShrink.php"; ?>');
// největší magie - PHP funkci zpřístupní do JavaScriptu
highlightShrink = await php.x`function ($input) { return highlight_string(phpShrink($input), true); }`;
shrink();
document.getElementById('input').oninput = shrink;
})();
function shrink() {
document.getElementById('output').innerHTML = highlightShrink(document.getElementById('input').value);
}
Php-Wasm má mnohem širší možnosti, kód se dá definovat i rovnou ve <script type="text/php">, existuje také CGI umožňující třeba i běh WordPressu v prohlížeči.
SimpleXML: jmenné prostory
Extenzi SimpleXML mám v oblibě pro velice jednoduchou práci s XML dokumenty. Konec konců jsem se jí nechal inspirovat při tvorbě NotORM. Např. pro získání hodnoty atributu <meta charset> se dá použít jednoduché $html->meta["charset"]. Pro složitější dotazy se dá použít XPath, např. všechny tabulky v dokumentu pomocí $html->xpath("//table").
Když dokument obsahuje jmenné prostory, tak je práce složitější a část magie mizí. Mějme takovýto dokument:
<movies xmlns="http://default" xmlns:a="http://a">
<movie xml:id="movie1" a:link="IMDB">
<a:actor>Onlivia Actora</a:actor>
</movie>
</movies>
Dá se s ním pracovat takhle:
<?php $movies = simplexml_load_string($file); // Namespace http://www.w3.org/XML/1998/namespace is available as "xml". echo $movies->movie->attributes("xml", true)["id"] . "\n"; // Namespaced attributes can be accessed with attributes(). echo $movies->movie->attributes("a", true)["link"] . "\n"; // Using namespace URI allows document to use any namespace alias. echo $movies->movie->attributes("http://a")["link"] . "\n"; // Children can be accessed with children(). echo $movies->movie->children("http://a")->actor . "\n"; // Using xpath() with namespace requires registering it first. $movies->registerXPathNamespace("a", "http://a"); echo count($movies->xpath("//a:actor")) . "\n"; // Even the default namespace must be registered. $movies->registerXPathNamespace("default", "http://default"); echo count($movies->xpath("//default:movie")) . "\n"; ?>
Adminer 5.3.0 - možnosti indexů
Největší změna v Admineru 5.3.0 je podpora algoritmu indexu (bug #1030). PostgreSQL podporuje šest algoritmů, MySQL jen dva a to jen u některých typů tabulek.
Druhou novinkou jsou částečné indexy. V PostgreSQL lze nastavit podmínku, při které se hodnota do indexu uloží (bug #1048).
Do PostgreSQL a CockroachDB jsem přidal možnost vytvářet tabulky s oddíly (bug #1031). PostgreSQL bohužel nedovoluje oddíly změnit po vytvoření tabulky a automatická migrace (jako ji v některých případech dělá ovladač pro SQLite) mi přišla trochu riskantní. S tím souvisí i přesun oddílů v PostgreSQL z menu do rodičovské tabulky.
Další změny jsou menší:
- Výsledky funkcí vracejících číslo (např.
COUNT(*)neboCHAR_LENGTH()jsem nechal zarovnat doprava stejně jako číselné sloupce. V PostgreSQL se z hodnotyCOUNT(*)vytvoří odkaz stejně jako v MySQL. - Autocomplete SQL nyní podporuje aliasy tabulek.
- Verze 5.1.1 rozbila vytváření uložených funkcí, nová verze typovou chybu opravuje (bug #1053).
- Akce sloupečků zobrazené po najetí myši mají nyní rámeček (bug #1072).
- Hodnoty typu
moneyjsem nechal zarovnat doprava stejně jako čísla (bug #1071). - V MySQL jsem opravil varování při zobrazení dat z tabulek s fulltext indexem (bug #1036).
- Verze 5.1.1 rozbila připojování přes
localhost:3306, zkoušel se hledat socket 3306. Nová verze to opravuje (bug #1057). - V PostgreSQL mohou uživatelské funkce vracet tabulku, kterou Adminer při zavolání funkce nyní ukáže (bug #1040).
- Do PostgreSQL jsem přidal operátor
NOT ILIKE(bug #1062). - V Editoru jsem opravil vyhledávání podle sloupců
bitaenum(bug #1062). - Pokud uživatelský styl v souboru
adminer.csspodporuje přepínání do tmavého režimu, tak Adminer svůj tmavý styl nevypne. - Pluginy můžou v metodě
css()určit, zda styl podporuje tmavý vzhled. Výchozí implementace u souboruadminer.csszkoumá přítomnostprefers-color-scheme: dark. - Pluginům jsem dal možnost přidat třídu do
<body class>. Adminer tam přidává tříduadminer, Editor třídueditor. - Přibyl překlad do hindštiny.
Starší články naleznete v archivu.

