• Aucun résultat trouvé

Preventing files from being overwritten

Dans le document DAVID POWERS Y (Page 188-191)

}

You could use the values of $typeOK and $sizeOK to create different error mes-sages depending on the reason for the failure, but it’s probably more user-friendly to indicate all restrictions at the same time

5.Save upload.php, and test it with a variety of files to make sure that only files of the right type and size get through. Check your code against upload07.phpif you encounter any problems.

Preventing files from being overwritten

If you have been testing upload.phpregularly through this chapter, by now you probably have quite a few files in the upload folder. If you have only a handful, it’s probably because you have been using the same files over and over again. As the script stands, PHP auto-matically overwrites existing files without warning. That may be exactly what you want. On the other hand, it may be your worst nightmare.

In Chapter 4, you used file_exists()to check the existence of a file. You may be think-ing it would be a good idea to use it here and display a message askthink-ing the user if the file should be replaced. It’s not the solution I’m going to suggest. You can never be 100% sure who is accessing your site, so giving users the opportunity to delete files is something you should approach with the utmost caution.

A very simple way of giving every file a unique name is to combine it with the date and time of upload. PHP bases date calculations on Unix timestamps, which measure the num-ber of seconds since midnight GMT on January 1, 1970. So, by prefixing the existing file-name with a Unix timestamp, the likelihood of two files ever having the same file-name is infinitesimal. Using a timestamp also has the advantage that files are listed in chronologi-cal order of receipt. By the way, PHP uses Unix timestamps on all operating systems, including Windows.

Don’t forget that when comparing values to see if they’re the same, you must use two equal signs. If you use just one equal sign, the test will always equate to true (see “Making comparisons” in Chapter 3 if you need reminding why).

6

Continue working with the same file. Alternatively, use upload07.php from the down-load files.

1.You create a current timestamp by calling the time() function, which takes no arguments. If you want to apply a timestamp to all filenames, simply add it between the UPLOAD_DIR constant and the filename in the second argument passed to move_uploaded_file()like this:

$success = move_uploaded_file($_FILES['image']['tmp_name'], ➥ UPLOAD_DIR.time().$file);

Notice that there are periods on either side of time(). This is the concatenation operator, so what you’re doing is joining three values together as a single string—

in other words, the path and filename.

2.If you want to prefix only potential duplicates with a timestamp, you need to check whether a file of the same name already exists, and then use an if... else con-struct to take the appropriate action. Amend the first section of the switch state-ment like this:

if ($sizeOK && $typeOK) {

switch($_FILES['image']['error']) { case 0:

// make sure file of same name does not already exist if (!file_exists(UPLOAD_DIR.$file)) {

// move the file to the upload folder and rename it

$success = move_uploaded_file($_FILES['image']['tmp_name'], ➥ UPLOAD_DIR.$file);

} else {

$success = move_uploaded_file($_FILES['image']['tmp_name'], ➥ UPLOAD_DIR.time().$file);

}

if ($success) {

$result = "$file uploaded successfully";

}

3.Save upload.phpand test it by uploading the same image twice. As you can see in Figure 6-5, the message displayed in the form still uses the original name, but the duplicate in the upload folder has a timestamp in its filename.

PHP Solution 6-5: Using a timestamp to create a unique name

Figure 6-5. Prefixing a filename with a timestamp prevents existing files from being overwritten.

4.If you find the timestamps difficult to understand, you can use the date()function instead to create a more readable date and time. (The date()function and its for-matting options are described in detail in Chapter 14.) Change the elsestatement in the previous step like this:

else {

// get the date and time

ini_set('date.timezone', 'Europe/London');

$now = date('Y-m-d-His');

$success = move_uploaded_file($_FILES['image']['tmp_name'], ➥ UPLOAD_DIR.$now.$file);

}

As explained in Chapter 4, PHP 5.1.0 and above requires a valid time zone when using date(), so it’s a good idea to future-proof your code by setting the time zone for your server (see www.php.net/manual/en/timezones.phpfor a list of valid time zones). The preceding code produces a filename like that on the right in Figure 6-6.

Figure 6-6. Using the date()function makes the date and time easier to read.

You can check your code against upload08.phpin the download files.

6

This is just a simple example of how you can prevent files from being overwritten, which also demonstrates the principle of giving upload files names of your choice, rather than accepting whatever is input by the user. Choosing your own filename also adds an extra level of security, as long as you don’t reveal the new name in a message displayed onscreen. PHP Solution 7-4 in the next chapter shows you how to rename files in a con-secutive series by appending the next available number to its filename.

Dans le document DAVID POWERS Y (Page 188-191)