-
Notifications
You must be signed in to change notification settings - Fork 81
Expand file tree
/
Copy pathtype-juggling.xml
More file actions
481 lines (429 loc) · 17.1 KB
/
type-juggling.xml
File metadata and controls
481 lines (429 loc) · 17.1 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
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
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 78a11d3ca004ee937549d932e77a79c51b9777cd Maintainer: mumumu Status: ready -->
<sect1 xml:id="language.types.type-juggling">
<title>型の相互変換</title>
<simpara>
PHP は変数宣言時に明示的な型定義を必要としません。
型を定義しない場合、変数の型は保存する値によって決まります。
これは、変数 <varname>$var</varname> に文字列を代入した場合、
<varname>$var</varname> の型は文字列 (<type>string</type>)
になることを意味しています。
その後、整数値を <varname>$var</varname> に代入すると、
その変数の型は整数 (<type>int</type>) になります。
</simpara>
<para>
コンテクスト(文脈)によっては、
PHP が値を別の型に自動変換しようとすることがあります。
自動変換が行われる異なるコンテクストが存在するのは、以下のとおりです:
<itemizedlist>
<listitem>
<simpara>数値のコンテクスト</simpara>
</listitem>
<listitem>
<simpara>文字列のコンテクスト</simpara>
</listitem>
<listitem>
<simpara>論理コンテクスト</simpara>
</listitem>
<listitem>
<simpara>整数と文字列のコンテクスト</simpara>
</listitem>
<listitem>
<simpara>比較のコンテクスト</simpara>
</listitem>
<listitem>
<simpara>関数のコンテクスト</simpara>
</listitem>
</itemizedlist>
</para>
<note>
<simpara>
値を別の型として解釈する必要がある場合でも、
値そのものの型は <emphasis>変わりません</emphasis>。
</simpara>
</note>
<simpara>
変数を強制的にある特定の型として評価させたい場合は、
<link linkend="language.types.typecasting">型キャスト</link> のセクションを参照ください。
ある変数の型を変更したい場合は、<function>settype</function> を参照ください。
</simpara>
<sect2>
<title>数値のコンテクスト</title>
<simpara>
これは、
<link linkend="language.operators.arithmetic">算術演算子</link>
を使った場合です。
</simpara>
<simpara>
このコンテクストでは、
オペランドのどちらかが <type>float</type>
(または整数と解釈できない場合) の場合か、
両方のオペランドが <type>float</type> の場合、
結果の型は <type>float</type> になります。
そうでない場合、オペランドは整数として解釈され、
結果の型も整数になります。
PHP 8.0.0 以降では、いずれかのオペランドが解釈できない場合、
<classname>TypeError</classname> がスローされます。
</simpara>
</sect2>
<sect2>
<title>文字列のコンテクスト</title>
<simpara>
これは、
<function>echo</function>,
<function>print</function> や
<link linkend="language.types.string.parsing">文字列中の変数のパース</link>、または
<link linkend="language.operators.string">文字列演算子</link>
を使った場合です。
</simpara>
<simpara>
値は文字列として解釈されます。
文字列として解釈できない場合、
<classname>TypeError</classname> がスローされます。
PHP 7.4.0 より前のバージョンでは、
<constant>E_RECOVERABLE_ERROR</constant> が発生していました。
</simpara>
</sect2>
<sect2>
<title>論理コンテクスト</title>
<simpara>
これは、
制御構文や
<link linkend="language.operators.comparison.ternary">三項演算子</link>,
<link linkend="language.operators.logical">論理演算子</link>
を使った場合です。
</simpara>
<simpara>
値は論理値 (<type>bool</type>) として解釈されます。
</simpara>
</sect2>
<sect2>
<title>整数と文字列のコンテクスト</title>
<simpara>
これは、
<link linkend="language.operators.bitwise">ビット演算子</link>
を使った場合です。
</simpara>
<simpara>
全てのオペランドが文字列の場合、
結果の型も文字列になります。
そうでない場合、
オペランドは整数として解釈され、
結果の型も整数になります。
PHP 8.0.0 以降では、いずれかのオペランドが解釈できない場合、
<classname>TypeError</classname> がスローされます。
</simpara>
</sect2>
<sect2>
<title>比較のコンテクスト</title>
<simpara>
これは、
<link linkend="language.operators.comparison">比較演算子</link>
を使った場合です。
</simpara>
<simpara>
このコンテクストで発生する型変換については、
<link linkend="language.operators.comparison.types">さまざまな型の比較表</link>
に説明があります。
</simpara>
</sect2>
<sect2 xml:id="language.types.type-juggling.function">
<title>関数のコンテクスト</title>
<simpara>
これは、値が型付きのパラメータ、型付きプロパティに渡された場合や、
戻り値の型を宣言している関数から値が返される場合です。
</simpara>
<para>
このコンテクストでは、値はその型の値でなければなりません。
これにはふたつ例外があります。
ひとつめは値の型が <type>int</type> で、
宣言されている型が <type>float</type> の場合、
整数が浮動小数点に変換されることです。
ふたつめは型が <emphasis>スカラー型</emphasis>、
または値がスカラー型に変換可能な場合で、
<!-- e.g. An object that implements __toString will pass a string type -->
かつ型の自動変換モードが有効な場合(デフォルト)、
スカラー型の値だけが別の変換可能なスカラー型に変換される可能性があることです。
この振る舞いに関する詳細は、以下を参照ください:
</para>
<warning>
<simpara>
<link linkend="functions.internal">内部関数</link> は、&null; を自動的にスカラー型に変換します。
この振る舞いは PHP 8.1.0 以降は <emphasis>推奨されなくなっています</emphasis>。
</simpara>
</warning>
<sect3 xml:id="language.types.type-juggling.function.simple">
<title>単一の型宣言における、型の自動変換</title>
<itemizedlist>
<listitem>
<simpara>
論理型(<type>bool</type>) が宣言されている場合: 値は <type>bool</type> として解釈されます。
</simpara>
</listitem>
<listitem>
<simpara>
整数型 (<type>int</type>) が宣言されてい場合: <type>int</type> への変換が定義されている場合は、<type>int</type> として解釈されます。たとえば、文字列が <link linkend="language.types.numeric-strings">数値形式</link> である場合です。
</simpara>
</listitem>
<listitem>
<simpara>
<type>float</type> が宣言されている場合: <type>float</type> への変換が定義されている場合は、<type>float</type> として解釈されます。たとえば、文字列が <link linkend="language.types.numeric-strings">数値形式</link> である場合です。
</simpara>
</listitem>
<listitem>
<simpara>
文字列 (<type>string</type>) 型として宣言されている場合: 値は文字列として解釈されます。
</simpara>
</listitem>
</itemizedlist>
</sect3>
<sect3 xml:id="language.types.type-juggling.function.union">
<title>union 型と型の自動変換</title>
<para>
<literal>strict_types</literal> が有効になっていない場合、
スカラー型の宣言は、限られた暗黙の型変換が行われます。
値の正確な型が union の一部に指定されていない場合、
次の順に対象となる型が選択されます:
<orderedlist>
<listitem>
<simpara>
<type>int</type>
</simpara>
</listitem>
<listitem>
<simpara>
<type>float</type>
</simpara>
</listitem>
<listitem>
<simpara>
<type>string</type>
</simpara>
</listitem>
<listitem>
<simpara>
<type>bool</type>
</simpara>
</listitem>
</orderedlist>
正確な型が union の中に存在し、
かつ値が PHP の既存の型チェックのセマンティクスによって型変換できる場合、
その型が選択されます。
そうでない場合、次の型を試そうとします。
</para>
<caution>
<para>
例外として、値が文字列で、int と float が union に含まれていた場合、
型は既存の <link linkend="language.types.numeric-strings">数値形式の文字列</link> を解釈するセマンティクスによって決まります。
たとえば、<literal>"42"</literal> の場合、
<type>int</type> が選ばれますし、
<literal>"42.0"</literal> の場合、<type>float</type> が選ばれます。
</para>
</caution>
<note>
<para>
上のリストに入っていない型については、
暗黙の型変換が行われる対象ではありません。
特に、暗黙のうちに
<type>null</type>, <type>false</type>, <type>true</type>
に変換されることはありません。
</para>
</note>
<example>
<title>union の型のひとつに変換される例</title>
<programlisting role="php">
<![CDATA[
<?php
// int|string
42 --> 42 // 正確に型が一致
"42" --> "42" // 正確に型が一致
new ObjectWithToString --> "Result of __toString()"
// オブジェクトは int と互換性がないので、文字列にフォールバック
42.0 --> 42 // float は int と互換性がある
42.1 --> 42 // float は int と互換性がある
1e100 --> "1.0E+100" // int には大きすぎる float なので、文字列にフォールバック
INF --> "INF" // int には大きすぎる float なので、文字列にフォールバック
true --> 1 // bool は int と互換性がある
[] --> TypeError // 配列はint, string と互換性はない。
// int|float|bool
"45" --> 45 // int の数値形式の文字列
"45.0" --> 45.0 // float の数値形式の文字列
"45X" --> true // 数値形式の文字列ではない。boolにフォールバック
"" --> false // 数値形式の文字列ではない。boolにフォールバック
"X" --> true // 数値形式の文字列ではない。boolにフォールバック
[] --> TypeError // 配列はint, float, bool と互換性はない。
?>
]]>
</programlisting>
</example>
</sect3>
</sect2>
<sect2 xml:id="language.types.typecasting">
<title>型キャスト</title>
<simpara>
型キャストは、変換しようとする型の名前を括弧で括り、
キャストする変数の前に置くことで、値を別の型に変換するものです。
</simpara>
<example>
<title>型キャストの例</title>
<programlisting role="php">
<![CDATA[
<?php
$foo = 10; // $foo は整数です
$bar = (bool) $foo; // $bar は boolean です
var_dump($bar);
?>
]]>
</programlisting>
</example>
<simpara>
使用可能なキャストを以下に示します:
</simpara>
<simplelist>
<member><literal>(int)</literal> - 整数(<type>int</type>) へのキャスト</member>
<member><literal>(bool)</literal> - 論理値(<type>bool</type>) へのキャスト</member>
<member><literal>(float)</literal> - <type>float</type> へのキャスト</member>
<member><literal>(string)</literal> - 文字列(<type>string</type>) へのキャスト</member>
<member><literal>(array)</literal> - 配列(<type>array</type>) へのキャスト</member>
<member><literal>(object)</literal> - オブジェクト(<type>object</type>) へのキャスト</member>
<member><literal>(unset)</literal> - <type>NULL</type> へのキャスト</member>
</simplelist>
<warning>
<para>
<literal>(integer)</literal> は、<literal>(int)</literal> のエイリアスです。
<literal>(boolean)</literal> は、<literal>(bool)</literal> のエイリアスです。
<literal>(binary)</literal> は、<literal>(string)</literal> のエイリアスです。
<literal>(double)</literal> と <literal>(real)</literal> は、<literal>(float)</literal> のエイリアスです。
これらのキャストは、正規化された型の名前を使っていません。
そのため PHP 8.5.0 以降では推奨されなくなりました。
</para>
</warning>
<warning>
<simpara>
キャストのエイリアス <literal>(real)</literal> を使うことは、PHP 7.4.0 以降は推奨されなくなり、PHP 8.0.0 で削除されました。
</simpara>
</warning>
<warning>
<simpara>
<literal>(unset)</literal> によるキャストは、
PHP 7.2.0 以降推奨されなくなりました。
<literal>(unset)</literal> によるキャストは、
値に <type>NULL</type> 値を代入することと同じです。
<literal>(unset)</literal> によるキャストは、PHP 8.0.0 で削除されました。
</simpara>
</warning>
<caution>
<simpara>
将来サポートされることを見越して、<literal>(binary)</literal> によるキャストと <literal>b</literal> プレフィックスが存在しています。
<literal>(binary)</literal> と <literal>(string)</literal> は現状は等価ですが、将来変更される可能性があります。そのため、現状等価であることに依存すべきではありません。
</simpara>
</caution>
<note>
<para>
キャストの括弧内のホワイトスペースは無視されます。
よって、以下のふたつのキャストは等価です:
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo = (int) $bar;
$foo = ( int ) $bar;
?>
]]>
</programlisting>
</informalexample>
</para>
</note>
<informalexample>
<simpara>
以下の例は、リテラル文字列や変数を、バイナリ文字列にキャストします:
</simpara>
<programlisting role="php">
<![CDATA[
<?php
$binary = (binary) $string;
$binary = b"binary string";
?>
]]>
</programlisting>
</informalexample>
<!-- TODO Remove or move into string context section? -->
<simpara>
ある変数を文字列にキャストする代わりに、
二重引用符で括ることもできます。
</simpara>
<example>
<title>異なるキャストの仕組み</title>
<programlisting role="php">
<![CDATA[
<?php
$foo = 10; // $foo は整数です
$str = "$foo"; // $str は文字列です
$fst = (string) $foo; // $fst も文字列です
// これは、"they are the same"を出力します
if ($fst === $str) {
echo "they are the same", PHP_EOL;
}
?>
]]>
</programlisting>
</example>
<para>
型の間でキャストを行う際の動作は、必ずしも明確ではありません。
詳細については、以下の節を参照ください:
<simplelist>
<member><link linkend="language.types.boolean.casting">論理値への変換</link></member>
<member><link linkend="language.types.integer.casting">整数への変換</link></member>
<member><link linkend="language.types.float.casting">浮動小数点数への変換</link></member>
<member><link linkend="language.types.string.casting">文字列への変換</link></member>
<member><link linkend="language.types.array.casting">配列への変換</link></member>
<member><link linkend="language.types.object.casting">オブジェクトへの変換</link></member>
<member><link linkend="language.types.resource.casting">リソース型への変換</link></member>
<member><link linkend="language.types.null.casting">NULL への変換</link></member>
<member><link linkend="types.comparisons">型の比較表</link></member>
</simplelist>
</para>
<note>
<simpara>
PHP では配列の添字と同じ構文を使用した文字列へのアクセスをサポートしているので、次の例はあらゆるバージョンの PHP で成立します:
</simpara>
<example>
<title>文字列で配列の添字を使う</title>
<programlisting role="php">
<![CDATA[
<?php
$a = 'car'; // $a は文字列です
$a[0] = 'b'; // $a はここでも文字列です
echo $a; // bar
?>
]]>
</programlisting>
</example>
<simpara>
詳細は、
<link linkend="language.types.string.substr">文字列への文字単位のアクセス</link> を参照ください。
</simpara>
</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
-->