PHP Variable Storage & Object Comparison - Zend Value (zval) - Full PHP 8 Tutorial

Program With Gio
18 May 202111:20

Summary

TLDRThis video script explores object comparison in PHP, explaining the use of double and triple equal signs for equality checks. It clarifies that the double equals checks for property value equality within the same class, while triple equals verifies if two variables reference the same object instance. The script also delves into PHP's memory management, explaining how variables and objects are stored, and the implications of variable assignment on object references. It concludes with a discussion on recursive comparisons and the potential for circular references to cause errors, providing a comprehensive guide for PHP developers.

Takeaways

  • 🔍 PHP uses the double equal sign (==) for a loose comparison of object properties, which can result in unexpected outcomes due to type juggling.
  • 🔑 The triple equal sign (===) in PHP is used for a strict identity check, ensuring both the object and its properties are identical.
  • 📚 PHP's comparison operators check if objects are instances of the same class and have the same property values for the double equal sign, but only if they are the exact same instance for the triple equal sign.
  • 🔄 When assigning one object to another, PHP copies the reference, not the object itself, which means changes to one object's properties will reflect in the other.
  • 💡 PHP stores variable names in a symbols table, separate from their values, which are stored in a zval container.
  • 📦 For objects, the zval container holds an object identifier pointing to the actual object stored elsewhere in memory.
  • 🔄 Assigning an object to another variable creates a new variable pointing to the same zval container, which in turn points to the same object in memory.
  • 🔄 Changing a property of an object affects all variables pointing to that object, demonstrating PHP's pass-by-value behavior for objects.
  • 🔄 Extending a class does not affect object identity; an object of a subclass is not considered equal to an object of the parent class for identity checks.
  • 🔍 Recursive property comparison in PHP can lead to issues like fatal errors when dealing with circular references.
  • 📝 PHP allows the use of greater or less than signs to compare objects, which stops at the first property that fails the check.

Q & A

  • How does PHP determine if two objects are equal using the double equal sign (==)?

    -In PHP, the double equal sign (==) checks for equality by comparing if the two objects are instances of the same class and have the same property values. It performs a loose comparison, which can result in unexpected outcomes when types do not match strictly.

  • What does the triple equal sign (===) operator do when comparing two objects in PHP?

    -The triple equal sign (===) is the identity operator in PHP. It checks if two objects are not only equal in value but also refer to the exact same instance in memory.

  • Why would a comparison using the double equal sign (==) fail even if two objects have the same property values?

    -A comparison using the double equal sign (==) can fail if the objects are not of the same class instance, even if their property values are identical.

  • What is the difference between an object comparison using the double equal sign and the triple equal sign in PHP?

    -The double equal sign checks for value equality and type compatibility, while the triple equal sign checks for both value equality and identity, ensuring the two variables point to the exact same object in memory.

  • How does PHP handle type casting during a loose comparison with the double equal sign?

    -PHP performs type juggling during a loose comparison, attempting to match different data types. For example, it might consider the integer 1 and the boolean true to be equal.

  • What happens when you assign one object to another in PHP, like assigning invoice1 to invoice3?

    -When you assign one object to another in PHP, you are not duplicating the object; instead, you are creating a new reference that points to the same object in memory. Changes to the object through either reference will be reflected in all references.

  • Can you explain the concept of 'copy on write' in the context of PHP objects?

    -Copy on write is a technique where a copy of an object is only created when it is modified. In PHP, when you assign an object to another variable, you are not creating a copy of the object; you are copying the reference to the same object. Modifications will affect all references to that object.

  • What is a 'zval' in PHP, and how does it relate to object storage?

    -A 'zval' is a data structure in PHP used to store information about a variable, including its type and value. For objects, the zval contains an object identifier that points to the actual object stored in a separate data structure.

  • Why might recursive comparison of objects in PHP cause fatal errors?

    -Recursive comparison can cause fatal errors if there is a circular reference between objects, leading to an infinite loop during the comparison process.

  • How can you compare objects using greater or less than signs in PHP?

    -In PHP, you can use greater or less than signs to compare objects by their property values. The comparison stops and returns false at the first property that does not match.

  • What is the role of the 'symbols table' in PHP variable storage?

    -The 'symbols table' in PHP is a data structure that stores variable names separately from their values. Each entry in the symbols table points to a zval container, which holds the actual value of the variable, including objects.

