CLIL-4-PHP-4. Files - part 2. There are three functions that allow you to work more intimately with the contents

Similar documents
CLIL-3-PHP-3. Files - part 1. Once you master the art of working with files, a wider world of PHP web

Requirements Management tool makes traceability easy. See how!

File handling is an important part of any web application. You often need to open and process a file for different tasks.

FILE TYPES 1/2/12 CHAPTER 5 WORKING WITH FILES AND DIRECTORIES OBJECTIVES. Binary. Text PHP PROGRAMMING WITH MYSQL, 2ND EDITION

File uploading in PHP

File uploading in PHP

In a Linux/Unix operating system, it is expressed as:

COMS 469: Interactive Media II

Lecture 6: More Arrays & HTML Forms. CS 383 Web Development II Monday, February 12, 2018

Server-side Web Development (I3302) Semester: 1 Academic Year: 2017/2018 Credits: 5 (50 hours) Dr Antoun Yaacoub

Chapter 7 PHP Files & MySQL Databases

Automating Digital Downloads

CSI 402 Systems Programming LECTURE 4 FILES AND FILE OPERATIONS

Intermediate Programming, Spring 2017*

CLIL-5-PHP-5. Files - part 3. At some point in time, you are almost certainly going to come into contact with file

What is PHP? [1] Figure 1 [1]

Master Syndication Gateway V2. User's Manual. Copyright Bontrager Connection LLC

CSCU9B2 Practical 1: Introduction to HTML 5

Introduction to Linux

CSI 402 Lecture 2 (More on Files) 2 1 / 20

CIT 590 Homework 5 HTML Resumes

Database Systems Fundamentals

C How to Program, 6/e by Pearson Education, Inc. All Rights Reserved.

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #47. File Handling

Lecture 12 CSE July Today we ll cover the things that you still don t know that you need to know in order to do the assignment.

ROBOTLINKING THE POWER SUPPLY LEARNING KIT TUTORIAL

PHP INTERVIEW QUESTION-ANSWERS

Reading How the Web Works

Chapter 7:- PHP. Compiled By:- Sanjay Patel Assistant Professor, SVBIT.

Web Application Development (WAD) V th Sem BBAITM(Unit-1) By: Binit Patel

Ruby on Rails Welcome. Using the exercise files

UNIT-VI CREATING AND USING FORMS

(Refer Slide Time: 01:25)

CLIL-6-PHP-6. Arrays - part 1. So far we've looked at the basic variables types such as strings and integers, as

USING DRUPAL. Hampshire College Website Editors Guide

User authentication, passwords

CSI 402 Lecture 2 Working with Files (Text and Binary)

Grapevine web hosting user manual. 12 August 2005

Using X-Particles with Team Render

PHP 5 if...else...elseif Statements

L.A.M.P. Stack Part I

Creating the Data Layer

CS 471 Operating Systems. Yue Cheng. George Mason University Fall 2017

One of the fundamental kinds of websites that SharePoint 2010 allows

Client Side JavaScript and AJAX

Your . A setup guide. Last updated March 7, Kingsford Avenue, Glasgow G44 3EU

PROGRAMMAZIONE I A.A. 2017/2018

Week 9 Lecture 3. Binary Files. Week 9

Unix as a Platform Exercises. Course Code: OS-01-UNXPLAT

Authoring World Wide Web Pages with Dreamweaver

File Handling with PHP

CSCI 1100L: Topics in Computing Lab Lab 11: Programming with Scratch

File System Interface. ICS332 Operating Systems

CGI Architecture Diagram. Web browser takes response from web server and displays either the received file or error message.

Table Of Contents. 1. Zoo Information a. Logging in b. Transferring files 2. Unix Basics 3. Homework Commands

H E R ALD LE AD E R P H OTO.COM

Aculab licence activation server system

PHP Hypertext Preprocessor

Student Success Guide

COMP284 Scripting Languages Lecture 11: PHP (Part 3) Handouts

CSCI 201 Lab 1 Environment Setup

CREATING WEBSITES. What you need to build a website Part One The Basics. Chas Large. Welcome one and all

