Nemám rád PHP (MySQL 4.0 versus 4.1)!

MyEgo.cz

home foto blogy mywindows.cz kontakt

Nemám rád PHP (MySQL 4.0 versus 4.1)!

PHP 17.10.04

Představte si, že v roce 2004 zhruba 95% hostingů na celém světě používá MySQL 4.0.x, nebo nižší (z těch, co MySQL podporují). V PHP se k MySQL 4.0 přistupuje například takto (pro získání veškerých položek článku číslo 1):

// MySQL 4.0.x a nizsi
$resource = mysql_connect('localhost','root','heslo');
mysql_select_db('blogcms',$resource);
$query = mysql_query(
  'select * from items where id=1',
  $resource);
if ($row = mysql_fetch_object($query)) {
  // zpracovani vysledku
}

Jednoduché a funkční. Nicméně, pak si nainstalujete PHP 5 a MySQL 4.1.6-gamma, která je oficiálně doporučená pro veškerý nový vývoj, a veškeré Vaše současné skripty přestanou fungovat, přestože používáte jak mysql (pro vezi 4.0 a nižší) PHP extension, tak mysqli (pro vezi 4.1.2 a vyšší) PHP extensions. Prostě Vaše skripty musíte přepsat na mysqli, zpětná kompatibilita s mysql neexistuje, přestože by měla (dle dokumentace) fungovat.

MySQL ve verzi 4.1.2 a vyšší změnila svůj interní komunikační protokol. Podporuje také pár funkcí navíc, zejména nativně znakové sady jako je utf-8 a unicode, a umožňuje nativní české řazení podle utf-8. To je sám o sobě dost dobrý důvod proč na MySQL 4.1 přejít.

phpMyAdmin

Nicméně, chlapci co pracují na PHP engine (Zend engine), si drasticky zjednodušili svoji práci. Místo, aby současné MySQL funkce, fungující pro verzi 4.0, a 3.2.xx, napsali transparentně, aby fungovaly nově i pro verzi 4.1.x, tak jim přidali písmenko i, což má podle nich znamenat improved, podle mého názoru spíše idiotic, protože veškeré funkce se nyní nejenže jmenují místo mysql_funkce nově mysqli_funkce, ale mají zcela záměrně prohozené pořadí parametrů.

Takže náš testovací příklad musíte psát takto:

// MySQL 4.1.2 a vyssi
$resource = mysqli_connect('localhost','root','heslo');
mysqli_select_db($resource,'blogcms');
$query = mysql_query(
  $resource,
  'select * from items where id=1');
if ($row = mysqli_fetch_object($query)) {
  // zpracovani vysledku
}

Jinak řečeno, kvůli zprasené práci chlapců, co dělají PHP, veškeré skripty, co pracují s MySQL 4.0, nebudou s MySQL 4.1 fungovat.

Není sice složité to obejít, napsat si něco takovéhoto, a pak používat jen mysqli i na PHP 4 a MySQL 4.0:

if (!is_callable("mysqli_connect")) {
  function mysqli_connect($h,$u,$p) {
    return mysql_connect($h,$u,$p);
  }
  function mysqli_select_db($r,$db) {
    mysql_select_db($db,$r);
  }
  function mysqli_query($r,$q) {
    return mysql_query($q,$r);
  }
}

Pokud si podobný triviální patch uděláte i pro další mysqli funkce, Váš skript poběží jak oproti PHP 4 a PHP 5, tak hlavně oproti MySQL 3.2.xx, MySQL 4.0 a MySQL 4.1. Otázkou zůstává, proboha proč??? To chlapcům z PHP nic neříká slovo kompatibilita?

Pokud používám Oracle, mohu se spolehnout na to, že skripty psané oproti Oracle 7, poběží i proti Oracle 8i, 9i, a 10g. U open-source produktů se nemohu spolehnout naprosto na nic. ;-)

