ru en uk

  sing in

(044) 362 48 16   (098) 294 41 60


   Services
   Portfolio
   Prices
   Articles
   Services
   Printing
   Multimedia
   Hosting
   Contacts

Home   |   WEB development   |   Articles   |   Programming in PHP

In the PHP Manual on flock () is written as follows:


"Warning! On most operation systems flock () is implemented at the process level. When using a multithreaded server API like ISAPI you cannot rely on flock () to protect files against other PHP scripts running in parallel threads of the same server instance! "


That is, literally, if you use multitredny (trade - they have a trade;) API, such as ISAPI (for example, IIS instead of Apache for Windows NT/2000), you can not use flock () to protect files against other PHP crunchTOV running in parallel trade of one and the same server process.
Briefly, the method, which will be referred to, looks like this: before you open a file that is available to record, we create a corresponding unique lock-file, which is removed after closing the "main" file. Sothem, the other a copy of the process before opening your file, it checks the availability of appropriate Blocking "flag" and, if it is present, the process waits when the "flag" will be removed, after which itself creates a file "flag" by blocking access to workingfile for other running copies of the script.

It is desirable to use a lock, not only when writing to a file, but when you read so-so, in theory, there is always the possibility of opening the file read and write different copies of the script (in both cases I am talking only about the filescontents will vary).
Typically, write to the file occurs simultaneously with or appended to the end of the string / strings (as in the guest book), or reset it and re-recorded (counters, voting system), the same can be said about reading, so the delay time loadKey page, even with a very large number of hits on this file will be minimal. By the way, although it was a really small time interval, however, when working with large files, to minimize the delay, advise you to read only the function file () (andDo fileToArray () - see below), unless, of course, you do not need to read 1-2 lines, and, in the case record, to create a temporary buffer, filling it to the extent of running that script, and in the end dismissed it in the working file. This common practice is used not only PHP, really speeds up the work, especially esland readable file, each line is exposed lexical reviewed (parsed), or each line of the recording - is generated separately.
Now, actually, of blocking. To begin, select a directory, which will be stored lock-files. You can, of course, use the current directory, but thenBehold these catalogs will be available to record all users, which is not desirable and not very convenient. The best way to implement it outside of the directory with our HTML-documents. On UNIX-like machine (in the future it will be implied), it might be $ HOME / lock (telnet-imsya and type the commandFirst line: mkdir $ HOME / lock; chmod 0777 $ HOME / lock), or if access to the home directory is no, we do it in the WWW-root directory using the FTP-client, not forgetting to put 777 permissions (rwxrwxrwx), and be sure to create in the file. htaccess, here prohibiting access to HTTP, c these lines:

Order Deny, Allow
Deny from all


Create a file lib.php - it will be kept general functions and variables, and throws it, let's also the root of your WWW-project (but not over here, too, will create the file. Htaccess with the line:

Order Deny, Allow
Deny from all

to prohibit access to our file library for browsers. In lib.php write:

<?
$ LOCK_DIR = "$ HOME / lock";
/ * Or $ LOCK_DIR = "[path of the file system to your www-root] / lock"* /

/ *
* Internal function that locks a file directly, we refer to it
will not
* /
function safeLock ($ file) (
global $ LOCK_DIR;
$ lck = "$ LOCK_DIR /". basename ($ file). ". LCK";
while (1) (
if (is_file ($ lck)) continue;
)
)
/ *
* TS, just to unlock
* /
function safeUlock ($ file) (
global $ LOCK_DIR;
$ lck = "$ LOCK_DIR /". basename ($ file). ". LCK";
return unlink ($ lck);
)

/ *
* A safe replacement built f.unktsii file ()
* /
function fileToArray ($ file) (
if (! is_readable ($ file)) return FALSE;
safeLock ($ file);
$ buf = file ($ file);
safeUlock ($ file);
return $ buf;
)

/ *
* And this - rather than systemic fopen () - the arguments of those same -
* /
function safeOpen ($ file, $ mode) (
safeLock ($ file);
return fopen ($ file, $ mode);
)

/ *
* Replacing the system fclose ()
*! CAUTION! In this function, 2 arguments, in contrast to the fclose ():
* First $ fd - identical to fclose ();
* Second $ file - string with the name of the file closed,
* /
function safeClose ($ fd, $ file) (
$ st = fclose ($ fd);
safeUlock ($ file);
return $ st;
)
>


Now you can safely begin to use our alternate block: instead of file (), we will use fileToArray (), instead of fopen () - safeOpen (), but instead of fclose () - safeClose (), not forgetting the second argument is the name of the file. And most importantly - connect our lib.php:

<?
include ( "$ DOCUMENT_ROOT / lib.php");
/ *
* If your address has the form/ / www.someisp.com/ ~ user5 "target =" _blank "> http://www.someisp.com/ ~ user5
* Instead of $ DOCUMENT_ROOT you can set the full path of the file system
* To the root of your page, eg:
"/ usr/home/www-users/user5/.public_html/lib.php"
* /

/ * ... * /

$ gbfile= "$ HOME / wwwdata / guestbook.dat";

$ guestBook = fileToArray ($ gbfile);

while (list (, $ key) = each ($ guestBook)) (
/ * ... * /
)

/ * ... * /

$ counter = "$ HOME / wwwdata / counter.txt";

$ fdCount = safeOpen ($ counter, 'w');


safeClose ($ fdCount, $ counter);

/ * ... * /
>


Disadvantages


1. As shown in the code, there is potential for conflict, while also blocking two different files with the samevymi names, because lock-file name "is not unique, in principle, it is easily solved by adding a name to, say, the date of the file object, or MD5-sum generated from the lines of its full path. But since the case can be described except in a rather complicated mnogopolzovatelSoviet project with a total lock-directory, I did not do so.
2. Again, in theory, remains an opportunity for the hacker to calculate the location of the directory for the lock-file and their names and run on the same server, your PHP-script with the appropriate code, "zalochit" your page for everforever, but I understand that this is possible only if the configuration file is not prescribed a PHP "safe_mode = On".

 
Introduction to PHP5
29.05.2007
Lock files
29.05.2007
Introduction to PHP5
29.05.2007