COMP 3500 Introduction to Operating Systems Project 5 Virtual Memory Manager

How to lay out a web page with CSS

Setting up a ColdFusion Workstation

Content Author's Reference and Cookbook

CS 326: Operating Systems. Process Execution. Lecture 5

Installation... 3 Starting the installation... 3 The installation instructions... 3 Welcome... 3 Software License Agreement... 3 Choose Destination

8 MANAGING SHARED FOLDERS & DATA

The Stack, Free Store, and Global Namespace

Subversion was not there a minute ago. Then I went through a couple of menus and eventually it showed up. Why is it there sometimes and sometimes not?

CITS2401 Computer Analysis & Visualisation

Exam Actual. Higher Quality. Better Service! QUESTION & ANSWER

Agenda. 1. Brief History of PHP. 2. Getting started. 3. Examples

HTML 5 Form Processing

Some (semi-)advanced tips for LibreOffice

eftp Application User Guide

Introduction to Ardora

Keep Track of Your Passwords Easily

PASS4TEST. IT Certification Guaranteed, The Easy Way! We offer free update service for one year

CST8207: GNU/Linux Operating Systems I Lab Six Linux File System Permissions. Linux File System Permissions (modes) - Part 1

8/31/2015 BITS BYTES AND FILES. What is a bit. Representing a number. Technically, it s a change of voltage

COMS 6100 Class Notes 3

Learning to Program with Haiku

CSCI S-Q Lecture #12 7/29/98 Data Structures and I/O

INTERNET BASICS. GETTING STARTED PAGE 02 Prerequisites What You Will Learn

Unit 2 : Computer and Operating System Structure

Subject Name: Advanced Web Programming Subject Code: (13MCA43) 1. what is PHP? Discuss different control statements

This lab exercise is to be submitted at the end of the lab session! passwd [That is the command to change your current password to a new one]

CS/IT 114 Introduction to Java, Part 1 FALL 2016 CLASS 2: SEP. 8TH INSTRUCTOR: JIAYIN WANG

NETB 329 Lecture 13 Python CGI Programming

COPYRIGHTED MATERIAL. Starting Strong with Visual C# 2005 Express Edition

cwhois Manual Copyright Vibralogix. All rights reserved.

CERTIFICATE IN WEB PROGRAMMING

Lecture 9: File Processing. Quazi Rahman

Dynamism and Detection

web.py Tutorial Tom Kelliher, CS 317 This tutorial is the tutorial from the web.py web site, with a few revisions for our local environment.

If you re the administrator on any network,

CS Fundamentals of Programming II Fall Very Basic UNIX

A QUICK GUIDE TO PROGRAMMING FOR THE WEB. ssh (then type your UBIT password when prompted)

Transcription:

Files - part 2 Other file functions bool rewind ( resource handle) int fseek ( resource handle, int offset [, int from_where]) There are three functions that allow you to work more intimately with the contents of a file, which are rewind(), fseek(), and fwrite(). We already looked at fwrite(), but the other two functions are new. Rewind() is a very helpful function that moves the file pointer for a specified file handle (parameter one) back to the beginning. That is, if you call rewind($handle), the file pointer of $handle gets reset to the beginning - this allows you to re-read in a file, or write over whatever you have already written. Fseek() allows you to move a file handle's pointer to an arbitrary position, specified by parameter two, with parameter one being the file handle to work with. If you do not specify a third parameter, fseek() sets the file pointer to be from the start of the file, meaning that passing 23 will move to byte 24 of the file (files start from byte 0, remember). For the third parameter you can either pass SEEK_SET, the default, which means "from the beginning of the file", SEEK_CUR, which means "relative to the current location", or SEEK_END, which means "from the end of the file". Here is a simple example of rewind() and fseek() in action: $handle = fopen($filename, "w+"); fwrite($handle, "Mnnkyys\n"); 1

