2010-05-31 90 views
3

我認爲已經有一個問題了,但我找不到一個。也許解決方案太簡單了...無論如何,我有一個平面文件,並希望讓用戶根據名稱更改值。我已經整理出創造新名稱+使用fopen('a')模式,使用jQuery發送AJAX調用與newValuenewName值對。但說的內容是這樣的:使用PHP查找並替換平面文件中的值

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

現在我想改變folder值。所以我會發送folder作爲oldName/tags/作爲newValue。覆蓋價值的最佳方式是什麼?列表中的順序無關緊要,名稱始終位於左側,然後是|(管道),然後是值new-line

我首先想到的就是閱讀列表,它存儲在數組中,搜索所有[0]的爲oldName,然後更改屬於它的[1],然後將它寫回文件。但我覺得有更好的方法呢?有任何想法嗎?也許regex

+1

不要忘記某種鎖定機制。如果兩個腳本同時編輯文件,一定會遇到麻煩。 – extraneon 2010-05-31 14:23:29

+1

CSV是「逗號分隔值」的首字母縮寫,而分隔符是管道而不是逗號。儘管許多CSV導入程序允許您將分隔符設置爲非逗號,但我仍然認爲最好將其稱爲「平面文件」。 http://en.wikipedia.org/wiki/Flat_file_database – HostileFork 2010-05-31 14:32:27

+0

@extraneon是的,這隻適用於管理員。每個管理員將有一個文件。但我會看看到鎖定機制,只是爲了安全起見(:謝謝你提醒我 @Hostile叉,是的,我知道,但實在是沒有任何兩者之間的實際差別,有沒有? – peirix 2010-05-31 14:35:01

回答

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這個信息很可能不是開始與最好的。如果你不想使用真正的RDMS(MySQL),那麼我建議使用SQLite。在這種情況下,它提供了所需的所有功能(UPDATE),它的行爲與CSV完全相同,因爲它只是硬盤上的文件,並沒有併發性。

如果這不是一個選項,另一種方式是使用像sed & awk的外殼級命令來執行內嵌的正則表達式的變化。最後,將整個文件讀入一個字符串,對其執行討厭的正則表達式調整(s///),然後再次寫出它將會起作用

+0

性能不是問題,真的。該文件最多可能有5行,這就是爲什麼我不打算使用MySQL。但是每個客戶端/用戶將會有一個文件。不過,我會看看SQLite。謝謝。 – peirix 2010-05-31 14:31:10