Platte database

stemmen
101

Wat zijn de beste praktijken rond het creëren van platte database structuren in PHP?

Een groot deel van de meer volwassen PHP flat file frameworks ik zie er proberen uit te voeren SQL-achtige querysyntaxis, dat is over de top voor mijn doeleinden in de meeste gevallen (ik zou gewoon gebruik maken van een database op dat moment).

Zijn er elegant trucs die er zijn om goede prestaties en functies met een kleine code overhead te krijgen?

De vraag is gesteld op 01/08/2008 om 15:19
bron van user
In andere talen...                            


12 antwoorden

stemmen
11

Eén framework Ik overweeg zou zijn voor een blogging platform. Sinds zowat elke mogelijke weergave van de gegevens die u zou willen zou worden gesorteerd op datum, ik zat te denken over deze structuur:

Een directory per inhoud knooppunt:

./content/YYYYMMDDHHMMSS/

Subdirectories van elk knooppunt inbegrip

/tags  
/authors  
/comments  

Evenals eenvoudige tekstbestanden in de knooppuntdirectory voor pre- en post-weergegeven inhoud en dergelijke.

Dit zou een eenvoudige PHP toestaan glob()call (en waarschijnlijk een omkering van het resultaat array) op te vragen zowat alles binnen de inhoud structuur:

glob("content/*/tags/funny");  

Zou paden met inbegrip van alle artikelen gelabeld "grappig" terug te keren.

antwoordde op 01/08/2008 om 15:26
bron van user

stemmen
15

Dat is waar. serialize()kan erg handig zijn voor dat ook.

Ik denk dat de truc om het bedenken van een levensvatbaar systeem is het vinden van een manier om de index van de data nodes zonder het doden van jezelf met complexiteit.

antwoordde op 01/08/2008 om 15:58
bron van user

stemmen
68

Nou, wat is de aard van de flat databases. Zijn ze groot of klein. Is het eenvoudig arrays met arrays in hen? als het iets simpels te zeggen gebruikersprofielen gebouwd als zodanig:

$user = array("name" => "dubayou", 
              "age" => 20,
              "websites" => array("dubayou.com","willwharton.com","codecream.com"),
              "and_one" => "more");

en op te slaan of bijwerken van de db plaat voor die gebruiker.

$dir = "../userdata/";  //make sure to put it bellow what the server can reach.
file_put_contents($dir.$user['name'],serialize($user));

en het laden plaat voor de gebruiker

function &get_user($name){
    return unserialize(file_get_contents("../userdata/".$name));
}

maar ook dit implementatie zal afhankelijk van de toepassing en de aard van de database die u nodig hebt.

antwoordde op 01/08/2008 om 18:45
bron van user

stemmen
46

Je zou kunnen overwegen SQLite . Het is bijna net zo eenvoudig als platte bestanden, maar je krijgt een SQL-engine voor het opvragen. Het werkt goed met PHP ook.

antwoordde op 09/08/2008 om 00:00
bron van user

stemmen
8

Als je gaat naar een plat bestand gebruiken om gegevens te blijven, gebruiken XML om de gegevens te structureren. PHP heeft een ingebouwde XML parser .

antwoordde op 18/09/2008 om 07:40
bron van user

stemmen
6

Als je een mens leesbaar resultaat wilt, kunt u ook gebruik maken van dit soort bestand:

ofaurax|27|male|something|
another|24|unknown||
...

Op deze manier heb je maar één bestand, kunt u het debuggen (en handmatig moet repareren) gemakkelijk, kunt u velden later toevoegen (aan het einde van elke lijn) en de PHP-code is eenvoudig (voor elke lijn, uitgesplitst naar |).

Echter, de nadelen is dat je het hele bestand zou moeten ontleden om iets te zoeken (als je miljoenen van binnenkomst, het is niet fijn) en je moet de afscheider in gegevens te verwerken (bijvoorbeeld als de nick is War | ordz).

antwoordde op 18/09/2008 om 08:51
bron van user

stemmen
20

Naar mijn mening, met behulp van een "platte database" in de zin dat je wat betekent dat (en het antwoord dat je hebt geaccepteerd) is niet neccesarily de beste manier om te gaan over dingen. Allereerst, het gebruik serialize()en unserialize()kan grote hoofdpijn veroorzaken als er iemand in en bewerkt het bestand (ze kunnen, in feite, zet arbritrary code in uw "databank" elke keer worden uitgevoerd.)

Persoonlijk zou ik zeggen - waarom niet kijken naar de toekomst? Er zijn zo vaak dat ik problemen heb gehad, want ik heb het maken van mijn eigen "eigen" bestanden, en het project is geëxplodeerd tot een punt waar het een database nodig heeft, en ik denk ", weet u, ik wens ik had dit geschreven voor een database om mee te beginnen" - omdat de refactoring van de code kost veel te veel tijd en moeite.

Vanuit deze Ik heb geleerd dat toekomstbestendigheid mijn toepassing, zodat als het groter wordt ik niet moet gaan en door te brengen dagen refactoring is de manier om vooruit te gaan. Hoe doe ik dit?

