-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path09-classes-3.html
More file actions
199 lines (169 loc) · 7.77 KB
/
09-classes-3.html
File metadata and controls
199 lines (169 loc) · 7.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Classes, Static Methods, and Object Identity | A Moderately Short PHP Tutorial</title>
<link rel="stylesheet" href="css/styles.css?v=1.0">
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script async defer data-domain="a-moderately-short-php-tutorial.com" src="https://plausible.io/js/plausible.js"></script>
</head>
<body>
<div>
<h1><a href="/">
A Moderately Short PHP Tutorial
</a>
</h1>
<div id="pages">
<ul>
<li >
<a href="01-introduction.html">1: Introduction</a>
</li>
<li >
<a href="02-getting-php.html">2: Getting PHP</a>
</li>
<li >
<a href="03-hello-world.html">3: Hello, world</a>
</li>
<li >
<a href="04-http.html">4: HTTP</a>
</li>
<li >
<a href="05-variables.html">5: Variables, arrays and loops</a>
</li>
<li >
<a href="06-functions.html">6: Functions</a>
</li>
<li >
<a href="07-classes-1.html">7: Classes and Objects</a>
</li>
<li >
<a href="08-classes-2.html">8: Classes and Composer</a>
</li>
<li class="current" >
<a href="09-classes-3.html">9: Classes, Static Methods, and Object Identity</a>
</li>
<li >
<a href="10-testing.html">10: Testing</a>
</li>
<li >
<a href="11-databases.html">11: Databases</a>
</li>
<li >
<a href="12-templating.html">12: Templating</a>
</li>
<li >
<a href="13-static-analysis.html">13: Static Analysis</a>
</li>
<li >
<a href="14-what-next.html">14: What next?</a>
</li>
</ul>
</div>
<article>
<h2>Classes, Static Methods, and Object Identity</h2>
<h3>Static methods</h3>
<p>Not all the methods on a class have to run in the context of an object. Methods that work without a <code>$this</code> object
instance are called static methods. Let's add a static method to the Planet class in <code>src/Planet.php</code>:</p>
<pre><code class="language-php"><?php declare(strict_types=1);
namespace AModeratelyShortPhpTutorial;
final class Planet
{
private string $name;
private float $populationSize;
public function __construct(string $name, float $populationSize)
{
$this->name = $name;
$this->populationSize = $populationSize;
}
public function getName(): string
{
return $this->name;
}
public function getPopulationSize(): float
{
return $this->populationSize;
}
public static function earth(): self
{
return new self('Earth', 7.7 * 10**9);
}
}</code></pre>
<!--
Where is self officially defined? It isn't listed at https://www.php.net/manual/en/reserved.keywords.php . Only
mentioned in passing at https://www.php.net/manual/en/language.oop5.basic.php .
-->
<p>The <code>self</code> keyword refers to whatever class it's written in. It's more convenient to write <code>self</code> than to repeat
<code>Planet</code> many times.</p>
<p>And let's edit start.php:</p>
<pre><code class="language-php"><?php declare(strict_types=1);
namespace AModeratelyShortPhpTutorial;
require_once __DIR__. '/vendor/autoload.php';
$planet = Planet::Earth();
echo "Planet {$planet->getName()} has a population of {$planet->getPopulationSize()}.\n";</code></pre>
<p>The double colon is the <strong>Scope Resolution Operator</strong>. It accesses static methods (and properties) of classes - there is
no need to have an object first. In this case our method returns an instance of the class, but it could do anything.</p>
<h3>Object Identity</h3>
<p>A PHP variable can't actually hold an object - instead it holds an <strong>object identifier</strong>, also known as a <strong>reference</strong>.</p>
<p>Two objects created the same way, with the same properties will have distinct identities. But if one object is created
and then assigned to two variables, they will both hold identifiers for the same object. This becomes important when we
make our objects mutable. This extra complexity is a good reason to prefer immutable objects, but sometimes we need
mutability.</p>
<p>Let's add a function to change the world - edit <code>src/Planet.php</code> again, adding the following function inside the class:</p>
<pre><code class="language-php"> public function receiveImmigrant(): void
{
$this->populationSize++;
}</code></pre>
<p><code>void</code> is the return type for functions that don't actually return any information.</p>
<p>Now let's write a script to illustrate object identities. Enter the following in 'identities.php'</p>
<pre><code class="language-php"><?php declare(strict_types=1);
namespace AModeratelyShortPhpTutorial;
require_once __DIR__. '/vendor/autoload.php';
$mercury = new Planet('Mercury', 0);
$secondMercury = new Planet('Mercury', 0);
$theSameMercury = $mercury;
echo "Mercury is equal to second Mercury:\n";
var_dump($mercury == $secondMercury);
echo \PHP_EOL;
echo "But Mercury is not **identical** to second Mercury:\n";
var_dump($mercury === $secondMercury);
echo \PHP_EOL;
echo "Mercury is equal **and** identical to the same Mercury:\n";
var_dump($mercury == $theSameMercury);
var_dump($mercury === $theSameMercury);
echo \PHP_EOL;
$mercury->receiveImmigrant();
echo "Population of Mercury: {$mercury->getPopulationSize()}.\n";
echo "Population of second Mercury: {$secondMercury->getPopulationSize()}.\n";
echo "Population of the same Mercury: {$theSameMercury->getPopulationSize()}.\n";</code></pre>
<p>We see that <code>$mercury</code> and <code>$theSameMercury</code> are just two names for the same object, while <code>$secondMercury</code> is an
entirely separate object with its own properties, lifecycle, hopes and dreams.</p>
<p>If a function accepts an object as a parameter, or returns an object, PHP doesn't make a copy of the object - it just
copies the identifier. This means that code within and without the function can access and potentially change the same
object. It's an important part of how communication happens between the parts of a PHP program, but it can easily get
confusing if not managed carefully.</p>
</article>
<div id="previous">
<a href="08-classes-2.html">← Classes and Composer ←</a>
</div>
<div id="next">
<a href="10-testing.html">→ Testing →</a>
</div>
<div style="clear: both"/>
<div id="footer">
<div id="byline">
<em>
© <a href="https://twitter.com/sorsoup">Barney Laurance</a> <br>
Site generated from <a href="https://github.com/bdsl/phpTutorial">sources</a>
at 23:55 London time on
Fri 11 Feb 2022.
</em>
</div>
</div>
<script src="js/scripts.js"></script>
</div>
</body>
</html>