Sign In | Subscribe
Start learning today, and be successful in your academic & professional career. Start Today!
Loading video...
This is a quick preview of the lesson. For full access, please Log In or Sign up.
For more information, please see full course syllabus of Advanced PHP
  • Discussion

  • Download Lecture Slides

  • Table of Contents

  • Transcription

  • Related Services

Bookmark and Share

Start Learning Now

Our free lessons will get you started (Adobe Flash® required).
Get immediate access to our entire library.

Sign up for Educator.com

Membership Overview

  • Unlimited access to our entire library of courses.
  • Search and jump to exactly what you want to learn.
  • *Ask questions and get answers from the community and our teachers!
  • Practice questions with step-by-step solutions.
  • Download lesson files for programming and software training practice.
  • Track your course viewing progress.
  • Download lecture slides for taking notes.
  • Learn at your own pace... anytime, anywhere!

Web Application Development

Lecture Slides are screen-captured images of important points in the lecture. Students can download and print out these lecture slide images to do practice problems as well as take notes while watching the lecture.

  • Intro 0:00
  • Version 8.0 Review 0:12
    • Version 8.0 Review
  • private Object Properties 1:15
    • private Object Properties
    • Coding Example
  • _toString() Methods 6:51
    • _toString() Methods
    • Coding Example
  • DataFile Class 13:27
    • DataFile Class & I/O Operations
    • Using DataFile Class: Instantiate a DataFile, DataFile open () Method, and DataFile close () Method
  • Homework Challenge 29:35
    • Homework Challenge

Transcription: Web Application Development

Hello again, and welcome back to Educator.com's Advanced PHP with MySQL course.0000

In today's lesson, we are going to be continuing development of our web application, 0005

incorporating what we learned in our last lesson about some new magic methods.0008

One of the things that we will do before we get into the magic methods is that we have made0014

all of our object properties and all of the classes in our web application private.0018

For our Customer, our Item, and our Department classes, we have made all of the variables that they have private.0023

Because they are private, and we need access to those variables, we are going to be defining the __get magic method for those classes,0030

as well as a couple of public setters to be able to set some of those private variables.0041

In addition, we have added the to_string method to our Item and Department classes0046

(which, as we learned about, is a method of--when you use an object variable within a string context, 0051

it is your way of deciding how you want the object to look represented as a string).0056

Then, we are also going to create a new class called DataFile, which is similar to the one we used in our last lecture,0062

which is going to encapsulate all of our file input/output operations.0069

So again, all of the properties for our Customer, Item, and Department classes were made private.0077

And because we need to access these different properties, for example, when we are outputting information about an item on Item.php,0083

we need to be able to have access to them, so we have added the magic method __get to each of these.0093

And what we have done in that __get method is provided access to those properties.0099

For example, it just returns the value of whatever property you are trying to access by this name parameter, which we will see in a second.0104

And then also, to our Item class, we have added two public setter methods 0121

for the item ID and image file extension private properties, so that they can be set from outside the class.0125

And here, we are not using the __set method--again, because that allows the creation of additional object properties that we don't want.0133

And we are only providing setter methods for item ID and image file extension, 0145

because we only want to provide access for users to be able to set these particular properties.0149

We don't need them to be able to set description, price, and name, because those are set in the constructor,0155

and that falls under the category of data encapsulation, which we have talked a little bit about,0161

which the object-oriented concept of having the object control all of the information about its data, as much as possible.0166

