Domanda

Sto scrivendo un'app PHP che ha un 'pannello di controllo' che scrive un file prefs con determinate variabili. Su ogni POST, se il file non esiste, viene creato. Se esiste, è unlinked e un nuovo file è touched con lo stesso nome file e nuove variabili. Questo file viene quindi incluso in un'altra pagina con contenuto visualizzato in base alle variabili al suo interno.

$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); 

È un modo sicuro per scrivere le preferenze, a condizione che questo file venga sovrascritto più volte al giorno? Qual è un buon modo per avvisare l'utente di questo pannello di controllo se il file non è stato salvato correttamente, e in tal caso, quale sarebbe un buon piano di emergenza per evitare di spezzare la pagina che questo file di prefs è incluso a breve definire set predefinito di variabili da compilare se !(file_exists)?

È stato utile?

Soluzione

Se memorizzi le tue impostazioni in un array, puoi serializzarle () e scriverle in un file di testo, piuttosto che scrivere php grezzo in un file php e includerlo.

Se non stai disinfettando il tuo input per quelle preferenze e dici che $ mypref1 rappresenta il nome di qualcuno, non c'è nulla che impedisca loro di riempirlo nel campo del modulo:

\"; echo \"PWNED

e il PHP risultante diventerà

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

Quindi, in primo luogo, archiviare le tue preferenze in un array e usare serialize () è molto più sicuro:

$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"

Nella tua domanda, dici anche che se il file esiste, è scollegato. Puoi semplicemente troncarlo a lunghezza zero passando & Quot; w & Quot; come secondo argomento da aprire - non è necessario eliminarlo manualmente. Questo dovrebbe impostare comunque l'ora, annullando la necessità di toccare la chiamata ().

Se i valori scritti nel file sono preferenze, sicuramente ogni preferenza potrebbe avere un valore predefinito, a meno che non ce ne siano centinaia? array_merge ti consentirà di sovrascrivere in base alla chiave, quindi se fai qualcosa del genere:

// 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 il problema è che ci sono molti cumuli e non si desidera inizializzarli tutti, è possibile disporre di un metodo get_preference che avvolge semplicemente una chiamata isset all'array prefs.

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

Al di là di tutte le domande che questo solleva, la realtà è che con la tua app, nell'improbabile caso in cui qualcosa non vada storto con il fopen, dovrebbe comunque essere considerato un grave fallimento, e la manciata di utenti che probabilmente utilizzerai questa funzione ti contatteranno molto rapidamente se qualcosa va storto.

Altri suggerimenti

È sempre meglio archiviare lo stato degli utenti in una sessione e persistere solo quando necessario.

Perché non usare semplicemente le capacità di troncamento di fopen ()? Credo invece di & Quot; r + & Quot ;, dovrai passare & Quot; w + & Quot; ... Quindi se il file esiste, verrà troncato, se non lo fa ti limiterai a creare un nuovo file. Quindi il codice diventa:

$file = "phpsettings.php";
$handle = fopen( $file, 'w+' );
$str = "<?php \$pref1 = \"$mypref\"; ?>";
fwrite ($handle, $str); 
fclose ($handle);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top