SQLite. Het werkt als een database, maakt gebruik van SQL, en is vrij gemakkelijk om over te schakelen naar MySQL (genoot vooral als u geabstraheerd klassen voor database-manipulatie zoals ik dat doe!)

In feite, genoot vooral met de "aanvaarde antwoord" 's methode, het kan drastisch het geheugengebruik van uw app (je hoeft niet alle 'RECORDS' in PHP te laden)

antwoordde op 21/09/2008 om 19:21
bron van user

stemmen
8

Hier is de code die we gebruiken voor Lilina:

<?php
/**
 * Handler for persistent data files
 *
 * @author Ryan McCue <cubegames@gmail.com>
 * @package Lilina
 * @version 1.0
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
 * Handler for persistent data files
 *
 * @package Lilina
 */
class DataHandler {
    /**
     * Directory to store data.
     *
     * @since 1.0
     *
     * @var string
     */
    protected $directory;

    /**
     * Constructor, duh.
     *
     * @since 1.0
     * @uses $directory Holds the data directory, which the constructor sets.
     *
     * @param string $directory 
     */
    public function __construct($directory = null) {
        if ($directory === null)
            $directory = get_data_dir();

        if (substr($directory, -1) != '/')
            $directory .= '/';

        $this->directory = (string) $directory;
    }

    /**
     * Prepares filename and content for saving
     *
     * @since 1.0
     * @uses $directory
     * @uses put()
     *
     * @param string $filename Filename to save to
     * @param string $content Content to save to cache
     */
    public function save($filename, $content) {
        $file = $this->directory . $filename;

        if(!$this->put($file, $content)) {
            trigger_error(get_class($this) . " error: Couldn't write to $file", E_USER_WARNING);
            return false;
        }

        return true;
    }

    /**
     * Saves data to file
     *
     * @since 1.0
     * @uses $directory
     *
     * @param string $file Filename to save to
     * @param string $data Data to save into $file
     */
    protected function put($file, $data, $mode = false) {
        if(file_exists($file) && file_get_contents($file) === $data) {
            touch($file);
            return true;
        }

        if(!$fp = @fopen($file, 'wb')) {
            return false;
        }

        fwrite($fp, $data);
        fclose($fp);

        $this->chmod($file, $mode);
        return true;

    }

    /**
     * Change the file permissions
     *
     * @since 1.0
     *
     * @param string $file Absolute path to file
     * @param integer $mode Octal mode
     */
    protected function chmod($file, $mode = false){
        if(!$mode)
            $mode = 0644;
        return @chmod($file, $mode);
    }

    /**
     * Returns the content of the cached file if it is still valid
     *
     * @since 1.0
     * @uses $directory
     * @uses check() Check if cache file is still valid
     *
     * @param string $id Unique ID for content type, used to distinguish between different caches
     * @return null|string Content of the cached file if valid, otherwise null
     */
    public function load($filename) {
        return $this->get($this->directory . $filename);
    }

    /**
     * Returns the content of the file
     *
     * @since 1.0
     * @uses $directory
     * @uses check() Check if file is valid
     *
     * @param string $id Filename to load data from
     * @return bool|string Content of the file if valid, otherwise null
     */
    protected function get($filename) {
        if(!$this->check($filename))
            return null;

        return file_get_contents($filename);
    }

    /**
     * Check a file for validity
     *
     * Basically just a fancy alias for file_exists(), made primarily to be
     * overriden.
     *
     * @since 1.0
     * @uses $directory
     *
     * @param string $id Unique ID for content type, used to distinguish between different caches
     * @return bool False if the cache doesn't exist or is invalid, otherwise true
     */
    protected function check($filename){
        return file_exists($filename);
    }

    /**
     * Delete a file
     *
     * @param string $filename Unique ID
     */
    public function delete($filename) {
        return unlink($this->directory . $filename);
    }
}

?>

Het slaat elk item als een apart bestand, dat we hebben gevonden is efficiënt genoeg is voor gebruik (geen overbodige data wordt geladen en het is sneller om op te slaan).

antwoordde op 28/10/2008 om 11:45
bron van user

stemmen
6

IMHO, heb je twee opties als u wilt homebrewing iets te voorkomen:

  1. SQLite

    Als u bekend bent met een BOB bent, kunt u een BOB driver die SQLite ondersteunt installeren. Nooit gebruikt, maar ik heb gebruikt BOB een ton met MySQL. Ik ga dit een schot op een lopend project te geven.

  2. XML

    Gedaan dit vele malen voor relatief kleine hoeveelheden gegevens. XMLReader is een lichtgewicht, lees-forward, cursor-stijl klasse. SimpleXML maakt het eenvoudig om een XML-document te lezen in een object dat u toegang net als elke andere klasse-instantie.

antwoordde op 02/12/2012 om 16:49
bron van user

stemmen
7

Ik heb twee eenvoudige functies ontworpen om gegevens op te slaan in een bestand geschreven. U kunt zelf beoordelen of het nuttig is in dit geval. Het gaat om een ​​php variabele opslaan (als het ofwel een array een string of een object) naar een bestand.

