Pergunta

Eu estou escrevendo um aplicativo PHP que tem um 'painel de controle' que grava um arquivo prefs com determinadas variáveis. Em cada POST, se o arquivo não existir, ele será criado. Se ela existe, é unlinked e um novo arquivo é touched com o mesmo nome do arquivo e novas variáveis. Este arquivo é então incluída em outra página com conteúdo exibe com base nas variáveis ??dentro dela.

$file = "phpsettings.php";

if (!file_exists($file)) {
   touch($file);
  $handle = fopen ($file, 'r+'); 
$str = "<?php \$pref1 = \"$mypref\"; ?>";

} else {

unlink($file);
   touch($file);
   $handle = fopen ($file, 'r+'); 
   $str = "<?php \$pref1 = \"$mypref\"; ?>";

}

fwrite ($handle, $str); 
fclose ($handle); 

Esta é uma maneira segura de escrever preferências, desde este arquivo será substituído muitas vezes por dia? O que é uma boa maneira de ambos alertando o usuário deste painel de controle se o arquivo não foi salvo corretamente, e, nesse caso, o que seria um bom plano de contingência para evitar quebrar a página deste arquivo prefs está incluído na falta de definição de uma conjunto padrão de variáveis ??para preencher se !(file_exists)?

Foi útil?

Solução

Se você armazenar suas configurações em uma matriz, você pode serializar ()-los e escrever para um arquivo de texto, em vez de escrever php cru para um arquivo php e incluindo-o.

Se você não está saneantes sua entrada para essas preferências, e dizer $ mypref1 representa o nome de alguém, não há nada impedindo-os de preencher esta no campo de formulário:

\"; echo \"PWNED

e seu resultante PHP vai se tornar

<?php \$pref1 = \"$mypref\"; echo \"PWNED\"; ?>

Assim, em primeiro lugar, armazenar as suas preferências em uma matriz e utilizando serialize () é muito mais seguro:

$prefs = array('mypref1' => 'somethingorother');
$handle = fopen ($file, 'w'); 
fwrite($handle, serialize($prefs));
fclose($h);

// example code demonstrating unserialization
$prefs2 = unserialize(file_get_contents($file));
var_dump($prefs == $prefs2); // should output "(bool) true"

Em sua pergunta, você também mencionar que se o arquivo existir, ele é desvinculado. Você pode simplesmente truncar-lo para comprimento zero, passando de "w" como o segundo argumento para fopen - você não precisa para excluí-lo manualmente. Isto deve definir o mtime de qualquer maneira, negando a necessidade da chamada ao toque ().

Se os valores que estão sendo gravadas no arquivo são preferências, certamente cada preferência poderia ter um padrão, a menos que haja centenas? array_merge lhe permitirá substituir em uma base per-chave, por isso, se você faz algo parecido com isto:

// array of defaults
$prefs = array(
    'mypref1' => 'pants',
    'mypref2' => 'socks',
);
if (file_exists($file)) {
    // if this fails, an E_NOTICE is raised. are you checking your server error
    // logs regularly?
    if ($userprefs = unserialize(file_get_contents($file))) {
        $prefs = array_merge($prefs, $userprefs);
    }
}

Se o problema é que há montes, e você não quer ter que inicializar todos eles, você poderia ter um método get_preference que apenas envolve uma chamada isset para a matriz prefs.

function get_preference($name, &$prefs) {
    if (isset($pref[$name]))
        return $pref[$name];
    return null;
}
var_dump(get_preference('mypref1', $prefs));

Além de todas as perguntas Isto levanta, porém, a realidade é que, com a sua aplicação, no caso improvável de que algo faz dar errado com o fopen, deve ser considerado como uma falha grave de qualquer maneira, e um punhado de usuários é provável que você tem a fazer uso desse recurso vai estar em contato com você muito danado rápido se algo der errado.

Outras dicas

É sempre melhor para armazenar seu estado usuários em uma sessão e só persistem nesse estado quando necessário.

Porque não basta usar os recursos de truncamento de fopen ()? Eu acredito que em vez de "r +", você vai precisar passar "w +" ... Então, se o arquivo existir, ele será truncado, se não você só vai criar um novo arquivo. Assim, o código torna-se:

$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top