Outlines

00:00

🔍 PHP Object Comparison Basics

This paragraph introduces the concept of object comparison in PHP. It explains the use of the double equal sign (==) for a simple comparison, which checks if two objects are instances of the same class and have identical property values. The triple equal sign (===) is used for identity comparison, which only returns true if the two objects are the exact same instance. The script demonstrates this with two 'invoice' objects, showing that different property values result in both comparison operators returning false. It also touches on the concept of loose comparison and type juggling in PHP, which can lead to unexpected results when comparing different data types.

05:01

📚 Deep Dive into PHP Object Identity and References

This section delves deeper into how PHP handles object identity and references. It clarifies that assigning one object to another (e.g., invoice3 = invoice1) does not create a new object but rather a new reference to the same object in memory. This is why both the double and triple equal signs return true when comparing the two variables. The paragraph also discusses the concept of 'zval', a data structure in PHP that stores information about the variable type and value, and how objects are stored within this structure. It further explains the implications of this behavior, such as changing a property of one reference affecting all references to the same object.

10:04

🔄 Understanding Class Hierarchies and Object Comparison

This paragraph explores the impact of class hierarchies on object comparison in PHP. It demonstrates that an object of a subclass (e.g., 'custom invoice' extending 'invoice') is not considered equal to an object of the parent class using either comparison operator, even if they have the same property values. The summary also addresses the recursive nature of object comparison when properties are objects themselves, and how circular references can lead to fatal errors due to infinite recursion during comparison.

Mindmap

Keywords

💡Equality Comparison

Equality comparison in PHP is the process of determining if two variables hold the same value. In the context of the video, this concept is explored through the use of the double equal sign (==) operator, which compares two objects for equality by checking if they are instances of the same class and have the same property values. The script uses the 'invoice' class objects to demonstrate this, showing that two distinct objects with different property values do not pass the equality check.

💡Identity Operator

The identity operator in PHP, represented by the triple equal sign (===), is used to check if two variables refer to the exact same instance of an object. The video script explains that two objects will only be considered equal with this operator if they point to the same memory location, indicating they are the same object. This is contrasted with the 'invoice' class example where two different objects do not pass the identity check.

💡Loose Comparison

Loose comparison in PHP, as demonstrated by the double equal sign, allows for type juggling, where PHP automatically casts different variable types to a common type to perform the comparison. The script illustrates this with an example where an integer and a boolean are compared, and PHP casts the boolean 'true' to an integer '1', resulting in a true comparison result.

💡Type Hinting

Type hinting is a feature in PHP that allows a function or method to require that a parameter must be of a certain type. In the script, it is mentioned that even though 'amount' is type hinted to be a float, without strict types enabled, PHP will perform its own type casting during loose comparisons. This can affect how equality checks are performed.

💡Object Properties

Object properties refer to the variables that are associated with an object. In the video script, the 'invoice' class has two properties: 'amount' and 'description'. The comparison of objects is shown to be dependent on the values of these properties. When the properties of two objects match, the double equal sign comparison returns true, demonstrating the importance of properties in object equality.

💡Object Instances

An object instance in PHP is a specific occurrence of an object created from a class. The script explains that two objects are only considered equal with the identity operator if they are instances of the same class and refer to the same memory location. The creation of 'invoice' and 'custom invoice' objects in the script illustrates how different instances are treated in comparisons.

💡Memory Management