Používat funkce MySQL 4.1 stejně nemůžete, pokud se jedná o open-source projekt, musíte stále počítat i se starou MySQL 3.2.xx. Ze stejného důvodu mimochodem nemají velký smysl databázové layery (i když, tento patch není nic jiného než jednoduchý DB layer), je sice pěkné, že PostgreSQL podporuje triggery a views, ale pokud je nepodporuje MySQL, musíte se ve Vašem kódu omezit na nejnižšího společného jmenovatele. A tím je MySQL 3.2.xx.


Mimochodem, taková dobrá rada, MySQL 4.1.x zavádí jiný systém pro kódování hesel, pokud se tedy vůbec chcete připojit k MySQL 4.1 pomocí mysql extension (tedy extension pro MySQL 4.0), a až tak moc svoje skripty nepřepisovat, založte si nového uživatele, třeba old_root a přidělte mu heslo pomocí funkce OLD_PASSWORD, a připojujte se pomocí tohtoto uživatele. Tedy takto:

REVOKE ALL PRIVILEGES ON *.* FROM old_root@localhost;
GRANT ALL PRIVILEGES ON *.* TO 
  old_root@localhost 
  WITH 
    GRANT 
	OPTION 
	  MAX_QUERIES_PER_HOUR 0 
	  MAX_CONNECTIONS_PER_HOUR 0 
	  MAX_UPDATES_PER_HOUR 0 ;
SET PASSWORD FOR 
  old_root@localhost = OLD_PASSWORD( "heslo" ) ;

