Enter your Sign on user name and password.

Forgot password?
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

  • Study Guides

  • Download Lecture Slides

  • Table of Contents

  • Transcription

  • Related Services

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!

More Magic Methods

  • In PHP, any methods starting with ‘__’ are known as magic methods.
  • Magic methods have special functionality in the PHP language and are called automatically by PHP.
  • Object methods should not be given the same name as any PHP magic methods.
  • A destructor is an object method called automatically by PHP when an object is no longer being used or it has been unset (or set to NULL). They are used to ‘clean-up’ the state of an object before its destruction, such as closing any open file resources.
  • In PHP, destructors are magic methods and have the name __destruct().
  • __toString() is a magic method that is automatically called by PHP anytime an object variable is used in a string context. By defining this method, you can explicitly set how objects should be represented in string form.
  • In PHP, object properties and methods have a visibility associated with them that describes where they can be accessed from.
  • An object property or method can have one of three visibility values, known as access modifiers:
    • public – accessible inside OR outside class definition
    • private – accessible inside class definition ONLY
    • protected – accessible inside class definition OR by inherited classes (not covered in this course)
  • __get() is a magic method that is used to access inaccessible, or private, properties from code outside of a class’s definition.
  • __set() is a magic method that is used to set inaccessible, or private, properties from code outside of a class’s definition.
  • An alternative means of getting/setting private object properties is to create public getter and setter methods that provide the ability to get and set an object’s private properties. For example:
    • Getter for a 'lastName' property: public function getLastName() {...
    • Setter for a 'lastName' property: public function setLastName($lastName) {...
  • Additional Resources:

More Magic Methods

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
  • Lesson Overview 0:13
    • Lesson Overview
  • Magic Methods 1:12
    • Magic Methods
  • Destructors 2:45
    • Destructors Overview
    • Coding Example: Calling Destructors
    • Coding Example: Object Destructor
  • _to String () 16:12
    • _to String () Overview
    • Coding Example: _to String () Magic Method
  • Access Modifiers 21:23
    • Introduction to Access Modifiers
    • Access Modifiers: Public
    • Access Modifiers: Private
    • Access Modifiers: Protected
    • Object Properties and Methods
    • Coding Example: Public Access Modifiers
    • Coding Example: Private Access Modifiers
  • _get() 31:37
    • _get() Overview
    • Coding Example: _get () Magic Method
  • _set () 36:23
    • _set () & the Magic Method
  • Using Getters & Setters 44:37
    • Coding Example: Using Getters & Setters
  • Homework Challenge 50:33
    • Homework Challenge: 1 - 6
  • Homework Challenge (cont.) 51:41
    • Homework Challenge: 7 - 12

Transcription: More Magic Methods

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

In today's lesson, we are going to be discussing the topic of magic methods again--0005

which, as we learned in our constructors lesson, is a special type of method in PHP.0009

We are going to be specifically getting into a few more details about what magic methods actually are in PHP.0015

We have used them before (when we talked about a constructor, that is a magic method in PHP).0021

But now, we are going to provide a more formal definition of that.0025

We are going to talk about what are known as destructors, which, in PHP, is a special magic method.0028

Then, we are going to talk about three different magic methods in PHP: __toString, __get, and __set.0035

And then, we are also going to talk about the concept of access modifiers, which relates to declaring, for example, all of our properties and functions.0046

So far, I have the public keyword listed before them.0055

We are going to talk a little bit more about why that is, and how we are going to change that.0058

And then, we are going to finish up talking about using getters and setters in general (which are ways to get and set properties of a particular object).0062

In PHP, any method that starts with this (which is a double underscore) is known as a magic method.0073

And any time you create an object or a class file, you shouldn't create any methods that begin with an underscore,0081

because PHP reserves the right to, in the future, use those as magic methods.0089

In particular, for example, we know that __construct is a magic method; so, you wouldn't want to define your own construct method0094

in a PHP class, unless you were actually planning on using it as a constructor,0105

because otherwise, PHP is going to treat it as a constructor, and it is not going to be something you could run on your own.0109

Magic methods are special in that they are automatically called by PHP.0118

For example, we know that a constructor...whenever we use a new statement (for example, new Item) and pass it some data,0123

this construct method is implicitly, automatically called by PHP.0135

And that is why you don't want to name methods construct--because then, for example, if we had an Item object,0140

you wouldn't really be able to call that construct method.0149

And there are a number of different magic methods that are available to objects in PHP.0155

And we are going to be talking about a number of those different ones that are available in today's lesson.0160

First of all, I want to talk about the concept of a destructor.0167

It is the analog to a constructor: a constructor is called automatically when a new instance of an object is created.0170

On the other hand, when an instance of an object is destroyed (which means that it is no longer being used),0178

you can have a method, that is called a destructor, that is called.0187

And what that does is: it is used to clean up any object state before the object is destroyed.0189

For example, maybe you have some open files that were used by a particular object.0196

By having this destructor method that always gets called--and it is something that, if you define it,0202

always gets called, automatically, by PHP, then you can ensure that all of your files will always be closed,0206

which is a good practice so that you don't have file locking issues and stuff like that.0212

That is just one particular example; but it allows you to run any code that you would like to run every time an object is destroyed, before its lifetime ends.0216

And it is automatically called any time an object is no longer being used--0229

for example, when the script ends, or if an object is explicitly set to not be used0233

(which means you call the unset method, or you explicitly set it to null--that is telling PHP you don't need that object anymore).0241

When that occurs, the destructor is automatically called.0247

In PHP, destructors are magic methods, and they have a name similar to construct, except it's __destruct.0250

And it is within this method that you can define any operations that are code that you would like to occur whenever an object gets destructed by PHP.0259

For example, let's take a look at...we have a class here called DataFile that we are going to be building up during this lecture.0272

What DataFile is: it is a class that is going to encapsulate all of the things that we do for a file.0281

For example, we use fopen, fclose, and fwrite to open, write, and close a particular file.0286

Well, what we are going to do is wrap that functionality into this object called DataFile.0294

And what we are going to do, for example, is: for each DataFile object, we are going to give it a file name and an access mode.0298

And then, what you can do is: after you create this DataFile object, you can run an open function on it, which we are going to see.0304

Then, you can run a write operation on it, and a close operation on it.0312

And those open and close operations are calling, underneath the surface0316

contained within the object's code, these fopen, fgets, fclose methods, and so forth.0322

That is what our DataFile class is going to be used for--to represent access to a data file.0329

In this first version, we are just going to give it one public property called fileName.0337

And as you can see here, we have our constructor function, which is a magic method.0343

that takes one parameter, and it just sets the value of our fileName property.0350

We also have an echo statement here; and this is going to be used to show how PHP is working behind the scenes.0355

It just says, "OK, we are in the DataFile constructor."0359

And then, here is a new magic method, the destruct method.0363

And it just simply outputs a message that says that we are in the destructor.0368

We are going to be improving on this, so that this destructor method will close any open files that we may have open.0373

But for now, we are just going to output a message, so you can see at what point during a particular script the destructor gets called.0379

For example, we include our DataFile class in this particular script called destructor.php.0387

We output a message that says "before the object is created"; then we call the constructor, which is implicitly going to call the construct method.0393

So, we should see that output message from our construct method we defined.0403

Then, we output a message stating that this is the last statement in the script, and then the script ends.0408

And then, what we will notice is that another statement gets output.0413

It is the statement that is saying we are in the destructor, because when the script ends, the lifetime of this DataFile object0418

that we have created in the script is no more, and it is going to be destroyed.0424

And so, PHP automatically calls the destruct method.0428

So, if we run this particular version of destructor.php, we can see that we have a statement "this is before the object is created."0431

The next thing that happens is that you are inside the constructor.0442

Then, you can see that we execute the last statement in the script.0445

And yet, even though we have executed the last statement in the script, we have another piece of output.0449

And it says "inside the DataFile destructor," so that shows you that, when that script ends, if any objects still haven't been destroyed yet,0454

the destructors still get called; and so code is actually running, even though we are not in the script anymore.0461

An alternative version to that is: here we have the same DataFile class in this new version, but what we are going to do is:0468

instead, we are going to say to output the message that says "this is before the object is created."0476

We are going to call its constructor, and then we are going to explicitly destroy the object by setting it equal to null--0482

which, as we mentioned on the slide, is essentially going to call that destruct method, because the object exists no more.0489

What is going to happen is: because the destructor gets called here, that message that says you are in the destructor0497

is going to get output before we get to this last output statement within our script.0501

So, the other of those last few statements is going to change.0507

If we go over here to version 2 of this, now we can see the output before the object is created;0511

we are inside the constructor; we are inside the destructor; and then, we execute the last statement in the script.0519

And the reason that "in DataFile destructor" doesn't occur afterwards, as well, is because the object has already been destroyed.0525

It has already had its destruct method called, and it was called when we set it equal to null.0531

So here, in this case, when the last statement of the script ends, the script actually ends, in that particular case--and no destructors get called.0535

What we are going to do now is have an updated version (it looks like...here it is...); this is version 3.0 of our DataFile class.0560

I am going to show you how I have updated it, because we are going to be using it throughout the rest of the lecture.0570

I have added a couple more properties to it.0574

I have added an accessMode property, which says you can set the access mode0577

for which you want to open this particular file--this DataFile object it is going to represent.0582

There is a variable called fileHandle, which is going to hold a reference to the open file that this DataFile class represents.0587

And we are going to use that in the different methods within this class definition,0600

to open the file, close the file, write to it, and so forth.0605

Here, in the constructor (you can see that the constructor has been updated), it takes two parameters:0610

one to set the file name of the file that this is going to represent, and then also the access mode we are going to want to open it in.0615

And then, we initialize the file handle, initially, to null.0621

Then, if you will look down here, we can see that we have an open method.0626

It is an object method that you can call after you create an instance of the object.0630

And what it does is just opens the file that we have specified, using the access mode we have specified,0635

and then sets the object property fileHandle equal to the file handle that that returns.0641

Then, we have created another object method called appendLine, which is going to allow us to append a line to the data file this object represents.0647

And it uses the fwrite method.0657

And what we make use of is the file handle that we have created up here in the open class.0658

And then, it just writes whatever string we pass to appendLine to this file handle.0664

Finally, there is a close method; and the first thing it does is outputs an echo statement that says we are in close.0670

And you can see why we are doing that in a second: it is mainly for educational purposes.0676

It wouldn't be something we would normally do.0680

And then, you can see: we just use the fclose method within this objects close method.0682

And it closes the open file that is pointed to by this fileHandle object property.0687

And then, we go ahead and set the fileHandle object property equal to null; and there is a reason for that.0695

What we have is: our destructor has changed a little bit--we have a message that shows we are in the destructor.0703

But what it does is: we use the destructor to close the file that this DataFile object represents if it has not been closed yet.0710

What it does is checks to see if the fileHandle is not equal to null.0723

And if it is not equal to null, it goes ahead and runs this objects close method (which, as we saw, is down here).0727

And as we can see now, the close method, again--the last thing that it does is sets the fileHandle to null.0735

When the destructor is called, and it runs this test "Is fileHandle not equal to null?" that is its way of knowing whether the file has already been closed.0741

If it has already been closed, it doesn't do anything; if it hasn't been closed, it goes ahead and closes this method.0749

And this is our way of cleaning up this DataFile object, to make sure that the open file that it has, has been properly closed.0754

And let me open up...it looks like I accidentally closed one of the files.0765

If we look at destructor.php, this new version, we are including our DataFile class that we just talked about.0775

We are creating a path to a temporary file; in this case, it is just going to be a file called temp.txt in the current directory.0784

And then, we are going to create a new DataFile object using that DataFile constructor we just talked about,0791

which takes the file name that we want to open, and then the method that we are going to use to open it in--0796

which, in this case...the access mode is going to be overwrite mode.0804

Then, we call the open method, which is going to call that fopen function that is going to open the file and set the object variable fileHandle.0808

We are going to append a line to it; in this case, we are just simply going to append a date/time stamp with a new line.0817

And then, we are going to call the close method on it to close that data file.0824

And then, our script is going to end.0830

In this particular order...when we run the script, we can see a couple of things.0831

We can see...if you remember, we had an output statement in our close method that says we are in the close method.0840

And we had an output statement in our destructor method that says we are in the destructor method.0846

In this case, you can see that "in close" has been output first; and that is because, in our file,0849

close was explicitly called; so that output statement that is in close gets executed.0858

And then, the file ends; the script ends down here.0864

And when the file ends, the destructor automatically gets called.0867

And when the destructor gets called, it is going to output that statement that it has in it that says "inside DataFile constructor."0870

And that is why that statement is output last.0876

Now, let's say that instead, in our main script, we didn't call the close function.0880

So, let's say somebody had written a script, and they didn't know how to use our DataFile object appropriately,0889

and so they opened it; they appended a line to it; but they didn't call the close.0896

Well, what is going to happen is: when the script ends, the destructor is going to get called for this class.0900

And because close hasn't occurred yet, our destructor is going to get run.0906

And it knows to close the file that has not been opened yet.0910

So, what you are going to see is that the destructor is going to get called.0914

You are going to see that you are in the destructor method.0916

And then, when we look at our destructor method, we can see that it also calls the close method.0920

Then, you are going to see this output statement that shows that the close method is being run.0928

These statements that we last saw are going to be reversed: where before we saw that0932

we had the close method, and then we were in the destructor method,0935

now it is going to be reversed, because close was never called; the destructor gets called;0939

and then, the destructor, because the file is still open, calls the close method.0943

So, when we do that and refresh our page, we can see that they are reversed.0947

We are in the destructor, and the destructor, because the file is still open, is going to call the close method.0953

And so, that is a common example of how to use an object destructor to make sure0959

that any cleanup work that you need to get done before an object is destroyed actually gets done.0964

Another magic method that all objects can create is called __toString.0974

And what that does is: that is called any time you reference an object in a string context.0980

For example, let's say you create a new variable, a, and you set it equal to an Item.0986

You set it equal to an instance of an Item object.0996

Well, any time you were to use that object variable in a string context (for example, here within an echo statement),1001

this __toString method is going to get called automatically, if it exists.1015

And if it exists, it allows you to say how you want to output the particular object as a string.1018

For example, for an Item, we might have it output, as its string, the name of the item.1024

Whenever you would run echo name...let's say we had an Item class that is different from our web application.1032

It just takes one parameter that is the name of the item.1043

So now, when you would go to echo a (you are saying, "I want to echo this Item object"),1047

the __toString method is going to get automatically called by PHP, and that is because it is a magic method.1052

And then, what would actually get output would be the string 'Basketball,' which would be the name of the object--1057

assuming our __toString method returns the name of the item as the string that it wants to represent the object as.1063

What you can do in this __toString method is represent an object in whatever string form you want to represent it as.1073

Let me close these files.1085

In this example we have...it is called toString.php, and it is basically the same as our last script example,1092

except that we are not calling any open or write operations or close operations on the particular object.1101

We are just creating a new DataFile object, having it represent a file called tmp.txt.1108

And then, what we are going to do is use the object within a string context.1118

We are going to just include the variable that holds the object instance of DataFile.1124

And when we put it in double quotes, PHP is going to know to call a __toString method on that object, assuming one exists.1131

Well, we have actually updated our DataFile class to include a __toString method.1138

And because we defined this method, we can describe how we want our DataFile object to be represented as a string.1153

In this case, our string that we are going to return is simply the name of the file,1161

followed by a colon, and then followed by the access mode, within single quotation marks.1166

Any time you include a DataFile object within a string context in an echo statement within another string,1171

the __toString is going to be automatically or implicitly called by PHP.1184

And it is going to output the name of the file, followed by a colon, followed by the access mode.1187

If we go and look at this in action, and we run the __toString script, we can see that our DataFile object is a string.1192

When it is output as a string (and we can see here that we include it during these HTML pre tags, so here we have included1203

our df, which is our object that represents a DataFile) it is going to call the __toString method.1212

And as you can see, what it does is outputs the name of the file that that object represents, followed by a colon, followed by the w.1218

We can do whatever we want within that __toString method to output a DataFile class.1227

For example, maybe we just want to include the file name.1233

So, if we change this, now any time we reference df, or any time we use a DataFile object within a string context, it is only going to output the file name.1240

And here, you can see, the w is gone.1254

And again, you can do whatever you want within this method; we could simply even (if we wanted to) just say DataFile Object.1255

Now, when we run this, it is just going to simply output the string DataFile Object every time we try to use DataFile object within a string.1267

That is how the __toString method works.1280

Now, one thing I want to talk about is something known as access modifiers.1285

What that refers to is: all object properties and methods have what is known as a visibility associated with them,1288

which describes where they can be accessed from.1297

For example, all of our properties we have declared so far in all of our classes have been declared public.1300

They have public visibility; they use the public access modifier.1308

If we look at our DataFile classes, we can see that we have used this public keyword here before all of our properties.1311

Now, what that does is says that anybody outside that class has access to that property--they can get or set that property.1323

You can also access it inside the class, using the $this variable.1332

Now, on the other hand, you could declare something as private.1339

And that means that it is only accessible within the class definition file.1342

So, you can only access it using $this within any methods within the class definition file.1346

If you try to access it, for example, in your script--if you try to access a private method, you are going to get an error from PHP.1354

There is one other access modifier, called protected, which we are not going to go over,1362

which says that any property that is listed as protected is accessible inside the class definition1366

(which means inside any of the methods within the class), or by inherited classes.1372

And we are not going to be going over inheriteds in this course, so it doesn't really apply.1376

So, we are just going to be talking about public and private access modifiers in this course.1380

The reason that you declare something as private is to facilitate an object-oriented method called data encapsulation.1388

What it does is: if you declare all of the properties of a particular object private,1397

that means that any code outside of that object can't go ahead and directly change those.1402

And so, one of the foundations of object-oriented programming is that the object should be able1407

to control and know everything about its state (all of its values), and make sure that it is kept in a consistent state.1413

That is why, in our constructor, for example, we initialize all of the object's properties in the constructor--1420

so that our object is in a known state.1429

Now, all of our objects we have used so far have had a public access modifier, which means that code outside the object could run it.1431

For example, we had talked, in our last web application, about the items array that is part of our Department object.1440

In our constructor for our Department object, we explicitly set that equal to an empty array1456

so that any time it is attempted to be accessed, it is accessed as an array, and it will be treated as an array.1463

That is how we want our class to function.1470

However, because items is declared public at the beginning of the file, anybody outside the class,1472

if they have a reference to this Department class (for example, maybe they have a Department object called department),1482

could go ahead and set items equal to the empty string, or any other string.1488

So now, our object is in an inconsistent state.1497

It has this items property that is supposed to be an array, but now it can be set to a string.1500

Our object methods that might count on the fact that that items property is an array might not work.1509

So, the way we handle this is by keeping all of the data in a particular class private.1517

And then, that way, any time you need to set (for example) pieces of data,1525

you either have to do it through a constructor (which is going to allow you to make sure that only valid values get set),1529

or through what are known as setter methods, or any other object methods that you describe.1533

Any time you want to touch the state (which is basically the values of the properties of an object),1538

you have to go through an object's methods; and that allows you to keep control over that data within that class.1544

One other thing is that methods can also be declared public or private.1552

And they have the same functionality that we described up here for object properties.1555

If an object method is public, it can be used outside of the class.1559

For example, on our Department class, we have a public method called addItem.1563

We pass it an item ID; that is a public method.1572

However, you can also declare a method as private, which means that it can only be used within the class.1577

So, if we declare a method as private--for example, if we declared addItem as private,1582

when we tried to call this outside of the class definition, we would get an error.1586

If a method is private, the only way it can be called is by using the $this special variable, and then calling the function.1592

This applies for methods, as well.1603

Let's take a look at what a public version of our class looks like.1609

In this place, it is exactly the file that we had before.1617

We have all of our properties declared as public, all of our methods...1619

in this case, we have the three non-magic methods close, appendLine, and open--they are all declared as public.1626

And then, what we are going to do is create in our script a new instance of this data file.1631

And then, we are going to show that we can go ahead and set our object property values,1636

using the regular accessor syntax, because those properties are declared public.1643

If they were private, we wouldn't be able to do this.1649

We are going to set the file name to change it from what was set in the constructor to index.html.1651

We are going to set the access mode to r.1659

And then, down here, what we are going to do is access these values.1662

Because these properties are public, you can use the regular accessor syntax in order to access those values from outside the class.1665

So, here we are going to access the file name in access mode, and we are going to output that.1675

When we run our script, we should get no problems, and we should be able to set those values and then output them.1678

And here, as you can see, we were obviously able to set them, because when we output them,1688

they were output to the new values that we had specified, index.html and r,1692

which is opposed to what they were initially set to, which was w and tmpFile.1696

So, as you can see, when properties are public, you have the ability to get and set them outside of a class.1700

Now, as an alternative to that, we have a private version of our DataFile class,1711

where we have declared all of our object properties with the access modifier private,1718

which means they can only be accessed from within the class.1724

And for example, you can see down here that they are able to be accessed using the $this variable,1731

because that is within a function within the class.1737

And the reason for that is because they are accessible within the class definition; you can access it with any of the class methods.1741

However, if we try to do the same thing that we did before--we declare a new DataFile object (and this is this new version1747

of the DataFile with the private properties), and then we try to set those private properties--1754

for example, we try to set the file name to index.html--and we try to run this new file called private.php,1759

what we can see is that we get an error: "Fatal error: Cannot access private property DataFile::$filename."1769

That shows how you are not able to set private properties using this regular accessor syntax.1775

And that is because they were declared private.1781

Let's get rid of these, and now, down here, we are going to try to output or to get the values of these private properties.1783

We are going to try to get the filename property; we are going to try1793

to get the accessMode property--or the values of those properties--and then output them, just as we had done before.1795

Now, because they are private, we should not be able to do this.1802

So, when we run our script, we are going to get a new message that says "Fatal error: Cannot access private property DataFile::$filename."1803

And it is saying on line 38...so if we go back and look at line 38, we can see here--1814

this is where we tried to access this private object property from outside the class.1819

That shows how you cannot get private properties from outside the class, as well.1825

Now, the other thing that we have done is declared this open function...1832

Just temporarily, for illustrative purposes, we have declared this private, which means it is only accessible within the class definition.1838

For example, you can only access it within other object methods.1845

For example, right here--this would work OK.1852

Let's save it back to its original state.1863

So now, this is declared private.1865

Down here, when we try to call this private method, we are going to get an error, because it is going to say,1867

"You can't call that method; it is a private method, only accessible within the class."1871

When we refresh this page, "Fatal error: Call to private method DataFile::$open."1875

So again, this illustrates how that private access modifier on object properties and on object methods1883

affects your ability to access the properties and call those methods from outside a particular class.1891

So, now that we have created these properties as private, and we have said that you should keep your object properties private--1899

you want to protect them and make sure that they stay in an appropriate state--1907

well, sometimes you are going to need to access those properties.1913

You are going to need, for example, to...in this particular case, maybe we want to get the name of the particular file.1915

Well, PHP provides another magic method called __get.1921

And what that does is allows you to access these private properties.1926

And what it does is: any time...for example, let's say we have been using our new DataFile class that has the filename property declared as private.1932

And we want to set it outside...1956

Actually, we are using __get...we want to echo it.1958

When we tried to do this before, we got an error that says the filename is a private property.1969

However, if we define this magic method __get, any time PHP encounters you trying to access a private object property,1974

it is going to invoke this __get method that you can define, and it is going to allow you the ability1985

to provide access to those private property values, if you want.1989

And so, it gives you access to these private properties.1996

And this is the only way to access those private properties, assuming that you don't have any other public methods1999

that allow you to access those properties, which we are going to see a little bit more of in a future slide.2005

For example, if we look at our new version of DataFile.php, we have declared this magic method __get.2011

And here, we output a statement that says that we are inside this __get method.2020

That is going to let us know when PHP is invoking this method, because what we are going to see in our code2026

is that we never actually call this method, __get, with some value.2030

It is done automatically by PHP; and that is how magic methods work.2040

This is going to let us know when __get is being called.2043

What our __get method does is takes the name of a property as its parameter.2047

And then, it allows you, because this function has access to private properties...it can use the $this variable2051

to access whatever property we want, that we pass into this __get magic method.2059

What happens is: any time you try to access a private property, for example, here--like the dash, greater than, filename,2067

essentially, what PHP is doing is calling our __get method that we defined.2083

And we are passing it the value filename; that is essentially what is happening behind the scenes.2093

In our __get method that we have defined, which takes one parameter, which is the name of a property we want to get,2098

what it does is takes that name, and then it just returns the value of that.2105

So, this is going to allow us to have access to private properties.2110

For example, in this get.php script, it is going to show that this is the same script that we had before, where we are trying to access private properties.2114

But they are going to work now, because we have defined this __get method that allows us to access inaccessible or private properties of an object.2123

So now, when we run this script (which is now called get.php), we can see a couple of things.2131

First of all, we can see that we are in this __get magic method, which is interesting, because we never actually call that __get method.2139

And again, PHP automatically calls that any time you try to access a private variable using this accessor syntax,2149

and that variable is private, and you have defined that __get method.2160

So again, this is a magic method, so it gets called automatically.2164

So, we can see that we are in the __get method twice: we are in it once when we try to get the filename2167

(and now we are able to get the filename that we have set for this particular object),2171

and then, we are also able to get the access mode.2176

So, this __get magic method allows us access to private properties.2178

Well, there is an analog to this called __set, which is another magic method that works in the same way,2184

except it allows you to set the values of private properties which are considered inaccessible.2190

Normally, when we had our old version of the script (let's take a look at it...let's go to version 5),2199

when we tried to set private properties before, it works when they are public, but it doesn't work when they are private.2227

Well, this set method is going to allow us to change that.2237

What you do is define this __set method that is going to work the same way as...2240

Any time you try to set a method using the accessor syntax, for example (just .txt is the name of the file)--any time we try to do this,2244

if filename is private, any time PHP sees this accessor syntax going on, because it is a private variable,2265

it is going to go ahead and invoke this __set magic method.2272

The __set magic method, by definition, has two parameters that it takes.2277

One is name, and one is value; and you can set them to whatever name you want, but that is essentially what they represent.2283

And what it does is: name is the name of the property that you want to set.2291

So, in this case, when we try to access this up here, what we are going to be doing is calling $df-->__set.2297

We are going to be passing it filename, which is the name of the property we are going to set.2312

And then here, this is the value we are trying to set it to, so it also takes a value parameter.2317

This is essentially how this __set magic method works.2326

It takes the name of the object property you want to set and the value, and then it allows you to go ahead and set them.2332

And it allows you to define the way you want to do that.2338

And also, one thing to mention is that it will allow you, for example, to maybe perform some error checking.2341

Maybe you don't want to let a file called .txt be set for this particular file.2347

So, within your __set method, you can say, "If the value equals .txt, don't do it."2353

So, this allows you to have the control, again, over access to these private properties.2359

For example, if we go look at our new DataFile class, we still have all of our private object properties.2367

We have our __get magic method, and we have our __set magic method.2379

And again, it takes two values: the name of the property we want to set, and the value.2383

And in this case, any time this method is called (and it is going to get called automatically by PHP), we are saying,2387

"Whatever the name of the property is that we implicitly pass to this __set magic method,2395

we are going to set the value of this object's property that has that name to the value that we passed in."2402

So, as we saw in our example, in this case, __set would set the filename.2408

When we call this up here, and we try to run this code up here, we are going to be calling the __set method2416

with filename as the property name, and then .txt as the value we are trying to set it to.2424

One other thing to note is that we have also included a statement here that shows when we actually are in the __set method.2433

And that is, again, to show how PHP implicitly calls it.2438

If we look at our file set.php, we declare a new DataFile instance.2441

We set it equal to a temporary file named tmp.txt, and we give it a w access modifier.2447

Now, we are going to try and set these private object properties (the filename and the access mode--in this case, to index.html and r).2453

What is going to happen is: because we have declared this __set magic method, we are going to be able to do that now.2461

It is going to provide us the ability to set those private properties.2469

When we go to run this new version, we are going to see two things.2472

It is going to say, "OK, it is in __set, and it is setting" and it says what property it is setting.2479

Here, it is going to be setting the filename; here, it is going to be setting the access mode.2485

Because these __set methods don't return anything, we are not outputting what it gets set to.2489

We are just saying that, when we are in this method, it is going to output and say, "This is the name of the value that we are trying to set."2493

So, in this particular case, it is going to set it equal to index.html and r.2507

And then, if we wanted to, we could echo these--let's just echo the filename, for example.2512

Because we have our __get magic method defined, we should be able to see that it outputs the new value that we set the filename object property to.2519

And we were able to do that because we had defined this __set method.2535

Now, one thing to note is that the __set method allows you to dynamically add properties to an object instance,2540

which often is undesirable--and in most cases, is.2549

For example, because we have this __set method, we could go ahead and add another property to our DataFile class.2553

Let's create an object property called fake, and I'll set it equal to fakeValue.2566

Now, because this __set method works, the other thing that these __get and __set magic methods do is:2575

not only does it allow access to private properties, but if you try to set a property that doesn't exist,2584

or get a property that doesn't exist, it also is going to call that __get or __set method,2592

and provide it, in this case, the name of the property you are trying to set, and then also, the value.2596

In this case, down here, if we echo fake, this is going to try to return the value of the property fake.2602

And it is going to allow that, because when we look at our code...for example, when we call __set first,2613

we are going to be able to say...2619

What this is going to do is create this new property fake and set it equal to the value we set it to.2622

And then, this is going to allow us, because we have set it, to access that value.2627

For example, if we try to create this new object property, fake, and then we try to output it,2632

and we run our file again, we can see that we are setting that fake variable to that setter method that is called.2645

And then, we are also able to access that object property.2651

So, in a sense, we have added a property to our object, and that is something that you are typically not going to want to do.2655

This __set method is going to be used in certain more advanced circumstances.2661

But I did want to show that to you, because you will see that used in code that is out there--2666

for example, in frameworks and different projects on the Web.2674

The alternative to using these __get and __set magic methods is to create your own public getter and setter methods.2680

And they are also ways to provide access to private properties.2688

For example, we can define a new data file class with private properties.2691

But now, for each property, we are going to define getters and setters.2699

We are going to define a public function (which means it is accessible to everybody) that says, "get filename."2702

And when it is called on this particular object, it is going to return the value of this private variable filename.2707

And the reason it can do that is because, within this function, you have access to the values of these private variables.2713

So, this way, we have provided a way to get the value of the private filename variable.2718

We provided a way to get the accessMode variable.2723

And as you can see, we create a separate method for each one.2726

That is one way to do it, and it is something you might see out there.2729

And typically, the nomenclature used for doing that is: you call the method get, starting with a lowercase g,2733

followed by the name of the variable you are trying to get.2742

And it uses upper CamelCase notation: so here, for example, Filename is capitalized; here, AccessMode--the first letters of each are capitalized.2745

Similarly, you can define set functions that typically are called set, followed by the name of the property you are trying to set.2754

And they take the value you want to set it to, and then within the function, all they do is:2760

they access that private variable and set it to the value you passed in.2764

As you can see, in this script, there is no __get or __set method.2769

So, theoretically, we shouldn't automatically be able to access those variables.2775

And in fact, in this new file gettersSetters.php, here we are just creating our DataFile, as we had been in our other scripts.2779

Let's say that we try to access filename.2790

Now, this is something that has been declared private.2798

And when we try to use this, PHP is going to look for that __get magic method.2800

If it doesn't find it, it is not going to allow you to access this; if it does find it, it will allow you to output that private property, if you want.2806

We haven't defined it in this class; so when we call this now, and try to run this new script, we can see that it can't access private property.2812

Let's go ahead and get rid of this line.2822

And then, what you can see down here is: we have made use of these getters and setters that we have created; they are these new methods.2824

So, instead of using the accessor syntax (dash, greater than, and then the name of the property),2831

we are using these public functions that we created in order to set these private variables.2840

We are going to set the filename to index.html and the access mode equal to r (which is different from the values that were set in the constructor).2844

And then, we are going to use these getters we defined--these public methods--to access those private variables, filename and accessMode.2851

So, when we go to output them, we should see that filename had been set to index.html (and therefore, it will get output),2859

and accessMode had been set to r, so it is going to get output.2865

So now, when we refresh our file, we can see that, in fact, that is what happens.2868

filename has been set to index.html, and accessMode has been set to r.2872

So, what you can see is that these setter methods that we have defined allow us to set private properties.2877

And then, these getters that we have defined allow us to get access to private properties, as well,2885

without using the __get and __set magic methods that you can provide, that PHP will call automatically for you.2890

Typically, you might use a combination of __get, __set, and any public setters and getters you define2903

to provide the ability to get access to an object's properties.2911

The way we are typically going to do in this course is: we are going to be using the __get method to provide access to private properties.2915

And instead of providing this __set method (because that allows you to add properties to an object,2922

which is not really typically a desired feature), for any private properties we want to be able to set,2927

we are going to define some public setter methods.2935

And so, that is what we are going to use in this course; and that is to set any private properties.2937

And I just want to mention that, in general, it is good practice to allow other code2943

to only be able to get and set private properties when it is necessary.2948

You don't want them to be able...for example, let's say you have a class with 10 different properties.2954

You could provide a setter method called setX, with X being the name of the property, that would take a value for all 10 of your properties.2963

But unless you really need the other code to be able to do that, you don't want to do that.2973

And again, that is that idea of data encapsulation, of protection--that you want to be able to have control over your data.2979

So, you don't really want people getting, or particularly setting, the data if they don't need to be.2986

And then also, you don't want them to be able to get the data as often,2993

because typically, with object-oriented programming, you want the object to be able to provide any functions it needs.2997

For example, when you call a get method on a function, you are basically saying, "Give me a property, and I am going to do something with it."3006

Well, one of the methodologies behind object-oriented programming is that the object should be able to do any functionality associated with it.3011

So, if you are getting that filename (for example) to do something with it, maybe you should define a method3019

within your DataFile object (for example) that does whatever operation this other code may be trying to do.3024

For the homework challenge, I want you to create a Person class that has two private properties: firstName and lastName.3034

And then, provide a constructor that accepts no arguments, but it initializes both of these properties to the empty string.3043

Then, provide a destructor that simply just outputs a message that says, "Hey, I am in the destructor."3049

Provide a __toString method, which is a magic method that, when you use a Person object in a string context,3054

is just going to output the firstName and the lastName properties of the Person, separated by a space.3063

So, it is basically going to output their full name.3070

Create a __get magic method that allows you to access the private firstName and lastName properties of the Person class.3073

And then, provide a public setter method; so, instead of providing a __set method to be able to set both of these private properties,3084

provide public setter methods for each one (for example, one of them would be called setFirstName for the firstName property).3092

Then, create a script that instantiates a Person object.3103

Use these public setter methods that we just described to set the Person's firstName and lastName properties.3108

And then, using the accessor syntax, go ahead and output the value of both of those properties (the firstName and lastName) that you had set.3116

That is going to show you, first of all, how to use public setter methods.3123

Then, when you try to access it, it is going to show you that that setter method actually worked, assuming it had been implemented correctly.3128

And then, what this is going to show you is that, when you use this accessor syntax on private properties,3136

PHP is automatically going to call that __get method that we defined, that allows you to get access to those properties.3142

Then, I just want you to output the Person object as a string by just including it in double quotes--echo and then double quotes with the object.3148

And what that is going to do is convert it to a string, which means PHP is going to implicitly call that __toString method.3156

So, that full name should be output.3161

Then, what I want you to do is unset the Person object, using the unset construct in PHP, where you just provide it...3163

for example, it is a DataFile object called df, you just provide it the name of the variable.3173

What that is going to do is unset the variable and set it to null.3177

It is going to destroy the variable; that is going to implicitly call the destructor.3179

And that will allow you to see that destructor message.3184

Just verify that you are able to output the first and last name properties that you set, using the public setter methods, as you expect,3187

that the __toString method will actually output the person's full name,3196

and after you call this unset method, that the destructor actually gets called.3200

And you can see that by the message you have in your destructor being output on the screen.3205

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