File: visibility.xml

package info (click to toggle)
php-doc 20241205~git.dfcbb86%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 70,956 kB
  • sloc: xml: 968,269; php: 23,883; javascript: 671; sh: 177; makefile: 37
file content (444 lines) | stat: -rw-r--r-- 11,478 bytes parent folder | download
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
 <sect1 xml:id="language.oop5.visibility" xmlns="http://docbook.org/ns/docbook">
  <title>Visibility</title>
  <para>
   The visibility of a property, a method or (as of PHP 7.1.0) a constant can be defined by prefixing
   the declaration with the keywords <literal>public</literal>,
   <literal>protected</literal> or
   <literal>private</literal>. Class members declared public can be
   accessed everywhere. Members declared protected can be accessed
   only within the class itself and by inheriting and parent
   classes. Members declared as private may only be accessed by the
   class that defines the member.
  </para>

  <sect2 xml:id="language.oop5.visibility-members">
   <title>Property Visibility</title>
   <para>
    Class properties may be defined as public, private, or
    protected. Properties declared without any explicit visibility
    keyword are defined as public.
   </para>
   <example>
    <title>Property declaration</title>
    <programlisting role="php">
<![CDATA[
<?php
/**
 * Define MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // We can redeclare the public and protected properties, but not private
    public $public = 'Public2';
    protected $protected = 'Protected2';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}

$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->protected; // Fatal Error
echo $obj2->private; // Undefined
$obj2->printHello(); // Shows Public2, Protected2, Undefined

?> 
]]>
    </programlisting>
   </example>
   <sect3 xml:id="language.oop5.visibility-members-aviz">
    <title>Asymmetric Property Visibility</title>
    <simpara>
     As of PHP 8.4, properties may also have their
     visibility set asymmetrically, with a different scope for
     reading (<literal>get</literal>) and writing (<literal>set</literal>).
     Specifically, the <literal>set</literal> visibility may be
     specified separately, provided it is not more permissive than the
     default visibility.
    </simpara>
    <example>
     <title>Asymmetric Property visibility</title>
     <programlisting role="php">
<![CDATA[
<?php
class Book
{
    public function __construct(
        public private(set) string $title,
        public protected(set) string $author,
        protected private(set) int $pubYear,
    ) {}
}

class SpecialBook extends Book
{
    public function update(string $author, int $year): void
    {
        $this->author = $author; // OK
        $this->pubYear = $year; // Fatal Error
    }
}

$b = new Book('How to PHP', 'Peter H. Peterson', 2024);

echo $b->title; // Works
echo $b->author; // Works
echo $b->pubYear; // Fatal Error

$b->title = 'How not to PHP'; // Fatal Error
$b->author = 'Pedro H. Peterson'; // Fatal Error
$b->pubYear = 2023; // Fatal Error
?>
]]>
     </programlisting>
    </example>
    <para>There are a few caveats regarding asymmetric visibility:</para>
    <itemizedlist>
     <listitem>
      <simpara>
       Only typed properties may have a separate <literal>set</literal> visibility.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       The <literal>set</literal> visibility must be the same
       as <literal>get</literal> or more restrictive. That is,
       <code>public protected(set)</code> and <code>protected protected(set)</code>
       are allowed, but <code>protected public(set)</code> will cause a syntax error.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       If a property is <literal>public</literal>, then the main visibility may be
       omitted.  That is, <code>public private(set)</code> and <code>private(set)</code>
       will have the same result.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       A property with <literal>private(set)</literal> visibility
       is automatically <literal>final</literal>, and may not be redeclared in a child class.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       Obtaining a reference to a property follows <literal>set</literal> visibility, not <literal>get</literal>.
       That is because a reference may be used to modify the property value.
      </simpara>
     </listitem>
     <listitem>
      <simpara>
       Similarly, trying to write to an array property involves both a <literal>get</literal> and
       <literal>set</literal> operation internally, and therefore will follow the <literal>set</literal>
       visibility, as that is always the more restrictive.
      </simpara>
     </listitem>
    </itemizedlist>
    <note>
     <simpara>
      Spaces are not allowed in the set-visibility declaration.
      <literal>private(set)</literal> is correct.
      <literal>private( set )</literal> is not correct and will result in a parse error.
     </simpara>
    </note>
    <simpara>
     When a class extends another, the child class may redefine
     any property that is not <literal>final</literal>.  When doing so,
     it may widen either the main visibility or the <literal>set</literal>
     visibility, provided that the new visibility is the same or wider
     than the parent class.  However, be aware that if a <literal>private</literal>
     property is overridden, it does not actually change the parent's property
     but creates a new property with a different internal name.
    </simpara>
    <example>
     <title>Asymmetric Property inheritance</title>
     <programlisting role="php">
<![CDATA[
<?php
class Book
{
    protected string $title;
    public protected(set) string $author;
    protected private(set) int $pubYear;
}

class SpecialBook extends Book
{
    public protected(set) $title; // OK, as reading is wider and writing the same.
    public string $author; // OK, as reading is the same and writing is wider.
    public protected(set) int $pubYear; // Fatal Error. private(set) properties are final.
}
?>
]]>
     </programlisting>
    </example>
   </sect3>
  </sect2>

  <sect2 xml:id="language.oop5.visiblity-methods">
   <title>Method Visibility</title>
   <para>
    Class methods may be defined as public, private, or
    protected. Methods declared without any explicit visibility
    keyword are defined as public.
   </para>
   <example>
    <title>Method Declaration</title>
    <programlisting role="php">
<![CDATA[
<?php
/**
 * Define MyClass
 */
class MyClass
{
    // Declare a public constructor
    public function __construct() { }

    // Declare a public method
    public function MyPublic() { }

    // Declare a protected method
    protected function MyProtected() { }

    // Declare a private method
    private function MyPrivate() { }

    // This is public
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}

$myclass = new MyClass;
$myclass->MyPublic(); // Works
$myclass->MyProtected(); // Fatal Error
$myclass->MyPrivate(); // Fatal Error
$myclass->Foo(); // Public, Protected and Private work


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // This is public
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // Fatal Error
    }
}