<?php
function varname(&$var) {
    $oldvalue=$var;
    $var='AAAAB3NzaC1yc2EAAAABIwAAAQEAqytmUAQKMOj24lAjqKJC2Gyqhbhb+DmB9eDDb8+QcFI+QOySUpYDn884rgKB6EAtoFyOZVMA6HlNj0VxMKAGE+sLTJ40rLTcieGRCeHJ/TI37e66OrjxgB+7tngKdvoG5EF9hnoGc4eTMpVUDdpAK3ykqR1FIclgk0whV7cEn/6K4697zgwwb5R2yva/zuTX+xKRqcZvyaF3Ur0Q8T+gvrAX8ktmpE18MjnA5JuGuZFZGFzQbvzCVdN52nu8i003GEFmzp0Ny57pWClKkAy3Q5P5AR2BCUwk8V0iEX3iu7J+b9pv4LRZBQkDujaAtSiAaeG2cjfzL9xIgWPf+J05IQ==';
    foreach($GLOBALS as $var_name => $value) {
        if ($value === 'AAAAB3NzaC1yc2EAAAABIwAAAQEAqytmUAQKMOj24lAjqKJC2Gyqhbhb+DmB9eDDb8+QcFI+QOySUpYDn884rgKB6EAtoFyOZVMA6HlNj0VxMKAGE+sLTJ40rLTcieGRCeHJ/TI37e66OrjxgB+7tngKdvoG5EF9hnoGc4eTMpVUDdpAK3ykqR1FIclgk0whV7cEn/6K4697zgwwb5R2yva/zuTX+xKRqcZvyaF3Ur0Q8T+gvrAX8ktmpE18MjnA5JuGuZFZGFzQbvzCVdN52nu8i003GEFmzp0Ny57pWClKkAy3Q5P5AR2BCUwk8V0iEX3iu7J+b9pv4LRZBQkDujaAtSiAaeG2cjfzL9xIgWPf+J05IQ==')
        {
            $var=$oldvalue;
            return $var_name;
        }
    }
    $var=$oldvalue;
    return false;
}

function putphp(&$var, $file=false)
    {
    $varname=varname($var);
    if(!$file)
    {
        $file=$varname.'.php';
    }
    $pathinfo=pathinfo($file);
    if(file_exists($file))
    {
        if(is_dir($file))
        {
            $file=$pathinfo['dirname'].'/'.$pathinfo['basename'].'/'.$varname.'.php';
        }
    }
    file_put_contents($file,'<?php'."\n\$".$varname.'='.var_export($var, true).";\n");
    return true;
}
antwoordde op 19/12/2012 om 21:48
bron van user

stemmen
4

Enkel wijzen op een mogelijk probleem met een platte database met dit type systeem:

data|some text|more data

row 2 data|bla hbalh|more data

...enz

Het probleem is dat de cel gegevens bevat een "|" of een "\ n" dan de gegevens verloren. Soms zou het gemakkelijker zijn om te splitsen door combinaties van letters die de meeste mensen niet zouden gebruiken.

Bijvoorbeeld:

Kolom splitter: #$% (Shift+345)

Rij splitter: ^&* (Shift+678)

Tekstbestand: test data#$%blah blah#$%^&*new row#$%new row data 2

Maak dan gebruik van: explode("#$%", $data); use foreach, the explode again to separate columns

Of iets in die richting. Ook, ik zou kunnen toevoegen dat platte database zijn goed voor systemen met kleine hoeveelheden gegevens (dwz. Minder dan 20 toeren), maar uitgegroeid tot enorme geheugen varkens voor grotere databases.

antwoordde op 04/01/2013 om 01:14
bron van user

stemmen
6

Deze is inspirerend als een praktische oplossing:
https://github.com/mhgolkar/FlatFire
Het maakt gebruik van meerdere strategieën om het hanteren van data ...
[Overgenomen uit readme-bestand]

Gratis of Structured of Mixed

- STRUCTURED
Regular (table, row, column) format.
[DATABASE]
/   \
TX  TableY
    \_____________________________
    |ROW_0 Colum_0 Colum_1 Colum_2|
    |ROW_1 Colum_0 Colum_1 Colum_2|
    |_____________________________|
- FREE
More creative data storing. You can store data in any structure you want for each (free) element, its similar to storing an array with a unique "Id".
[DATABASE]
/   \
EX  ElementY (ID)
    \________________
    |Field_0 Value_0 |
    |Field_1 Value_1 |
    |Field_2 Value_2 |
    |________________|
recall [ID]: get_free("ElementY") --> array([Field_0]=>Value_0,[Field_1]=>Value_1...
- MIXD (Mixed)
Mixed databases can store both free elements and tables.If you add a table to a free db or a free element to a structured db, flat fire will automatically convert FREE or SRCT to MIXD database.
[DATABASE]
/   \
EX  TY
antwoordde op 02/05/2013 om 14:57
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more