感谢您抽出宝贵时间阅读本文,我将感谢每一个回复,无论内容的质量如何。 :)
我正在尝试创建一个php脚本,用于在文本文件中搜索特定文本。一个人在HTML表单中键入特定文本,php脚本应该在文本文件中搜索该特定文本。
HTML表单的输入字段的值是“username”,在php文档中,变量“$ username”是输入的数据,示例如下所示:
$username = $_POST['username'];
下面的文本文件名为“begin.txt”:
“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”
如果一个人输入HTML表单“AULLAH1”,我希望php脚本能够获取文本文件中的最后一个“AULLAH1”条目(例如,它应该抓住第三行而不是第一行,作为第三行line是包含文本“AULLAH1”的最后一个条目。此外,当一个人键入特定文本时,它不应该只是抓取文档或文本,它应该抓住整行:“AULLAH1”“07/07/2010 15:05”“55621454”“189450 “”123456.00“并将其放入php变量,可能是”$ grabbed“之类的东西?如果可能的话。
感谢所有的帮助,我期待着您的回复;谢谢。 :)如果我没有清楚地解释任何内容和/或您希望我更详细地解释,请回复。 :)
谢谢。
答案 0 :(得分: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;
}
}
}
?>
你也可以使用explode witch更快,但仅限于自动生成数组键!
<?php
$lines = file('begin.txt');
foreach($lines as $line)
{
$parts = explode(',',$line);
if($_POST['username'] == $parts[0])
{
//Do what you need here.
break;
}
}
?>
答案 1 :(得分:2)
您可以使用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
条件以测试=== 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);
答案 2 :(得分: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
应该保留该用户最后一行的值。
相关链接:
答案 3 :(得分: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;
}
}
答案 4 :(得分:2)
这是我能想到的最短时间:
$list = file_get_contents('data.txt');
echo strstr(substr($list, strrpos($list, 'AULLAH1')-1), PHP_EOL, TRUE);
这会将文件读入内存。然后它找到字符串'AULLAH1'的最后一次出现的偏移量。在此出现之前一直到下一个换行符的所有内容都将被返回。
由于strstr()
的第三个参数,这需要PHP5.3,并且需要比上面的iterator solution更多的内存。根据您的换行符,您可能必须将PHP_EOL更改为文件中使用的换行符。