-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathbasic.xml
838 lines (773 loc) · 21.6 KB
/
basic.xml
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
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
<?xml version="1.0" encoding="utf-8"?>
<!-- EN-Revision: 512670405c88acf7f0c9124f98c249e530ecd3cb Maintainer: pastore Status: ready -->
<!-- Reviewed: yes Maintainer: cucinato -->
<!-- CREDITS: montefoschi,cucinato -->
<sect1 xml:id="language.oop5.basic" xmlns="http://docbook.org/ns/docbook">
<title>Nozioni di base</title>
<sect2 xml:id="language.oop5.basic.class">
<title>class</title>
<para>
La definizione più semplice di una classe è composta
dal termine <literal>class</literal>, seguito dal nome della classe,
seguito da una coppia di parentesi graffe che racchiudono le definizioni
delle proprietà e dei metodi che fanno parte della classe stessa.
</para>
<para>
Il nome della classe può essere una qualunque etichetta valida che non
sia una <link linkend="reserved">parola riservata</link> di PHP.
Un nome di classe valido inizia con una lettera o un underscore, seguiti da
lettere, numeri, o underscores. Questa regola può essere rappresentata
dalla seguente espressione regolare:
<literal>^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$</literal>.
</para>
<para>
Una classe può contenere le proprie
<link linkend="language.oop5.constants">costanti</link>, <link linkend="language.oop5.properties">variabili</link>
(chiamate "proprietà"), e funzioni (chiamate "methods").
</para>
<example>
<title>Semplice definizione di una classe</title>
<programlisting role="php">
<![CDATA[
<?php
class SimpleClass
{
// dichiarazione di proprietà
public $var = 'un valore di default';
// dichiarazione di metodi
public function mostraVar() {
echo $this->var;
}
}
?>
]]>
</programlisting>
</example>
<para>
La pseudo-variabile <varname>$this</varname> è disponibile quando un
metodo è invocato dall'interno del contesto di un oggetto.
<varname>$this</varname> è il valore dell'oggetto chiamante.
</para>
<warning>
<para>
La chiamata in modo statico di un metodo non statico genera un
<classname>Error</classname>.
Prima di PHP 8.0.0, questo generava un avviso di deprecazione
e <varname>$this</varname> non sarebbe stato definito.
</para>
<example xml:id="language.oop5.basic.class.this">
<title>Esempi della pseudo-variabile <varname>$this</varname></title>
<programlisting role="php">
<![CDATA[
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this è definito (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this non è definito.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
]]>
</programlisting>
&example.outputs.7;
<screen>
<![CDATA[
$this è definito (A)
Deprecated: Non-static method A::foo() should not be called statically in %s on line 27
$this non è definito.
Deprecated: Non-static method A::foo() should not be called statically in %s on line 20
$this non è definito.
Deprecated: Non-static method B::bar() should not be called statically in %s on line 32
Deprecated: Non-static method A::foo() should not be called statically in %s on line 20
$this non è definito.
]]>
</screen>
&example.outputs.8;
<screen>
<![CDATA[
$this è definito (A)
Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27
Stack trace:
#0 {main}
thrown in %s on line 27
]]>
</screen>
</example>
</warning>
<sect3 xml:id="language.oop5.basic.class.readonly">
<title>Classi readonly</title>
<para>
A partire da PHP 8.2.0, una classe può essere marcata con il
modificatore <modifier>readonly</modifier>.
Marcando una classe come <modifier>readonly</modifier> si aggiungerà il
<link linkend="language.oop5.properties.readonly-properties">modificatore <modifier>readonly</modifier></link>
ad ogni proprietà dichiarata, e preverrà la creazione di
<link linkend="language.oop5.properties.dynamic-properties">proprietà dinamiche</link>.
Inoltre, è impossibile aggiungere il loro supporto utilizzando
l'attributo <classname>AllowDynamicProperties</classname>. Provando ad utilizzarlo
si innescherà un errore in fase di compilazione.
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
#[\AllowDynamicProperties]
readonly class Foo {
}
// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
?>
]]>
</programlisting>
</informalexample>
<para>
Poiché né le proprietà non tipizzate né quelle statiche possono essere contrassegnate con il
modificatore <literal>readonly</literal>, le classi readonly non possono dichiarare
nemmeno loro:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
readonly class Foo
{
public $bar;
}
// Fatal error: Readonly property Foo::$bar must have type
?>
]]>
</programlisting>
<programlisting role="php">
<![CDATA[
<?php
readonly class Foo
{
public static int $bar;
}
// Fatal error: Readonly class Foo cannot declare static properties
?>
]]>
</programlisting>
</informalexample>
<para>
Una classe <modifier>readonly</modifier> può essere
<link linkend="language.oop5.basic.extends">estesa</link>
se, e solo se, la classe figlia è anche una
classe <modifier>readonly</modifier>.
</para>
</sect3>
</sect2>
<sect2 xml:id="language.oop5.basic.new">
<title>new</title>
<para>
Per creare un'istanza di una classe, deve essere usata la parola chiave <literal>new</literal>.
Un oggetto sarà sempre creato a meno che la classe abbia un
<link linkend="language.oop5.decon">costruttore</link> definito il quale sollevi un'
<link linkend="language.exceptions">eccezione</link> in caso di errore. Le classi
dovrebbero essere definite prima dell'istanziazione (in alcuni casi questo è un
requisito).
</para>
<para>
Se viene usata una <type>stringa</type> contenente il nome di una classe con
<literal>new</literal>, verrà creata una nuova istanza di quella classe. Se
la classe appartiene ad un namespace, deve essere utilizzato il suo nome completamente
qualificato.
</para>
<note>
<para>
Se non ci sono argomenti da passare al costruttore della classe,
le parentesi dopo il nome della classe possono essere omesse.
</para>
</note>
<example>
<title>Creazione di un'istanza</title>
<programlisting role="php">
<![CDATA[
<?php
$instance = new SimpleClass();
// è anche possibile istanziare una classe il cui nome sia contenuto in una variabile:
$className = 'SimpleClass';
$instance = new $className(); // new SimpleClass()
?>
]]>
</programlisting>
</example>
<para>
Da PHP 8.0.0, l'utilizzo di <literal>new</literal> con espressioni arbitrarie
è supportato. Ciò consente istanziazioni più complesse se l'espressione
produce una <type>stringa</type>. Le espressioni devono essere racchiuse tra parentesi.
</para>
<example>
<title>Creazione di un'istanza utilizzando un'espressione arbitraria</title>
<para>
Nell'esempio fornito mostriamo più esempi di espressioni arbitrarie valide che producono un nome di classe.
Questo mostra una chiamata a una funzione, la concatenazione di stringhe e la costante <constant>::class</constant>.
</para>
<programlisting role="php">
<![CDATA[
<?php
class ClassA extends \stdClass {}
class ClassB extends \stdClass {}
class ClassC extends ClassB {}
class ClassD extends ClassA {}
function getSomeClass(): string
{
return 'ClassA';
}
var_dump(new (getSomeClass()));
var_dump(new ('Class' . 'B'));
var_dump(new ('Class' . 'C'));
var_dump(new (ClassD::class));
?>
]]>
</programlisting>
&example.outputs.8;
<screen>
<![CDATA[
object(ClassA)#1 (0) {
}
object(ClassB)#1 (0) {
}
object(ClassC)#1 (0) {
}
object(ClassD)#1 (0) {
}
]]>
</screen>
</example>
<para>
Nel contesto di una classe, è possibile creare un nuovo oggetto con le espressioni
<literal>new self</literal> e <literal>new parent</literal>.
</para>
<para>
Quando si assegna un'istanza già creata ad una nuova variabile, la nuova variabile
farà riferimento alla stessa istanza cui fa riferimento la variabile originale. Questo stesso
comportamento si ha quando vengono passate istanze ad una funzione. Si può ottenere una copia
di un oggetto già creato per mezzo della
<link linkend="language.oop5.cloning">clonazione</link>.
</para>
<example>
<title>Assegnazione di oggetti</title>
<programlisting role="php">
<![CDATA[
<?php
$instance = new SimpleClass();
$assigned = $instance;
$reference =& $instance;
$istance->var = '$assigned avrà questo valore';
$instance = null; // $instance e $reference diventano null
var_dump($instance);
var_dump($reference);
var_dump($assigned);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
NULL
NULL
object(SimpleClass)#1 (1) {
["var"]=>
string(30) "$assigned avrà questo valore"
}
]]>
</screen>
</example>
<para>
È possibile creare istanze di un oggetto in due modi:
</para>
<example>
<title>Creazione di nuovi oggetti</title>
<programlisting role="php">
<![CDATA[
<?php
class Test
{
static public function getNew()
{
return new static;
}
}
class Child extends Test
{}
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);
$obj3 = Test::getNew();
var_dump($obj3 instanceof Test);
$obj4 = Child::getNew();
var_dump($obj4 instanceof Child);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
bool(true)
bool(true)
bool(true)
]]>
</screen>
</example>
<para>
È possibile accedere ad un membro di un oggetto appena creato
in una singola espressione:
</para>
<example>
<title>Accesso al membro dell'oggetto appena creato</title>
<programlisting role="php">
<![CDATA[
<?php
echo (new DateTime())->format('Y');
?>
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
2016
]]>
</screen>
</example>
<note>
<simpara>
Prima di PHP 7.1, gli argomenti non vengono valutati se non esiste una funzione
costruttore definita.
</simpara>
</note>
</sect2>
<sect2 xml:id="language.oop5.basic.properties-methods">
<title>Proprietà e metodi</title>
<para>
Le proprietà e i metodi della classe vivono in "namespace" separati, quindi è
possibile avere una proprietà ed un metodo con lo stesso nome. Dato che
sia una proprietà che un metodo hanno la stessa notazione, e la scelta se
verrà letta la proprietà o se verrà chiamato il metodo, dipende solo dal contesto,
per esempio se l'uso è un accesso ad una variabile o una chiamata ad una funzione.
</para>
<example>
<title>Accesso alla proprietà vs. chiamata del metodo</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
public $bar = 'property';
public function bar() {
return 'method';
}
}
$obj = new Foo();
echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
property
method
]]>
</screen>
</example>
<para>
Ciò significa che chiamare una <link linkend="functions.anonymous">funzione
anonima</link> che è stata assegnata ad una proprietà non è direttamente
possibile. Per esempio, la proprietà deve essere assegnata prima ad una
variabile. È possibile chiamare questo tipo di proprietà direttamente
racchiudendola tra parentesi.
</para>
<example>
<title>Chiamare una funzione anonima memorizzata in una proprietà</title>
<programlisting role="php">
<![CDATA[
<?php
class Foo
{
public $bar;
public function __construct() {
$this->bar = function() {
return 42;
};
}
}
$obj = new Foo();
echo ($obj->bar)(), PHP_EOL;
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
42
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.basic.extends">
<!-- TODO Example about class constant redefinition -->
<!-- TODO Split into it's own page? -->
<title>extends</title>
<para>
Una classe può ereditare le costanti, i metodi e le proprietà di un'altra classe
utilizzando la parola chiave <literal>extends</literal> nella dichiarazione
della classe. Non è possibile estendere più di una classe per volta; ogni classe può
ereditare da una sola altra classe.
</para>
<para>
Le costanti, i metodi e le proprietà ereditate possono essere sovrascritte
ridichiarandole nella nuova classe con lo stesso nome definito nella classe
padre. Questo non sarà comunque possibile se il metodo o la costante
che si intende ridefinire è stato dichiarato nella classe padre come
<link linkend="language.oop5.final">final</link>. Si può accedere alle proprietà
statiche e ai metodi ridefiniti riferendosi ad essi
con <link linkend="language.oop5.paamayim-nekudotayim">parent::</link>.
</para>
<note>
<simpara>
A partire da PHP 8.1.0, le costanti possono essere dichiarate come final.
</simpara>
</note>
<example>
<title>Ereditarietà semplice</title>
<programlisting role="php">
<![CDATA[
<?php
class ExtendClass extends SimpleClass
{
// Ridefinisce il metodo presente in ClasseSemplice
function displayVar()
{
echo "Classe figlia\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Classe figlia
un valore di default
]]>
</screen>
</example>
<sect3 xml:id="language.oop.lsp">
<title>Regole di compatibilità della firma</title>
<para>
Quando si sovrascrive un metodo, la sua firma deve essere compatibile con il metodo
padre. Altrimenti, viene emesso un errore fatale o, prima di PHP 8.0.0, viene
generato un errore di livello <constant>E_WARNING</constant>.
Una firma è compatibile se rispetta le
regole di <link linkend="language.oop5.variance">varianza</link>, rende
facoltativo un parametro obbligatorio e se i nuovi parametri sono opzionali.
Questo è noto come Principio di Sostituzione di Liskov, o LSP in breve.
I metodi <link linkend="language.oop5.decon.constructor">costruttore</link>
e <literal>privati</literal> sono esenti da queste regole di
compatibilità della firma e quindi non genereranno un errore fatale nel caso di una
mancata corrispondenza della firma.
</para>
<example>
<title>Metodi figli compatibili</title>
<programlisting role="php">
<![CDATA[
<?php
class Base
{
public function foo(int $a) {
echo "Valido\n";
}
}
class Extend1 extends Base
{
function foo(int $a = 5)
{
parent::foo($a);
}
}
class Extend2 extends Base
{
function foo(int $a, $b = 5)
{
parent::foo($a);
}
}
$extended1 = new Extend1();
$extended1->foo();
$extended2 = new Extend2();
$extended2->foo(1);
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Valido
Valido
]]>
</screen>
</example>
<para>
I seguenti esempi dimostrano che un metodo figlio che rimuove un parametro o rende obbligatorio un
parametro facoltativo non è compatibile con il metodo padre.
</para>
<example>
<title>Errore fatale quando un metodo figlio rimuove un parametro</title>
<programlisting role="php">
<![CDATA[
<?php
class Base
{
public function foo(int $a = 5) {
echo "Valido\n";
}
}
class Extend extends Base
{
function foo()
{
parent::foo(1);
}
}
]]>
</programlisting>
&example.outputs.8.similar;
<screen>
<![CDATA[
Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13
]]>
</screen>
</example>
<example>
<title>Errore fatale quando un metodo figlio rende obbligatorio un parametro facoltativo</title>
<programlisting role="php">
<![CDATA[
<?php
class Base
{
public function foo(int $a = 5) {
echo "Valido\n";
}
}
class Extend extends Base
{
function foo(int $a)
{
parent::foo($a);
}
}
]]>
</programlisting>
&example.outputs.8.similar;
<screen>
<![CDATA[
Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13
]]>
</screen>
</example>
<warning>
<para>
Rinominare il parametro di un metodo in una classe figlia non è un'incompatibilità
di firma. Tuttavia, questo è sconsigliato poiché risulterà in un
<classname>Errore</classname> di runtime se
vengono utilizzati gli
<link linkend="functions.named-arguments">argomenti con nome</link>.
</para>
<example>
<title>Errore durante l'utilizzo di argomenti e parametri con nome rinominati in una classe figlia</title>
<programlisting role="php">
<![CDATA[
<?php
class A {
public function test($foo, $bar) {}
}
class B extends A {
public function test($a, $b) {}
}
$obj = new B;
// Passa i parametri in base al contratto A::test()
$obj->test(foo: "foo", bar: "bar"); // ERRORE!
]]>
</programlisting>
&example.outputs.similar;
<screen>
<![CDATA[
Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14
Stack trace:
#0 {main}
thrown in /in/XaaeN on line 14
]]>
</screen>
</example>
</warning>
</sect3>
</sect2>
<sect2 xml:id="language.oop5.basic.class.class">
<title>::class</title>
<para>
La parola chiave <literal>class</literal> è anche usata per la risoluzione
del nome della classe.
Per ottenere il nome completo di una classe <literal>ClassName</literal>
utilizzare <literal>ClassName::class</literal>. Questo è particolarmente utile con
le classi presenti nei <link linkend="language.namespaces">namespace</link>.
</para>
<para>
<example xml:id="language.oop5.basic.class.class.name">
<title>Risoluzione del nome della classe</title>
<programlisting role="php">
<![CDATA[
<?php
namespace NS {
class ClassName {
}
echo ClassName::class;
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
NS\ClassName
]]>
</screen>
</example>
</para>
<note>
<para>La risoluzione del nome della classe utilizzando <literal>::class</literal> è una
trasformazione in fase di compilazione. Ciò significa che al momento della creazione della stringa del nome
della classe non è ancora stato eseguito il caricamento automatico. Di conseguenza, i nomi delle classi
vengono espansi anche se la classe non esiste. In questo caso non viene emesso
alcun errore.
</para>
<example xml:id="language.oop5.basic.class.class.fail">
<title>Risoluzione del nome della classe mancante</title>
<programlisting role="php">
<![CDATA[
<?php
print Does\Not\Exist::class;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Does\Not\Exist
]]>
</screen>
</example>
</note>
<para>
A partire da PHP 8.0.0, la costante <literal>::class</literal> può essere utilizzata anche sugli
oggetti. Questa risoluzione avviene in fase di esecuzione, non in fase di compilazione. Il suo effetto è
lo stesso della chiamata di <function>get_class</function> sull'oggetto.
</para>
<example xml:id="language.oop5.basic.class.class.object">
<title>Risoluzione del nome dell'oggetto</title>
<programlisting role="php">
<![CDATA[
<?php
namespace NS {
class ClassName {
}
}
$c = new ClassName();
print $c::class;
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
NS\ClassName
]]>
</screen>
</example>
</sect2>
<sect2 xml:id="language.oop5.basic.nullsafe">
<title>Metodi e proprietà nullsafe</title>
<para>
A partire da PHP 8.0.0, è possibile accedere alle proprietà e ai metodi anche con
l'operatore "nullsafe": <literal>?-></literal>. L'operatore nullsafe
funziona allo stesso modo dell'accesso alla proprietà o al metodo come sopra, tranne per il fatto che se l'
oggetto da dereferenziare è &null; allora &null;
verrà restituito piuttosto che un'eccezione generata. Se la dereferenziazione fa parte di una
catena, il resto della catena viene saltato.
</para>
<para>
L'effetto è simile ad effettuare prima il wrap su ogni accesso in un controllo
<function>is_null</function>, ma più compatto.
</para>
<para>
<example>
<title>L'Operatore Nullsafe</title>
<programlisting role="php">
<![CDATA[
<?php
// A partire da PHP 8.0.0, questa riga:
$result = $repository?->getUser(5)?->name;
// È equivalente al seguente blocco di codice:
if (is_null($repository)) {
$result = null;
} else {
$user = $repository->getUser(5);
if (is_null($user)) {
$result = null;
} else {
$result = $user->name;
}
}
?>
]]>
</programlisting>
</example>
</para>
<note>
<para>
L'operatore nullsafe viene utilizzato al meglio quando null è considerato un valore possibile
valido e previsto per una proprietà o return di un metodo. Per indicare un errore,
è preferibile un'eccezione generata.
</para>
</note>
</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
-->