rewind($handle); fseek($handle, 1); fwrite($handle, "o"); fseek($handle, 2, SEEK_CUR); fwrite($handle, "e"); fclose($handle); Note: do not forget that the first byte of a file is byte 0, and you count upwards from there - the second byte is at index 1, the third at index 2, etc. To begin with, the string "Mnnkyys" is written to $handle, which is straightforward enough. However, rewind() is then called to move the file pointer back to the beginning of the file (the letter "M"), then fseek() is called with 1 as the second parameter to move the file pointer to offset 1 in the file, which is currently the first of two letter "n"s. Fwrite() is called again, writing an "o" - this will replace the current letter "n" at that offset with an "o". Fseek() is called again, passing in 2 and SEEK_CUR, which means "move to the byte 2 ahead of the current byte", which happens to be the first of two letter "y"s. Fwrite() is called for the last time, replacing that "y" with an "e", and finally the file is closed - I will leave it to you to figure out its contents! 2

Checking whether a file exists bool file_exists ( string filename) The act of checking whether a file exists is one of the most basic file-related tasks you'll want to do, and thankfully file_exists() makes it as easy as it should be. In fact, it's so easy you should be able to guess the parameter list and return value! Still here? Oh, alright then - you specify the filename to check as the only parameter, and it returns true if the file exists and false otherwise. Example: if (file_exists("snapshot1.png")) { print "Snapshot1.png exists!\n"; } else { print "Snapshot1.png does not exist!\n"; } Although you're only part-way through this book, I hope you managed to guess how it worked yourself! Note: The result of file_exists() is cached, which means you first need to call the clearstatcache() function if you want to be absolutely sure a file exists. 3

Retrieving a file's status bool is_readable ( string filename) bool is_writeable ( string filename) bool is_executable ( string filename) bool is_file ( string filename) bool is_dir ( string filename) void clearstatcache ( void ) If you're sick of getting errors when you try to work with a file to which you have no permissions, there is a solution: is_readable() and its cousin functions, is_writeable(), is_executable(), is_file(), and is_dir(), takes a string as its only parameter, and either returns true or false. Naturally is_readable() will return true if the string parameter is readable, is_dir() will return false if the parameter is not a directory, etc. Here is an example: if (is_file($filename) && is_writeable($filename)) { $handle = fopen($filename, "w+");...[snip]... } Is_readable() and friends have their results cached for speed purposes - if you call is_file() on a filename several times in a row, PHP will calculate it the first time around then used the same value again and again in the future. If you want to clear this cached data so that PHP will have to check is_file() properly, you need to use the clearstatcache() function. Calling clearstatcache() wipes PHP's file information cache, forcing it recalculate 4

is_file(), is_readable() and such afresh. Clearstatcache() is therefore particularly useful if you are checking a file several times in a script and are aware that that file might change status during execution. Clearstatcache() takes no parameters and returns no value. Note: is_readable(), is_writeable(), is_executable(), is_file(), and is_dir() will all fail to work for remote files, as the file/directory to be examined must be local to the web server so that it can check it properly. 5

Dissecting filename information array pathinfo ( string path) string basename ( string path [, string suffix]) The pathinfo() function is designed to take a filename and return the same filename broken into various components. It takes a filename as its only parameter, and returns an array with three elements: dirname, basename, and extension. Dirname contains the name of the directory the file is in (e.g. "c:\windows" or "/var/www/public_html"), basename contains the base filename (e.g. index.html, or somefile.txt), and extension contains the file extension if any (e.g. "html" or "txt"). Here is an example of pathinfo() in action: $fileinfo = pathinfo($filename); var_dump($fileinfo); If $filename were set to '/home/paul/sandbox/php/foo.txt', that script would output the following: array(3) { ["dirname"]=> string(22) "/home/paul/sandbox/php" ["basename"]=> string(7) "foo.txt" ["extension"]=> string(3) "txt" } 6

If all you want to do is get the filename part of a path, you can use the basename() function. This takes a path as its first parameter, and, optionally, an extension as its second parameter. The return value from the function is the name of the file without the directory information. If the filename has the same extension as the one you specified in parameter two, the extension is taken off also. For example: $filename = basename("/home/paul/somefile.txt"); $filename = basename("/home/paul/somefile.txt", ".php"); $filename = basename("/home/paul/somefile.txt", ".txt"); The first line sets $filename to "somefile.txt", the second also sets it to "somefile.txt" because the filename does not have the extension.php, and the last line sets it to "somefile". 7

