2

感谢您花时间阅读本文,无论内容质量如何,我都会感谢每一个回复。:)

我正在尝试创建一个在文本文件中搜索特定文本的 php 脚本。一个人在 HTML 表单中键入特定文本,php 脚本应该在文本文件中搜索该特定文本。

HTML 表单的输入字段的值为“用户名”,在 php 文档中,变量“$username”是输入的数据,示例如下:

$username = $_POST['username'];

下面的文本文件称为“begin.txt”:

“AULLAH1”“01/07/2010 15:28”“55621454”“123456”“123456.00”

“用户名”“2010 年 7 月 3 日下午 6:21”“55621454”“123456”“123456.00”

“AULLAH1” “07/07/2010 15:05” “55621454” “189450” “123456.00”

“超级玩家”“2010 年 7 月 8 日下午 6:42”“55621454”“123456”“123456.00”

如果一个人输入 HTML 表单“AULLAH1”,我希望 php 脚本抓取文本文件中的最后一个“AULLAH1”条目(例如,它应该抓取第三行而不是第一行,因为第三行是最后一个条目包含文本“AULLAH1”)。此外,当一个人输入特定文本时,它不应该简单地抓取文档或文本,它应该抓取整行:“AULLAH1”“07/07/2010 15:05”“55621454”“189450” " "123456.00" 并将其放入 php 变量中,可能类似于 "$grabbed"?如果可能的话。

感谢您提供所有帮助,我期待您的回复;谢谢你。:) 如果我没有清楚地解释任何事情和/或您希望我更详细地解释,请回复。:)

谢谢你。

4

5 回答 5

3

您可以SplFileObject逐行使用和迭代文件。

请注意,迭代文件比使用更节省内存,file()或者file_get_contents()因为它不会将整个文件内容读入数组或变量中。

$username = 'AULLAH1';
$file = new SplFileObject("data.csv");
$grabbed = FALSE;
while (!$file->eof()) {
     $data = $file->fgetcsv(' ');
     if($data[0] === $username) {
         $grabbed = $file->current();
     }
}
echo $grabbed;

因为fgetcsv()在解析行时考虑了分隔符、外壳和转义字符,所以它并不是很快。如果您必须以这种方式解析数百或数千行,请确保您确实需要它。


另一种方法是检查当前行是否在某处包含用户名字符串。在您在问题中显示的文件格式中,这是可行的,因为其余字段包含数字,因此不会有任何误报:

$username = 'AULLAH1';
$file = new SplFileObject("data.txt");
$grabbed = FALSE;
foreach($file as $line) {
    if(strpos($line, $username) !== FALSE) {
        $grabbed = $line;
    }
}
echo $grabbed;

如果要确保在位置 1 找到 $username,请将if条件更改为 test for === 1


如果由于某种原因,您希望所有行都出现用户名,您可以编写一个自定义 FilterIterator 来迭代文件内容,例如

class UsernameFilter extends FilterIterator
{
    protected $_username;
    public function __construct(Iterator $iterator, $username)
    {
        $this->_username = $username;
        parent::__construct($iterator);
    }
    public function accept()
    {
        return strpos($this->current(), $this->_username) !== FALSE;
    }
}

然后你可以简单地使用foreach. FilterIterator 将传递每一行,accept()并且只有那些它返回 TRUE 的行才会被实际使用。

$filteredLines = new UsernameFilter(new SplFileObject('data.txt'), 'AULLAH1');
foreach($filteredLines as $line) {
    echo $line;
}

以上将输出

"AULLAH1" "01/07/2010 15:28 " "55621454" "123456" "123456.00"
"AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00"

如果你想要这些行在一个数组中,你可以做

$lines = iterator_to_array($filteredLines);

并查看最后一项

echo end($lines);
于 2010-08-21T21:20:13.403 回答
3

我不会使用文本文件来存储凭据,但如果您必须至少将文本文件的格式更改为 CSV 布局

像这样

AULLAH1,01/07/2010 15:28,55621454,123456,123456.00
USERNAME,7/3/2010 6:21 PM,55621454,123456,123456.00
AULLAH1" "07/07/2010 15:05 " "55621454" "189450" "123456.00
SUPREMEGAMER,7/8/2010 6:42 PM,55621454,123456,123456.00

在 PHP 中读取文件行我的行

<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
     if(preg_match('/(?<username>.*?),(?<ts>.*?),(?<id_1>.*?),(?<id_2>.*?),(?<balance>.*?)/',$line,$parts))
     {
         if($_POST['username'] == $parts['username'])
         {
             //Do what you need here.
             break;
         }
     }
}
?>

您也可以使用爆炸女巫更快,但仅限于为数组自动生成键!

<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
    $parts = explode(',',$line);
     if($_POST['username'] == $parts[0])
     {
         //Do what you need here.
         break;
     }
}
?>
于 2010-08-21T21:40:16.433 回答
2

使用preg_match_all()可能是一个解决方案:

$file = file_get_contents($filename);
$username = 'ALLUAH1';
preg_match_all('/^"'.preg_quote($username, '/').'".*$/m', $file, $matches);
  // Note that the '/m' flag of the regex makes '^' and '$' match
  // the beginning and end of each line.
  // Also note that I am using preg_quote() to escape special regex characters

$grabbed = array_pop($matches[0]);

现在$grabbed应该保存该用户最后一行的值。

相关链接:

于 2010-08-21T21:57:12.690 回答
2

这是我能想到的最简单的实现方式。此方法只是以相反的顺序遍历文件的行,因此不需要搜索每一行。它还假设用双引号括起来的用户名是输入文件每一行的第一件事。

$username = "AULLAH1";
$input_file = file("begin.txt");

$grabbed = "";

for($i = count($input_file) - 1; $i >= 0; $i--)
{
  // Note: Exactly zero (string starts the line), NOT "FALSE"
  if(strpos($input_file[$i], "\"$username\"") === 0)
  {
    $grabbed = $input_file[$i];
    break;
  }
}
于 2010-08-21T22:01:23.710 回答
2

这是我能想到的最短的:

$list = file_get_contents('data.txt');
echo strstr(substr($list, strrpos($list, 'AULLAH1')-1), PHP_EOL, TRUE);

这会将文件读入内存。然后它找到字符串'AULLAH1'最后一次出现的偏移量。将返回此事件之前的一个字母直到下一个换行符。

由于 的第三个参数,这需要 PHP5.3,并且比上面的迭代器解决方案strstr()需要更多的内存。根据您的换行符,您可能必须将 PHP_EOL 更改为文件中使用的换行符。

于 2010-08-21T22:26:16.797 回答