2009-11-19 11 views
28

Tôi đang tạo chương trình này và tôi đang cố gắng tìm hiểu cách ghi dữ liệu vào đầu tệp thay vì kết thúc. "a"/nối thêm chỉ ghi vào cuối, làm thế nào tôi có thể ghi nó vào đầu? Bởi vì "r +" hiện nó nhưng ghi đè dữ liệu trước đó.Cần viết ở đầu tệp bằng PHP

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

Dưới đây là toàn bộ tập tin của tôi:

<!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> 

Trả lời

47

Các nhanh chóng và dơ bẩn:

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

Tôi nghĩ rằng không có cách nào tốt hơn để chèn dữ liệu vào đầu tập tin. Bạn phải di chuyển tất cả dữ liệu hiện có trong tệp. Đối với các tệp lớn hơn, bạn có thể cần phải đọc từng phần một phần để phù hợp với nó trong bộ nhớ. –

+0

Làm thế nào về việc sử dụng chế độ "c" của fopen? Điều này không ghi vào đầu tập tin? –

+0

@SSHThó có nó, nhưng nó cũng viết lại bất cứ điều gì trong cách :) –

3

Tôi nghĩ rằng những gì bạn có thể làm là lần đầu tiên đọc nội dung của tập tin và giữ nó trong một biến tạm thời, bây giờ chèn dữ liệu mới vào đầu tệp trước khi thêm nội dung của biến tạm thời.

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

Hey, cảm ơn từ tương lai! Điều này giải quyết vấn đề của tôi đối với tôi. Tôi đánh giá cao nó ... – Keven

1

Không có cách nào để ghi vào đầu tệp như bạn nghĩ. Đây là tôi đoán do lý do làm thế nào hệ điều hành và HDD đang nhìn thấy tập tin. Nó đã có một khởi đầu cố định và mở rộng kết thúc. Nếu bạn muốn thêm một cái gì đó ở giữa hoặc beggining nó đòi hỏi một số trượt. Nếu nó là một tập tin nhỏ chỉ cần đọc tất cả và làm thao tác của bạn và viết lại. Nhưng nếu không, và nếu bạn luôn luôn thêm vào đầu chỉ ngược dòng, xem xét kết thúc như bắt đầu ...

1

Bạn có thể sử dụng fseek để thay đổi con trỏ trong ghi chú.

Cần lưu ý rằng nếu bạn sử dụng fwrite, nó sẽ xóa nội dung hiện tại. Vì vậy, về cơ bản bạn phải đọc toàn bộ tập tin, sử dụng fseek, viết nội dung mới của bạn, ghi dữ liệu cũ của tập tin.

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

Nếu tập tin của bạn thực sự rất lớn và bạn không muốn sử dụng quá nhiều bộ nhớ, bạn có thể muốn có cách tiếp cận hai tập tin như

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

Các giải pháp của Ben có vẻ là đơn giản hơn theo ý kiến ​​trung thực của tôi.

Điểm cuối cùng: Tôi không biết bạn đang lưu trữ số nào trong database.txt nhưng bạn có thể thực hiện tương tự dễ dàng hơn bằng cách sử dụng máy chủ cơ sở dữ liệu.

30

Nếu bạn không muốn tải toàn bộ nội dung của tập tin vào một biến, bạn có thể sử dụng Streams tính năng của PHP:

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

Điều này không là viết chuỗi bạn muốn thêm vào trước để tạm thời , sau đó nó ghi nội dung của tệp gốc vào cuối tệp tạm thời (sử dụng luồng thay vì sao chép toàn bộ tệp vào một biến), sau đó xóa tệp gốc và đặt lại tên tệp tạm thời để thay thế tệp đó.

Lưu ý: Mã này ban đầu được dựa trên bài đăng blog hiện tại không còn tồn tại của Chao Xu. Mã này đã bị phân tách, nhưng bài đăng gốc có thể được xem in the Wayback Machine.

+0

Thx! Điều này làm việc rất tốt, nhưng chỉ khi tập tin tồn tại (tôi đã có một trường hợp mà các tập tin có thể bị mất. Thực sự dễ dàng để làm việc xung quanh: if (! File_exsists ($ filename) [...]) – qualbeen

+0

Yep này thực sự làm việc , ty Jordan –

+1

PHP có tempnam() để tạo ra một tên tập tin duy nhất md5() có một nguy cơ nhỏ khi tạo ra một vụ va chạm với một tệp hiện có. Xem http://php.net/manual/en/function.tempnam. php –

1

Mã này ghi nhớ dữ liệu từ đầu tệp để bảo vệ chúng khỏi bị ghi đè. Tiếp theo nó viết lại tất cả các dữ liệu tồn tại trong tập tin chunk bởi chunk.

$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()file_put_contents() sử dụng bộ nhớ hơn bằng cách sử dụng fopen(), fwrite(), và fclose() chức năng:

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

Điều này không nói bất cứ điều gì về chức năng "prepending" mà OP đã yêu cầu .. –

3

Bạn có thể sử dụng đoạn mã sau để thêm văn bản ở đầu và cuối của tập tin.

$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. mở một tập tin trong w + chế độ không phải là một chế độ +.
  2. Lấy chiều dài của văn bản để thêm ($ chunkLength)
  3. thiết lập một con trỏ tập tin đến đầu của file nếu cần thiết
  4. đọc $ chunkLength byte từ tập tin
  5. trở lại con trỏ đến $ chunkLength * $ i;
  6. ghi $ thêm vào trước
  7. bộ $ thêm vào trước một giá trị từ bước 4
  8. làm các bước này, trong khi 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);