For the record, the example given here has an explicit command to truncate the file, however with a 'write mode' of 'w', it will do this for you automatically, so the truncate call is not needed.(PHP 5 >= 5.1.0, PHP 7, PHP 8)
SplFileObject::flock β ΠΠ»ΠΎΠΊΠΈΡΡΠ΅Ρ ΡΠ°ΠΉΠ» ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠΈΠΌΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ
ΠΠ»ΠΎΠΊΠΈΡΡΠ΅Ρ ΠΈΠ»ΠΈ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΡΠ΅Ρ ΡΠ°ΠΉΠ» ΡΠ΅ΠΌ ΠΆΠ΅ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠΈΠΌΡΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ, ΡΡΠΎ ΠΈ ΡΡΠ½ΠΊΡΠΈΡ flock().
operation
operation ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ:
LOCK_SH Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠ°Π·Π΄Π΅Π»ΡΠ΅ΠΌΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ (ΡΡΠ΅Π½ΠΈΠ΅).
LOCK_EX Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΊΡΠΊΠ»ΡΠ·ΠΈΠ²Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ (Π·Π°ΠΏΠΈΡΡ).
LOCK_UN Π΄Π»Ρ ΡΠ½ΡΡΠΈΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ (ΡΠ°Π·Π΄Π΅Π»ΡΠ΅ΠΌΠΎΠΉ ΠΈΠ»ΠΈ ΡΠΊΡΠΊΠ»ΡΠ·ΠΈΠ²Π½ΠΎΠΉ).
Π€Π»Π°Π³ LOCK_NB Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ
ΠΊΠ°ΠΊ Π±ΠΈΡΠΎΠ²ΡΡ ΠΌΠ°ΡΠΊΡ ΠΊ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΈΠ· ΡΠΏΠΈΡΠΊΠ° Π²ΡΡΠ΅,
Π΅ΡΠ»ΠΈ ΡΡΠ½ΠΊΡΠΈΡ flock() Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π°
Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°ΡΡΡΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠΏΡΡΠΊΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΡΠ°ΠΉΠ»Π°.
wouldBlock
ΠΠΎΠ»ΡΡΠ°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ true, Π΅ΡΠ»ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π±ΡΠ΄Π΅Ρ Π±Π»ΠΎΠΊΠΈΡΡΡΡΠ΅ΠΉ
(Π² ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ errno Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΠΈΡΠ°Π½ ΠΊΠΎΠ΄ ΠΎΡΠΈΠ±ΠΊΠΈ EWOULDBLOCK).
Π€ΡΠ½ΠΊΡΠΈΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ true, Π΅ΡΠ»ΠΈ Π²ΡΠΏΠΎΠ»Π½ΠΈΠ»Π°ΡΡ ΡΡΠΏΠ΅ΡΠ½ΠΎ, ΠΈΠ»ΠΈ false, Π΅ΡΠ»ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ°.
ΠΡΠΈΠΌΠ΅Ρ #1 ΠΡΠΈΠΌΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΌΠ΅ΡΠΎΠ΄Π° SplFileObject::flock()
<?php
$file = new SplFileObject("/tmp/lock.txt", "w");
if ($file->flock(LOCK_EX)) { // ΠΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌ ΡΠΊΡΠΊΠ»ΡΠ·ΠΈΠ²Π½ΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ
$file->ftruncate(0); // ΠΡΠΈΡΠ°Π΅ΠΌ ΡΠ°ΠΉΠ»
$file->fwrite("ΠΠΈΡΠ΅ΠΌ ΡΡΠΎ-Π½ΠΈΠ±ΡΠ΄Ρ ΡΡΠ΄Π°\n");
$file->flock(LOCK_UN); // Π‘Π½ΠΈΠΌΠ°Π΅ΠΌ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ
} else {
echo "ΠΠ΅ ΡΠ΄Π°Π»ΠΎΡΡ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ!";
}
?>
For the record, the example given here has an explicit command to truncate the file, however with a 'write mode' of 'w', it will do this for you automatically, so the truncate call is not needed.@digitalprecision What you said is not completely true, ftruncate(0); is needed if there was a write to the file before the lock is acquired. You also may need fseek(0); to move back the file pointer to the beginning of the file
<?php
$file = new SplFileObject("/tmp/lock.txt", "w");
$file->fwrite("xxxxx"); // write something before the lock is acquired
sleep(5); // wait for 5 seconds
if ($file->flock(LOCK_EX)) { // do an exclusive lock
$file->fwrite("Write something here\n");
$file->flock(LOCK_UN); // release the lock
} else {
echo "Couldn't get the lock!";
}
?>
"lock.txt" content:
xxxxxWrite something here