If we look at our new classes (let's blow this up a little bit)--for example, our Customer class--0175

one thing we notice, first, is that in our documentation here, we can see a list of all of the variables for our Customer class.0187

And it describes each of them, and says that firstName represents the first name of the customer; its access is public.0196

Well, in our new version, we don't have those variables; and that is because they have been declared as private.0202

Because they are private...this documentation is meant for people that are going to be using your class.0207

Because they don't have access to those variables directly, it doesn't list them on here.0214

So, that is one thing to notice.0218

Then also, what you can see is...actually, let's look at the source code of the file.0221

You can see that we have declared each of the object properties as private.0228

And then, we have created our __get magic method; and all it does is returns the value of whatever private property we are trying to get.0235

Now, we have also done the same thing for Department, which, as you can see, 0246

no longer lists the department variables, because they are no longer public; they are all private.0250

And we have the same __get magic method that just returns the value of the private property which allows access to it.0257

And item does the same thing, so we have essentially replicated this in three different spots.0264

And we have done so for each class; and that is to make all of the variables private, and then also to provide getters to access them.0271

Now, in addition, for our Item class--for example, on our addItem page in our admin website--0278

when we initially create an Item object to insert into the database, we don't know its item ID, and we don't know its image file extension yet.0285

For example, when we call the constructor, we don't have values for item ID and image file extension, so we set them equal to null.0292

So, we need ways to be able to set these now-private properties after the object is created.0299

So, we have created two public setter methods, setImageFileExt and setItemID.0305

And if we go and look at these, it simply takes the value that we want to set 0313

for the image file extension, and then sets the private property equal to that value.0316

And the same thing for the setItemID: it takes an item ID as its parameter, and then sets the private itemID object property to that value.0322

If we go and look at our insertItem function, an insertItem function is what is called 0335

from our addItem.php page in our admin site, that is used to create a new item.0347

And we pass it an item object, but it is an incomplete item object.0352

The item ID is missing, and the image file extension is missing.0356

Here you can see that what we do is: we use this new public setter method that we have defined 0359

to set the item ID to the one that we get from our lastAdded file.0366

Here is an example of using that new setter method for the same thing.0374

We get our image file extension from the name of the image that was uploaded, 0379

and then we can set that new item that we have created, using this new setter method that we have, setImageFileExt.0383

And this is opposed to in our last version of this, where we just explicitly accessed the properties, using this accessor,0391

because they were public properties, so we could just directly set image file extension and item ID.0399

Now that these properties are not public (they are private) we can't do that anymore.0404

The other thing that we have done is implemented the __toString magic method for our Item and Department classes.0412

What we have done is: previously, we have had functions createDeptDataString and createItemDataString.0421

And those, we have been using to take an Item object, take a Department object, 0429

and combine them into a delimited string that we store in our items.txt file and our departments.txt file.0433

These functions have been stand-alone functions in our file library of functions that we have had.0440

Well, now it kind of, in a way, makes sense to move them into the object methods.0447

For example, because a Department object knows all of the information about an object,0454

why not have a method in it that is able to create a string that represents that?0459

Well, to be able to do that, and to illustrate the use of the __toString method, we are going to implement the __toString method for both those classes.0463

And it is going to perform the same functionality that these two createDataString methods provided.0473

We are eliminating those from fileLIB.php, and then we are creating __toString methods in our Item and Department classes.0478

For example, if we look at our older version, we had createDeptDataString.0490

And what that would do is: we would simply pass it a department object.0496

And then, it would go through and build up this string that we store in departments.txt, which is delimited by vertical pipes.0499

And then, the items in the department are separated by commas.0508

That just builds up this Department string, the same way our Item data string builds up a string that represents the item.0514

And again, we pass it an Item object.0522

We are passing it an Item object to create a string from that Item object; 0525

why not include that in the Item object already, as a defined method?--because that Item object 0529

already has access to all the information that we are already passing in.0536

We are going to make use of the __toString method, in this case.0539

If we look at our new Item class, for example, you can see we have a __toString method.0543

And let's just look at the source code.0551

And in our __toString method, you can see, it pretty much does the same exact thing as we had in our other version,0558

except that, whereas in createItemDataString, because we passed it a variable that is an Item object,0565

we use that variable name to access the different property values of that object;0573

well, now we have defined __toString within the object class; so this is within our Item class definition.0581

Now, to access these properties, we use the $this variable to access them, because if you notice,0594

we don't have a variable to pass in, because we don't need to pass it an item variable, because via this $this variable,0599

this object method will have access to the properties in the class.0606

Here, we perform the same functionality, except we use it as a __toString method.0610

The same thing happens in our Department class: we have a __toString method, and it performs the same functionality 0616

as in our createDeptDataString method, except it is now using the $this variable 0622

(as opposed to the departments variable) in order to access these different properties.0629

And of course, because these are private properties--private properties are accessible within class methods.0635

And so, we can use the $this variable to access them.0646

If we take a look at how some of these are used--if we look at insertItem in the new version,0650

we can see that one of the things that we do is: when we insert a new item into our database,0666

we create that item data string and insert it into the items file.0674

In our last version, the way we did that was (this is within the insertItem method): we would open the items data file,0678

and then we would call this createItemDataString method, append a new line to it, and then write it to the file.0690

Well, now what we are doing: because we already have this __toString magic method built into our class now,0696

now we can simply create an item string that just includes the variable that represents the Item object within double quotes,0702

which means it is going to be used in a string context, which means that __toString method is going to be automatically called by PHP.0711

So, that __toString method that we have now defined that creates that item data string is going to be generated.0717

We append a new line to it, and then we add it to our file.0722

And we are going to talk in a minute about the new method we are using for doing that.0725

Similarly, in our updateDept method, when we update a department, we add lines to the Department file,0730

or update lines in the Department file, with new items added to a particular department.0738

And let's go to the previous version: the way we previously did that was: we would call createDeptDataString,0746

pass it an object, append a new line to it...and then, we would loop over all of the lines we had extracted from the file 0755

and add these department data strings back to the file.0765

Well, in our new version, we don't need to do that anymore.0771

Let's see, where is...0776

And what we can do instead is: now, instead of calling createDeptDataString, 0781

we just enclose the variable that represents our Department object within double quotes and append a new line to it.0786

And now, that is going to implicitly (again) call the __toString method that we created for the department.0795

It is going to create that department data string, and then we are going to be able to go ahead and add it to our particular file.0799

Probably one of the biggest things that we did in this new version of the web application is created a new class called DataFile.0808

And its purpose was to encapsulate all of the file operations that we have been doing,0815

because in all of our different methods that we have had...and we introduced this concept a little in our lecture on magic methods,0822

where we introduced the DataFile class during the lecture.0829

If we look at, for example, our last version of the web application: we have all of these functions within our file library,0834

most of which access a file; they open a file up; they read from it; the open a file up; they write to it; they close the file; and so forth.0841

So, there are a lot of similar operations going on here.0852

We even have three separate functions: for example, openDeptsDataFile, openItemsDataFile, openLastAddedFile.0854

And all of these different functions (let's look at the source code) essentially perform the same thing.0862

If we look at the code for openDeptsDataFile, and we look at the code for openItemsDataFile, the code looks almost exactly the same.0880

So, our rule is: if we have code that we are reusing over and over--the same code--why not put it in one spot and be able to reuse it?0889

By putting this code in a single class, we can take advantage of reusing that code.0898

That is going to eliminate making mistakes, because now, let's say, any time we want to change how this operation works,0906

we have to change it...for example, in this case, we might have to change it in three different spots,0912

because we have three different methods that are used to open files.0915

Now, we can put this open method within our new DataFile class.0918

And any time we want to change how we open a file, we can just do it in that one spot.0925

So, what we are essentially going to be doing is: for every file that we are going to be accessing or opening,0930

we are going to be creating a DataFile object that is going to represent access to that particular file.0934

In our new version, we are going to be getting rid of all three of these openDeptsDataFile methods.0940

And what that is going to do is: for example, one of the things that we do is: they all use the fopen method.0947

They all also output an error message and return false, for example, if there is an error opening the file.0954

Now, we can put that same functionality into one place, so we don't have to replicate this in multiple spots.0961

The other thing is: for example, if we go to our old getItem function, we have our openItemsDataFile,0971

which we just discussed as our way of opening a file.0978

Then, we manually loop over all of the lines in the file, looking for...0981

Actually, let's look at the itemsExist one; that might be a better example.0986

We manually loop over all of the items in the file, using this feof method and fgets method to try and find a particular item in a file.0989

Well, for example, if we look at the deptExists file, we are going to see that it looks very similar.0998

What we are going to do is put this file access, this feof call and this fgets call, all into this DataFile class that we are going to create.1007

And we are going to create a method, for example, called nextLine, that is going to allow us to read the next line from a particular file.1016

So again, this is taking code that we have used in multiple spots, and we are going to put it in one class.1023

Let's go and take a look at this new class that we have created, DataFile.1029

First, it has three different private properties: one is accessMode, one is fileHandle, and one is filename.1040

accessMode and filename are the name of the file that this object is going to represent, 1047

because this object is going to allow us to perform operations on a file.1052

filename is going to be what file it is going to be performing the operations on.1055

accessMode is going to be how we are going to be opening that file.1059

Are we going to open it in append mode? Are we going to open it in overwrite mode? Are we just going to open it for reading?1062

And we can set both of these; our constructor is going to take both filename and accessMode, so we can set them.1068

And then, we also have a fileHandle property, which is used internally within the class.1075

It is not accessible outside of this DataFile class.1080

And so, what it is going to do is: for example, the way you use a DataFile object (let's go to the slide for this)1086

that we have created is: you instantiate the object; you provide it with a filename and an accessMode;1097

then you call the open method that is provided by this class.1102

You perform some operations on it--such as, for example, getting the next line.1108

We will also see that there is an appendLine method that we have created.1111

And then, when you are done, you call the close method that is provided.1114

If we go and look, for example, we can see that there is a close function that is provided, which closes the connection to a file.1118

Let's see...there is an open method that allows you to open a file.1131

That encapsulates all of that code that we saw before for opening a particular file.1136

And then, we have other methods, such as...here we have a method appendLine, which is going to allow us to append a line to a file.1141

We have a function getLine, which is going to allow us to read the next line from a file,1150

and then a function getLines, which is going to allow us to pull an array containing all of the lines in the particular file.1155

We have this private fileHandle that gets created by our open method.1166

If we look down at the open method, we can hopefully see (I don't know why I called it and it's not working on this one)1171

that we have an fopen method that gets called within this open function.1180

And what it does is: it sets a private fileHandle object property equal to the fileHandle generated by fopen.1184

And fopen is just going to be called on the file name that we have set for our particular file that this object represents.1192

And we are going to open it in the access mode specified.1201

And again, both of those were able to be specified in our constructor.1204

Our constructor takes the filename and the accessMode and does a little bit of error checking.1208

It tests to make sure that the filename is a valid filename, and if so, it sets filename equal to that.1213

Otherwise, it sets it equal to null.1221

It checks to make sure that accessMode isn't empty, and it goes ahead and sets it equal to the empty string if it is empty; 1223

otherwise, it sets it equal to the value passed in.1231

And then, as part of our always initializing all of our object variables in our constructor, we initialize the fileHandle equal to null.1233

And that is because, when the user calls the open method, that is going to allow them the ability to set that private fileHandle variable.1240

And that is going to be created by the fopen method.1248

Let's take a look at this class in action.1254

If we look at our getItem function, for example...1257

And this DataFile class is used in all of our functions within our file library that have access to a file.1262

And we don't have time to go over all of the examples of it.1270

They are documented in the change log for this web application.1272

But we are going to go over a couple of the different examples, so you can see how this new DataFile class is used.1276

For example, in our getItem class, where we are trying to load information about a particular Item 1281

from our items text file, based on an Item's ID; the first thing we do is create a new DataFile object.1286

The name of the file is going to be the name of this constant ITEMS_DATA_FILE, 1295

which is something that we set in our config file, which ends up being a path to items.txt.1300

We are going to open it; we are going to set that this file, when it gets opened, will be opened in read mode.1306

Then, what we do is perform the public method open on this file.1312

And open returns true or false, based on whether or not the function is able to successfully open a connection 1317

to the file specified by the filename parameter of the DataFile constructor.1324

And so, what this is also going to do is: as we had said, the open method is going to set that fileHandle object property of our DataFile class.1331

So now, when we run other operations on this DataFile class, they will be able to access that file.1340

For example, the thing that we do in this particular function is: we loop over each of the lines in the file,1347

reading a line and extracting information to see if it matches the item ID that we are looking for.1353

So here, after we have opened the file, and now we have a valid file handle, 1360

we are going to be calling this nextLine function that we have created in our DataFile class.1365

Let's open this up in another window.1374

And if we look at our nextLine class, what it does is says, "If it is at the end of the file, return false; there are no more lines to read."1380

If it is not, it says to go ahead and get the next line of the file.1388

It uses the fgets method, and it operates on this private variable fileHandle that was set by the open method.1392

And it accesses it by the $this variable, because it is a private method.1400

And any time you access an object property within an object method, you use the $this variable.1405

What we do here is: we loop over while this still returns the line, because what is going to happen is:1416

nextLine is going to return false when it reaches the end of the file.1422

Then, it is going to kick out of the loop.1424

While it is still returning the next line, we are going to perform the same functionality as it does before.1425

We are going to be pulling out the first data field from a particular line, checking to see if it is the same item ID we are looking for.1430

If it is, then we are going to be building up an item object using our buildItemObject function.1437

And then, that is what eventually gets returned.1442

Down here, we finish our operations by calling this close method on the itemsDataFile on our DataFile object.1444

And if we look at the close method, we can see that what it does is calls fclose on the fileHandle that we have that is open,1453

assuming that the fileHandle has not already been set equal to null.1462

One of the things that we do is: when we close the fileHandle for this particular object 1466

(that is a property of this particular object), we also set it equal to null.1473

And that is also for use in our destructor, which we created in this class, which we are going to talk about in a second.1478

And we talked a little bit about that in the last lecture.1482

The close method just checks to see if the fileHandle is already null.1485

If it is, it just returns true, because the file is closed.1488

Otherwise, it goes ahead and closes the file, and then it will output an error, for example, if there is an error in closing the particular file.1491

That is how using this new DataFile class works.1500

You instantiate an instance of it with a file name and an access mode.1505

You call the open method on it to open a connection to the file that you specified in the constructor.1509

You run operations on it; for example, in this case we are performing a read operation, which is readNextLine.1516

And then, you call the close method on it.1522

Another method that this class provides is called getLines, which returns an indexed array1525

where each value in that indexed array is a line of the particular file.1536

For example, we use this with our getDepartments file; we read all the lines from the departments file.1542

To use this in our getDepartments function, we create a new file that says it is going to represent the departments data file.1548

When we eventually open it, we are going to open it in read mode.1559

We open the file, and then we call this getLines method on it.1561

And it is going to pull an array of all the lines in that data file, represented by this departments.txt file, and put it in this lines variable.1565

And then, this function still performs the same operations as it did before.1575

It goes through and builds a Department object for each data line that it gets from that file.1579

And down here, you can see we finished the operation with the close method.1590

The one other method that we provide in this class is the appendLine method.1594

What it does is: it takes a string that we pass to it, and it appends it to the file that this DataFile object represents.1607

One thing it does is tests to see if the line...because it is appending a line, lines have new line characters at the end;1617

and it tests to see that the line that you have passed in, when you call this method, has a new line.1622

If it doesn't have a new line, it adds one to it.1627

And then, after it does that, it goes ahead and calls the fwrite method, 1629

which operates on the private fileHandle object property, and then just writes that line to the file.1633

And then, it returns true or false of whether that was successful or not.1641

We use this in our insertItem function when we insert a line in our items.txt file.1644

Here, in our insertItem function, we can see that we created a new DataFile object.1653

We set the items data file to open in append mode; we opened the file; and then, we use this appendLine method to append the new line to the file.1659

And then, we call our itemsDataFile close method to finish the process.1671

That is how that DataFile class that we have had works.1676

It takes all of these common operations that we have had spread out through different parts of the code,1679

and encapsulates them in a single class, so that we can reuse it in multiple spots.1685

Now, one other thing to note is that our DataFile class--we have actually added a destructor to it--1691

the __destruct method, which is a magic method in PHP, as we learned.1697

And we use our __destruct method to make sure that, when this object is no longer being used, it closes any open files.1702

Let's say, for example, what we had said--that the typical procedure for using a DataFile object is that you instantiate it;1708

you call the open method; you perform some operations on it (like appendLine); and then you call close.1715

Well, let's say that somebody that is using our object doesn't call this close method.1720

Well, when this script ends, or when that itemsDataFile variable gets set to null, the destructor is going to be called.1724

And the destructor--what it is going to do is test to see if the file has already been closed.1730

And it does that by testing to see if the file handle is null.1736

And if it isn't null, then it goes ahead and runs its own object method, close, which as we saw,1739

calls fclose on the file and then sets the fileHandle equal to null, which is how the destructor knows if a file has already been closed or not.1747

Our destructor just makes sure that the file was closed, so that we don't have a file left open.1757

And so, that is an example of using a destructor; and it is similar to what we used in our last lecture.1766

For today's homework challenge, I would really like you to just study the DataFile class, as it is somewhat of a complex class.1777

We are really starting to get more into our object-oriented programming.1784

We have constructors and destructors; we have magic methods; we are using private object properties.1787

So, this DataFile class incorporates a lot of that different stuff.1799

So, make sure you can understand the class and how it works, and specifically understand how it is being used within our fileLIB functions,1802

because a lot of functions within that fileLIB (and again, they are spelled out in the change log)1812

are going to make use of this DataFile object, because they are performing a lot of file operations.1821

So, this is going to be used in multiple spots.1825

And then also, just be sure to make sure you understand how the destructor works,1827

and how that ensures that when a DataFile object is destroyed, that it makes sure that any files it had open were closed beforehand,1833

which is important; you always want to close your file resources.1842

And so, that is a way of keeping things clean, to make sure that if your user didn't explicitly call (for example) the close method1848

on a DataFile object, that it will go ahead and still be closed anyway.1861

That ends today's lesson; thank you for watching Educator.com--I look forward to seeing you next time.1868