1. Trang chủ
  2. » Công Nghệ Thông Tin

Giải pháp thiết kế web động với PHP - p 21 pot

10 151 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 722,89 KB

Nội dung

USING PHP TO MANAGE FILES 181 PHP Solution 7-5. If the hosting company refuses, you should consider moving to one with a better understanding of PHP. Configuration settings that affect local file access If the Local Value column for open_basedir or safe_mode_include_dir displays no value, you can ignore this section. However, if it does have a value, the meaning depends on whether the value ends with a trailing slash, like this: /home/includes/ In this example, you can open or include files only from the includes directory or any of its subdirectories. If the value doesnt have a trailing slash, the value after the last slash acts as a prefix. For example, /home/inc gives you access to /home/inc, /home/includes, /home/incredible, and so on— assuming, of course, that they exist or you have the right to create them. PHP Solution 7-1 shows what happens when you try to access a file outside the limits imposed by open_basedir. Creating a file storage folder for local testing Storing data inside your site root is highly insecure, particularly if you need to set global access permissions on the folder. If you have access to a private folder outside the site root, create your data store as a subfolder and give it the necessary permissions. For the purposes of this chapter, I suggest that Windows users create a folder called private on their C drive. Mac users should create a private folder inside their home folder and then set Read & Write permissions in the folders Info panel as described in the previous chapter. Reading and writing files The restrictions described in the previous section reduce the attraction of reading and writing files with PHP. Using a database is more convenient and offers greater security. However, that assumes you have access to a database and the necessary knowledge to administer it. So, for small-scale data storage and retrieval, working directly with text files is worth considering. Reading files in a single operation The simplest way to read the contents of a text file is to use file_get_contents() or readfile(). PHP Solution 7-1: Getting the contents of a text file This PHP solution demonstrates how to use file_get_contents() and readfile(), and explains how they differ. 1. Create a text file in your private folder, type some text into it, and save it as filetest_01.txt (or use the version in the ch07 folder). 2. Create a new folder called filesystem in your phpsols site root, and create a PHP file called get_contents.php in the new folder. Insert the following code inside a PHP block CHAPTER 7 182 (get_contents_01.php in the ch07 folder shows the code embedded in a web page, but you can use just the PHP code for testing purposes): echo file_get_contents('C:/private/filetest_01.txt'); If youre on a Mac, amend the pathname like this, using your own Mac username: echo file_get_contents('/Users/username/private/filetest_01.txt'); If youre testing on a remote server, amend the pathname accordingly. For brevity, the remaining examples in this chapter show only the Windows pathname. 3. Save get_contents.php, and view it in a browser. Depending on what you wrote in filetest_01.txt, you should see something like the following screenshot. You shouldnt see any error messages on your local system, unless you typed the code incorrectly or you didnt set the correct permissions on a Mac. However, on a remote system, you may see error messages similar to this: The error messages in the preceding screenshot were created on a local system to demonstrate what happens when open_basedir has been set either in php.ini or on the server. They mean youre trying to access a file outside your permitted file structure. The first error message should indicate the allowed paths. On a Windows server, each path is separated by a semicolon. On Linux, the separator is a colon. 4. Change the code in get_contents.php like this (its in get_contents_02.php): readfile('C:/private/filetest_01.txt'); Download from Wow! eBook <www.wowebook.com> USING PHP TO MANAGE FILES 183 5. Save get_contents.php, and reload it in your browser. The contents of the text file are displayed as before. So, whats the difference? The original code uses echo to display the contents of the file. The amended code doesnt use echo. In other words, file_get_contents() simply gets the contents of a file, but readfile() also displays it immediately. The advantage of file_get_contents() is that you can assign the file contents to a variable and process it in some way before deciding what to do with it. 6. Change the code in get_contents.php like this (or use get_contents_03.php), and load the page into a browser: // get the contents of the file $contents = file_get_contents('C:/private/filetest_01.txt'); // split the contents into an array of words $words = explode(' ', $contents); // extract the first four elements of the array $first = array_slice($words, 0, 4); // join the first four elements and display echo implode(' ', $first); This stores the contents of filetest_01.txt in a variable, which is passed to the explode() function. This alarmingly named function “blows apart” a string and converts it into an array, using the first argument to determine where to break the string. In this case, a space is used, so the contents of the text file are split into an array of words. The array of words is then passed to the array_slice() function, which takes a slice out of an array starting from the position specified in the second argument. The third argument specifies the length of the slice. PHP counts arrays from 0, so this extracts the first four words. Finally, implode() does the opposite of explode(), joining the elements of an array and inserting the first argument between each one. The result is displayed by echo, producing the following outcome: Instead of displaying the entire contents of the file, the script now displays only the first four words. The full string is still stored in $contents. 7. If you need to extract the first few words from a string on a regular basis, you could create a custom function like this: function getFirstWords($string, $number) { CHAPTER 7 184 $words = explode(' ', $string); $first = array_slice($words, 0, $number); return implode(' ', $first); } You can extract the first seven words like this (the code is in get_contents_04.php): $contents = file_get_contents('C:/private/filetest_01.txt'); echo getFirstWords($contents, 7); 8. Among the dangers with accessing external files are that the file might be missing or its name misspelled. Change the code like this (its in get_contents_05.php): $contents = file_get_contents('C:/private/filetest_01.txt'); if ($contents === false) { echo 'Sorry, there was a problem reading the file.'; } else { echo $contents; } If the file_get_contents() function cant open the file, it returns false. Often, you can test for false by using the logical Not operator like this: if (!$contents) { If the file is empty or contains only the number 0, $contents is implicitly false. To make sure the returned value is explicitly false, you need to use the identical operator (three equal signs). 9. Test the page in a browser, and it should display the contents of the text file as before. 10. Replace the contents of filetest_01.txt with the number 0. Save the text file, and reload get_contents.php in the browser. The number displays correctly. 11. Delete the number in the text file, and reload get_contents.php. You should get a blank screen, but no error message. The file loads, but doesnt contain anything. 12. Change the code in get_contents.php so that it attempts to load a nonexistent file. When you load the page, you should see an ugly error message like this: “Failed to open stream” means it couldnt open the file. USING PHP TO MANAGE FILES 185 13. This is an ideal place to use the error control operator (see Chapter 4). Insert an @ mark immediately in front of the call to file_get_contents() like this (the code is in get_contents_07.php): $contents = @ file_get_contents('C:/private/filetest0.txt'); 14. Test get_contents.php in a browser. You should now see only the following custom error message: Always add the error control operator only after testing the rest of a script. When developing, you need to see error messages to understand why something isnt working the way you expect. Text files can be used as a flat-file database—where each record is stored on a separate line, with a tab, comma, or other delimiter between each field (see http://en.wikipedia.org/ wiki/Flat_file_database). With this sort of file, its more convenient to store each line individually in an array to process with a loop. The file() function builds the array automatically. PHP Solution 7-2: Reading a text file into an array To demonstrate the file() function, this PHP solution uses filetest_02.txt, which contains just two lines as follows: david, codeslave chris, bigboss This will be used as the basis for a simple login system to be developed further in Chapter 9. 1. Create a PHP file called file.php inside the filesystem folder. Insert the following code (or use file_01.php from the ch07 folder): <?php // read the file into an array called $users $users = file('C:/private/filetest_02.txt'); ?> <pre> <?php print_r($users); ?> </pre> This draws the contents of filetest_02.txt into an array called $users and then passes it to print_r() to display the contents of the array. The <pre> tags simply make the output easier to read in a browser. CHAPTER 7 186 2. Save the page, and load it in a browser. You should see the following output: It doesnt look very exciting, but now that each line is a separate array element, you can loop through the array to process each line individually. 3. You need to use a counter to keep track of each line; a for loop is the most convenient (see “The versatile for loop” in Chapter 3). To find out how many times the loop should run, pass the array to the count() function to get its length. Amend the code in file.php like this (or use file_02.php): <?php // read the file into an array called $users $users = file('C:/private/filetest03.txt'); // loop through the array to process each line for ($i = 0; $i < count($users); $i++) { // separate each element and store in a temporary array $tmp = explode(', ', $users[$i]); // assign each element of the temporary array to a named array key $users[$i] = array('name' => $tmp[0], 'password' => $tmp[1]); } ?> <pre> <?php print_r($users); ?> </pre> The count() function returns the length of an array, so in this case, the value of count($users) is 2. This means the first line of the loop is equivalent to this: for ($i = 0; $i < 2; $i++) { The loop continues running while $i is less than 2. Since arrays are always counted from 0, this means the loop runs twice before stopping. Inside the loop, the current array element ($users[$i]) is passed to the explode() function. In this case, the separator is defined as a comma followed by a space (', '). However, you can use any character or sequence of characters: using "\t" (see Table 3-4 in Chapter 3) as the first argument to explode() turns a tab-separated string into an array. USING PHP TO MANAGE FILES 187 The first line in filetest 02.txt looks like this: david, codeslave When this line is passed to explode(), the result is saved in $tmp, so $tmp[0] is david, and $tmp[1] is codeslave. The final line inside the loop reassigns $tmp[0] to $users[0]['name'], and $tmp[1] to $users[0]['password']. The next time the loop runs, $tmp is reused, and $users[1]['name'] becomes chris, and $users[1]['password'] becomes bigboss. 4. Save file.php, and view it in a browser. The result looks like this: 5. Take a close look at the gap between codeslave and the closing parenthesis of the first subarray. The file() function doesnt remove newline characters or carriage returns, so you need to do it yourself. Pass the final item of $tmp to rtrim() like this: $users[$i] = array('name' => $tmp[0], 'password' => rtrim($tmp[1])); The rtrim() function removes whitespace (spaces, tabs, newline characters, and carriage returns) from the end of a string. It has two companions: ltrim() which removes whitespace from the beginning of a string, and trim(), which removes whitespace from both ends of a string. If youre working with each line as a whole, pass the entire line to rtrim() . 6. As always, you need to check that the file is accessible before attempting to process its contents, so wrap the main PHP block in a conditional statement like this (see file_03.php): CHAPTER 7 188 $textfile = 'C:/private/filetest_02.txt'; if (file_exists($textfile) && is_readable($textfile)) { // read the file into an array called $users $users = file($textfile); // loop through the array to process each line for ($i = 0; $i < count($users); $i++) { // separate each element and store in a temporary array $tmp = explode(', ', $users[$i]); // assign each element of the temporary array to a named array key $users[$i] = array('name' => $tmp[0], 'password' => rtrim($tmp[1])); } } else { echo "Can't open $textfile"; } To avoid typing out the file pathname each time, begin by storing it in a variable. This simple script extracts a useful array of names and associated passwords. You could also use this with a series of sports statistics or any data that follows a regular pattern. Opening and closing files for read/write operations The functions we have looked at so far do everything in a single pass. However, PHP also has a set of functions that allow you to open a file, read it and/or write to it, and then close the file. The following are the most important functions used for this type of operation: • fopen(): Opens a file • fgets(): Reads the contents of a file, normally one line at a time • fread(): Reads a specified amount of a file • fwrite(): Writes to a file • feof(): Determines whether the end of the file has been reached • rewind(): Moves an internal pointer back to the top of the file • fclose(): Closes a file The first of these, fopen(), is the most difficult to understand, mainly because you need to specify how the file is to be used once its open: fopen() has one read-only mode, three write-only modes, and four read/write modes. Sometimes, you want to overwrite the existing content. At other times, you may want to append new material. At yet other times, you may want PHP to create a file if it doesnt already exist. The other thing you need to understand is where each mode places the internal pointer when it opens the file. Its like the cursor in a word processor: PHP starts reading or writing from wherever the pointer happens to be when you call fread() or fwrite(). Table 7-2 brings order to the confusion. USING PHP TO MANAGE FILES 189 Table 7-2. Read/write modes used with fopen() Type Mode Description Read-only r Internal pointer initially placed at beginning of file. Write-only w Existing data deleted before writing. Creates a file if it doesnt already exist. a Append mode. New data added at end of file. Creates a file if it doesnt already exist. x Creates a file only if it doesnt already exist, so no danger of deleting existing data. r+ Read/write operations can take place in either order and begin wherever the internal pointer is at the time. Pointer initially placed at beginning of file. File must already exist for operation to succeed. w+ Existing data deleted. Data can be read back after writing. Creates a file if it doesnt already exist. a+ Opens a file ready to add new data at end of file. Also permits data to be read back after internal pointer has been moved. Creates a file if it doesnt already exist. Read/write x+ Creates a new file, but fails if a file of the same name already exists. Data can be read back after writing. Choose the wrong mode, and you could end up deleting valuable data. You also need to be careful about the position of the internal pointer. If the pointer is at the end of the file, and you try to read the contents, you end up with nothing. On the other hand, if the pointer is at the beginning of the file, and you start writing, you overwrite the equivalent amount of any existing data. “Moving the internal pointer” later in this chapter explains this in more detail with a practical example. You work with fopen() by passing it the following two arguments: • The path to the file you want to open • One of the modes listed in Table 7-2 The fopen() function returns a reference to the open file, which can then be used with any of the other read/write functions. So, this is how you would open a text file for reading: $file = fopen('C:/private/filetest_02.txt', 'r'); Thereafter, you pass $file as the argument to other functions, such as fgets() and fclose(). Things should become clearer with a few practical demonstrations. Rather than building the files yourself, youll probably find it easier to use the files in the ch07 folder. Ill run quickly through each mode. CHAPTER 7 190 Mac users need to adjust the path to the private folder in the example files to match their setup. Reading a file with fopen() The file fopen_read.php contains the following code: // store the pathname of the file $filename = 'C:/private/filetest_02.txt'; // open the file in read-only mode $file = fopen($filename, 'r'); // read the file and store its contents $contents = fread($file, filesize($filename)); // close the file fclose($file); // display the contents echo nl2br($contents); If you load this into a browser, you should see the following output: Unlike file_get_contents(), the function fread() needs to know how much of the file to read. So you need to supply a second argument indicating the number of bytes. This can be useful if you want, say, only the first 100 characters of a text file. However, if you want the whole file, you need to pass the files pathname to filesize() to get the correct figure. The nl2br() function in the final line converts new line characters to HTML <br /> tags. The other way to read the contents of a file with fopen() is to use the fgets() function, which retrieves one line at a time. This means that you need to use a while loop in combination with feof() to read right through to the end of the file. This is done by replacing this line: $contents = fread($file, filesize($filename)); with this (the full script is in fopen_readloop.php): // create variable to store the contents $contents = ''; // loop through each line until end of file while (!feof($file)) { // retrieve next line, and add to $contents $contents .= fgets($file); } . a PHP file called get_contents .php in the new folder. Insert the following code inside a PHP block CHAPTER 7 182 (get_contents_01 .php in the ch07 folder shows the code embedded in a web page,. file .php like this (or use file_02 .php) : < ?php // read the file into an array called $users $users = file('C:/private/filetest03.txt'); // loop through the array to process. $users[0]['password']. The next time the loop runs, $tmp is reused, and $users[1]['name'] becomes chris, and $users[1]['password'] becomes bigboss. 4. Save file .php, and

Ngày đăng: 06/07/2014, 19:20

TỪ KHÓA LIÊN QUAN