Michal Čihař - Archive for Jan. 21, 2008

Že se ještě vůbec snažím někomu radit

Chápu, že občas na jabber konferenci pro phpMyAdmina vleze někdo kdo má problémy s MySQL. Ale když už někdo neví co dělá a chce provozovat redakční systém v PHP, tak by aspoň mohl mít trochu slušnosti. Pojmenovat se aaa na důvěryhodnosti moc nepřidá (a koneckonců anonymitu taky ne, stejně IP adresu vím ;-)) a po prvním dotazu "hele kde mám zjistit udaje MySQL?" už se člověk nemůže ubránit pocitu co že to za blbce sem zase dorazilo. Nicméně to mě neodradilo od toho se mu pokusit poradit, ale dobře míněná snaha stejně přišla vniveč. Ostatně posuďte sami . No nic je na čase jít spát.

Vlastní exportní formát

Před týdnem jsme se dozvěděli, jak exportovat data do podporovaných formátů. Co ale dělat, když potřebujeme data ve vlastním formátu? Napsat si vlastní exportní modul není nic těžkého, jak na to se dozvíte v dnešním článku.

Začátek

Nejdříve si rozmyslete, co všechno od exportu budete potřebovat a jaké možnosti nastavení bude export mít. Vždy je lepší si nejprve ujasnit požadavky, než se vrhneme na programování. Pro ukázku v tomto článku budeme vytvářet export do textového souboru, který půjde dále zpracovat pomocí Texy! . Nastavení použijeme stejná jako mají ostatní podobné exporty, tedy možnost vypnutí dat nebo struktury, zobrazení jmen sloupců a text, kterým nahradíme NULL hodnoty.

Hlavička

Každý plugin obsahuje hlavičku, která se provádí při načítání pluginů. Ta definuje jednak informace o pluginu a také parametry, které bude možné nastavit na stránce s exporty. Pro náš export tedy bude základní hlavička vypadat takto:

 
  <?php

/*Texy! export for phpMyAdmin */

if (isset($plugin_list)) {
    /* Jméno zaregistrovaného pluginu musí být stejné jako jméno souboru */
    $plugin_list['texytext'] = array(
        'text' => 'Texy! text',         /* Jméno pluginu které se zobrazí uživateli */
        'extension' => 'txt',           /* Přípona vygenerovaného souboru */
        'mime_type' => 'text/plain',    /* MIME typ vygenerovaného souboru */
        /* Definice parametrů: */
        'options' => array(
            array('type' => 'bool',
                'name' => 'structure',
                'text' => 'strStructure',
                'force' => 'data'),
            array('type' => 'bgroup',
                'name' => 'data',
                'text' => 'strData',
                'force' => 'structure'),
            array('type' => 'text',
                'name' => 'null',
                'text' => 'strReplaceNULLBy'),
            array('type' => 'bool',
                'name' => 'columns',
                'text' => 'strPutColNames'),
            array('type' => 'egroup'),
            ),
        'options_text' => 'strOptions',
        );
} else {

/* Sem přijde kód pro export */

}
?>
 

Pokud nyní soubor s tímto PHP kódem uložíme jako libraries/export/texytext.php , měl by phpMyAdmin už tento plugin zobrazit na stránce pro export.

Implementace exportu

Pro vlastní export je potřeba implementovat několik funkcí, které mají za úkol získat data z MySQL a poslat je na výstup pomocí funkce PMA_exportOutputHandler . Tato funkce zajišťuje zpravování výstupního bufferu, kompresi a posílání dat uživateli nebo ukládání na server. Vrací false, pokud operace selhala.

Funkce, které musíme implementovat jsou tyto:

  • PMA_exportComment
  • PMA_exportFooter
  • PMA_exportHeader
  • PMA_exportDBHeader
  • PMA_exportDBFooter
  • PMA_exportDBCreate
  • PMA_exportData
  • PMA_exportStructure

Všechny by opět měly vrátit false, pokud se něco nepodařilo. Funkcí je sice hodně, ale to je jen z důvodu usnadnění psaní exportů do rozličných formátů. Jejich názvy jsou snad celkem výstižné, takže ani nebudu popisovat k čemu která slouží. Pro náš případ potřebujeme jen funkce PMA_exportDBHeader , PMA_exportData a PMA_exportStructure , ostatní mohou jen vracet true a nic nedělat.

PMA_exportDBHeader

Tato funkce má za úkol vypsat hlavičku exportu a bude tedy poměrně triviální:

 
  function PMA_exportDBHeader($db) {
    return PMA_exportOutputHandler('===' .
        $GLOBALS['strDatabase'] . ' ' . $db . "\n\n");
}
 

PMA_exportData

Teď se již dostáváme ke komplikovanějšímu úkolu – exportu dat. Začneme opět nadpisem, aby uživatel věděl, o jakou tabulku se jedná:

 
  if (!PMA_exportOutputHandler('== ' . $GLOBALS['strDumpingData'] . ' ' . $table . "\n\n")) {
    return FALSE;
}
 

Jako další krok potřebujeme načíst data z MySQL. Pro to použijeme DBI vrstvu phpMyAdmina:

 
  $result      = PMA_DBI_query($sql_query, null, PMA_DBI_QUERY_UNBUFFERED);
$fields_cnt  = PMA_DBI_num_fields($result);
 

Uživatel měl možnost si vybrat, zda chce zobrazit v hlavičce jména sloupců. Zde poprvé použijeme přístup k parametrům a podle jeho hodnoty případně zobrazíme hlavičku:

 
  global $what;

if (isset($GLOBALS[$what . '_columns'])) {
    $text_output = "|------\n";
    for ($i = 0; $i < $fields_cnt; $i++) {
        $text_output .= '|' . htmlspecialchars(stripslashes(PMA_DBI_field_name($result, $i)));
    } // end for
    $text_output .= "\n|------\n";
    if (!PMA_exportOutputHandler($text_output)) {
        return FALSE;
    }
} // end if
 

Nyní nám už jen chybí vypsat data z databáze uživateli:

 
  while ($row = PMA_DBI_fetch_row($result)) {
    $text_output = '';
    for ($j = 0; $j < $fields_cnt; $j++) {
        if (!isset($row[$j]) || is_null($row[$j])) {
            $value = $GLOBALS[$what . '_null'];
        } elseif ($row[$j] == '0' || $row[$j] != '') {
            $value = $row[$j];
        } else {
            $value = ' ';
        }
        $text_output .= '|' . htmlspecialchars($value);
    } // end for
    $text_output .= "\n";
    if (!PMA_exportOutputHandler($text_output)) {
        return FALSE;
    }
} // end while
 

A uvolnit výsledky dotazu a vrátit návratovou hodnotu:

 
  PMA_DBI_free_result($result);
return TRUE;
 

PMA_exportStructure

Export struktury je asi nejnáročnější a určitě nejrozsáhlejší, nicméně neobjevují se zde již žádné nové věci týkající se exportu, proto se na její celý kód podívejte sami v přiloženém souboru. V úvodu se načtou z MySQL parametry tabulky, poté pomocí funkcí phpMyAdmina načteme informace o relacích a MIME typech sloupců a tyto informace zformátujeme do Texy!.

Hotovo

A tím by mělo být vše hotovo. Plugin vyzkoušíme a pokud to uznáme za vhodné, pošleme do patch trackeru , aby mohl být náš plugin začleněn v další verzi phpMyAdmina.

Celý hotový exportní plugin naleznete v příloze článku.

Přílohy: