Как мога да използвам file_put_contents() с FILE_APPEND | LOCK_EX безопасност?

Аз използвам:

file_put_contents("peopleList.txt", $person, FILE_APPEND | LOCK_EX);

за запис в края на файл и за да се уверите, че никой друг (или скрипт) също не пише в същия файл по същото време.

Ръководството за PHP казва, че ще върне фалшива стойност, ако не успее.

Ако не може да получи заключване на файла, ще се провали ли или ще продължи да опитва, докато успее? Ако се провали, когато не може да се получи заключване, какъв би бил най-добрият начин да се гарантира, че данните са записани?

Може би зацикляне на функцията в цикъл while, докато не върне false (свиване) или просто предоставяне на потребителя (посетителя на уебсайта) с някакъв вид GUI, изискващ да опитат отново?


person hozza    schedule 19.01.2012    source източник
comment
Apache създава нишка, в която се изпълнява PHP процес. Множество потребители = множество PHP процеси. Процесът, който е получил заключването, е единственият, на който е разрешено да работи с файла. Всички други процеси ще получат грешка от функцията file_put_contents и file_put_contents, издадени от тези потребители, няма да запишат нищо във файла. Това означава, че докато 1 потребител пише, на други се отказва и функцията ще върне булево false.   -  person Mjh    schedule 19.01.2012
comment
Причината защо LOCK_EX съществува е съвсем друга тема. Ако искате да пишете във файла независимо от това, просто премахнете LOCK_EX, тъй като не ви е необходим и последният човек, който има достъп до вашия уебсайт/скрипт, ще бъде този, който ще има данните, записани във файла. Освен това, тъй като правите добавяне - какъв е смисълът изобщо от заключването на файла? Просто го махнете.   -  person Mjh    schedule 19.01.2012
comment
Използвам LOCK_EX и FILE_APPEND заедно, защото други скриптове имат способността да пишат във файла и аз не знам какво да могат, докато данните се добавят към него и обратно.   -  person hozza    schedule 19.01.2012
comment
Всички скриптове добавят ли данни към файла?   -  person Mjh    schedule 19.01.2012
comment
Не, някои ще презапишат, а други просто ще прочетат.   -  person hozza    schedule 19.01.2012
comment
Ако наистина имате нужда от заключване за файл, за да запишете в края му, може би е по-добре да съхранявате тези данни в mysql и просто всяко ново записване да бъде нов ред и да комбинирате записите в един документ. По този начин няма да имате грешки при заключване. Но ще отговоря и на въпроса.   -  person WojonsTech    schedule 25.01.2012


Отговори (2)


Всъщност предишният ми отговор беше малко остарял. flock() блокира, докато не бъде получено желаното заключване:

PHP поддържа преносим начин за заключване на цели файлове по препоръчителен начин (което означава, че всички програми за достъп трябва да използват един и същ начин за заключване или няма да работи). По подразбиране тази функция ще блокира, докато не бъде получено исканото заключване; това може да се контролира (на различни от Windows платформи) с опцията LOCK_NB, документирана по-долу.

Тъй като file_get_contents() го използва, бих предположил, че е същото. Въпреки това, имайте предвид, че варира в зависимост от операционната система.

Малко по-важно е, че не е необходимо да заключвате файла в сценария, който описахте, поради причините N.B. вече е обяснено. Освен ако не използвате CLI SAPI, не мога да се сетя за общ сценарий, за който трябва да се притеснявате за заключване на файлове.

person yannis    schedule 19.01.2012
comment
@hozza, моля, няма нужда да гадаете какво си мисля, просто обяснявам нещата. Ако не ги разбирате, това е друго нещо. Използването на цикъл във връзка със заспиване е просто казано - глупаво. Вие правите FILE_APPEND, изобщо няма нужда да използвате LOCK_EX. Не копирайте примери от php.net сляпо, той ви казва кое какво е и за какво се използва. - person Mjh; 19.01.2012
comment
Кодът, който предоставих, е примерен. Сценарият е просто много скриптове, които могат да добавят, съкращават-записват или четат файла. Искам само едно от тези неща да се случва в даден момент, следователно искам да заключа файла с LOCK_EX, когато използвам file_put_contents(); - person hozza; 19.01.2012
comment
Тогава какво каза @NB. Опитайте да стартирате паралелни скриптове и вижте какво ще се случи - person yannis; 19.01.2012

Ако функцията не успее да получи ключалката за файла, тогава тя ще върне грешка, която можете да използвате.

if ($result === false) { print "failed to lock"; }

Сега, ако искате да опитате да получите заключването няколко пъти, просто използвайте цикъл, за да продължите да се опитвате да пишете във файла.

person WojonsTech    schedule 25.01.2012