Memory management in PHP involves how variables and objects are stored and manipulated within memory. The script touches on this by explaining that when an object is assigned to another variable, a copy of the pointer is made, not the object itself. This is crucial for understanding how object assignments and comparisons work, as changes to the object through one variable reference will affect all variables pointing to that object.

💡Zval Container

The Zval container is a data structure in PHP that stores information about variables, including their type and value. The script mentions Zval in the context of how PHP stores object identifiers, which are pointers to the actual object data structure. Understanding Zval is key to grasping the underlying mechanics of variable and object storage in PHP.

💡Circular References

Circular references occur when two or more objects reference each other, creating a loop. The script warns about the potential for fatal errors in PHP when performing recursive comparisons on objects with circular references, as it can lead to infinite loops. An example of this is provided with 'invoice' objects referencing each other.

💡Custom Classes

Custom classes in PHP are user-defined classes that can extend or inherit properties and methods from other classes. In the script, 'custom invoice' is a custom class that extends the 'invoice' class. The video uses this to demonstrate how objects of different classes, even if they share the same properties, do not pass equality checks due to their distinct class instances.

Highlights

Exploring object comparisons in PHP using the double equal sign (==) for simple comparison and the triple equal sign (===) for identity.

Double equal sign checks if two objects are instances of the same class with the same property values.

Triple equal sign only returns true if two objects point to the same instance.

Demonstration of how two different objects with different property values result in false comparisons.

Loose comparison with the double equal sign can lead to unexpected results due to type casting.

Changing property values to match results in a true comparison with the double equal sign, despite loose typing.

Assigning one object to another creates a new pointer to the same object, affecting both variables when the object's properties are changed.

Introduction to PHP's memory management and how variables and objects are stored in the symbols table and zval containers.

Explanation of how PHP handles object assignment by copying the zval container, leading to shared object references.

Demonstration of the effects of changing a property in one object that is reflected in another due to shared references.

Comparison of objects from different classes, even if one extends the other, results in false with both comparison operators.

Recursive comparison of nested object properties in PHP can lead to circular references and potential fatal errors.

The impact of circular references in object comparisons and how it can cause PHP to encounter fatal errors.

Mention of the possibility to use greater or less than signs to compare objects based on property values.

Announcement of an upcoming in-depth lesson on PHP's memory management, garbage collection, and how variables and objects are stored.

Invitation for viewers to provide feedback on the teaching style and the inclusion of advanced topics in future lessons.

Transcripts

play00:00

[Music]

play00:05

how can we compare

play00:06

two objects for equality in php let's

play00:09

dive right in and explore how object

play00:11

comparisons work in php i have two

play00:13

objects here of the invoice class

play00:15

where the invoice class just has two

play00:17

properties the amount and the

play00:19

description then in the index.php i'm

play00:21

comparing invoice 1 to

play00:23

invoice2 using the double equal sign

play00:25

also known as the comparison operator

play00:27

and then i'm comparing invoice 1 to

play00:29

invoice 2 using the triple equal sign

play00:31

also known as the identity operator the

play00:33

comparison operator

play00:35

does the simple comparison the two

play00:37

objects will be equal

play00:38

if they are instances of the same class

play00:40

and have the same properties and values

play00:43

in the case of the identity operator

play00:45

though two objects will only be equal if

play00:47

they point or refer

play00:49

to the same instance of the same class

play00:51

so in the current example

play00:53

we have two objects that have different

play00:55

values for the properties and therefore

play00:57

the double equal sign check should fail

play00:59

and then triple equal sign should also

play01:01

fail because these two objects are not

play01:04

the same object they're two different

play01:05

objects

play01:06

so if i run the code sure enough we get

play01:08

false for both comparisons

play01:10

something to note with the double equal

play01:12

sign comparison

play01:13

is that it does the comparison of the

play01:16

property values using the loose

play01:18

comparison

play01:19

what i mean by that is that let's say

