file ملف->إوف () دائما العودة كاذبة عند استخدام فب سبلفيلوبجيكت في وضع 'ص'

StackOverflow https://stackoverflow.com//questions/11706174

  •  13-12-2019
  •  | 
  •  

سؤال

لماذا هو بلدي النصي فب شنقا?

$path = tempnam(sys_get_temp_dir(), '').'.txt';
$fileInfo = new \SplFileInfo($path);
$fileObject = $fileInfo->openFile('a');
$fileObject->fwrite("test line\n");
$fileObject2 = $fileInfo->openFile('r');
var_dump(file_exists($path));          // bool(true)
var_dump(file_get_contents($path));    // string(10) "test line
                                       // "
var_dump(iterator_count($fileObject2)); // Hangs on this

إذا قمت بحذف السطر الأخير (iterator_count(...) واستبدالها بهذا:

$i = 0;
$fileObject2->rewind();
while (!$fileObject2->eof()) {
    var_dump($fileObject2->eof());
    var_dump($i++);
    $fileObject2->next();
}

// Output:
// bool(false)
// int(0)
// bool(false)
// int(1)
// bool(false)
// int(2)
// bool(false)
// int(3)
// bool(false)
// int(4)
// ...

ال $fileObject->eof() دائما يعود كاذبة حتى أحصل على حلقة لا نهائية.

لماذا تحدث هذه الأشياء?أنا بحاجة للحصول على عدد الخط.

هل كانت مفيدة؟

المحلول

لماذا تحدث هذه الأشياء?

كنت تعاني من خصوصية في الطريقة التي SplFileObject الطبقة مكتوبة.دون استدعاء next() و current() طرق-باستخدام الافتراضي (0) الأعلام-لا يتحرك المكرر إلى الأمام أبدا.

ال iterator_count() وظيفة يدعو أبدا current();فإنه يتحقق valid() والمكالمات next() فقط.حلقات مفصل الخاص بك فقط استدعاء واحد أو آخر من current() و next().

وينبغي اعتبار هذا خطأ (سواء في فب نفسها ، أو فشل في الوثائق) والرمز التالي ينبغي (ولا) يعمل كما هو متوقع.أدعوكم إلى أبلغ عن سوء السلوك هذا.

// NOTE: This currently runs in an infinite loop!
$file = new SplFileObject(__FILE__);
var_dump(iterator_count($file));

الحلول

واحد تجنب سريعة للحصول على الأشياء تتحرك هو تعيين READ_AHEAD العلم على الكائن.هذا سوف يسبب next() طريقة لقراءة السطر التالي المتاح.

$file->setFlags(SplFileObject::READ_AHEAD);

إذا ، لأي سبب من الأسباب ، كنت لا تريد اقرأ إلى الأمام السلوك ثم يجب عليك الاتصال على حد سواء next() و current() نفسك.

العودة إلى المشكلة الأصلية من اثنين من سبلفيلوبجيكتس

يجب أن يعمل ما يلي الآن كما هو متوقع ، مما يسمح بإلحاق ملف وقراءة عدد الأسطر الخاص به.

<?php
$info = new SplFileInfo(__FILE__);
$write = $info->openFile('a');
$write->fwrite("// new line\n");
$read = $info->openFile('r');
$read->setFlags(SplFileObject::READ_AHEAD);
var_dump(iterator_count($read));

نصائح أخرى

تحرير 01

إذا كان ما تحتاجه هو عدد الأسطر داخل الملف:

<?php

$path = tempnam(sys_get_temp_dir(), '').'.txt';

$fileInfo = new SplFileInfo($path);
$fileObject = $fileInfo->openFile('a+');

$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar".PHP_EOL);

echo count(file($path));  // outputs 2

?>


تحرير 02

هذا هو الرمز الخاص بك أعلاه ، ولكن دون الدخول في حلقات لانهائية بسبب مؤشر الملف:

<?php

$path = tempnam(sys_get_temp_dir(), '').'.txt';

$fileInfo = new SplFileInfo($path);
$fileObject = $fileInfo->openFile('a+');

$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar");

foreach($fileObject as $line_num => $line) {
    echo 'Line: '.$line_num.' "'.$line.'"'."<br/>";
}
echo 'Total Lines:' . $fileObject->key();

?>

النواتج

الخط:0 " فو "

الخط:1"بار"

مجموع الخطوط: 2



الجواب الأصلي

كان المنطق المطبق قليلا.لقد قمت بتبسيط الكود:

<?php

// set path to tmp with random file name
echo $path = tempnam(sys_get_temp_dir(), '').'.txt';
echo "<br/>";

// new object
$fileInfo = new \SplFileInfo($path);

// open to write
$fileObject = $fileInfo->openFile('a');

// write two lines
$fileObject->fwrite("Foo".PHP_EOL);
$fileObject->fwrite("Bar".PHP_EOL);

// open to read
$fileObject2 = $fileInfo->openFile('r');

// output contents
echo "File Exists: " .file_exists($path);
echo "<br/>";
echo "File Contents: " . file_get_contents($path);
echo "<br/>";

// foreach line get line number and line contents 
foreach($fileObject2 as $line_num => $line) {
  echo 'Line: '.$line_num;
  echo ' With: "'.$line.'" is the end? '.($fileObject2->eof()?'yes':'no')."<br>";
}

?>

النواتج:

/تمب / إيدكلي.النص

الملف موجود:1

محتويات الملف:فو بار

الخط:0 مع:"فو" هي النهاية?لا

الخط:1 مع:"بار" هو نهاية?لا

الخط:2 مع:""هي النهاية?نعم

في حين أنه قد يبدو غير بديهية ، مع فب 5.3.9 ، وهذا:

<?php
$f = new SplFileObject('test.txt', 'r');
while (!$f->eof()) {
    $f->next();
}

بينما تكون حلقة لا نهائية ، ولا تخرج أبدا.

سيتم الخروج مما يلي ، عند الوصول إلى نهاية الملف:

<?php
$f = new SplFileObject('test.txt', 'r');
while (!$f->eof()) {
    $f->current();
}

لذا:

$i = 0;
$fileObject2->rewind();
while (!$fileObject2->eof()) {
    var_dump($fileObject2->eof());
    var_dump($i++);
    $fileObject2->next();
}

يجب إعادة كتابتها على النحو التالي:

$fileObject2->rewind();
while (!$fileObject2->eof()) {
    $fileObject2->current();
}

$i = $fileObject2->key();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top