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 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
|
<?xml version="1.0" encoding="utf-8"?>
<chapter id="control-structures">
<title>제어 구조 (Control Structures)</title>
<simpara>
모든 PHP 스크립트는 일련의 구문으로 이루어 진다.
하나의 구문은 대입문이 될 수도 있고, 함수 호출, 반복문, 조건문이 될 수도 있으며
심지어는 아무 내용이 없는 빈 문장일 수도 있다.
한 구문은 일반적으로 세미콜론(;)으로 끝난다.
또한 여러개의 구문을 중괄호({,})를 사용하여 하나의 그룹으로 만들어 사용할 수도 있다.
이 구문-그룹은 그 그룹의 모든 구문들이 하나의 구문인 것처럼 인식된다.
여기서는 여러 가지 구문형태에 대해 알아본다.
</simpara>
<sect1 id="control-structures.if">
<title>
<literal>if</literal>
</title>
<para>
The <literal>if</literal> construct is one of the most important
features of many languages, PHP included. It allows for
conditional execution of code fragments.
PHP의 <literal>if</literal> 문은 C와 비슷하다.:
<informalexample>
<programlisting>
if (expr)
statement
</programlisting>
</informalexample>
</para>
<simpara>
As described in the section about expressions, expr is evaluated
to its truth value. If <replaceable>expr</replaceable> evaluates
to &true;, PHP will execute statement, and if it
evaluates to &false; - it'll ignore it.
</simpara>
<para>
The following example would display <computeroutput>a is bigger
than b</computeroutput> if <replaceable>$a</replaceable> is bigger
than <replaceable>$b</replaceable>:
<informalexample>
<programlisting role="php">
if ($a > $b)
print "a is bigger than b";
</programlisting>
</informalexample>
</para>
<para>
Often you'd want to have more than one statement to be executed
conditionally. Of course, there's no need to wrap each statement
with an <literal>if</literal> clause. Instead, you can group
several statements into a statement group. For example, this code
would display <computeroutput>a is bigger than b</computeroutput>
if <replaceable>$a</replaceable> is bigger than
<replaceable>$b</replaceable>, and would then assign the value of
<replaceable>$a</replaceable> into <replaceable>$b</replaceable>:
<informalexample>
<programlisting role="php">
if ($a > $b) {
print "a is bigger than b";
$b = $a;
}
</programlisting>
</informalexample>
</para>
<simpara>
If statements can be nested indefinitely within other
<literal>if</literal> statements, which provides you with complete
flexibility for conditional execution of the various parts of your
program.
</simpara>
</sect1>
<sect1 id="control-structures.else">
<title>
<literal>else</literal>
</title>
<para>
Often you'd want to execute a statement if a certain condition is
met, and a different statement if the condition is not met. This
is what <literal>else</literal> is for. <literal>else</literal>
extends an <literal>if</literal> statement to execute a statement
in case the expression in the <literal>if</literal> statement
evaluates to &false;. For example, the following
code would display <computeroutput>a is bigger than
b</computeroutput> if <replaceable>$a</replaceable> is bigger than
<replaceable>$b</replaceable>, and <computeroutput>a is NOT bigger
than b</computeroutput> otherwise:
<informalexample>
<programlisting role="php">
if ($a > $b) {
print "a is bigger than b";
} else {
print "a is NOT bigger than b";
}
</programlisting>
</informalexample>
The <literal>else</literal> statement is only executed if the
<literal>if</literal> expression evaluated to
&false;, and if there were any
<literal>elseif</literal> expressions - only if they evaluated to
&false; as well (see <link linkend="control-structures.elseif">elseif</link>).
</para>
</sect1>
<sect1 id="control-structures.elseif">
<title>
<literal>elseif</literal>
</title>
<para>
<literal>elseif</literal>, as its name suggests, is a combination
of <literal>if</literal> and <literal>else</literal>. Like
<literal>else</literal>, it extends an <literal>if</literal>
statement to execute a different statement in case the original
<literal>if</literal> expression evaluates to
&false;. However, unlike
<literal>else</literal>, it will execute that alternative
expression only if the <literal>elseif</literal> conditional
expression evaluates to &true;. For example, the
following code would display <computeroutput>a is bigger than
b</computeroutput>, <computeroutput>a equal to b</computeroutput>
or <computeroutput>a is smaller than b</computeroutput>:
<informalexample>
<programlisting role="php">
if ($a > $b) {
print "a is bigger than b";
} elseif ($a == $b) {
print "a is equal to b";
} else {
print "a is smaller than b";
}
</programlisting>
</informalexample>
</para>
<simpara>
There may be several <literal>elseif</literal>s within the same
<literal>if</literal> statement. The first
<literal>elseif</literal> expression (if any) that evaluates to
&true; would be executed. In PHP, you can also
write 'else if' (in two words) and the behavior would be identical
to the one of 'elseif' (in a single word). The syntactic meaning
is slightly different (if you're familiar with C, this is the same
behavior) but the bottom line is that both would result in exactly
the same behavior.
</simpara>
<simpara>
The <literal>elseif</literal> statement is only executed if the
preceding <literal>if</literal> expression and any preceding
<literal>elseif</literal> expressions evaluated to
&false;, and the current
<literal>elseif</literal> expression evaluated to
&true;.
</simpara>
</sect1>
<sect1 id="control-structures.alternative-syntax">
<title>제어구조의 다른 표현 (Alternative syntax for control structures)</title>
<para>
PHP는 대부분의 제어구조에 대해 기존의 방법과는 다른 표현 방법을 제공한다.
<literal>if</literal>, <literal>while</literal>, <literal>for</literal>,
<literal>foreach</literal>, <literal>switch</literal>의 5개의 제어구조에 대해,
여는 중괄호({) 대신 콜론( : )을 찍고, 닫는 중괄호(}) 대신 각각의 제어 구조에 따라
<literal>endif;</literal>나, <literal>endwhile;</literal>,<literal>endfor;</literal>,
<literal>endforeach;</literal>, <literal>endswitch;</literal>를 적어주면 된다.
<informalexample>
<programlisting role="php">
<?php if ($a == 5): ?>
A is equal to 5
<?php endif; ?>
</programlisting>
</informalexample>
</para>
<simpara>
위의 예에서 "A = 5"라는 HTML 블록이 <literal>if</literal>문 안에 사용되고 있다.
위의 HTML 블록은 $a가 5일 경우에만 표시된다.
</simpara>
<para>
다음과 같이 <literal>else</literal>와 <literal>elseif</literal>도 사용할 수 있다. :
<informalexample>
<programlisting role="php">
if ($a == 5):
print "a equals 5";
print "...";
elseif ($a == 6):
print "a equals 6";
print "!!!";
else:
print "a is neither 5 nor 6";
endif;
</programlisting>
</informalexample>
</para>
<para>
각각의 제어구조에 대한 예제는 <link linkend="control-structures.while">while</link>,
<link linkend="control-structures.for">for</link>, <link linkend="control-structures.if">if</link>를 보기 바란다.
</para>
</sect1>
<sect1 id="control-structures.while">
<title>
<literal>while</literal>
</title>
<para>
<literal>while</literal> 루프는 PHP의 가장 간단한 제어구조이다.
이것은 C와 동일하게 작동한다. <literal>while</literal>의 기본 형태는 다음과 같다. :
<informalexample>
<programlisting>
while (expr) statement
</programlisting>
</informalexample>
</para>
<simpara>
The meaning of a <literal>while</literal> statement is simple. It
tells PHP to execute the nested statement(s) repeatedly, as long
as the <literal>while</literal> expression evaluates to
&true;. The value of the expression is checked
each time at the beginning of the loop, so even if this value
changes during the execution of the nested statement(s), execution
will not stop until the end of the iteration (each time PHP runs
the statements in the loop is one iteration). Sometimes, if the
<literal>while</literal> expression evaluates to
&false; from the very beginning, the nested
statement(s) won't even be run once.
</simpara>
<para>
Like with the <literal>if</literal> statement, you can group
multiple statements within the same <literal>while</literal> loop
by surrounding a group of statements with curly braces, or by
using the alternate syntax:
<informalexample>
<programlisting>
while (expr): statement ... endwhile;
</programlisting>
</informalexample>
</para>
<para>
The following examples are identical, and both print numbers from
1 to 10:
<informalexample>
<programlisting>
/* example 1 */
$i = 1;
while ($i <= 10) {
print $i++; /* the printed value would be
$i before the increment
(post-increment) */
}
/* example 2 */
$i = 1;
while ($i <= 10):
print $i;
$i++;
endwhile;
</programlisting>
</informalexample>
</para>
</sect1>
<sect1 id="control-structures.do.while">
<title>
<literal>do..while</literal>
</title>
<simpara>
<literal>do..while</literal> 루프는 비교식이 앞이 아닌 맨 뒤에 있다는 점을 제외하면
<literal>while</literal> 루프와 비슷하다.
The main difference from regular <literal>while</literal> loops is
that the first iteration of a <literal>do..while</literal> loop is
guarenteed to run (the truth expression is only checked at the end
of the iteration), whereas it's may not necessarily run with a
regular <literal>while</literal> loop (the truth expression is
checked at the beginning of each iteration, if it evaluates to
&false; right from the beginning, the loop
execution would end immediately).
</simpara>
<para>
There is just one syntax for <literal>do..while</literal> loops:
<informalexample>
<programlisting role="php">
$i = 0;
do {
print $i;
} while ($i>0);
</programlisting>
</informalexample>
</para>
<simpara>
The above loop would run one time exactly, since after the first
iteration, when truth expression is checked, it evaluates to
&false; ($i is not bigger than 0) and the loop
execution ends.
</simpara>
<para>
Advanced C users may be familiar with a different usage of the
<literal>do..while</literal> loop, to allow stopping execution in
the middle of code blocks, by encapsulating them with
<literal>do..while</literal>(0), and using the <link linkend="control-structures.break">
<literal>break</literal>
</link>
statement. The following code fragment demonstrates this:
<informalexample>
<programlisting role="php">
do {
if ($i < 5) {
print "i is not big enough";
break;
}
$i *= $factor;
if ($i < $minimum_limit) {
break;
}
print "i is ok";
...process i...
} while(0);
</programlisting>
</informalexample>
</para>
<simpara>
Don't worry if you don't understand this right away or at all.
You can code scripts and even powerful scripts without using this
`feature'.
</simpara>
</sect1>
<sect1 id="control-structures.for">
<title>
<literal>for</literal>
</title>
<para>
<literal>for</literal> 루프는 PHP에서 가장 복잡한 루프이다.
이것의 형태은 C와 매우 유사하다. <literal>for</literal> 루프의 문법은 다음과 같다. :
<informalexample>
<programlisting>
for (expr1; expr2; expr3) statement
</programlisting>
</informalexample>
</para>
<simpara>
첫 번째 표현식(<replaceable>expr1</replaceable>)은 루프를 시작할 때 무조건 한번 평가(실행)된다.
</simpara>
<simpara>
매 반복의 시작 때마다 <replaceable>expr2</replaceable>가 평가된다.
만약 이것이 &true;면 루프는 계속되고 statement가 실행된다.
&false;이면 루프는 종료된다.
</simpara>
<simpara>
매 반복이 끝날 때 <replaceable>expr3</replaceable>가 평가(실행)된다.
</simpara>
<simpara>
각 평가식은 비워둘 수 있다. <replaceable>expr2</replaceable>가 비어있으면 무한 루프를 뜻한다.
(PHP는 C와 같이 비어있으면 &true;로 인식한다.)
이건 별로 좋은 방법이 아니지만, 종종 이렇게 사용하고 <link linkend="control-structures.break">
<literal>break</literal>
</link>를 사용하여 종료하는 방법도 있다.
</simpara>
<para>
다음 예는 1에서 10까지 출력하는 예제들이다. :
<informalexample>
<programlisting role="php">
/* example 1 */
for ($i = 1; $i <= 10; $i++) {
print $i;
}
/* example 2 */
for ($i = 1;;$i++) {
if ($i > 10) {
break;
}
print $i;
}
/* example 3 */
$i = 1;
for (;;) {
if ($i > 10) {
break;
}
print $i;
$i++;
}
/* example 4 */
for ($i = 1; $i <= 10; print $i, $i++) ;
</programlisting>
</informalexample>
</para>
<simpara>
물론 처음것이 가장 좋아보인다. 그러나 나머지도 가능하다는 것을 알아야 한다.
</simpara>
<para>
PHP는 <literal>for</literal> 루프에 대해서도 다음과 같은 "colon syntax"를 지원한다.
<informalexample>
<programlisting>
for (expr1; expr2; expr3): statement; ...; endfor;
</programlisting>
</informalexample>
</para>
<para>
Other languages have a <literal>foreach</literal> statement to
traverse an array or hash. PHP 3 has no such construct; PHP 4 does
(see <link linkend="control-structures.foreach">foreach</link>). In PHP 3, you
can combine <link linkend="control-structures.while">while</link>
with the <function>list</function> and <function>each</function>
functions to achieve the same effect. See the documentation for
these functions for an example.
</para>
</sect1>
<sect1 id="control-structures.foreach">
<title>
<literal>foreach</literal>
</title>
<para>
PHP4(PHP3는 아니다)는 perl 등의 다른 언어가 제공하는 foreach 구조를 제공한다.
이 구조는 배열에 있어서 반복적인 작업을 하는데 유용하다.
이것에는 두가지 문법이 있는데, 두 번째 것은 첫 번째 것의 부분 확장이라고
생각할 수 있으나 실제로 매우 유용하게 사용된다.
<informalexample>
<programlisting>
foreach(array_expression as $value) statement
foreach(array_expression as $key => $value) statement
</programlisting>
</informalexample>
</para>
<simpara>
첫 번째 모양은 <literal>array_expression</literal> 으로 주어진 배열에 대해 루프를 수행한다.
개개의 루프작업내에서, 배열의 원소는 <literal>$value</literal>에 저장되고
내부 배열 포인터(internal array pointer)는 하나 전진하여 다음 작업시에 새로운 원소를 가져오도록 한다.
</simpara>
<simpara>
두 번째 모양은 첫 번째와 동일한 작업을 하지만, <literal>$key</literal>에 해당 원소의 키값을 저장하게 된다.
</simpara>
<para>
<note>
<para>
<literal>foreach</literal> 문이 처음 수행될 때, 내부 배열 포인터(internal array pointer)는
자동적으로 배열의 첫번째 원소로 설정된다. 이말의 의미는 여러분이 <literal>foreach</literal>문을 사용할 때
<function>reset</function>을 미리 호출할 필요는 없다는 것이다.
</para>
</note>
</para>
<para>
<note>
<para>
Also note that <literal>foreach</literal> operates on a copy of
the specified array, not the array itself, therefore the array
pointer is not modified like with the each construct.
</para>
</note>
</para>
<para>
아래의 두 개의 문장은 동일한 결과를 만든다는 것을 알 수 있을 것이다. :
<informalexample>
<programlisting role="php">
reset ($arr);
while (list(, $value) = each ($arr)) {
echo "Value: $value<br>\n";
}
foreach ($arr as $value) {
echo "Value: $value<br>\n";
}
</programlisting>
</informalexample>
다음 두 개의 문장도 기능적으로 동일하다. :
<informalexample>
<programlisting role="php">
reset ($arr);
while (list($key, $value) = each ($arr)) {
echo "Key: $key; Value: $value<br>\n";
}
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br>\n";
}
</programlisting>
</informalexample>
</para>
<para>
추가적으로 몇 개의 예제를 보자. :
<informalexample>
<programlisting role="php">
/* foreach example 1: value only */
$a = array (1, 2, 3, 17);
foreach ($a as $v) {
print "Current value of \$a: $v.\n";
}
/* foreach example 2: value (with key printed for illustration) */
$a = array (1, 2, 3, 17);
$i = 0; /* for illustrative purposes only */
foreach($a as $v) {
print "\$a[$i] => $k.\n";
}
/* foreach example 3: key and value */
$a = array (
"one" => 1,
"two" => 2,
"three" => 3,
"seventeen" => 17
);
foreach($a as $k => $v) {
print "\$a[$k] => $v.\n";
}
</programlisting>
</informalexample>
</para>
</sect1>
<sect1 id="control-structures.break">
<title>
<literal>break</literal>
</title>
<simpara>
<literal>break</literal>는 <literal>for</literal>나, <literal>while</literal>,
<literal>switch</literal>에서 빠져 나가는 명령이다.
</simpara>
<simpara>
<literal>break</literal>에는 숫자 옵션을 줄 수 있는데,
이것은 한번에 빠져 나갈 제어 구조의 수를 의미한다.
</simpara>
<para>
<informalexample>
<programlisting role="php">
$arr = array ('one', 'two', 'three', 'four', 'stop', 'five');
while (list (, $val) = each ($arr)) {
if ($val == 'stop') {
break; /* You could also write 'break 1;' here. */
}
echo "$val<br>\n";
}
/* Using the optional argument. */
$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "At 5<br>\n";
break 1; /* Exit only the switch. */
case 10:
echo "At 10; quitting<br>\n";
break 2; /* Exit the switch and the while. */
default:
break;
}
}
</programlisting>
</informalexample>
</para>
</sect1>
<sect1 id="control-structures.continue">
<title>
<literal>continue</literal>
</title>
<simpara>
<literal>continue</literal> 는 현재 루프의 처음으로 가도록 하는 명령이다.
</simpara>
<simpara>
<literal>continue</literal>도 숫자 옵션을 줄 수 있는데,
이것도 <literal>break</literal>에서와 같이 한번에 처음으로 갈 제어 구조의 수를 의미한다.
</simpara>
<para>
<informalexample>
<programlisting role="php">
while (list ($key, $value) = each ($arr)) {
if (!($key % 2)) { // skip odd members
continue;
}
do_something_odd ($value);
}
$i = 0;
while ($i++ < 5) {
echo "Outer<br>\n";
while (1) {
echo " Middle<br>\n";
while (1) {
echo " Inner<br>\n";
continue 3;
}
echo "This never gets output.<br>\n";
}
echo "Neither does this.<br>\n";
}
</programlisting>
</informalexample>
</para>
</sect1>
<sect1 id="control-structures.switch">
<title>
<literal>switch</literal>
</title>
<simpara>
<literal>switch</literal>문은 내용상 동일한 표현식의 IF문을 나열한 것과 비슷하다.
많은 경우에 한 변수를 여러 다른 값과 비교하여,
두개의 값이 같는냐에 따라 서로 다른 코드들이 수행되기를 원하는 때가 있다.
바로 이런 경우에 <literal>switch</literal>문이 사용된다.
</simpara>
<para>
다음은 동일한 결과를 가져오는 예를 각각 <literal>if</literal>문과
<literal>switch</literal>문으로 표현한 것이다. :
<informalexample>
<programlisting role="php">
if ($i == 0) {
print "i equals 0";
}
if ($i == 1) {
print "i equals 1";
}
if ($i == 2) {
print "i equals 2";
}
switch ($i) {
case 0:
print "i equals 0";
break;
case 1:
print "i equals 1";
break;
case 2:
print "i equals 2";
break;
}
</programlisting>
</informalexample>
</para>
<para>
<literal>switch</literal>문은 문장 단위로 실행된다.
<literal>switch</literal>에 있는 평가식과 일치하는 <literal>case</literal>문을 찾아
그 이후부터 <literal>switch</literal> 블럭이 끝날 때의 모든 문장을 실행한다.
따라서 원하는 경우 <literal>break</literal>로 실행을 중지시킬 필요가 있다.
다음 예를 보자. :
<informalexample>
<programlisting role="php">
switch ($i) {
case 0:
print "i equals 0";
case 1:
print "i equals 1";
case 2:
print "i equals 2";
}
</programlisting>
</informalexample>
</para>
<simpara>
여기서 $i가 0이면 모든 print문을 실행할 것이다.
만약 $i가 1이면 마지막 두개의 print문을 실행한다.
따라서 각각의 경우에 하나의 print 문만이 실행되기를 원한다면,
<literal>break</literal>문을 잊지 않아야한다.
</simpara>
<simpara>
In a <literal>switch</literal> statement, the condition is
evaluated only once and the result is compared to each
<literal>case</literal> statement. In an <literal>elseif</literal>
statement, the condition is evaluated again. If your condition is
more complicated than a simple compare and/or is in a tight loop,
a <literal>switch</literal> may be faster.
</simpara>
<para>
The statement list for a case can also be empty, which simply
passes control into the statement list for the next case.
<informalexample>
<programlisting role="php">
switch ($i) {
case 0:
case 1:
case 2:
print "i is less than 3 but not negative";
break;
case 3:
print "i is 3";
}
</programlisting>
</informalexample>
</para>
<para>
특별한 case로 default case가 있다.
이것은 다른 어떤 case에도 맞지 않는 경우를 의미한다. 예를 들어 :
<informalexample>
<programlisting role="php">
switch ($i) {
case 0:
print "i equals 0";
break;
case 1:
print "i equals 1";
break;
case 2:
print "i equals 2";
break;
default:
print "i is not equal to 0, 1 or 2";
}
</programlisting>
</informalexample>
</para>
<para>
다른 중요한 점은 <literal>case</literal> 표현식에는 정수, 실수, 문자열같은
스칼리 타입으로 평가되는 어떤 표현식이와도 된다는 것이다.
배열이나 객체는 스칼리 타입으로 변환시켜 사용하지 않는 한 사용할 수 없다.
</para>
<para>
switch 문에 대해서도 Alternative syntax가 지원된다. 자세한 내용은
<link linkend="control-structures.alternative-syntax">Alternative syntax for control structures</link>를 살펴보자
<informalexample>
<programlisting role="php">
switch ($i):
case 0:
print "i equals 0";
break;
case 1:
print "i equals 1";
break;
case 2:
print "i equals 2";
break;
default:
print "i is not equal to 0, 1 or 2";
endswitch;
</programlisting>
</informalexample>
</para>
</sect1>
<sect1 id="function.require">
<title>
<function>require</function>
</title>
<simpara>
<function>require</function> 문은 C preprocessor의 <literal>#include</literal>와 비슷하게,
자신을 지정된 파일로 대체한다.
</simpara>
<simpara>
PHP에서 "URL fopen wrappers"가 enabled되어 있으면 (기본값은 enabled이다.),
<function>require</function>될 함수로 일반 파일 뿐 아니라 URL도 사용할 수 있다.
자세한 내용은 <link linkend="features.remote-files">Remote files</link>와
<function>fopen</function>을 살펴보기 바란다.
</simpara>
<simpara>
<function>include</function> 되거나 <function>require</function> 되어 읽혀지는 파일은
포함된 파일의 처음에 PHP모드에서 빠져나와 HTML모드로 들어가고, 마지막에 PHP모드로 복귀한다.
따라서 포함될 파일의 PHP 코드는 <link linkend="language.basic-syntax.phpmode">적절한 PHP 시작,
종료 택</link>에 둘러싸여 있어야 한다.
</simpara>
<simpara>
<function>require</function>는 함수가 아니라 제어구조이다.
따라서 당연히 함수와는 다른 규칙을 따른다.
이를테면 <function>require</function>는 다른 어떤 제어구조와도 함께사용할 수 없다.
또한, 이것은 반환값이 없다. (반환값을 돌려받으려하면 문법 에러가 난다.)
</simpara>
<simpara>
<function>include</function>와 다르게, <function>require</function>는 언제나 해당 파일을 읽어온다.
<emphasis>심지어 해당 라인이 전혀 실행되지 않아도 읽어온다.</emphasis>
만약 조건에 따라 파일을 포함시키고 싶다면 <function>include</function>문을 사용하여야 한다.
조건절은 <function>require</function>문에 아무 영향을 미치지 못한다.
그러나, <function>require</function>문이 있는 줄이 실행되지 않으면 읽어온 파일의 어떤 코드도 실행되지는 않는다.
</simpara>
<simpara>
마찬가지로, 순환문도 <function>require</function>문에 영향을 주지 못한다.
포함된 파일의 코드가 루프에 적용을 받기는 하지만,
<function>require</function> 동작 자체는 단지 한번만 일어나는 것이다.
</simpara>
<para>
이것은 매 순환시마다 다른 파일을 읽어오려 한다면
순환문 안에 <function>require</function> 문을 사용해서는 안된다는 것을 의미한다.
이런 경우에는 <function>include</function>문을 사용하여야 한다는 것이다.
<informalexample>
<programlisting role="php">
require ('header.inc');
</programlisting>
</informalexample>
</para>
<simpara>
When a file is <function>require</function>ed, the code it
contains inherits the variable scope of the line on which the
<function>require</function> occurs. Any variables available at
that line in the calling file will be available within the called
file. If the <function>require</function> occurs inside a
function within the calling file, then all of the code contained
in the called file will behave as though it had been defined
inside that function.
</simpara>
<para>
If the <function>require</function>ed file is called via HTTP
using the fopen wrappers, and if the target server interprets the
target file as PHP code, variables may be passed to the
<function>require</function>ed file using an URL request string as
used with HTTP GET. This is not strictly speaking the same thing
as <function>require</function>ing the file and having it inherit
the parent file's variable scope; the script is actually being run
on the remote server and the result is then being included into
the local script.
<informalexample>
<programlisting role="php">
/* This example assumes that someserver is configured to parse .php
* files and not .txt files. Also, 'works' here means that the variables
* $varone and $vartwo are available within the require()ed file. */
/* Won't work; file.txt wasn't handled by someserver. */
require ("http://someserver/file.txt?varone=1&vartwo=2");
/* Won't work; looks for a file named 'file.php?varone=1&vartwo=2'
* on the local filesystem. */
require ("file.php?varone=1&vartwo=2");
/* Works. */
require ("http://someserver/file.php?varone=1&vartwo=2");
$varone = 1;
$vartwo = 2;
require ("file.txt"); /* Works. */
require ("file.php"); /* Works. */
</programlisting>
</informalexample>
</para>
<simpara>
PHP3에서는 <function>require</function>로 포함된 파일안에서 <literal>return</literal> 문을 사용할 수 있었다.
단, return 문이 포함된 파일의 global scope에서만 가능하고, 어떠한 블록내({} 내부)에서도 사용할 수 없다.
그러나, PHP4에서는 이런 기능 자체가 없어져 버렸다.
만약 여러분이 이런 기능을 사용하고 싶다면 <function>include</function>문을 사용하기 바란다.
</simpara>
<simpara>
See also <function>include</function>, <function>require_once</function>,
<function>include_once</function>, <function>readfile</function>,
and <function>virtual</function>.
</simpara>
</sect1>
<sect1 id="function.include">
<title>
<function>include</function>
</title>
<simpara>
<function>include</function>문은 지정한 파일을 읽고 실행한다.
</simpara>
<simpara>
If "URL fopen wrappers" are enabled in PHP (which they are in the
default configuration), you can specify the file to be
<function>include</function>ed using an URL instead of a local
pathname. See <link linkend="features.remote-files">Remote
files</link> and <function>fopen</function> for more information.
</simpara>
<simpara>
<function>include</function>되거나 <function>require</function> 되어 읽혀지는 파일은
포함된 파일의 처음에 PHP모드에서 빠져나와 HTML모드로 들어가고, 마지막에 PHP모드로 복귀한다.
따라서 포함될 파일의 PHP 코드는 <link linkend="language.basic-syntax.phpmode">적절한 PHP 시작, 종료 택</link>에
둘러싸여 있어야 한다.
</simpara>
<para>
해당 파일을 읽어들이는 동작은 실행중 <function>include</function> 문을 만날 때 마다 일어난다.
따라서 <function>include</function> 문을 루프 구조 안에 두어 매번 다른 파일을 읽어 들이도록 할 수 있다.
<informalexample>
<programlisting role="php">
$files = array ('first.inc', 'second.inc', 'third.inc');
for ($i = 0; $i < count($files); $i++) {
include $files[$i];
}
</programlisting>
</informalexample>
</para>
<para>
<function>include</function>는 이 문장을 만날 때 마다 매번 새로 읽어들이고 실행된다는 점에서
<function>require</function>와 다르다. 반면에 require()문은 지정된 파일의 내용이 실행되는가에 관계없이
(예를들어 <link linkend="control-structures.if">if</link> 문 안에 들어있고 상태가 거짓인 경우에도),
이 문장을 처음 만났을 때 지정된 파일로 대체된다.
</para>
<para>
<function>include</function>는 특별한 구조이므로, 만약 이것이 조전절 안에 놓여있다면
반드시 {}(statement block)으로 둘러싸야 한다.
<informalexample>
<programlisting role="php">
/* This is WRONG and will not work as desired. */
if ($condition)
include($file);
else
include($other);
/* This is CORRECT. */
if ($condition) {
include($file);
} else {
include($other);
}
</programlisting>
</informalexample>
</para>
<simpara>
PHP3, PHP4 모두 <function>include</function>된 파일 내에서, 이 파일내의 수행을 종료하고,
이 파일을 부른 스크립트로 복귀하기 위해 <literal>return</literal>문을 사용할 수 있다.
약간 다른점이 있기는하다. 우선, PHP3에서는 해당 블록이 함수의 블록이 아닌한 return 문이 블록안에 올 수 없다.
(함수의 블록 안에 있는 경우는 해당 함수에서 return 하는 것이지 현재 파일에서 return 하는 것은 아니다.)
반드시 Global scope에 위치해야 한다. 그러나, PHP4에서는 이 제한이 없다.
또한 PHP4에서는 <function>include</function> 파일의 <literal>return</literal>시에 리턴값을 사용할 수 있다.
<function>include</function>문을 일반 함수처럼 사용하여 반환값을 받을 수 있다.
PHP3에서는 이렇게 사용하면 구문에러를 발생시킨다.
</simpara>
<example>
<title>
<function>include</function> in PHP 3 and PHP 4</title>
<para>
다음의 <filename>test.inc</filename>라는 파일이 메인 파일과 동일한 디렉토리에 있다고 가정한다. :
<programlisting role="php">
<?php
echo "Before the return <br>\n";
if (1) {
return 27;
}
echo "After the return <br>\n";
?>
</programlisting>
</para>
<para>
<filename>main.html</filename> 이라는 메인파일의 내용은 다음과 같다. :
<programlisting role="php">
<?php
$retval = include ('test.inc');
echo "File returned: '$retval'<br>\n";
?>
</programlisting>
</para>
<para>
<filename>main.html</filename>이 PHP3에서 불려지면, 이 파일은 두 번째 줄에서
"you can't take the value of an <function>include</function> " 라는 구문 에러를 발생시킨다.
그러나, PHP4에서는 다음돠 같은 결과를 출력한다. :
<screen>
Before the return
File returned: '27'
</screen>
</para>
<para>
이제 <filename>main.html</filename>을 다음과 같은 내용으로 고쳐서 실행해 보자. :
<programlisting role="php">
<?php
include ('test.inc');
echo "Back in main.html<br>\n";
?>
</programlisting>
</para>
<para>
PHP4에서는 다음과 같은 결과가 출력된다. :
<screen>
Before the return
Back in main.html
</screen>
그러나 PHP3에서는 다음과 같은 결과가 나온다. :
<screen>
Before the return
27Back in main.html
Parse error: parse error in /home/torben/public_html/phptest/main.html on line 5
</screen>
</para>
<para>
위의 구문 에러는 <filename>test.inc</filename>에서 <literal>return</literal> 문이
함수블록이외의 블록안에 사용되었기 때문에 생긴다.
<literal>return</literal> 문을 블록 밖으로 꺼내면 다음과 같은 경과가 출력된다. :
<screen>
Before the return
27Back in main.html
</screen>
</para>
<para>
위의 '27'이 출력된 것은 PHP3가 include파일로 부터의 값의 반환을 지원하지 않기 때문이다.
</para>
</example>
<simpara>
When a file is <function>include</function>ed, the code it
contains inherits the variable scope of the line on which the
<function>include</function> occurs. Any variables available at
that line in the calling file will be available within the called
file. If the <function>include</function> occurs inside a
function within the calling file, then all of the code contained
in the called file will behave as though it had been defined
inside that function.
</simpara>
<para>
If the <function>include</function>ed file is called via HTTP
using the fopen wrappers, and if the target server interprets the
target file as PHP code, variables may be passed to the
<function>include</function>ed file using an URL request string as
used with HTTP GET. This is not strictly speaking the same thing
as <function>include</function>ing the file and having it inherit
the parent file's variable scope; the script is actually being run
on the remote server and the result is then being included into
the local script.
<informalexample>
<programlisting role="php">
/* This example assumes that someserver is configured to parse .php
* files and not .txt files. Also, 'works' here means that the variables
* $varone and $vartwo are available within the include()ed file. */
/* Won't work; file.txt wasn't handled by someserver. */
include ("http://someserver/file.txt?varone=1&vartwo=2");
/* Won't work; looks for a file named 'file.php?varone=1&vartwo=2'
* on the local filesystem. */
include ("file.php?varone=1&vartwo=2");
/* Works. */
include ("http://someserver/file.php?varone=1&vartwo=2");
$varone = 1;
$vartwo = 2;
include ("file.txt"); /* Works. */
include ("file.php"); /* Works. */
</programlisting>
</informalexample>
</para>
<simpara>
See also <function>require</function>, <function>require_once</function>,
<function>include_once</function>, <function>readfile</function>,
and <function>virtual</function>.
</simpara>
</sect1>
<sect1 id="function.require-once">
<title>
<function>require_once</function>
</title>
<para>
The <function>require_once</function> statement replaces
itself with the specified file, much like the C preprocessor's
<literal>#include</literal> works, and in that respect is
similar to the <function>require</function> statement. The main
difference is that in an inclusion chain, the use of
<function>require_once</function> will assure that the code is
added to your script only once, and avoid clashes with variable
values or function names that can happen.
</para>
<para>
For example, if you create the following 2 include files
<literal>utils.inc</literal> and <literal>foolib.inc</literal>
<example>
<title>utils.inc</title>
<programlisting role="php">
<?php
define(PHPVERSION, floor(phpversion()));
echo "GLOBALS ARE NICE\n";
function goodTea() {
return "Oolong tea tastes good!";
}
?>
</programlisting>
</example>
<example>
<title>foolib.inc</title>
<programlisting role="php">
<?php
require ("utils.inc");
function showVar($var) {
if (PHPVERSION == 4) {
print_r($var);
} else {
var_dump($var);
}
}
// bunch of other functions ...
?>
</programlisting>
</example>
And then you write a script <literal>cause_error_require.php</literal>
<example>
<title>cause_error_require.php</title>
<programlisting role="php">
<?php
require("foolib.inc");
/* the following will generate an error */
require("utils.inc");
$foo = array("1",array("complex","quaternion"));
echo "this is requiring utils.inc again which is also\n";
echo "required in foolib.inc\n";
echo "Running goodTea: ".goodTea()."\n";
echo "Printing foo: \n";
showVar($foo);
?>
</programlisting>
</example>
When you try running the latter one, the resulting ouptut will be (using
PHP 4.01pl2):
<informalexample>
<programlisting>
GLOBALS ARE NICE
GLOBALS ARE NICE
Fatal error: Cannot redeclare goodTea() in utils.inc on line 5
</programlisting>
</informalexample>
By modifying <literal>foolib.inc</literal> and
<literal>cause_errror_require.php</literal>
to use <function>require_once</function>
instead of <function>require</function> and renaming the
last one to <literal>avoid_error_require_once.php</literal>, we have:
<example>
<title>foolib.inc (fixed)</title>
<programlisting role="php">
...
require_once("utils.inc");
function showVar($var) {
...
</programlisting>
</example>
<example>
<title>avoid_error_require_once.php</title>
<programlisting role="php">
...
require_once("foolib.inc");
require_once("utils.inc");
$foo = array("1",array("complex","quaternion"));
...
</programlisting>
</example>
And when running the latter, the output will be (using PHP 4.0.1pl2):
<informalexample>
<programlisting>
GLOBALS ARE NICE
this is requiring globals.inc again which is also
required in foolib.inc
Running goodTea: Oolong tea tastes good!
Printing foo:
Array
(
[0] => 1
[1] => Array
(
[0] => complex
[1] => quaternion
)
)
</programlisting>
</informalexample>
</para>
<para>
Also note that, analogous to the behavior of the
<literal>#include</literal> of the C preprocessor, this statement
acts at "compile time", e.g. when the script is parsed and before it
is executed, and should not be used for parts of the script that need
to be inserted dynamically during its execution. You should use
<function>include_once</function> or <function>include</function>
for that purpose.
</para>
<para>
For more examples on using <function>require_once</function> and
<function>include_once</function>, look at the PEAR code included in
the latest PHP source code distributions.
</para>
<para>
See also: <function>require</function>,
<function>include</function>, <function>include_once</function>,
<function>get_required_files</function>,
<function>get_included_files</function>, <function>readfile</function>,
and <function>virtual</function>.
</para>
</sect1>
<sect1 id="function.include-once">
<title>
<function>include_once</function>
</title>
<para>
The <function>include_once</function> statement includes and evaluates
the specified file during the execution of the script.
This is a behavior similar to the <function>include</function> statement,
with the important difference that if the code from a file has already
been included, it will not be included again.
</para>
<para>
As mentioned in the <function>require_once</function> description, the
<function>include_once</function> should be used in the cases in which
the same file might be included and evaluated more than once during a
particular execution of a script, and you want to be sure that it is
included exactly once to avoid problems with function redefinitions,
variable value reassignments, etc.
</para>
<para>
For more examples on using <function>require_once</function> and
<function>include_once</function>, look at the PEAR code included in
the latest PHP source code distributions.
</para>
<para>
<function>include_once</function> was added in PHP 4.0.1pl2
</para>
<para>
See also: <function>require</function>,
<function>include</function>, <function>require_once</function>,
<function>get_required_files</function>,
<function>get_included_files</function>, <function>readfile</function>,
and <function>virtual</function>.
</para>
</sect1>
</chapter>
<!-- 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:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
|