A working example: making a counter Counter scripts really are quite simple once you get down to it - you store a value representing the number of times a page has been visited, and show it to your visitors somewhere on the page. Naturally, given the current topic is file manipulation, we are going to store that variable inside a file. To open, read from, write to, and close files, we will be using some new functions - fopen, fread, fwrite, and fclose respectively - the f, of course, stands for "file". Here is an example counter script, making use of the new functions: // your content here... $filename = '/path/to/counter.txt'; // our counter file $fp = fopen( $filename,"r"); // open it for READING ("r") $counter = fread($fp, filesize($filename) ); // read in value fclose( $fp ); // close it whilst we work ++$counter; // increase the counter by one print "$counter hits to this page"; // print out the new value $fp = fopen( $filename,"w"); // open it for WRITING ("w") fwrite( $fp, $counter); // write in the new value fclose( $fp ); // close it Edit the $filename variable to point to a file you have created somewhere (make sure the PHP user ID is able to read from it and write to it), then save the above script as counter.php and run it in your web browser. At first you should see "1 hits to this page", but each time you refresh, the value should go up and up - you can reset the value by deleting the contents of the file (not the file itself). Let's break down the script, line by line. First we create a $filename variable to hold the name of the counter file. Following that, we use fopen() for the first time, specifying its first two parameters: our $filename variable, and the mode of 8

opening. The name of the file is simple enough, but the _mode_ parameter requires a little explanation - you need to specify whether you wish to read from the file, write to the file, or append to the file, and there are various modes to allow you to do so. In the example above, we use the "r" mode for reading, then the "w" mode for writing. You are able to combine the two together to make "rw", which would open a file and let you read _and_ write to it. Fopen() returns a file handle if it successfully opened the file in the mode you requested, otherwise it returns false. Our file handle is used immediately, in our fread() line. fread() takes a file handle as its first parameter, and the number of bytes to read from that file handle as its second parameter. Of course, the number of bytes to read is just what we wanted, because that is just what filesize() returns! So, in counter.php, we fread()filesize() bytes from $filename and place them into $counter. By using filesize() as the second parameter, we read the entire file into our variable - just the ticket for a counter. We use fclose() to close the file pointer. This allows other processes access to the file while we aren't using it, and it is generally best practice to keep files open for as short a time as you are able - it is very easy for something to go wrong and corrupt a file you left dangling open. Note: Even though PHP automatically cleans up for you when your script finishes (objects are deleted, MySQL connections are closed, files are fclose()d, and so on), I strongly recommend against leaving things lying around for PHP to clean up - do your own housekeeping now, and it will help you later on. With our file pointer closed, we are back onto easy PHP code - we take the 9

contents of $counter and increment it by one. Here is a great example of PHP's lack of strongly-typed variables - fread() returns a string, and yet we can increment that string as if it were an integer. After incrementing $counter, we print it out to the screen using print. Next we update our counter file, which is done in three stages, again starting with fopen(), but this time we are using the "W" mode to enable writing. We follow that up with a call to fwrite() passing in our file handle as the first parameter, and the information to write as the second parameter. Finally, we close our file handle using fclose(), and our counter script is complete. Now you just need to replace "// your content here..." with a witty and popular web site, and you will be a smash hit! 10

Handling file uploads bool move_uploaded_file ( string filename, string destination) It might be that you want visitors to upload pictures for a member biography page, enclose attachments to forum messages, or just share files on a public download area - the ability to handle file uploads can be a great addition to web sites. The basis for file uploads lies in a special variety of HTML input element, "file", which brings up a file selection dialog in most browsers that allows your visitor to select a file for uploading. You can include this element in a HTML form just like you would any other element - web browsers render it as a text box and a "select" (or "browse") button. When your form is submitted, it will automatically send with it the file. Here is an example HTML form (save it as upload1.php) that allows users to select a file for uploading to your server. Note that we specify "enctype" in our form in order that our file be transmitted properly, and that the action property of the form is set to point to upload2.php, which we will look at in a moment. <form enctype="multipart/form-data" method="post" action="upload2.php"> Send this file: <input name="userfile" type="file" /><br /> <input type="submit" value="send File" /> </form> You can see our new input file element in action - note that we give it the name "userfile". Now, here is the accompanying PHP script, upload2.php, which prints out a little information about the file just uploaded from upload1.php: print "Received {$_FILES['userfile']['name']} - its size is 11

