2009-06-30 13 views
14

मैं अनुमान लगा रहा हूं कि यह fgets है, लेकिन मुझे विशिष्ट वाक्यविन्यास नहीं मिल रहा है। मैं पढ़ने की कोशिश कर रहा हूं (एक स्ट्रिंग में जो मैं सोच रहा हूं वह आसान है) अंतिम फ़ाइल लॉग फ़ाइल में जोड़ दी गई है।PHP - फाइल में आखिरी पंक्ति लौट रहा है?

उत्तर

37

सरल अनुभवहीन समाधान बस है:

$file = "/path/to/file"; 
$data = file($file); 
$line = $data[count($data)-1]; 

हालांकि, इस स्मृति में पूरी फ़ाइल लोड होगा

तो तुम जैसे कुछ सरल कर सकता है। शायद एक समस्या (या नहीं)।

$file = escapeshellarg($file); // for the security concious (should be everyone!) 
$line = `tail -n 1 $file`; 
+0

स्पॉट, धन्यवाद मैथ्यू – waxical

+0

एफवाईआई, मैंने पूंछ का उपयोग किया ... – waxical

+1

ध्यान दें कि यह बहुत असुरक्षित है जब तक आप escapeshellarg() का उपयोग नहीं कर रहे हैं: http://de.php.net/manual/en/function.escapeshellarg.php – soulmerge

2

आपको या तो फ़ाइल को लाइन में पढ़ना होगा और इसे प्राप्त करने के लिए अंतिम पठन रेखा को सहेजना होगा।

या अगर यूनिक्स/लिनक्स पर आप शेल कमांड पूंछ

tail -n 1 filename 
13

यह की तरह लग रहा है विचार कर सकते हैं कि आप क्या देख रहे हैं:

tekkie.flashbit.net: Tail functionality in PHP

यह एक समारोह लागू करता है कि अंत में फ़ाइल को रोल करने के लिए एक नकारात्मक सूचकांक के साथ fseek() का उपयोग करता है। आप परिभाषित कर सकते हैं कि आप कितनी लाइनों को वापस करना चाहते हैं।

कोड भी उपलब्ध as a Gist on GitHub है:

// full path to text file 
define("TEXT_FILE", "/home/www/default-error.log"); 
// number of lines to read from the end of file 
define("LINES_COUNT", 10); 


function read_file($file, $lines) { 
    //global $fsize; 
    $handle = fopen($file, "r"); 
    $linecounter = $lines; 
    $pos = -2; 
    $beginning = false; 
    $text = array(); 
    while ($linecounter > 0) { 
     $t = " "; 
     while ($t != "\n") { 
      if(fseek($handle, $pos, SEEK_END) == -1) { 
       $beginning = true; 
       break; 
      } 
      $t = fgetc($handle); 
      $pos --; 
     } 
     $linecounter --; 
     if ($beginning) { 
      rewind($handle); 
     } 
     $text[$lines-$linecounter-1] = fgets($handle); 
     if ($beginning) break; 
    } 
    fclose ($handle); 
    return array_reverse($text); 
} 

$fsize = round(filesize(TEXT_FILE)/1024/1024,2); 

echo "<strong>".TEXT_FILE."</strong>\n\n"; 
echo "File size is {$fsize} megabytes\n\n"; 
echo "Last ".LINES_COUNT." lines of the file:\n\n"; 

$lines = read_file(TEXT_FILE, LINES_COUNT); 
foreach ($lines as $line) { 
    echo $line; 
} 
+0

Iiinteresting ... लेकिन मुद्दे को केवल पूंछ पर ले जाने की बहुत आसान विधि के बगल में पूरी तरह बेकार है (जब तक कि आप वास्तव में बहुत गंभीरता से अधिक कार्यरत सर्वर पर नहीं हैं) –

+6

"पूरी तरह से बेकार" थोड़ा कठोर – Tomalak

+0

ठीक है, शायद थोड़ा ... अभी भी, मैं इसका उपयोग करने के लिए तैयार नहीं हूं, जब तक कि कोई मुझे साबित न कर सके कि 'पूंछ' का उपयोग करना वास्तव में बाधा उत्पन्न कर रहा था और बड़े डेटाबेस पर संचालन नहीं कर रहा था। –

0

आप file समारोह लाइन द्वारा एक फ़ाइल, लाइन की सामग्री को पढ़ता है और एक का एक तत्व के रूप में प्रत्येक पंक्ति रिटर्न लाइन द्वारा एक फ़ाइल लाइन में पढ़ना चाहते हैं सरणी।

$lines = file('log.txt'); 
$lastLine = array_pop($lines); 
+3

वास्तव में? एक बहु-मेगाबाइट लॉग फ़ाइल के लिए जिसमें 99.99% मेरे लिए कोई रूचि नहीं है, मैं इसे सभी को तुरंत सरकाने के लिए सरणी में लोड करने से बचने की कोशिश करूंगा। – Tomalak

+0

कोई इनकार नहीं करता कि यह अक्षम है, लेकिन यह काम करता है; और कौन जानता है कि फाइल कितनी देर तक है? मैं अपने पर्यावरण में पूंछ कमांड का उपयोग करूंगा, लेकिन WiseDonkey ने कोई भी निर्दिष्ट नहीं किया था। हालांकि, यह एक अच्छा काम है जिसे आपने लिंक किया है। –

+1

