sql >> Database teknologi >  >> RDS >> Mysql

Hvordan får man tabelstrukturer fra en .frm-fil ved hjælp af PHP?

Ja, det er muligt at gendanne i det mindste en del af informationen. (Til gavn for andre læsere er spørgsmålsstilleren allerede klar over, at der er nemmere måder at få kolonnens metadata på).

Udfordringen er, at .frm-filer ikke er så veldokumenterede, fordi ethvert behov for at dechifrere dem af det generelle samfund er ret sjældent. Filernes format kan også variere med operativsystemet.

Men ved at se filerne med hexdump eller et lignende hjælpeprogram kan du delvist se, hvad der foregår. Så er du bedre informeret om at læse filerne i et PHP-program og afkode de rå binære data.

Jeg gjorde dette som en øvelse for noget tid tilbage, og jeg var i stand til at gendanne antallet af kolonner, kolonnenavne og kolonnetyper.

Nedenfor er et eksempel, der viser, hvordan man udtrækker kolonnenavne. Min .frm var for en tabelnavne "stop", men du kan erstatte din egen .frm.

<?php
$fileName = "stops.frm";

// read file into an array of char
//---------------------------------
$handle = fopen($fileName, "rb");
$contents = fread($handle, filesize($fileName));
fclose($handle);
$fileSize=strlen($contents);  // save the filesize fot later printing

// locate the column data near the end of the file
//-------------------------------------------------
$index = 6;    // location of io_size
$io_size_lo = ord($contents[$index]);  
$io_size_hi = ord($contents[$index+1]);
$io_size = $io_size_hi *0x100 + $io_size_lo; // read IO_SIZE

$index = 10;  // location of record length
$rec_len_lo = ord($contents[$index]);
$rec_len_hi = ord($contents[$index+1]);
$rec_len = $rec_len_hi * 0x100 + $rec_len_lo; // read rec_length

// this formula uses io_size and rec_length to get to column data
$colIndex = ( (  (($io_size + $rec_len)/$io_size)   + 1) * $io_size ) + 258;
$colIndex -= 0x3000;   // this is not documented but seems to work!

// find number of columns in the table
//------------------------------------------------- 
echo PHP_EOL."Col data at 0x".dechex($colIndex).PHP_EOL;
$numCols = ord($contents[$colIndex]);

//Extract the column names
//--------------------------------------
$colNameIndex = $colIndex+0x50;   //0X50 by inspection
echo "Col names at 0x".dechex($colNameIndex).PHP_EOL;
$cols=array();
for ($col = 0; $col < $numCols; $col++){
    $nameLen = ord($contents[$colNameIndex++]);          // name length is at ist posn
    $cols[]['ColumnName']= substr($contents,$colNameIndex,$nameLen-1); // read the name
    $colNameIndex+=$nameLen+2;        // skip ahead to next name (2 byte gap after \0)
}
print_r($cols);

Dette burde få dig i gang. Jeg vil tilføje til dette, når jeg har tid i de kommende dage, hvis du synes er på vej i den rigtige retning.

EDIT. Jeg opdaterede koden, så den burde virke for enhver .frm-fil (fra tabel). Der er helt sikkert et gratis værktøj til at gendanne mySQL (baseret på innoDB-motor) tilgængeligt på https:/ /github.com/twindb/undrop-for-innodb . Efter at have læst koden og de tilhørende blogs igennem, bruger de ikke .FRM-filerne til gendannelse. De samme tabeloplysninger er også gemt i innoDB-ordbogen, og de bruger denne til at gendanne tabelformater osv.

Der er også en måde at læse .FRM-filernes indhold på. Dette er beskrevet her https://twindb.com /how-to-recover-table-structure-from-frm-files-online/ . Men de bruger mySQL til at læse .frm-filerne og genskabe tabeller derfra.

Der er også et hjælpeprogram en pakke af hjælpeprogrammer, der findes her https://www .mysql.com/why-mysql/presentations/mysql-utilities/ der indeholder en .frm-læser. Dette blev lavet af Oracle, som er de eneste mennesker, der kender formatet på .frm-filerne! Hjælpeprogrammet er gratis, så du kan downloade det.

Oracle offentliggør nogle oplysninger om formatet af .frm-filer https://dev.mysql.com/doc/internals/en/frm-file-format.html , men det er både ufuldstændigt og forkert! Se dette forrige Stack-spørgsmål.https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-how-to-extract-column-info

Når alt kommer til alt, hvis du stadig vil prøve at parse .frm-filerne selv for sjov eller for at lære, så skal du være tålmodig og bruge tid på at optrevle en ret kompliceret struktur. Hvis du vil blive ved med at prøve, er det OK, men send mig din .FRM-fil ( til lex3d263f333d .com ), så jeg kan tjekke det ud, og jeg vil sende dig noget PHP-kode om et par dage, som vil udtrække nogle yderligere oplysninger såsom datatype og skærmstørrelser.




  1. Gå i dvale ved at sende fremmede forespørgsler til databasen

  2. MySQL - Forespørgsel efter ulæste meddelelser sammen med e-mails

  3. PHP/MySQL:Sådan opretter du en kommentarsektion på din hjemmeside

  4. Hvordan gendanner man en enkelt tabel fra en .sql postgresql backup?