{$_FILES['userfile']['size']}"; PHP pre-sets variables for you with regards to the file just uploaded using a superglobal variable, $_FILES, to hold them. Each file uploaded is placed into the $_FILES superglobal array in the form of another array made up of information about the file itself - so we have an array within an array (a multidimensional array). If we had two files - fileone and filetwo - rather than just 'userfile', PHP would put two arrays into $_FILES, each containing the name, size, and other information about fileone and filetwo respectively. As you can see above, PHP sets 'name' and 'size' to let you read the original filename given by the user, and the size of the file sent. It also sets 'tmp_name' to give you the name the file has on your server (might be something like /tmp/tmp000), and also 'type', which gives you the MIME type of the uploaded file (e.g. image/png) if it was provided by the uploading browser. Give your uploading script a try in your web browser - see if you can modify the script yourself to check whether your browser sends a MIME type or not. If you find files over a certain size aren't being uploaded properly, you may find you need to increase a setting in your php.ini file, "upload_max_filesize". Now that we are able to upload a file and read out information about, let's try something more useful - how to put the uploaded file in a place you choose. PHP makes this particularly easy through the move_uploaded_file() function. move_uploaded_file() takes two filenames as its parameters, and returns false if the file you tried to move was either not sent by HTTP upload (perhaps your user was trying to fool your script into touching /etc/passwd) or if it couldn't be moved (perhaps due to permissions problems). 12

The first parameter should be the name of the uploaded file you wish to work with. This corresponds to $_FILES['userfile']['tmp_name'] if you are using 'userfile' as the form element in your upload HTML page. The second parameter is the name of the filename you want the uploaded file to be moved to. If all goes well, PHP returns true, and the file will be where you expect it. Let's take a look at the whole operation in action: if (move_uploaded_file($_files['userfile']['tmp_name'], "/place /for/file")) { print "Received {$_FILES['userfile']['name']} - its size is {$_FILES['userfile']['size']}"; } else { print "Upload failed!"; } Note that you will need to edit /place/for/file to somewhere PHP has permission to copy files. As you can see, handling file uploads with PHP really couldn't be easier - a call to move_uploaded_file() checks security and does the copying work all for you. 13

Advanced file upload handling To make our upload system a little more advanced, let's take a look at adding a little more security to the system by checking the kind of file just uploaded. It would be great if we could rely on the 'type' information of uploaded files to tell us whether a file is to be accepted or not, but many browsers do not send MIME types with uploaded files. Instead, here is a simple bit of code that checks the extension of an uploaded file - you should recognise explode() already. $tmp = explode ( '.', $_FILES['userfile']['name']); $fileext = $tmp[count($tmp)-1]; In line one, we split the name of the uploaded file into an array. As we specified a full stop (.) as the first parameter to explode, our array will normally be split into two elements - file name (e.g. 'mysql'), and file extension (e.g. 'rpm'). If our filename was 'php-5.0.0.tar.gz', our array would contain elements 'php-5', '0', '0', 'tar', 'gz'. count() is a new function that merely returns the number of elements in an array, and by subtracting one from it (remember PHP uses zero-based arrays), we find ourselves reading the last element in the array. With php-5.0.0.tar.gz, this would return "gz". With mysql.rpm, this would return "rpm". Now we can read the extension of the file that was uploaded, let's compare it to a list of extensions we trust. $allowedexts = array("rpm", "gz", "tar", "bz2"); if (in_array($fileext, $allowedexts)) { print "File is trusted."; } else { print "File not trusted!"; } 14

