2009-11-19 2 views
28

Je fais ce programme et j'essaie de trouver comment écrire des données au début d'un fichier plutôt qu'à la fin. "a"/append écrit seulement à la fin, comment puis-je le faire écrire au début? Parce que "r +" le fait mais écrase les données précédentes.Besoin d'écrire au début du fichier avec PHP

$datab = fopen('database.txt', "r+"); 

Voici mon fichier entier:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
    <head> 
     <title>Facebook v0.1</title> 
     <style type="text/css"> 
      #bod{ 
       margin:0 auto; 
       width:800px; 
       border:solid 2px black; 
      } 
     </style> 
    </head> 

    <body> 
     <div id="bod"> 
      <?php 
       $fname = $_REQUEST['fname']; 
       $lname = $_REQUEST['lname']; 
       $comment = $_REQUEST['comment']; 
       $datab = $_REQUEST['datab']; 
       $gfile = $_REQUEST['gfile']; 

       print <<<form 
       <table border="2" style="margin:0 auto;"> 
        <td> 
         <form method="post" action=""> 
           First Name : 
           <input type ="text" 
             name="fname" 
             value=""> 
           <br> 

           Last Name : 
           <input type ="text" 
             name="lname" 
             value=""> 
           <br> 

           Comment : 
           <input type ="text" 
             name="comment" 
             value=""> 
           <br> 
           <input type ="submit" value="Submit"> 
         </form> 
        </td> 
       </table> 
       form; 
       if((!empty($fname)) && (!empty($lname)) && (!empty($comment))){ 
        $form = <<<come 

        <table border='2' width='300px' style="margin:0 auto;"> 
         <tr> 
          <td> 
           <span style="color:blue; font-weight:bold;"> 
           $fname $lname : 
           </span> 

           $comment 
          </td> 
         </tr> 
        </table> 
        come; 

        $datab = fopen('database.txt', "r+"); 
        fputs($datab, $form); 
        fclose($datab); 

       }else if((empty($fname)) && (empty($lname)) && (empty($comment))){ 
        print" please input data"; 
       } // end table 

       $datab = fopen('database.txt', "r"); 

       while (!feof($datab)){ 
        $gfile = fgets($datab); 
        print "$gfile"; 
       }// end of while 
      ?> 
     </div> 
    </body> 
</html> 

Répondre

47

Le rapide et sale:

<?php 
$file_data = "Stuff you want to add\n"; 
$file_data .= file_get_contents('database.txt'); 
file_put_contents('database.txt', $file_data); 
?> 
+1

Je pense qu'il n'y a pas de meilleure façon d'insérer des données au début de le fichier. De toute façon, vous devez déplacer toutes les données contenues dans le fichier. Pour les fichiers plus volumineux, vous devrez peut-être lire le fichier pièce par pièce pour l'insérer dans la mémoire. –

+0

Comment utiliser le mode "c" de fopen? Cela n'écrit-il pas au début du fichier? –

+0

@SSHThis oui c'est le cas, mais il réécrit aussi quelque chose sur le chemin :) –

3

Je pense que ce que vous pouvez faire est d'abord lire le contenu du fichier et le maintenir en une variable temporaire, insérez maintenant les nouvelles données au début du fichier avant d'ajouter également le contenu de la variable temporaire.

 
$file = file_get_contents($filename); 
$content = 'Your Content' . $file; 
file_put_contents($content); 
+1

Hey, merci du futur! Cela a résolu mon problème pour moi. Je l'apprécie ... – Keven

1

Il est impossible d'écrire au début d'un fichier comme vous le pensez. C'est ce que je suppose en raison de la façon dont OS et HDD voient le fichier. Il a un départ fixe et une fin en expansion. Si vous voulez ajouter quelque chose au milieu ou au début, il faut glisser. Si c'est un petit fichier il suffit de tout lire et de faire votre manipulation et de réécrire. Si ce n'est pas le cas, et si vous ajoutez toujours au début l'ordre inverse des lignes, considérez la fin comme commençant ...

1

Vous pouvez utiliser fseek pour changer le pointeur dans la note.

Il est à noter que si vous utilisez fwrite, le contenu actuel sera effacé. Donc, fondamentalement, vous devez lire le fichier entier, utilisez fseek, écrire votre nouveau contenu, écrire les anciennes données du fichier.

$file_data = file_get_contents('database.txt') 
$fp = fopen('database.txt', 'a'); 
fseek($fp,0); 
fwrite($fp, 'new content'); 
fwrite($fp, $file_data); 
fclose($fp); 

Si votre fichier est vraiment énorme et vous ne voulez pas utiliser trop de mémoire, vous voudrez peut-être avoir l'approche de deux fichiers comme