play01:21

that instead of 25 we passed in one

play01:23

and instead of 100 we passed in true and

play01:26

we don't have the strict types enabled

play01:28

so even though we are type hinting

play01:30

amount to be float

play01:32

because we don't have the streak types

play01:34

enabled php will still try to figure out

play01:36

the type on its own and do its own

play01:38

casting behind the scenes so essentially

play01:40

what double equal sign

play01:41

does here is that it does this kind of

play01:43

comparison one double

play01:45

equals true and when we compare one to

play01:47

true in this manner

play01:49

this will return true so if i run the

play01:51

code now we're still getting false the

play01:53

reason for that is because

play01:55

the description property here is

play01:57

different let's remove that

play01:58

and now the description also matches and

play02:01

if we run the code again

play02:02

and now it returns true when we compare

play02:04

invoice one to invoice two even though

play02:07

1 and true are not exactly the same so

play02:09

let's change this back to

play02:10

25 and let's also set this to 25 and now

play02:14

we have two different objects but they

play02:16

have the same property values

play02:18

if i run the code same as before we're

play02:21

going to get the

play02:22

true for the first comparison and we're

play02:23

going to get the false for the second

play02:25

comparison

play02:26

so why are we getting false for the

play02:28

second comparison the reason for that

play02:30

is because invoice 1 and invoice 2 are

play02:33

two different objects

play02:34

they're pointing to two different parts

play02:37

in the memory they're not pointing to

play02:38

the same

play02:39

object in the memory let's look at the

play02:41

next example let's say that we have

play02:43

invoice three

play02:44

that equals to invoice one now let's

play02:46

change this comparison to compare

play02:48

invoice 1 with invoice 3 instead of the

play02:51

invoice 2

play02:52

and see what we get so now we're simply

play02:54

comparing invoice 1 object with invoice

play02:56

3. let's clear this out

play02:58

run the code and we're getting true for

play03:00

the both cases that's because

play03:02

invoice 3 is actually the same object as

play03:05

invoice one it simply points to the same

play03:08

objects that invoice one points to in

play03:10

memory invoice one and invoice three

play03:12

variables here

play03:13

are simply pointers that point to some

play03:15

spot in the memory

play03:17

that contains that object and therefore

play03:19

when we assign invoice 1 to invoice 3

play03:21

we're not actually duplicating or

play03:23

copying or cloning this object

play03:25

we're simply creating a copy of a

play03:27

pointer that will point to the same

play03:30

location in the memory that contains

play03:32

that object there are a lot more details

play03:34

about this and i'm going to go over some

play03:36

of those details in this lesson but it

play03:38

is a bit complicated topic itself

play03:40

on how variables references and objects

play03:43

are stored in php behind the scenes

play03:45

so i'm not going to go into a lot of

play03:47

detail in this lesson about it however

play03:49

i'm working on a separate video to

play03:51

explain this in more detail

play03:53

including memory management garbage

play03:55

collection references variables and how

play03:57

they're stored and so on so stay tuned

play03:59

for that video but let me show you and

play04:01

explain in simple terms what happens in

play04:04

php when you create variables

play04:06

like this and then when you assign a

play04:08

variable to another variable

play04:10

like this so when a variable is created

play04:12

in php php will

play04:14

store the actual variable name

play04:15

separately from its value the variable

play04:17

name is stored into something called the

play04:20

symbols table

play04:20

so essentially a variable is just a

play04:22

symbol and every variable

play04:24

has an entry in the symbols table each

play04:26

entry in the symbols table points to

play04:29

some sort of container or data structure

play04:32

that contains the value of the variable

play04:34

so you can think of the variable as just

play04:36

a pointer that points to some sort of

play04:38

data structure

play04:39

this container or the data structure

play04:41

where the value is stored is called a z

play04:44

val which is short for zen value and is

play04:47

a c language structure

play04:48

it stores information about the variable

