sql >> Databasteknik >  >> RDS >> Mysql

Hur får man tabellstrukturer från en .frm-fil med PHP?

Ja, det är möjligt att återställa åtminstone en del av informationen. (Till fördel för andra läsare är frågeställaren redan medveten om att det finns enklare sätt att få kolumnmetadata).

Utmaningen är att .frm-filer inte är så väldokumenterade eftersom det är ganska sällsynt att dechiffrera dem i allmänheten. Formatet på filerna kan också variera med operativsystemet.

Men genom att titta på filerna med hexdump eller liknande verktyg kan du delvis se vad som händer. Då är du bättre informerad om att läsa filerna i ett PHP-program och avkoda den råa binära datan.

Jag gjorde detta som en övning för en tid sedan, och jag kunde återställa antalet kolumner, kolumnnamn och kolumntyper.

Nedan är ett exempel som visar hur man extraherar kolumnnamn. Min .frm var för en tabell som heter "stoppar", men du kan ersätta 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);

Detta bör få dig igång. Jag kommer att lägga till detta när jag har tid under de kommande dagarna om du tycker är på väg åt rätt håll.

REDIGERA. Jag uppdaterade koden så att den borde fungera för alla .frm-filer (från tabell). Det finns säkert ett gratis verktyg för att återställa mySQL (baserat på innoDB-motorn) tillgängligt på https:/ /github.com/twindb/undrop-for-innodb . Efter att ha läst igenom koden och de tillhörande bloggarna använder de inte .FRM-filerna för återställning. Samma tabellinformation lagras också i innoDB-ordboken och de använder denna för att återställa tabellformat etc.

Det finns också ett sätt att läsa .FRM-filernas innehåll. Detta beskrivs här https://twindb.com /how-to-recover-table-structure-from-frm-files-online/ . Däremot använder de mySQL för att läsa .frm-filerna och återskapa tabeller därifrån.

Det finns också ett verktyg ett paket med verktyg som finns här https://www .mysql.com/why-mysql/presentations/mysql-utilities/ som innehåller en .frm-läsare. Detta gjordes av Oracle, som är de enda som känner till formatet på .frm-filerna! Verktyget är gratis så du kan ladda ner det.

Oracle publicerar lite information om formatet för .frm-filer https://dev.mysql.com/doc/internals/en/frm-file-format.html , men det är både ofullständigt och felaktigt! Se denna föregående stackfråga.https://dba.stackexchange.com/questions/208198/mysql-frm-file-format-how-to-extract-column-info

Nu när allt kommer omkring, om du fortfarande vill försöka analysera .frm-filerna själv för skojs skull eller för att lära dig, måste du ha tålamod och lägga tid på att reda ut en ganska komplicerad struktur. Om du vill fortsätta att försöka är det OK, men skicka mig din .FRM-fil ( till lex1d3e3e33d3d2633f .com ) så att jag kan kolla upp det och jag kommer att skicka lite PHP-kod till dig om några dagar som extraherar lite ytterligare information som datatyp och skärmstorlekar.




  1. Hur man aktiverar pdo_mysql i php docker-bilden

  2. Ställ in databassortering i Entity Framework Code-First Initializer

  3. PHP/MySQL Uppdateringskod

  4. mysql + importera en fil med mellanslag i kolumnrubriken + hur man hanterar