$fp_source = fopen('database.txt', 'r'); 
$fp_dest = fopen('database_temp.txt', 'w'); // better to generate a real temp filename 
fwrite($fp_dest, 'new content'); 
while (!feof($fp_source)) { 
    $contents .= fread($fp_source, 8192); 
    fwrite($fp_dest, $contents); 
} 
fclose($fp_source); 
fclose($fp_dest); 
unlink('database.txt'); 
rename('database_temp.txt','database.txt'); 

La solution de Ben semble être plus simple à mon avis honnête.

Un dernier point: je ne sais pas ce que vous avez stocké dans database.txt mais vous pouvez faire la même chose plus facilement en utilisant un serveur de base de données.

30

Si vous ne voulez pas charger le contenu du fichier dans une variable, vous pouvez utiliser la fonction de PHP Streams:

function prepend($string, $orig_filename) { 
    $context = stream_context_create(); 
    $orig_file = fopen($orig_filename, 'r', 1, $context); 

    $temp_filename = tempnam(sys_get_temp_dir(), 'php_prepend_'); 
    file_put_contents($temp_filename, $string); 
    file_put_contents($temp_filename, $orig_file, FILE_APPEND); 

    fclose($orig_file); 
    unlink($orig_filename); 
    rename($temp_filename, $orig_filename); 
} 

Ce que cela fait est écrit la chaîne que vous voulez préfixer à un temporaire fichier, puis il écrit le contenu du fichier d'origine à la fin du fichier temporaire (en utilisant des flux au lieu de copier le fichier entier dans une variable), puis il supprime le fichier d'origine et renomme le fichier temporaire pour le remplacer.

Remarque: À l'origine, ce code était basé sur un article de blog défait par Chao Xu. Le code a depuis divergé, mais le message original peut être consulté in the Wayback Machine.

+0

Thx! Cela fonctionne très bien, mais seulement si le fichier existe (j'ai eu un cas où le fichier pourrait être manquant.) Très facile à contourner: if (! File_exsists ($ filename) [...]) – qualbeen

+0

Oui, cela fonctionne vraiment , ty Jordan –

+1

PHP a tempnam() pour la génération d'un nom de fichier unique.md5() a un faible risque de générer une collision avec un fichier existant.Voir http://php.net/manual/en/function.tempnam. php –

1

Ce code mémorise les données du début du fichier pour les protéger contre l'écrasement. Ensuite, il réécrit toutes les données existantes dans le morceau de fichier par morceau.

$data = "new stuff to insert at the beggining of the file"; 
$buffer_size = 10000; 

$f = fopen("database.txt", "r+"); 
$old_data_size = strlen($data); 
$old_data = fread($f, $old_data_size); 
while($old_data_size > 0) { 
    fseek($f, SEEK_CUR, -$old_data_size); 
    fwrite($f, $data); 
    $data = $old_data; 
    $old_data = fread($f, $buffer_size); 
    $old_data_size = strlen($data); 
} 
fclose($f); 
0

file_get_contents() et file_put_contents() utiliser plus de mémoire que d'utiliser les fopen(), fwrite() et fclose() fonctions:

$fh = fopen($filename, 'a') or die("can't open file"); 
fwrite($fh, $fileNewContent); 
fclose($fh); 
+1

Cela ne dit rien sur la fonctionnalité "avant" que l'OP demandait .. –

3

Vous pouvez utiliser le code suivant pour ajouter du texte au début et à la fin du fichier.

$myFile = "test.csv";<br> 
$context = stream_context_create();<br> 
    $fp = fopen($myFile, 'r', 1, $context);<br> 
    $tmpname = md5("kumar");<br> 

//this will append text at the beginning of the file<br><br> 
    file_put_contents($tmpname, "kumar");<br> 
    file_put_contents($tmpname, $fp, FILE_APPEND);<br> 
    fclose($fp);<br> 
    unlink($myFile);<br> 
    rename($tmpname, $myFile);<br><br> 
    //this will append text at the end of the file<br> 
    file_put_contents($myFile, "ajay", FILE_APPEND); 
2
  1. Ouvrir un fichier en mode w + pas un mode +.
  2. Obtenir la longueur du texte pour ajouter (chunkLength $)
  3. définir un curseur de fichier au début du fichier si nécessaire
  4. lire $ chunkLength octets du fichier
  5. retour le curseur sur la chunkLength de $ * $ i;
  6. écrire $ précédez
  7. set $ précédez une valeur à l'étape 4
  8. faire ces étapes, alors que EOF

    $handler = fopen('1.txt', 'w+');//1 
    rewind($handler);//3 
    $prepend = "I would like to add this text to the beginning of this file"; 
    $chunkLength = strlen($prepend);//2 
    $i = 0; 
    do{ 
        $readData = fread($handler, $chunkLength);//4 
        fseek($handler, $i * $chunkLength);//5 
        fwrite($handler, $prepend);//6 
    
        $prepend = $readData;//7 
        $i++; 
    }while ($readData);//8 
    
    fclose($handler);