play04:50

like the type

play04:51

and value and we're not going to go in a

play04:54

lot of detail on this because as i

play04:56

mentioned before we'll cover that in a

play04:57

separate video

play04:58

now the way objects are stored in this

play05:01

zval container

play05:02

is a bit different than the way other

play05:04

simple types like integers are stored

play05:06

values for simple types like integers

play05:09

are stored

play05:10

directly in the xero container but for

play05:12

objects it only stores an

play05:14

object identifier which again is just a

play05:17

pointer to another complex data

play05:19

structure or an object store

play05:21

that contains the actual object now when

play05:23

we assign invoice 1 to invoice 3

play05:26

we are again creating a new variable

play05:28

invoice 3 which gets added to the

play05:30

symbols table

play05:31

and xeval container is simply copied

play05:34

from the invoice 1

play05:35

and invoice 3 will now point to that new

play05:38

zevo container the thing is though both

play05:41

zival containers contain the same

play05:44

object identifier in the value so they

play05:46

indeed point to the same location where

play05:49

the actual object is stored

play05:51

this is why triple equal comparison is

play05:53

passing because it's the same

play05:55

object even though there are different

play05:57

variables as shown

play05:58

in this diagram they still point to the

play06:00

same object we can further prove this

play06:02

and simply var dump both

play06:04

invoice 1 and invoice 3 and run the code

play06:07

and we see that they are indeed the same

play06:09

object

play06:10

in fact if we try to change the property

play06:12

on invoice 3

play06:13

let's say we change the amount to

play06:15

something like 250

play06:17

this would also affect invoice one so if

play06:20

we clear this out and run it again

play06:22

we see that both invoice one and invoice

play06:25

three

play06:25

have the property set to 250. and again

play06:28

this is because

play06:29

as we established in the diagram both

play06:32

invoice one and invoice 3 are

play06:34

pointing to the same object in memory so

play06:36

making changes

play06:37

affects all variables that point to the

play06:39

same object

play06:40

this is why it is sometimes said and

play06:43

believed that objects by default are

play06:45

passed by reference

play06:46

which is actually not true and objects

play06:48

by default are passed returned and

play06:50

assigned

play06:51

by value as to why and how we'll cover

play06:53

that in that separate video which will

play06:56

be more in depth with a lot of details

play06:58

about memory management garbage

play06:59

collection how variables references and

play07:02

objects are stored behind the scenes and

play07:04

so on so don't worry about the zen value

play07:06

container and object location in memory

play07:08

or symbols table or anything like that

play07:10

for now we'll get to that in that

play07:12

separate lesson

play07:13

i just wanted to give you a short

play07:14

overview of what happens behind the

play07:16

scenes

play07:17

and kind of introduce you to the topic

play07:19

that we'll cover in that video alright

play07:20

back to code let's create another class

play07:23

called custom invoice and create an

play07:24

object of that class so instead of

play07:26

having new invoice for the

play07:28

invoice 2 here we'll have new custom

play07:30

invoice

play07:31

and let's create that class and we could

play07:34

simply extend

play07:35

the regular invoice so that way we reuse

play07:38

the same constructor

play07:39

now we know that both invoice and custom

play07:42

invoice have the same property values

play07:44

because we are creating two objects with

play07:46

the same values right let's see what

play07:48

happens when we compare

play07:49

invoice 1 to invoice 2 using double and

play07:52

triple equal signs

play07:53

let's get rid of this let's clear this

play07:56

out

play07:56

run the code and we see that it returns

play07:59

false in both cases and this makes sense

play08:01

right

play08:02

especially after what we saw in the

play08:03

diagram the first check

play08:05

fails because they're not of the same

play08:07

instance invoice 1 is an instance of

play08:09

invoice class

play08:10

and invoice 2 is an instance of custom

play08:12

invoice class even though custom invoice

play08:15

class extends

play08:16

