PHP Conference Japan 2024

ftell

(PHP 4, PHP 5, PHP 7, PHP 8)

ftell傳回檔案讀/寫指標的目前位置

說明

ftell(資源 $stream): int|false

傳回 stream 所參考的檔案指標位置。

參數

stream

檔案指標必須有效,並且必須指向一個由 fopen()popen() 成功開啟的檔案。ftell() 對於僅附加的串流(以 "a" 旗標開啟)會產生未定義的結果。

返回值

以整數形式返回由 stream 參照的檔案指標位置;亦即,它在檔案串流中的偏移量。

如果發生錯誤,則返回 false(假)。

注意由於 PHP 的整數類型是有號數,且許多平台使用 32 位元整數,因此某些檔案系統函式對於大於 2GB 的檔案可能會返回非預期的結果。

範例

範例 #1 ftell() 範例

<?php

// 開啟一個檔案並讀取一些資料
$fp = fopen("/etc/passwd", "r");
$data = fgets($fp, 12);

// 我們現在的位置?
echo ftell($fp); // 11

fclose($fp);

?>

參見

  • fopen() - 開啟檔案或 URL
  • popen() - 開啟處理程序檔案指標
  • fseek() - 在檔案指標上搜尋
  • rewind() - 重設檔案指標的位置

新增註記

使用者貢獻的註記 8 則註記

7
Mindaugas
9 年前
當透過 fopen('file','a+') 開啟檔案以進行讀寫時,檔案指標應該位於檔案的末尾。然而,即使檔案不是空的,ftell() 也會返回 int(0)。此外,似乎有兩個指標,一個用於讀取,另一個用於寫入,因為它在第一個操作(讀取或寫入)時的行為不同。

範例
<?php
$file
= fopen('counter.txt', 'w');
fwrite($file, '123456789');
fclose($file);

$file = fopen('counter.txt', 'r');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'a+');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'r+');
fwrite($file, 'rr');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'a+');
fwrite($file, 'aa');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'r');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);
?>

結果
0 "123456789" 9
0 "123456789" 9
2 "3456789" 9
2 "" 2
0 "rr3456789aa" 11
2
burninleo at gmx dot net
15 年前
當透過 fopen('file','ab') 開啟檔案以進行附加時,檔案指標應該位於檔案的末尾。然而,即使檔案不是空的,甚至在將一些文字寫入檔案後,ftell() 也會返回 int(0)。
0
d9k at ya dot ru
2 年前
必須使用

<?php
posix_isatty
(STDIN) == false
?>

來取代

<?php
ftell
(STDIN) !== false
?>

在 Ubuntu 上從 PHP 7 升級到 8 之後。
0
d9k at ya dot ru
2 年前
必須使用

<?php
posix_isatty
(STDIN) == false
?>

來取代

<?php
ftell
(STDIN) !== false
?>

在 Ubuntu 上從 PHP 7 升級到 8 之後。
0
mbirth at webwriters dot de
19 年前
注意!如果您以「text」修飾符(例如 'rt')開啟檔案,且該檔案包含 \r\n 作為行尾,則 ftell() 傳回的位置如同只有 \n 作為行尾。

範例
如果第一行只包含 1 個字元,後接 \r\n,則第二行的開頭應該是位置 3。(1 個字元 + \r + \n = 3 個位元組) 但 ftell() 會傳回 2 - 忽略一個位元組。如果您在第 3 行呼叫 ftell(),則該值與實際值將相差 2 個位元組。 這個錯誤會隨著每一行而增加。

(在 Windows 版的 PHP 5.0.4 中觀察到此行為。)

但是:fseek() 的運作符合預期 - 使用真正的位元組值。
0
mweierophinney at gmail dot com
19 年前
實際上,對於僅附加的串流,ftell() 提供的結果並非未定義;它提供的結果是附加任何資料之前定義的檔案結尾的偏移量。 因此,如果您開啟一個包含 3017 個字元的檔案,並附加 41 個字元,然後執行 ftell(),則傳回的值將是 41。
-2
php at michielvleugel dot com
19 年前
當嘗試判斷是否有東西被管道傳輸到命令列腳本時,執行 fgets(STDIN) 並不明智,因為如果沒有管道傳輸任何東西,它將無限期地等待。 相反地,我發現 ftell 在 STDIN 上非常方便:當有東西被管道傳輸時,它會傳回整數零,如果沒有東西被管道傳輸到腳本,則不會傳回任何東西。

#!/usr/bin/php4 -q
<?
#如果沒有管道傳輸任何東西,以下程式碼將會掛起
#$sometext = fgets(STDIN, 256)

$tell = ftell(STDIN);

if (is_integer($tell)==true)
{echo "有東西被管道傳輸: ".fread(STDIN,256)."\n";}
else
{echo "沒有東西被管道傳輸\n";}

?>
-3
missilesilo at gmail dot com
17 年前
回覆 php at michielvleugel dot com

在 PHP 5.2.0 和 FreeBSD 5.4 中似乎並非如此。

#!/usr/local/bin/php
<?php
$tell
= ftell(STDIN);
var_dump($tell);
?>

root@localhost:/home/david# echo Hello World | ./test.php
int(0)
root@localhost:/home/david# ./test.php
int(6629927)

當有東西被管道傳輸到腳本時,它會傳回整數值 0,但是,當沒有東西被管道傳輸到腳本時,它也會傳回一個整數。

程式碼應該修改為這樣

#!/usr/local/bin/php
<?php
$tell
= ftell(STDIN);

if (
$tell === 0)
echo
"有東西從管道輸入: " . fread(STDIN,256) . "\n";
else
echo
"沒有東西從管道輸入\n";
?>

結果如下:

root@localhost:/home/david# echo Hello World | ./test.php
有東西從管道輸入: Hello World
root@localhost:/home/david# ./test.php
沒有東西從管道輸入
To Top