In the above code, we create an array of trusted file extensions, then, using in_array(), we compare our $fileext variable (which contains everything after the final full stop in the name of our uploaded text file) to the array of allowed extensions. Naturally, merely checking file extensions does not guarantee security, but every little helps. 15

Checking uploaded files bool is_uploaded_file ( string filename) The move_uploaded_file() function is basically the same as the rename() function with the difference that it only succeeds if the file was just uploaded by the PHP script - this adds extra security to your script, by stopping people trying to move secure data, such as password files, into a public directory. If you want to perform this check yourself, use the is_uploaded_file() function - it takes a filename as its sole parameter, and returns true if the file was uploaded by the script and false if not. Here is a simple example: if (is_uploaded_file($somefile)) { copy($somefile, "/var/www/userfiles/$somefile"); } If you just want to check whether a file was uploaded before you move it, move_uploaded_file() is better. 16

Locking files with flock() bool flock ( resource handle, int operation [, int &wouldblock]) The key problem with file system operations is the precarious situation you are in if two scripts attempt to write to a file at the same time. The fopen() function, when called on a file, does not stop that same file from being opened by another script, which means you might find one script reading from a file as another is writing, or, worse, two scripts writing to the same file simultaneously. The solution to this problem is to use file locking, which is implemented in PHP using the flock() function. When you lock a file, you have the option of marking it a read-only lock, thereby sharing access to the file with other processes, or an exclusive lock, allowing you to make changes to the file. On Unix, flock() is advisory, meaning that the OS is free to ignore it. On Windows, flock() is mandatory, meaning that files are locked by the OS whether you ask for it or not! The flock() function takes a file handle as its first parameter, and a lock operation as its second parameter. File handles you know already, and the operations are simple: LOCK_SH requests a shared lock, LOCK_EX requests an exclusive lock, and LOCK_UN releases a lock. Calling flock() will return true if the file lock was retrieved successfully, or false if it failed. So, for example, flock() could be used like this: $fp = fopen( $filename,"w"); // open it for WRITING ("w") if (flock($fp, LOCK_EX)) { // do your file writes here flock($fp, LOCK_UN); // unlock the file } else { // flock() returned false, no lock obtained print "Could not lock $filename!\n"; } 17

File locking requires a fairly modern file system, such as NTFS (Windows), ext3/ext4 (Linux) and HFS+ (Mac). Furthermore, the Network File System (NFS), commonly used to provide file sharing across Unix boxes, is not suitable for use with flock(). The file locking mechanism in PHP automatically makes processes queue up for their locks by default. For example, save this next script as flock.php: $fp = fopen("foo.txt", "w"); if (flock($fp, LOCK_EX)) { print "Got lock!\n"; sleep(10); flock($fp, LOCK_UN); } That script attempts to lock the file foo.txt, so you will need to create that file. The script locks it with LOCK_EX, which means no other program can lock that file. Once the lock is obtained, the script sleeps for ten seconds, then unlocks the file and quits. If a lock cannot be obtained because another application has a lock, the script waits at the flock() call for the lock to be released, then locks it itself and continues. To test this out, open up two command prompts and run the script twice. The first script run will get a lock immediately and print "Got lock!", then sleep for ten seconds. If while the first script is sleeping you launch the second script, it will wait ("block") on the flock() call and wait for the first script to finish. When the first script finishes, the second script will succeed in getting its lock, print out "Got lock!" then sleep for ten more seconds until it finally terminates. Sometimes it is not desirable to have your scripts wait for a file to become 18

unlocked, and in this situation you can add an extra option to the second parameter using the bitwise OR operator,. If you pass in LOCK_NB ORed with your normal second parameter, PHP will not block when it requests a file lock. This means that if the file lock is not available, flock() will return immediately with false rather than hang around waiting for a lock to become available. Here is how that looks in code: $fp = fopen("foo.txt", "w"); if (flock($fp, LOCK_EX LOCK_NB)) { echo "Got lock!\n"; sleep(10); flock($fp, LOCK_UN); } else { print "Could not get lock!\n"; } This time, the first script will get the lock and print "Got lock!", whereas the second will fail to get the lock, return immediately, and print "Could not get lock!" 19