invoice class now in the case of triple

play08:18

equal comparison this also fails because

play08:20

it's not the same object this actually

play08:22

points to the different object

play08:24

and invoice 2 points to the different

play08:26

object and i have a typo here this is

play08:28

supposed to be in voice two we can even

play08:29

further prove that by var dumping both

play08:32

invoice one and invoice two

play08:34

and looking at their ids we see that

play08:36

this is an object number three and this

play08:38

is an object number two

play08:39

note that if your class contains a

play08:41

property that is an object of another

play08:43

class then comparison is done in a

play08:45

recursive manner for example say that

play08:47

invoice class had a property called

play08:50

customer let's say that we were

play08:51

accepting an object

play08:53

of a customer class and we define that

play08:55

property let's create this class

play08:57

also and let's say that this simply has

play09:00

one property

play09:01

called name now in the index.php we can

play09:04

simply

play09:04

create a new object here new customer

play09:07

customer one

play09:08

and let's duplicate that for the invoice

play09:10

too and we don't need to use the custom

play09:12

invoice in this case now when we clear

play09:14

this out

play09:14

and run the code let's scroll it up we

play09:17

see that

play09:17

invoice one compared to invoice two with

play09:19

the double equal sign

play09:20

returns true again but triple equal sign

play09:22

returns false it returns true for the

play09:25

double equal sign because

play09:26

all the property values are same however

play09:28

if the property value

play09:30

of the nested object is different then

play09:32

it will fail

play09:33

so if we change this to customer 2 for

play09:35

example and we clear that out and we run

play09:37

the code

play09:38

we see that now invoice 1 compared with

play09:40

invoice 2 with double equal sign

play09:42

returns false another thing to note

play09:45

about this is that

play09:46

since it does recursive comparison if

play09:48

you have circular relations it can cause

play09:51

fatal errors

play09:52

say that we want to have a property

play09:53

within the invoice class that holds

play09:55

another invoice object to create some

play09:57

sort of linking between invoices so we

play09:59

would have something like

play10:01

public invoice linked invoice and that

play10:04

way we can link invoices to each other

play10:06

we can make this nullable and set it to

play10:08

null by default

play10:09

and now in the index.php we can do

play10:11

something like this

play10:12

invoice1 linked invoice equals to

play10:14

invoice2 and invoice2

play10:17

linked invoice equals to invoice one so

play10:19

as you can see we're creating this

play10:21

circular relationship here now when we

play10:23

try to compare invoice one within ways

play10:25

to like this

play10:25

and we run the code we're going to get

play10:27

this fatal error

play10:28

also before we wrap this up i want to

play10:30

mention is that in addition to use the

play10:32

equality checks like this

play10:33

you could also use greater or less than

play10:36

signs to compare

play10:38

objects it will stop and return false at

play10:40

the first

play10:41

property that fails the check this is it

play10:43

for this video as i mentioned earlier in

play10:45

this video i'm working on a very

play10:46

interesting lesson though it's a bit

play10:48

advanced topic and i'm not sure if i

play10:50

should include it in the second section

play10:52

of the course or wait until the third

play10:54

section of the course when we move on to

play10:56

more advanced topics let me know in the

play10:58

comments what you think about it if you

play11:00

wish to learn more about how variables

play11:02

are stored in php including references

play11:04

and objects and if you actually like

play11:05

that style of

play11:06

teaching where in addition to learning

play11:08

php or also learning how certain things

play11:11

work behind the scenes thank you so much

play11:12

for watching if you enjoy my lessons

play11:14

please give my videos thumbs up

play11:16

share and subscribe if you're new to the

play11:18

channel and i'll see you next time

Rate This

5.0 / 5 (0 votes)

Related Tags
PHP ComparisonObject EqualityProgramming TutorialPHP IdentityEquality OperatorIdentity OperatorPHP TutorialCode ComparisonObject PropertiesRecursive Comparison