Komentáře

  1. 1 olda 17.10.04, 01:10:30
    FB

    ja mam soubor s funkcema na ovladani mysql a pak pouzivam jenom ty funkce ktery sem si napsal, takze mi staci zmenit jenom tenhle jeden soubor a zbytek muzu nechat...

  2. 2 Radek Hulán 17.10.04, 01:10:33
    FB

    [1] ale ono to nestačí přepsat, ale napsat mírně jinak, aby to fungovalo s MySQL 3.2.x až 4.1.x, je to sice práce jen na pár desítek minut, i s důkladným otestováním, nicméně, o to nejde..

    Nechápu, jak někdo může zcela nabourat kompatibilitu miliónů skriptů, takto nebude v praxi MySQL 4.1 nasazena ještě MOC DLOUHO..

  3. 3 Tom 17.10.04, 02:10:01
    FB

    Naprosty souhlas. Nekompatibilita PHP mezi verzemi me hodne prudi.

    Nemam cas furt prepisovat stranky pro jednotlive verze, kdyz se napr. na Pipni.cz rozhodnou upgradovat PHP.

    Java, napr. udrzuje zpetnou kompatibilitu az zbytecne dlouho a PHP je zase druhy extrem. Co fungovalo vcera, dnes nemusi... :-(

    BTW: Radku: Ten predchozi design blogu se mi libil vic ;-) A tim nemyslim, ta modra pismena, ta mi zas tak nevadi ;-)

  4. 4 Radek Hulán 17.10.04, 02:10:03
    FB

    [3] v pravém menu se na ten classic design můžeš přepnout.. Někomu se líbí víc tento, někomu předchozí, proto jsem nechal oba..

  5. 5 Jiri Zahradil 17.10.04, 03:10:49
    FB

    Na svých stránkách používám db layer (ez_sql), pro možnost přepnutí databáze (např. SQLite x MySQL) takže přejmenování funkcí pro mě znamená jen přepis jednoho souboru. Myslím, že pokud má někdo systém dobře navrhnutý nemůže pro něj tato změna znamenat katastrofu.

  6. 6 Marabu 17.10.04, 03:10:54
    FB

    Koukam jedine stesti ze uz asi rok pouzivam kompletne pro veskerou komunikaci s databazi vlastni objekt... kdyz se neco zmeni, staci to zmenit v nem a jede se dal.

  7. 7 Petr Bříza 17.10.04, 03:10:59
    FB

    Já bych k tomu ODS možná přidal i tu vlaštovku :-)

  8. 8 Ján "johno" Suchal 17.10.04, 04:10:08
    FB

    Radku, nechápem vsuvku o nevhodnosti použitia DB layerov. Veď DB layer presne takého veci rieši. Nemusím sa vôbec babrať s nejakými "nízkymi" DB funkciami ale zavolám si SQL::connect('mysqli://username:password@hostspec/database'); a potom už veselo používam metódy viac menej nezávisle na DB.

    V podstate si to tak vyriešil aj ty, ale uniká mi zmysel toho celého skriptu keď sú knižnice, ktoré to riešia elegantnejšie a majú aj nejakú tú funkcionalitu naviac. Ja napríklad nedám dopustiť na PEARovský DB package. Sú tam metódy, ktoré sú síce triviálne ale naozaj vedia ušetriť čas a pridať na prehľadnosti. Napríklad spomeniem getOne(), getAll(), getCol() či getAssoc().

    Netreba si tak pamätať názvy funkcii a parametrov pre každú DB a ozajstné výhody DB layeru sa ukážu pri portácii na inú DB. To síce nie je skoro nikdy pravdepodobné ale poznáme zákon schválnosti.

  9. 9 Roman 17.10.04, 04:10:40
    FB

    Uz cca 3 roky pouzivam ADODB (odkedy mi ho Havran nanutil) a stihli sme uz medzitym urobit veci pre Mysql, PostgreSQL a MSSQL.. keby niekto povedal ze ma Oracle (coz tusim hrozi od jedneho mojho buduceho klienta ktoremu sa mam ozvat po svadbe), tak predpokladam ze to nejak zmakneme.. len aby tam bolo nejake PHP ;-).

  10. 10 Radek Hulán 17.10.04, 04:10:52
    FB

    [8] ale já své projekty taky píšu jinak, ale zde je důvod prozaicky historický - Nucleus 1.0 a rok 2000 ;-)

    To nic nemění na faktu, že PHP a MySQL kašle na zpětnou kompatibilitu, a to je hodně špatně.. I když řešitelné během pár desítek minut, tak, kdoví co bude příště za šílenost..

  11. 11 martin 17.10.04, 04:10:58
    FB

    [3] Ona ta kompatibilita u PHPka je docela dobra, kdyz lide pisou skripty ciste. Jenomze kazdy tam vlozi nejaky specialni funkcni vymysl, a pak to prestane makat.

    Ja jsem napriklad pri prechodu z PHP4 na PHP5 u ciste napsanych skriptu nemel skoro zadne problemy, ale kdyz to byla prasarna, nefungovalo to skoro vubec.

    [2] Ja si myslim, ze je to jen pro ucel ladeni, ze casem tu kompatibilitu zajisti, preci jenom MySQL 4.1 je dost nova vec. Mozna je z duvodu novinek lepsi oddelit stary vyvoj MySQL od noveho, na serveru preci jenom neni problem provozovat dva databazove servery, navic databazove servery se zrovna moc bezne neaktualizuji. Nejaky duvod to jiste mit bude, a proto bych na tvem miste tady nestenal a zeptal se lidi od Zendu, co je k tomu vedlo, ja se jich parkrat zeptal, a odpovedi meli docela dobrou logiku

  12. 12 llook 17.10.04, 05:10:09
    FB

    Zrovna si píšu něco pro MySQL a celkem bez rozmyslu jsem začal psaním mezivrstvy. Ne ani tak kvůli mysqli, ale hlavně proto, abych to v budoucnu po přechodu na PHP5 mohl provozovat třeba i nad SQLite.
    Docela se mi líbí rozšíření dbx, ale není moc rozšířené a navíc má své nevýhody - třeba že drží celý výsledek dotazu v poli.

    MySQL 5.0.x je zatím pouze vývojová, ale až bude vhodná pro produkční prostředí, tak to bude dost velký skok. Například umí i ty postrádané views.

    [6] PEAR DB je přívětivé k vývojářům, ale co jsem četl, tak dost zdržuje - http://phplens.com/lens/adodb/...

  13. 13 Prochaine 17.10.04, 06:10:38
    FB

    Já jsem ještě úpně nepochopil rozdíl mezi mysql a mysqli.. Uměl bys to Radku vysvětlit?

  14. 14 Radek Hulán 17.10.04, 06:10:50
    FB

    [13] MySQL 4.1 používá jiný protokol pro komunikaci, proto i PHP 5.0.x má dvě extensions, mysqli pro MySQL 4.1, a mysql pro verze 4.0.x a nižší. Při použití mysql oproti MySQL 4.1 by se skript teoreticky nemusel přepisovat (až na jiné kódování hesel), nicméně, v praxi to nefunguje...

    A vtip je v tom, že PHP taky zavádí nové funkce, typu mysqli_nazevfunkce, které dělají přesně to samé, co mysql_nazevfunkce, tedy funkce pro MySQL 4.0, nicméně, mají uvnitř sebe prohozené pořadí parametrů.

    Třeba mysqli_query se volá s paramatry $databaze,$sqldotaz, kdežto mysql_query pro změnu s parametry $sqldotaz,$databaze..

    Není složité skript upravit, aby pracoval s oběma extensions, ale.. otázkou je, proč to PHP udělalo takto blbě.

  15. 15 Ján "johno" Suchal 17.10.04, 07:10:17
    FB

    [12] No tak to je ďalší z testov, ktorý nemá v podstate žiadnu hodnotu. Keď tam napíšu priemer bez štandardnej odchýlky alebo rozptylu tak to vlastne nič nedokazuje.

  16. 16 Tom 18.10.04, 08:10:27
    FB

    [11] Ted nemam na mysli jenom MySQL. Napsal jsem si cely web za pouziti XML a XSLT a tyto funkce proste v 5.0 nejsou. Jsou tam misto nich uplne jiny.

    Rozhodli se je odstrihnout a ja muzu nekolikatydenni praci vyhodit, protoze nemam cas to prepisovat/opravovat. Takovej peknej web to byl.. :-(

    Muj web byl nekomercni, ale jak bych to vysvetlil treba nekteremu svemu zakaznikovi? Mel by pocit ze s neho taham prachy :-(

  17. 17 Vojtěch Semecký 26.10.04, 02:10:21
    FB

    [16] Hlavne ze je v PHP manualu u XSLT podpory napsano:

    "Toto rozšíření je EXPERIMENTÁLNÍ. Chování tohoto rozšíření, názvy funkcí a všechno ostatní, co je zde zdokumentováno, se v budoucích verzích PHP může bez ohlášení změnit. Berte to v úvahu a používejte tento modul na vlastní nebezpečí."

    Proc myslite, ze to tam je?

  18. 18 barquux 08.01.05, 05:01:16
    FB

    pro pripojeni k novejsim mysql 4.1.x pomoci mysql funkci by melo stacit zkompilovat mysql extenzi oproti mysql klientovi z 4.1.x distribuce, cimz pada veta Jinak řečeno, kvůli zprasené práci chlapců, co dělají PHP, veškeré skripty, co pracují s MySQL 4.0, nebudou s MySQL 4.1 fungovat.. bc existuje, jen ji najit..

  19. 19 Radek Hulán 31.01.05, 10:01:48
    FB

    [18] máte pravdu, ale v době psaní článku toto s MySQL 4.1.6-gamma nefungovalo, s dnešní 4.1.8 to jede v pohodě (až na pár rozdílů v řazení)

  20. 20 Krutohlav 03.02.05, 03:02:00
    FB

    "i" v slove nemusí znamenať improved ale:
    The extension is called ext/mysqli, with the 'i' standing for any one of: improved, interface, ingenious, incompatible or incomplete.
    Takže tým "i" sami tvorcovia zvýrazňujú, že táto extenzia je "incompatible"