Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.
Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.
Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.
Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Byl vydán Mozilla Firefox 138.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 138 je již k dispozici také na Flathubu a Snapcraftu.
Šestnáctý ročník ne-konference jOpenSpace se koná 3. – 5. října 2025 v Hotelu Antoň v Telči. Pro účast je potřeba vyplnit registrační formulář. Ne-konference neznamená, že se organizátorům nechce připravovat program, ale naopak dává prostor všem pozvaným, aby si program sami složili z toho nejzajímavějšího, čím se v poslední době zabývají nebo co je oslovilo. Obsah, který vytvářejí všichni účastníci, se skládá z desetiminutových
… více »Richard Stallman přednáší ve středu 7. května od 16:30 na Technické univerzitě v Liberci o vlivu technologií na svobodu. Přednáška je určená jak odborné tak laické veřejnosti.
Jean-Baptiste Mardelle se v příspěvku na blogu rozepsal o novinkám v nejnovější verzi 25.04.0 editoru videa Kdenlive (Wikipedie). Ke stažení také na Flathubu.
TmuxAI (GitHub) je AI asistent pro práci v terminálu. Vyžaduje účet na OpenRouter.
Tiskni
Sdílej:
SELECT * FROM users WHERE id = 1 SELECT * FROM users WHERE id = 2 SELECT * FROM users WHERE id = 3 SELECT * FROM users WHERE id = 4 SELECT * FROM users WHERE id = 5 ...tak vám cachování v PHP na nic není, serveru to samozřejmě v tomto triviálním případě pomůže, ale síťové komunikaci se nevyhnete. Zabránění SQL injection (tedy pokud si někdo stejně nenacpe uživatelský vstup i do prepared statements) mi připadá jako dostatečně dobrý důvod pro použití prepared statements. Query2 samozřejmě poloautomaticky řeší SQL injection (oním escapováním). Na rozdíl ale od prepared statements dokáže vložit i už escapovaný řetězec (ano, i to je občas potřeba). S použitím prepared statements byste musel řetězec jaksi odescapovat ...
Query2 samozřejmě poloautomaticky řeší SQL injection (oním escapováním). Na rozdíl ale od prepared statements dokáže vložit i už escapovaný řetězec (ano, i to je občas potřeba). S použitím prepared statements byste musel řetězec jaksi odescapovat ...To je právě ono, někde se escapuje, někde se na to zapomene, někde se to udělá dvakrát… Proto to považuju za hack, ne za řešení.
// SQL injection není možný $stmt = $db->prepare("SELECT * FROM users WHERE id = ?"); $stmt->bind_param($user_id); $q->query("SELECT * FROM users WHERE id = %i", $user_id); // Možný SQL injection $stmt = $db->prepare("SELECT * FROM users WHERE id = $user_id"); $q->query("SELECT * FROM users WHERE id = $user_id");Pokud se držíte standardního psaní dotazů (tedy data přes modifikátory), SQL injection v Query2 není možný.
Principiálně pomalejší být nemusí, ale v praxi pomalejší jsou.To se ale týká jen MySQL, podobně jako to, že problém s vytvářením prováděcího plánu.
Mezi instancemi requestu souhlasím, v rámci jednoho requestu málokdy.Proto jsem psal, že se to asi týká jen PHP. Jinak si aplikace samozřejmě může pamatovat připravený dotaz libovolně dlouho.
Pokud se držíte standardního psaní dotazů (tedy data přes modifikátory), SQL injection v Query2 není možný.Pokud někde nepoužíváte escapování mimo tuto knihovnu. Pak ale tahle knihovna stejně jen obchází to, že prepared statements jsou (prý) v MySQLi pomalejší(což je taky divné, logicky znovupoužitelnost měla vést naopak ke zrychlení).
function sqlDotaz($dotaz, $parametry = null) { try { $dotaz = $db->prepare($dotaz); if ($parametry != null) { for($i = 0; $i < count($parametry); $i++) { $dotaz->bindParam($i+1, $parametry[$i]); } } $dotaz->execute(); $r = $dotaz->fetchAll(); return $r; } catch (PDOException $e) { logujChybu("sqlDotaz($dotaz)"); } }
------------- mysql --------------- elapsed time: 1.03722381592 ------------- mysql pdo --------------- elapsed time: 1.04643011093 elapsed time prepared, parsing: 1.07211589813 elapsed time prepared, one time parse: 1.03426194191 ------------- mysqli --------------- elapsed time: 1.3649790287 elapsed time prepared, parsing: 1.40571093559 elapsed time prepared, one time parse: 0.898549079895Ty rozdíly nejsou nijak extrémní... MySQLI je hodně rychlé pokud se jedná o opakované dotazy, jinak je docela pomalé - no, nejpomalejší ze všech možností přístupu k MySQL... A teď příklad kdy prepared statements opravdu něco znamenají:
-------------oracle pdo --------------- elapsed time with flushed shared pool: 3.47801780701 elapsed time with shared pool: 0.90004491806 elapsed time prepared flushed shared pool, parse each: 0.939059972763 elapsed time prepared, parsing: 0.884253025055 elapsed time prepared, one time parse: 0.42867898941Pro jistotu jsem udělal 3000 dotazů s vyprázdněným shared poolem a s již naplněným - rozdíl 2,5s. Pokud následně použiju prepared statement, rychlost už je jen o cca 0,02s lepší, nicměně, bez prep. stmt. mám v paměti 3000 nacachovaných exekučních plánů, s prep. statementem jen 1 - tzn. 3000x menší paměťová náročnost.
Nezávislost na DB je iluze, pokud nepoužíváte pouze triviální dotazy (na to je stejně lepší ORM).PDO má stejný interface (metody pro dotazy, fetch apod) ať už použiju jakoukoliv databázi. Tvorbu SQL pak nechává na lidech, takže nějakou nezávislost na DB nabízí. Jak říkají sami autoři je to "data-access abstraction layer", ne "database abstraction layer". Je v tom takový drobný rozdíl.
PDO má stejný interface (metody pro dotazy, fetch apod) ať už použiju jakoukoliv databázi. Tvorbu SQL pak nechává na lidech, takže nějakou nezávislost na DB nabízí.Pokud pisete cokoliv trosku vetsiho (tim fakt nemyslim vlastni blog nebo neco podobneho), nemate sanci se vyhnout psani vlastnich SQL dotazu. A kdyz uz je treba je psat, je snaha psat je prenositelne zbytecna. Nebudete prece delat kompromisy v rychlosti a vykonu proto, ze byste mozna hypoteticky mohl chtit casem zmenit databazi...?
Používáš JDBC?
LOB
ů nebo XMLTYPE
s mě už tak trošku přestávají bavit. Né že by to nefungovalo. To ono jó. Ale je to víc kódu, takže i víc chyb.
jinak je docela pomalé - no, nejpomalejší ze všech možností přístupu k MySQL...Tady bude záležet na použitým driveru. Dneska existuje mysqlnd (MySQL native driver), kterej nahrazuje libmysql a teoreticky a snad i prakticky je rychlejší, než používání libmysql. Tenhle driver mohou používat všechny extenze ext/mysql, ext/mysqli i PDO_MYSQL.
Občas se totiž stává, že vstup už máme escapovaný a znovu to dělat přirozeně nechceme.Tohle nechápu. Jak se to může stát. To je chyba, ne?
při zapnutém magic_quotes_gpcTohle je jedna z největších prasáren v PHP, naprosto chybný návrh.
Ve svých skriptech kontroluji, jestli je magic_quotes_gpc zapnuté a pokud ano, všechen vstup odescapuju.
Coz je prave to zbytecne ustupovani, diky kteremu budou v php ci na beznych hostinzich takoveto (omluvte prosim to slovo) sra*ky.
Vas hosting neumoznuje vypnout magic_quotes_gpc? Ok, takze nashle. Takoveto fusery nema cenu dale podporovat
Pak nemáte čas ani vůli přesvědčovat každého z nich.
Spravne, od toho jsou ale pozadavky na kterych system bezi, ktere si otestuje a rekne ze na tomto proste nepobezi a vysvetli uzivateli proc.
Neresme prosim porad dokola nezmary php verze 4 a niz.
Pak se ale těžko vysvětluje, proč jsou příjmy poloviční. Jen kvůli boji za čistotu PHP ...
Pak se ale tezko vysvetluje, proc je php tak zprasene. Jen kvuli neschopnosti vysvetlit potrebu zmeny a podlozit ji argumenty
Soudit zákazníky podle hostingu je IMHO trochu dětinské.
To tu ale nikdo netvrdi.
Kazdy rozumny zakaznik si necha vysvetlit, ze tento hosting ne, protoze ... Pokud mu to ale neumite vysvetlit a sve nazory si obhajit, je problem jinde.
Opravdu si myslite, ze nekdo bude chtit pouzivat knihovnu, ktera neni otagovana a ani o branche se ji taky vubec nezda? Pekne ze nabizite neco lidem, co ani sam nepovazujete za stabilni : )
Jinak k layeru:Omlouvam se za trochu kriticky prispevek, je ale pravda, ze kazdy php programator si musi napsat to sve kolo v podobe databazove knihovny, parseru pro html kod, redakcniho systemu atp. Sam sem si tim prosel : )
A perlicka na zaver, jak je na tom knihovna v porovnani s pdo_mysql co se rychlosti a pametove narocnosti tyce? Ja myslim ze uz dopredu je vysledek znam.
A ted jeste posledni "rejp" do prepare statements, co bude rychlejsi, kdyz cele pole projdu a data oslashuji v php, nebo to necham na db, ktera to vi beztak imho lepe?
Ja vim, dej jim prst a sezerou te celeho
Toto je první veřejná verze - tagování ani branchování nebylo jednoduše dosud potřeba![]()
I tak mi to prijde takove ... Osobne nic co neotaguji nepovazuji za stabilni a pokud to nekdo pouzije, je to jen na jeho riziko a ja to vyslovne nedoporucuji. Co kdyz si usmyslim, ze tady ty parametry metody jsou pro me zbytecne, tak je odstranim?
Jednoduše není potřeba. O kontrolu dat se stará Query2 jinak a jediná další výhoda je potenciální zvýšení výkonu - což u MySQL neplatí.
Otazkou je, jestli dostatecne a jestli ten mytus o rychlosti porad plati. Mysql uz davno neni ve verzi 4.1
Jelikož MySQL nepodporuje zanořené transakce, na co vám bude dobré mít AUTOCOMMIT na nule?
Otazka znela proc ho dava na 1, imho je to zbytecne, jen dalsi sitova komunikace navic
Volá se při destrukci objektu Query2Result.
Coz imho neni spravne
Unbuffered query? Toto Query2 nepodporuje. Můžete uvést nějaký příklad použití? AFAIK není možné volat další dotaz dokud nedojde k odfetchování všech výsledků, takže rychlostní ani paměťový benefit nevidím.
Napr vsechny dotazy typu INSERT/UPDATE/DELETE, kde me zajima pouze true/false vysledku?
Samozřejmě hůř, je to totiž knihovna vyšší úrovně. Query2 ale upravuje SQL jen velmi málo (de facto jen substituce modifikátorů), takže myslím, že rozdíl nebude relevantní.
A ted k otazce, co Vam chybi na std. pdo, ze musite psat toto kolecko?
IMHO rozdíl v rychlosti escapování nebude relevantní.
na malem poctu bindovanych promennych urcite, na vetsich bych si tak jisty nebyl, natoz u napr. text/blob sloupce
Nerikam, ze psat si vlastni layer je spatne, naopak clovek se toho hodne nauci, vesmes ale nakonec dojde k zaveru, ze std. reseni je lepsi a efektivnejsi :D
Mimochodem, jak dokážete poslat parametr (soubor) serveru bez toho, abyste ho nemusel najednou načíst do paměti? Streamem?jj, např. v Javě by to mělo jít takhle:
File file = new File("myimage.gif"); FileInputStream fis = new FileInputStream(file); PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)"); ps.setString(1, file.getName()); ps.setBinaryStream(2, fis, (int)file.length()); ps.executeUpdate(); ps.close(); fis.close();viz Processing Binary Data in JDBC.
$fp = fopen($_FILES['file']['tmp_name'], 'rb');
$stmt->bindParam(':mujLob', $fp, PDO::PARAM_LOB);
Toto bez PP možné není. Samozřejmě že PDO podporuje nejen fopen, ale všechny stream API. A například Oracle OCI nepotřebuje ani stream a stačí mu předat filename, se kterým si pak oracle client poradí sám.
Opět, nikdo netvrdí, že prepared statements jsou k ničemu. Jinak, pokud se prepared statements skutečně takto zrychlí, není problém knihovnu reimplementovat pro práci s prepared statements beze změny API.
Proč to tedy neudělat rovnou, například jako parametr při inicializaci "USE_PREPARED_STATEMENTS" a pokud bude nastaven, budou použity. Někdo je třeba používat chce kvůli 100% bezpečnosti nebo kvůli rychlosti při opakovaných query (zde je přínos měřitelný i na MySQL).
$q->query("SELECT * FROM users WHERE login %in ORDER BY %t", array("Eva", "Filip", "Jakub"), "lo'gi`n");
Je sice hezké že pro IN můžu použít array se seznamem hodnot. ale pojďme se podívat na nějaký dotaz:
SELECT * FROM tabulka WHERE pozdrav = "Ahoj" OR osloveni = "Ahoj"
Je to triviální dotaz, ten se dá napsat i takto:
SELECT * FROM tabulka WHERE "Ahoj" IN (pozdrav, osloveni)
Tzn. v IN nemám hodnoty, ale názvy sloupců. Tento zápis se zcela běžně používá a osobně ho považuji za přehlednější. Bohužel Query2 nebo DIBI a předpokládám že i query ze Zend_Db udělají to, že vstupní pole automaticky považují za seznam hodnot a proto hodnoty uzavírají do uvozovek, což pak samozřejmě znamená že takový dotaz fungovat nebude... Výhoda kompozice dotazů tak dostává na frak. A nezbývá než to napsat "natvrdo".
$q->query("SELECT * FROM tabulka WHERE "Ahoj" %in", array( new Query2Statement("pozdrav"), new Query2Statement("osloveni") ));Query2Statement je triviální třída vytvořená přesně na toto. Problém je v tom, že v onom poli nemáme moc způsobů jak knihovně říct, jak data interpretovat. Dal by se použít nový modifikátor, ale toto funguje obecně pro všechny modifikátory s argumenty - poli.
IN
je tam MATCH (sloupce) AGAINST výraz
. A nejspíš jde najít spoustu dalších případů, kde je problém rozlišit escapování názvů sloupců (popř. tabulek) a hodnot (např. když dopředu nevíte, jaké sloupce bude potřeba nebo v které tabulce data jsou).
Zatím jsem viděl jen jedno řešení, kde veškeré předávané parametry byly objekty, které samy věděly, jestli jsou název nebo hodnota, takže se korektně před použitím samy oescapovávaly (hodnoty v normálních apostrofech, názvy v otočených), ale osobně se mi to zdá poněkud težkopádné. Spíš by se mi líbila ona druhá možnost mít přímo v řetězci samostatné modifikátory pro názvy a pro hodnoty, jenže to znamená napsat si vlastní funkci na zparsování řetězce, poněvač PHP bohužel nemá u printfoidních funkcí definovatelné callbacky pro vlastní modifikátory.
SELECT 'fuj' AS "To je ale 100% prasárna";(vyzkoušej)
"To je ale 100% prasárna";
Mně to jako prasárna nepřipadá. Třeba pro reporty je skvělý, nemusíš hákovat nějaký formátování. Prostě ti z SQL*Plus rovnou vypadne přehledná tabulka s lidsky čitelným nadpisem. T_########
a sloupce v nich C_########
kde #
je zástupce pro číslo. function printf_escape($str) { return str_replace('%', '%%', $str); } mysql_query(vsprintf(vsprintf($query, array_map('printf_escape', $cols)), $vals))... k neprůstřelnosti tomu ale chybí ještě doplňování uvozovek a escapování obsahu $cols a $vals.
Pokud chci pouze pocet bez limitu, muzu pouzit modifikator pro select SQL_FOUND_ROWS, jde toto provest s Query2? Jistě, úplně stejně jako byste to udělal třeba pomocí mysql_query()
Koukam do zdrojaku a na kazdy sloupec se aplikuje pomoci array_map volani metody escape. Zkouset jsem to tedy nezkousel, ale logicky mi z toho vychazi, ze mi to SQL_FOUND_ROWS oslashuje, coz zkonci leda tak na nenalezenem sloupci. Mozna jsem ale nejaky hack predtim prehledl.
Chvalim za pouziti spravne fce pro escapovani - mysql_real_escape_string nikde uz ale nevidim volani mysql_client_encoding, bez ktereho je i mysql_real_escape_string za urcitych okolnosti derava. Přiznám se, že o děravosti při nenastavení encoding jsem ještě neslyšel, pokusím se to nastudovat. Díky.Pokud klient, běžící v jednobytovém kódování (např. Win CP-1250, ISO 8859-2 ...), neví, že zpracovává řetězec s vícebytovými znaky, může pustit ven řetězec, který je z pohledu klienta naprosto korekntní, ale z pohledu serveru používajícího vícebytového kódování (např. UTF-8), už ne - stačí vpašovat na vhodné místo vhodný znak (např. s hodnotou nad 127), který při převodu do vícebytového kódování "pozře" přidané escapování. Sice na SQL injection by to asi nestačilo, ale na rozhození query, chybovou hlášku a případné znefukčnení stránky to stačí.
$q = new Q(); $q->add_from('from T as t'); $q->add_select('x'); if ($id) { $q->add_where('t.id = '.$id); } if ($add_name) { $q->add_left_join('N as n', 't.id = n.id'); $q->add_select('n.name'); } $q->execute();Takováhle věc se mi osvědčila už mnohokrát a drasticky to zjednodušuje tvorbu SQL dotazů. Navíc ani nemusí řešit spojení k DB, stačí aby výstupem byl vlastní dotaz.
sloupec like '%slovo1% or sloupec like '%slovo2%' or sloupec like '%slovo3%' + 30x
DISTINCT
. WINDOW
nad ní definovanou analytickou funkcí. Hoši nemohli pochopit, proč že náročnost dotazu roste miliónkrát s každým novým řádkem. Prý proto, že u sloupců s datovým typem DATE
nalze použít index. NVL(sloupec, '')
COALESCE(sloupec1, sloupec2, '')
VARCHAR2
už ani nemluvím. Pak je to samý TO_CHAR()
, TO_NUMBER()
a že je to pomalý. REPLACE
y... -D
parametry aplikáče. No to právě ne. Jak už tě upozornili ostatní, tohle řešení má (v budoucnu bude mít) velké výkonnostní problémy, jelikož na to není to schéma připraveno. De facto by jsi musel přidat index na každý sloupec a jejich kombinace. Jak pak dopadne insert
asi netřeba připomínat.
Je nejlepší pro ni připravit aplikaci, kde si nakliká co potřebuje a app si pak efektivně s pokecá s DB serverem.Asi tak nějak. Chce to hlubší analýzu. Potřebou uživatele totiž není „filtrovat data z tabulky podle X různých kritérií“* – jeho potřebou je vyřešit nějaký „byznys“ problém. Takže je potřeba si udělat analýzu procesů** a zjistit, jaké je vlastně zadání. A pokud se dojde k tomu, že uživatel opravdu potřebuje ten multidimenzionální pohled na data a dolovat z nich předem neznámé skutečnosti, pak je to úloha pro ten OLAP, jak tu psal Pavel. *) což si myslí programátor **) přičemž se pravděpodobně zjistí, že spousta činností je prováděna naprosto zbytečně jen proto, že se to tak „vždycky dělalo“ (jenže tehdy ještě nebyly počítače a všechno se strkalo do šanonů a psalo se na stroji). Aneb přínos IT není v tom, že elektronizujeme staré procesy, ale že se pokusíme navrhnout nové, které využívají možností IT a jsou díky tomu efektivnější.
Returns additional information from the notifying process. Currently, this feature is unimplemented and always returns an empty String.Pak by bylo možné např. posílat triggerem zprávu o tom, že se změnil nebo přibyl záznam s určitým ID (pak je ještě otázka jak do toho napasovat data, kde máme složený PK – asi přes OID). A taky: půjde někdy v JDBC čekat na události? Aby nebylo nutné se cyklicky dotazovat, zda už nějaká zpráva přišla. Zatím jsem totiž v dokumentaci našel:
A key limitation of the JDBC driver is that it cannot receive asynchronous notifications and must poll the backend to check if any notifications were issued.V céčkové knihovně čekat na událost lze (i když způsobem, který mi přijde trochu dost nízkoúrovňový). P.S. tak už jsem to našel v TODO – funkce přidání dat do zprávy by měla být už hotová
$allowed_orderby = array("id" => 1, "name" => 1, "phone_number" => 1, "salary" => 1, "citizen_of" => 1); if(!isset($allowed_orderby[$orderby])) $orderby = "id"; // default $q->query("SELECT * FROM users ORDER BY %t", $orderby);místo:
$queries = array( "id" => "SELECT * FROM users ORDER BY id", "name" => "SELECT * FROM users ORDER BY name", "phone_number" => "SELECT * FROM users ORDER BY phone_number", "salary" => "SELECT * FROM users ORDER BY salary", "citizen_of" => "SELECT * FROM users ORDER BY citizen_of", ); if(!isset($queries[$orderby])) $orderby = "id"; // default $q->query($queries[$orderby]);Tohle je samozřejmě triviální příklad, s počtem "proměnných" roste počet konečných dotazů exponenciálně.