फ़ाइल() और file_get_contents() दोनों महान फ़ाइल मैनिपुलेशन फ़ंक्शंस हैं, विशेष रूप से यदि आप जानते हैं कि शामिल फाइलें अपेक्षाकृत छोटी हैं और बस कुछ जल्दी और आसानी से करना चाहते हैं। –

7
define('YOUR_EOL', "\n"); 
$fp = fopen('yourfile.txt', 'r'); 

$pos = -1; $line = ''; $c = ''; 
do { 
    $line = $c . $line; 
    fseek($fp, $pos--, SEEK_END); 
    $c = fgetc($fp); 
} while ($c != YOUR_EOL); 

echo $line; 

fclose($fp); 

यह बेहतर है, क्योंकि यह स्मृति में पूरी फाइल लोड नहीं करता है ...

अपने सही लाइन अंत करने के लिए

सेट YOUR_EOL, एक ही आप का उपयोग करता है, तो: एक बेहतर समाधान यह है लाइन की समाप्ति ओएस की डिफ़ॉल्ट पंक्ति समाप्ति के रूप में जहां आपकी स्क्रिप्ट रहता है, आप निरंतर PHP_EOL का उपयोग कर सकते हैं।

1

यह 1 या 0 लाइन फ़ाइल के लिए नहीं टूट जाएगा।

function readlastline($fileName) 
{ 

     $fp = @fopen($fileName, "r"); 
     $begining = fseek($fp, 0);  
     $pos = -1; 
     $t = " "; 
     while ($t != "\n") { 
      fseek($fp, $pos, SEEK_END); 
      if(ftell($fp) == $begining){ 
       break; 
      } 
      $t = fgetc($fp); 
      $pos = $pos - 1; 
     } 
     $t = fgets($fp); 
     fclose($fp); 
     return $t; 
} 
4
function seekLastLine($f) { 
    $pos = -2; 
    do { 
     fseek($f, $pos--, SEEK_END); 
     $ch = fgetc($f); 
    } while ($ch != "\n"); 
} 

-2 क्योंकि पिछले चार \n

1

... क्यों सिर्फ अंतिम पंक्ति को पढ़ने हो सकता है?

function readLines($fp, $num) { 

    $line_count = 0; $line = ''; $pos = -1; $lines = array(); $c = ''; 

    while($line_count < $num) { 
     $line = $c . $line; 
     fseek($fp, $pos--, SEEK_END); 
     $c = fgetc($fp); 
     if($c == "\n") { $line_count++; $lines[] = $line; $line = ''; $c = ''; } 
    } 
    return $lines; 
} 

$filename = "content.txt"; 
$fp = @fopen($filename, "r"); 

print_r(readLines($fp, 2)); 

fclose($fp); 
+2

क्योंकि ओपी की यही आवश्यकता है? lol – dtbarne

0

@unique_stephen, आपका उत्तर त्रुटिपूर्ण है। PHP fseek सफलता के लिए 0 और असफलता के लिए -1 देता है। $ Begining (sic) में परिणाम संग्रहीत करना और फिर बाद में ftell() के लिए फ़िल्टर में इसका उपयोग करना सही नहीं है। अगर मेरी प्रतिष्ठा अधिक थी तो मैंने आपको वोट दिया होगा और एक टिप्पणी छोड़ दी होगी। अद्वितीय_स्टेफेन के फ़ंक्शन का एक संशोधित संस्करण यहां दिया गया है।

function readlastline($fileName) 
{ 
    $fp = @fopen($fileName, "r"); 
    if (fseek($fp, 0) == -1) 
     exit('Cannot seek to beginning of the file'); 
    $pos = -1; 
    $t = " "; 
    while ($t != "\n") { 
     if (fseek($fp, $pos, SEEK_END) == -1) 
      exit('Cannot seek to the end of the file'); 
     if (ftell($fp) == 0) { 
      break; 
     } 
     $t = fgetc($fp); 
     $pos = $pos - 1; 
    } 
    $t = fgets($fp); 
    fclose($fp); 
    return $t; 
} 

नोट: PHP के fseek फ़ाइलों के अंत PHP_MAX_INT से बड़ा जो भी 64 बिट binaries पर हस्ताक्षर किए 32 बिट है की तलाश करने का प्रबंधन नहीं कर सकते हैं।

+1

यह प्रश्न का उत्तर नहीं प्रदान करता है। एक बार आपके पास पर्याप्त [प्रतिष्ठा] (https://stackoverflow.com/help/whats-reputation) हो जाने पर आप [किसी भी पोस्ट पर टिप्पणी कर सकेंगे] (https://stackoverflow.com/help/privileges/comment); इसके बजाय, [उन उत्तरों को प्रदान करें जिन्हें पूछताछ से स्पष्टीकरण की आवश्यकता नहीं है] (https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can- i-कर-बजाय)। - [समीक्षा से] (/ समीक्षा/कम गुणवत्ता वाली पोस्ट/18 9 23154) –

+0

हां, पहले से ही प्रश्न के उत्तर हैं।उत्तर पर कोई टिप्पणी छोड़ने में सक्षम नहीं होने वाला मुद्दा यह है कि यदि आप मुझे टिप्पणी के रूप में उत्तर छोड़ना नहीं चाहते हैं तो उसे हल करने की आवश्यकता है। मैं @ unique_stephen की प्रतिक्रिया का सही संस्करण देने के लिए उत्तर संपादित करूंगा। – Earnie

संबंधित मुद्दे