使用PHP在平面文件中查找并替换值

3

我想这个问题已经有人问过了,但是我找不到相关的问题。也许解决方案太简单了...无论如何,我有一个平面文件,希望让用户根据名称更改值。我已经通过使用fopen('a')模式创建新的名称+值对,使用jQuery发送带有newValuenewName的AJAX调用来解决这个问题。但是,假设内容看起来像这样:

host|http:www.stackoverflow.com
folder|/questions/
folder2|/users/

现在我想要更改folder的值。因此,我将以oldName的形式发送folder,并以/tags/作为newValue。最好的覆盖值方式是什么?列表中的顺序无关紧要,并且名称始终位于左侧,后跟|(管道),然后是值,最后是new-line
我的第一个想法是读取列表,将其存储在数组中,搜索所有[0]中的oldName,然后更改属于它的[1],然后将其写回文件。但我感觉有更好的方法解决这个问题?有什么想法吗?也许可以使用正则表达式

1
不要忘记使用某种锁定机制。如果两个脚本同时编辑文件,肯定会出问题。 - extraneon
1
CSV是“逗号分隔值”的缩写,而您的分隔符是管道而不是逗号。虽然许多CSV导入程序允许您将分隔符字符设置为不是逗号的其他字符,但我仍然认为最好将其称为“平面文件”。http://en.wikipedia.org/wiki/Flat_file_database - HostileFork says dont trust SE
@extraneon 是的,这只针对管理员。每个管理员将有一个文件。但我会查看锁定机制,以确保安全 (: 谢谢你提醒我。 @Hostile Fork,是的,我知道,但实际上两者之间没有什么实质性的区别,不是吗? - peirix
1
“当我使用一个词时,”亨普蒂·韦尔德说道,语气相当轻蔑。“它的意思就是我选择的意思,既不多也不少。”-- “问题是,”爱丽丝说,“你能否让一个词有如此多的不同含义。” :) 选择精确的术语可以避免混淆,并协助相关标记。 - HostileFork says dont trust SE
1
@Hostile Fork(:)引用Lewis Carroll的话来说明语义学的观点是无与伦比的。已经理解了。 - peirix
我不是PHP程序员(出于选择),但搜索“PHP平面文件”会显示一些东西,如果你正在寻找面向数据库的API而不是更方便的黑客技巧,那么这些可能有用...! - HostileFork says dont trust SE
2个回答

9

一个非常简单的方法是在整个文件上使用str_replace():

// read the file
$file = file_get_contents('filename.csv');
// replace the data
$file = str_replace('folder|oldValue', 'folder|newValue', $file);
// write the file
file_put_contents('filename.csv', $file);

这应该可以工作,因为一次只有一个用户能够使用该文件。但是,使用数据库总是更好的选择。如果您需要CSV格式的数据,最好有一个额外的将数据库导出为CSV格式的脚本,而不仅仅是一个CSV文件。


5
您可以使用像APC这样的PHP特性将列表保存在内存中,并定期将其写入磁盘。这样,只有在内存中不存在时才需要读取它。
如果您想要强调性能,那么最好不要将此信息存储在CSV中。如果您不想使用真正的关系型数据库(MySQL),那么我建议您使用SQLite。它提供了您正在查找的所有功能(在这种情况下是UPDATE),并且在与CSV相同的意义上完全像一个硬盘上的文件,没有并发问题。
如果那不可行,另一种方法是使用类似于sed和awk的shell级命令进行内联正则表达式更改。最后,将整个文件读入字符串,对其进行恶意的正则表达式调整(s///),然后再将其写回即可。

性能不是问题,真的。最多文件可能只有5行,所以我不会费心去使用MySQL。但每个客户/用户将有一个文件。我会研究一下SQLite,谢谢。 - peirix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接