Pergunta

Quais são as melhores práticas em torno da criação de arquivo simples estruturas de banco de dados em PHP?

Muito mais madura do PHP arquivo plano quadros que eu vejo lá fora, tentar implementar de consulta semelhante a SQL a sintaxe, que é mais alto para os meus propósitos, na maioria dos casos (que eu só ia usar um banco de dados em que ponto).

Há elegante truques para um bom desempenho e recursos com um pequeno código em cima?

Foi útil?

Solução

Bem, qual é a natureza da televisão bancos de dados.São elas pequenas ou grandes.É simples matrizes com matrizes no-los?se é algo simples de dizer userprofiles construído como tal:

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

para salvar ou atualizar o db registro para esse usuário.

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

e para carregar o registro para o usuário

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

mas, novamente, esta implementação vai variar de acordo com a aplicação e a natureza do banco de dados que você precisa.

Outras dicas

Você pode considerar SQLite.É quase tão simples como arquivos simples, mas é um motor SQL para a consulta.Ele funciona bem com PHP muito.

Na minha opinião, um "Plano de Arquivo de Banco de dados", no sentido de que você está sentido (e a resposta que você aceite) não neccesarily a melhor maneira de ir sobre as coisas.Primeiro de tudo, usando serialize() e unserialize() pode causar GRANDES dores de cabeça, se alguém se mete no e edita o arquivo (que pode, na verdade, colocar arbritrary código em seu "banco de dados" para ser executado a cada vez.)

Pessoalmente, eu diria - por que não olhar para o futuro?Houve tantas vezes que eu tive problemas porque fui criando a minha própria "propriedade" de arquivos, e o projeto explodiu um ponto em que ele precisa de um banco de dados, e eu estou pensando "você sabe, eu gostaria de ter escrito isso para um banco de dados para iniciar com" - porque a refatoração do código leva muito tempo e esforço.

A partir deste aprendi que prova a minha aplicação para que, quando ele se torna maior que eu não tenho que ir e passar os dias a refatoração é o caminho para avançar.Como eu faço isso?

O SQLite.Ele funciona como um banco de dados, usa o SQL, e é muito fácil a mudança para o mySQL (espescially se você estiver usando abstraídos classes para manipulação de banco de dados, assim como eu!)

Na verdade, espescially com o "aceite resposta"do método, pode reduzir drasticamente o uso de memória do seu aplicativo (você não tem que carregar todos os "REGISTROS" em PHP)

Um quadro que eu estou considerando seria para uma plataforma de blogging.Uma vez que apenas sobre qualquer um possível modo de exibição de dados, você iria querer seria ordenada por data, eu estava pensando sobre essa estrutura:

Um diretório por cada nó de conteúdo:

./content/YYYYMMDDHHMMSS/

Subdiretórios de cada nó, incluindo

/tags  
/authors  
/comments  

Bem como arquivos de texto simples no nó de diretório para pré - e pós-processado conteúdo e o como.

Isso permitiria que um simples PHP glob() ligue para (e, provavelmente, uma inversão da matriz de resultado) a consulta sobre qualquer coisa dentro da estrutura do conteúdo:

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

Seria vias de retorno, incluindo todos os artigos com a tag "engraçado".

Aqui está o código que usamos para 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);
    }
}

?>

Ele armazena cada entrada como um arquivo separado, o que encontramos é eficiente o suficiente para o uso (sem os dados desnecessários são carregados e é mais rápido para salvar).

Se você estiver indo para usar um arquivo plano para persistir os dados, o uso de XML para estruturar os dados.O PHP tem um construído em analisador de XML.

Eu escrevi duas funções simples projetado para armazenar dados em um arquivo.Você pode julgar por si mesmo se é útil neste caso.O ponto é para salvar uma variável do php (se a é uma matriz de uma seqüência de caracteres ou um objeto) para um arquivo.

<?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;
}

Se você quiser um ser humano-legível resultado, você também pode usar este tipo de ficheiro :

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

Desta forma, você terá apenas um arquivo, você pode depurar-lo (e corrigir manualmente) facilmente, você pode adicionar campos ao final de cada linha) e o código PHP é simples (para cada linha, dividida de acordo com |).

No entanto, a desvantagem é que você deve analisar todo o arquivo para algo de busca (se você tem milhões de entrada, não muito fina) e você deve lidar com o separador de dados (por exemplo, se o nick é de Guerra|ordz).

Este é inspirador como uma solução prática:
https://github.com/mhgolkar/FlatFire
Ele usa várias estratégias para manipulação de dados...
[Copiado do Arquivo Leiame]

Livre ou Estruturada ou Misto

- 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

IMHO, você tem duas opções se você quiser evitar homebrewing algo:

  1. SQLite

    Se você estiver familiarizado com DOP, você pode instalar um driver PDO que oferece suporte a SQLite.Nunca usei, mas eu tenho usado DOP uma tonelada com o MySQL.Eu vou dar a este um tiro em um projeto atual.

  2. XML

    Feito isso muitas vezes para quantidades relativamente pequenas de dados. XMLReader é um peso leve, de leitura para a frente, estilo de cursor de classe. SimpleXML facilita a leitura de um documento XML em um objeto que você pode acessar como qualquer outra instância de classe.

Apenas apontando um problema potencial com uma televisão de arquivo de banco de dados com este tipo de sistema:

data|some text|more data

row 2 data|bla hbalh|more data

etc ...

O problema é que os dados da célula contém um "|" ou " ", em seguida, os dados serão perdidos.Às vezes seria mais fácil dividir por combinações de letras que a maioria das pessoas não iria usar.

Por exemplo:

Coluna do divisor: #$% (Shift+345)

Linha do divisor: ^&* (Shift+678)

Arquivo de texto: test data#$%blah blah#$%^&*new row#$%new row data 2

Então use: explode("#$%", $data); use foreach, the explode again to separate columns

Ou qualquer coisa nesse sentido.Além disso, eu poderia acrescentar que a televisão de arquivo de bancos de dados são boas para sistemas com pequenas quantidades de dados (ie.menos de 20 linhas), mas tornam-se enormes porcos de memória para bancos de dados maiores.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top