$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Works
$myclass2->Foo2(); // Public and Protected work, not Private

class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}

class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}

$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>
]]>
    </programlisting>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.visiblity-constants">
   <title>Constant Visibility</title>
   <para>
    As of PHP 7.1.0, class constants may be defined as public, private, or
    protected. Constants declared without any explicit visibility
    keyword are defined as public.
   </para>
   <example>
    <title>Constant Declaration as of PHP 7.1.0</title>
    <programlisting role="php">
<![CDATA[
<?php
/**
 * Define MyClass
 */
class MyClass
{
    // Declare a public constant
    public const MY_PUBLIC = 'public';

    // Declare a protected constant
    protected const MY_PROTECTED = 'protected';

    // Declare a private constant
    private const MY_PRIVATE = 'private';

    public function foo()
    {
        echo self::MY_PUBLIC;
        echo self::MY_PROTECTED;
        echo self::MY_PRIVATE;
    }
}

$myclass = new MyClass();
MyClass::MY_PUBLIC; // Works
MyClass::MY_PROTECTED; // Fatal Error
MyClass::MY_PRIVATE; // Fatal Error
$myclass->foo(); // Public, Protected and Private work


/**
 * Define MyClass2
 */
class MyClass2 extends MyClass
{
    // This is public
    function foo2()
    {
        echo self::MY_PUBLIC;
        echo self::MY_PROTECTED;
        echo self::MY_PRIVATE; // Fatal Error
    }
}

$myclass2 = new MyClass2;
echo MyClass2::MY_PUBLIC; // Works
$myclass2->foo2(); // Public and Protected work, not Private
?>
]]>
    </programlisting>
   </example>
  </sect2>

  <sect2 xml:id="language.oop5.visibility-other-objects">
   <title>Visibility from other objects</title>
   <para>
    Objects of the same type will have access to each others private and
    protected members even though they are not the same instances. This is
    because the implementation specific details are already known when inside
    those objects.
   </para>
   <example>
    <title>Accessing private members of the same object type</title>
    <programlisting role="php">
<![CDATA[
<?php
class Test
{
    private $foo;

    public function __construct($foo)
    {
        $this->foo = $foo;
    }

    private function bar()
    {
        echo 'Accessed the private method.';
    }

    public function baz(Test $other)
    {
        // We can change the private property:
        $other->foo = 'hello';
        var_dump($other->foo);

        // We can also call the private method:
        $other->bar();
    }
}

$test = new Test('test');

$test->baz(new Test('other'));
?>
]]>
    </programlisting>
    &example.outputs;
    <screen>
<![CDATA[
string(5) "hello"
Accessed the private method.
]]>
    </screen>
   </example>
  </sect2>
 </sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->