3. PHP 基础
3.1. 第一个示例
下面是一个演示 PHP 基本功能的程序。
3.1.1. 该程序(example_01)
<?php
// this is a comment
// variable used without being declared
$nom = "dupont";
// a screen display
print "nom=$nom\n";
// an array with elements of different types
$tableau = array("un", "deux", 3, 4);
// its number of elements
$n = count($tableau);
// a loop
for ($i = 0; $i < $n; $i++)
print "tableau[$i]=$tableau[$i]\n";
// initialize 2 variables with the contents of an array
list($chaine1, $chaine2) = array("chaine1", "chaine2");
// concatenation of the 2 strings
$chaine3 = $chaine1 . $chaine2;
// result display
print "[$chaine1,$chaine2,$chaine3]\n";
// use function
affiche($chaine1);
// the type of a variable can be known
afficheType($n);
afficheType($chaine1);
afficheType($tableau);
// the type of a variable can change at runtime
$n = "a changé";
afficheType($n);
// a function can return a result
$res1 = f1(4);
print "res1=$res1\n";
// a function can return a table of values
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";
// we could have retrieved these values in a table
$t = f2();
for ($i = 0; $i < count($t); $i++)
print "t[$i]=$t[$i]\n";
// testing
for ($i = 0; $i < count($t); $i++)
// displays only channels
if (getType($t[$i]) == "string")
print "t[$i]=$t[$i]\n";
// other tests
for ($i = 0; $i < count($t); $i++){
// displays only integers >10
if (getType($t[$i]) == "integer" and $t[$i] > 10)
print "t[$i]=$t[$i]\n";
}
// a while loop
$t = array(8, 5, 0, -2, 3, 4);
$i = 0;
$somme = 0;
while ($i < count($t) and $t[$i] > 0) {
print "t[$i]=$t[$i]\n";
$somme+=$t[$i]; //$s//$somme=$somme+$t[$i]
$i++; //$i=$i+1
}
print "somme=$somme\n";
// end of program
exit;
//----------------------------------
function affiche($chaine) {
// displays $chaine
print "chaine=$chaine\n";
}
//----------------------------------
function afficheType($variable) {
// displays the type of $variable
print "type[$variable]=" . getType($variable) . "\n";
}
//----------------------------------
function f1($param) {
// adds 10 to $param
return $param + 10;
}
//----------------------------------
function f2() {
// returns 3 values
return array("un", 0, 100);
}
?>
结果:
注释
- 第 5 行:在 PHP 中,变量类型无需声明。变量具有动态类型,其类型会随时间变化
- $name 表示标识符为 name 的变量
- 第 8 行:要在屏幕上显示文本,可以使用 print 语句或 echo 语句
- 第 11 行:关键字
*array*用于定义数组。变量$name[$i]表示数组$array的第$i个元素。 - 第 14 行:count($tableau) 函数返回 $tableau 数组中的元素个数
- 第 18 行:字符串用双引号 " 或单引号 ' 括起来。在双引号内,变量 $variable 会被求值,但在单引号内则不会。
- 第 21 行:list 函数允许您将变量分组到一个列表中,并通过单次赋值操作为它们赋值。这里,$string1="string1" 且 $string2="string2"。
- 第 24 行:. 运算符是字符串连接运算符。
- 第 88 行:关键字 function 用于定义函数。函数可以通过 return 语句返回值,也可以不返回值。调用代码可以忽略函数的结果,也可以获取结果。函数可以在代码的任何位置定义。
- 第 90 行:预定义函数 getType($variable) 返回一个字符串,表示 $variable 的类型。该类型可能会随时间变化。
- 第 79 行:预定义函数 exit 用于终止脚本。
3.2. 变量作用域
3.2.1. 程序 1 (example_02)
<?php
// variable scope
function f1() {
// we use the global variable $i
$i = &$GLOBALS["i"];
$i++;
$j = 10;
print "f1[i,j]=[$i,$j]\n";
}
function f2() {
// we use the global variable $i
$i = &$GLOBALS["i"];
$i++;
$j = 20;
print "f2[i,j]=[$i,$j]\n";
}
function f3() {
// we use a local variable $i
$i = 4;
$j = 30;
print "f3[i,j]=[$i,$j]\n";
}
// tests
$i = 0;
$j = 0; /// these two variables are known to a function f via the table $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>
结果:
注释
- 第 29–30 行:在主程序中定义两个变量 $i 和 $j。这些变量在函数内部是未知的。因此,在第 9 行中,函数 f1 中的变量 $j 是函数 f1 的局部变量,与主程序中的变量 $j 不同。函数可以通过一个名为 $GLOBALS 的全局变量数组访问主程序中的变量 $variable。 在第 7 行中,$GLOBALS["i"] 表示主程序的全局变量 $i。如果我们写
,则局部变量 $i 被赋予全局变量 $i 的值。这两个变量是不同的,修改局部变量 $i 不会改变全局变量 $i。该表示法
会导致局部变量 $i 与全局变量 $i 拥有相同的内存地址。此时,对局部变量 $i 的操作等同于对全局变量 $i 的操作。
3.2.2. 程序 2 (example_03)
<?php
// the scope of a variable is global to code blocks
$i = 0; {
$i = 4;
$i++;
}
print "i=$i\n";
?>
结果:
注释
在某些语言中,定义在花括号内的变量其作用域仅限于该花括号内:在花括号外部无法访问该变量。上面的结果表明,PHP 并非如此。第 5 行花括号内定义的变量 $i 与第 4 行和第 8 行花括号外部使用的变量是同一个。
3.3. 数组
3.3.1. 经典的一维数组(example_04)
<?php
// classic paintings
// initialization
$tab1 = array(0, 1, 2, 3, 4, 5);
// routes - 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// routes - 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
print "tab1[$clé]=$valeur\n";
// add elements
$tab1[] = $i++;
$tab1[] = $i++;
// routes - 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
print "tab1[$i]=$élément\n";
$i++;
}
// delete last item
array_pop($tab1);
// routes - 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// delete first element
array_shift($tab1);
// routes - 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// addition at end of table
array_push($tab1, -2);
// routes - 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
// addition at the beginning of the table
array_unshift($tab1, -1);
// routes - 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
print "tab1[$i]=$tab1[$i]\n";
?>
结果:
注释
上面的程序演示了如何操作数组。PHP 中有两种数组表示法:
数组 1 被称为数组,数组 2 被称为字典,其中元素以键 => 值的形式表示。符号 $opposites["beautiful"] 指的是与键 "beautiful" 关联的值。在此,该值是字符串 "ugly"。数组 1 只是字典的一种变体,可以写成:
因此,我们得到 $array[2]="three"。归根结底,所有数据结构本质上都是字典。对于经典的 n 元素数组,其键是 [0,n-1] 范围内的整数。
- 第 15 行:each($array) 函数允许你遍历一个字典。每次调用时,它都会从字典中返回一个 (键, 值) 对。
- 第 14 行:reset($dictionary) 函数将 each 函数的起始位置设置为字典中的第一个 (键, 值) 对。
- 第 15 行:当 each 函数在字典结尾返回一个空元组时,while 循环停止。
- 第 19 行:$array[]=value 这种写法将元素 value 作为 $array 的最后一个元素添加进去。
- 第 25 行:使用 foreach 循环遍历数组。该语法允许您使用两种语法遍历字典(因此也包括数组):
第一种语法在每次迭代时返回一个 (键,值) 对,而第二种语法仅返回字典中的值元素。
- 第 31 行:array_pop($array) 函数从 $array 中移除最后一个元素
- 第 39 行:array_shift($array) 函数从 $array 中移除第一个元素
- 第 47 行:array_push($array,value) 函数将 value 作为 $array 的最后一个元素添加
- 第 39 行:array_unshift($array, value) 函数将 value 作为 $array 的第一个元素添加
3.3.2. 字典(example_05)
<?php
// dictionaries
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");
// routes - 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
print "conjoints[$clé]=$valeur\n";
// dictionary sorting on key
ksort($conjoints);
// routes - 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
print "conjoints[$clé]=$valeur\n";
// list of dictionary keys
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
print "clés[$i]=$clés[$i]\n";
// list of dictionary values
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
print "valeurs[$i]=$valeurs[$i]\n";
// key search
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");
// deleting a key-value
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
print "conjoints[$clé]=$valeur\n";
}
// end
exit;
function existe($conjoints, $mari) {
// checks whether the key $mari exists in the dictionary $conjoints
if (isset($conjoints[$mari]))
print "La clé [$mari] existe associée à la valeur [$conjoints[$mari]]\n";
else
print "La clé [$mari] n'existe pas\n";
}
?>
结果:
注释
上面的代码将我们之前针对简单数组所介绍的内容应用到了字典上。我们仅对新功能进行说明:
- 第 13 行:ksort(按键值排序)函数会按键值的自然顺序对字典进行排序。
- 第 21 行:array_keys($dictionary) 函数将字典的键列表作为数组返回
- 第 26 行:array_values($dictionary) 函数将字典的值列表作为数组返回
- 第 47 行:isset($variable) 函数在 $variable 已定义时返回 true,否则返回 false。
- 第 36 行:unset($variable) 函数删除 $variable。
3.3.3. 多维数组(example_06)
<?php
// classic multidimensional tables
// initialization
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// route
for ($i1 = 0; $i1 < count($multi); $i1++)
for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// multidimensional dictionaries
// initialization
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// route
foreach ($multi as $clé => $valeur)
for ($i2 = 0; $i2 < count($valeur); $i2++)
print "multi[$clé][$i2]=" . $multi[$clé][$i2] . "\n";
?>
结果:
注释
- 第 5 行:$multi 数组的元素本身也是数组
- 第 12 行:$multi 数组被转换为一个 (键, 值) 形式的字典,其中每个值都是一个数组
3.3.4. 字符串与数组之间的关联(示例_07)
<?php
// string to array
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);
// parcours tableau
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n";
// table to string
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";
// add an empty field
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);
// parcours tableau
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n"; //// we now have 5 elements, the last being empty
// let's add another empty field
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);
// parcours tableau
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
print "tab[$i]=$tab[$i]\n"; //// we now have 6 elements, the last two being empty
?>
结果:
注释
- 第 5 行:explode($separator,$string) 函数提取 $string 中以 $separator 分隔的字段。因此,explode(":",$string) 会将 $string 中以字符串 ":" 分隔的元素作为数组返回。
- implode($separator,$array) 函数与 explode 函数的操作相反。它返回一个字符串,该字符串由 $array 的元素组成,并以 $separator 分隔。
3.4. 字符串
3.4.1. 语法(示例_08)
<?php
// string notation
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>
结果:
3.4.2. 比较(示例_09)
<?php
// string comparison tests
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;
function compare($chaine1, $chaine2) {
// compare string1 and string2
if ($chaine1 == $chaine2)
print "[$chaine1] est égal à [$chaine2]\n";
else
print "[$chaine1] est différent de [$chaine2]\n";
}
?>
结果:
3.5. 正则表达式 (example_10)
<?php
// regular expression in PHP
// retrieve the various fields of a string
// the model: a sequence of numbers surrounded by any characters
// you only want to retrieve the sequence of digits
$modèle = "/(\d+)/";
// the chain is compared with the
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");
// the model: a sequence of numbers surrounded by any characters
// we want the sequence of numbers and the fields that follow and precede them
$modèle = "/^(.*?)(\d+)(.*?)$/";
// the chain is compared with the
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");
// the template - a date in dd/mm/yy format
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compare($modèle, "10/05/97");
compare($modèle, " 04/04/01 ");
compare($modèle, "5/1/01");
// the model - a decimal number
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compare($modèle, "187.8");
compare($modèle, "-0.6");
compare($modèle, "4");
compare($modèle, ".6");
compare($modèle, "4.");
compare($modèle, " + 4");
// end
exit;
// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
// compares the $chaîne string with the $modèle model
// the chain is compared with the model
$correspond = preg_match($modèle, $chaîne, $champs);
// displaying results
print "\nRésultats($modèle,$chaîne)\n";
if ($correspond) {
for ($i = 0; $i < count($champs); $i++)
print "champs[$i]=$champs[$i]\n";
} else
print "La chaîne [$chaîne] ne correspond pas au modèle [$modèle]\n";
}
?>
结果:
注释
- 第 3-4 行:这里我们使用正则表达式从字符串中提取各个字段。正则表达式使我们能够克服 implode 函数的局限性。其原理是使用 preg_match 函数将一个字符串与另一个称为“模式”的字符串进行比较:
$correspond = preg_match($modèle, $chaîne, $champs);
preg_match 函数返回一个布尔值,表示模式是否能在字符串中被找到。如果找到,$fields[0] 代表与模式匹配的子字符串。此外,如果模式包含用括号括起的子模式,$champs[1] 是 $string 中对应第一个子模式的部分,$champs[2] 是 $string 中对应第二个子模式的部分,以此类推……
考虑第一个示例。模式在第 8 行定义:它表示字符串中任意位置的一个或多个 (+) 数字 (\d) 序列。此外,该模式还定义了一个用括号括起的子模式。
- 第 10 行:将正则表达式 /(\d+)/(字符串中任意位置的一个或多个数字序列)与字符串 "xyz1234abcd" 进行匹配。我们可以看到子字符串 1234 与该正则表达式匹配。因此,$fields[0] 将等于 "1234"。此外,该正则表达式包含用圆括号括起的子模式。 此时 $champs[1]="1234"。
- 第 11 行:将正则表达式 /(\d+)/ 与字符串 "12 34" 进行匹配。我们发现子字符串 12 和 34 都与该正则表达式匹配。匹配操作会在遇到第一个匹配的子字符串时停止。因此,$champs[0] = 12 且 $champs[1] = 12。
- 第 12 行:将正则表达式 /(\d+)/ 与字符串 "abcd" 进行匹配。未找到匹配项。
下面解释代码其余部分中使用的模式:
$modèle = "/^(.*?)(\d+)(.*?)$/";
字符串开头 (^),接着是 0 个或多个 (*) 任意字符 (.),然后是 1 个或多个 (+) 数字,最后又是 0 个或多个 (*) 任意字符 (.)。正则表达式 (.*) 表示 0 个或多个任意字符。这样的正则表达式将匹配任何字符串。 因此,正则表达式 /^(.*)(\d+)(.*)$/ 永远无法匹配,因为第一个子模式 (.*) 会消耗整个字符串。正则表达式 (.*?)(\d+) 表示 0 个或多个任意字符,直到下一个子模式 (?) 为止,在本例中即 \d+。因此,数字部分不再被 (.*) 模式捕获。 因此,上述模式匹配 [字符串开头 (^),任意字符序列 (.*?),一个或多个数字序列 (\d+),任意字符序列 (.*?),字符串结尾 ($)]。
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
匹配 [字符串开头 (^),2 个数字 (\d\d),字符 / (\/),2 个数字,/,2 个数字,0 个或多个空格 (\s*),字符串结尾 ($)]
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
[字符串开头 (^),0 个或多个空格 (\s*),一个 + 或 - 符号 [+|-] 出现 0 次或 1 次 (?),0 个或多个空格的序列 (\s*), 1 个或多个数字后跟一个小数点,再后跟 0 个或多个数字 (\d+\.\d*) 或 (|) 一个小数点 (\.) 后跟一个或多个数字 (\d+) 或 (|) 一个或多个数字 (\d+),0 个或多个空格 (\s*)]。
3.6. 函数参数传递模式(示例_11)
<?php
// parameter step mode
function f(&$i, $j) {
// $i will be obtained by reference
// $j will be obtained by value
$i++;
$j++;
print "f[i,j]=[$i,$j]\n";
}
// ----------------------------------------tests
$i = 0;
$j = 0;
// $i and $j passed by values
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>
结果:
注释
上面的代码演示了向函数传递参数的两种方式。让我们来看以下示例:
- 第 1 行:定义函数 f 的形式参数 $a 和 $b。该函数对这两个形式参数进行处理并返回结果。
- 第 7 行:调用函数 f,并传入两个实际参数 $i 和 $j。形式参数 ($a, $b) 与实际参数 ($i, $j) 之间的绑定由第 7 行定义
- &$a:&符号表示形式参数 $a 将取实际参数 $i 的地址值。换言之,$a 和 $i 是指向同一内存位置的两个引用。 操作形式参数 $a 等同于操作实际参数 $i。代码执行过程验证了这一点。这种传递方式适用于输出参数以及数组和字典等大型数据集。这种传递方式称为按引用传递。
- $b:形式参数 $b 将取实际参数 $j 的值。这是按值传递。形式参数和实际参数是两个不同的变量。操作形式参数 $b 不会影响实际参数 $j。代码执行结果验证了这一点。这种传递模式适用于输入参数。
- 考虑 swap 函数,它接受两个形式参数 $a 和 $b。该函数会交换这两个参数的值。因此,在调用 swap($i,$j) 时,调用方期望两个实际参数的值被交换。因此,它们是输出参数(会被修改)。因此,我们将编写:
3.7. 函数返回的结果(示例_12)
<?php
// results rendered by a function
// a function can return several values in an array
list($res1, $res2, $res3) = f1(10);
print "[$res1,$res2,$res3]\n";
$res = f1(10);
for ($i = 0; $i < count($res); $i++)
print "res[$i]=$res[$i]\n";
// a function can render a pseudo-object
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";
// end
exit;
// function f1
function f1($valeur) {
// returns an array ($valeur+1,$aleur+2,$baleur+3)
return array($valeur + 1, $valeur + 2, $valeur + 3);
}
// function f2
function f2($valeur) {
// renders a pseudo-object ($valeur+1,$aleur+2,$baleur+3)
$res->res1 = $valeur + 1;
;
$res->res2 = $valeur + 2;
$res->res3 = $valeur + 3;
// makes the object
return $res;
}
?>
结果
注释
- 前面的程序展示了 PHP 函数可以返回一组结果(而非单一结果),形式可以是数组或对象。关于对象的概念将在下文中进行更详细的说明
- 第 19–22 行:函数 f1 以数组的形式返回多个值
- 第 25–33 行:函数 f2 以对象的形式返回多个值
3.8. 文本文件(example_13)
<?php
// sequential operation of a text file
// this is a set of lines of the form login:pwd:uid:gid:infos:dir:shell
// each line is put into a dictionary in the form login => uid:gid:infos:dir:shell
// set the file name
$INFOS = "infos.txt";
// we open it in creation
if (!$fic = fopen($INFOS, "w")) {
print "Erreur d'ouverture du fichier $INFOS en écriture\n";
exit;
}
// generate arbitrary content
for ($i = 0; $i < 100; $i++)
fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// close the file
fclose($fic);
// we use it - fgets keeps the end-of-line marker
// this prevents the retrieval of an empty string when reading a blank line
// we open it in creation
if (!$fic = fopen($INFOS, "r")) {
print "Erreur d'ouverture du fichier $INFOS en lecture\n";
exit;
}
while ($ligne = fgets($fic, 1000)) {
// delete the end-of-line marker if it exists
$ligne = cutNewLineChar($ligne);
// put the line in a table
$infos = explode(":", $ligne);
// retrieve login
$login = array_shift($infos);
// we neglect the pwd
array_shift($infos);
// create a dictionary entry
$dico[$login] = $infos;
}
// close it
fclose($fic);
// using the dictionary
afficheInfos($dico, "login10");
afficheInfos($dico, "X");
// end
exit;
// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
// displays the value associated with key in the $dico dictionary if it exists
if (isset($dico[$clé])) {
// value exists - is it a painting?
$valeur = $dico[$clé];
if (is_array($valeur)) {
print "[$clé," . join(":", $valeur) . "]\n";
} else {
// $valeur is not an array
print "[$clé,$valeur]\n";
}
} else {
// $clé is not a key in the $dico dictionary
print "la clé [$clé] n'existe pas\n";
}
}
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
$L = strlen($ligne); // // line length
while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
$ligne = substr($ligne, 0, $L - 1);
$L--;
}
// end
return($ligne);
}
?>
infos.txt 文件:
login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99
结果:
评论
- 第 11 行:fopen(filename, "w") 以写入模式(w = 写入)打开文件 filename。如果文件不存在,则创建该文件;如果文件已存在,则清空其内容。如果创建失败,fopen 返回 false。 在语句 if (!$fic = fopen($INFOS, "w")) {…} 中,包含两项连续的操作:1) $fic=fopen(..) 2) if( ! $fic) {...}
- 第 18 行:fputs($fic,$string) 将字符串写入 $fic 文件。
- 第 20 行:fclose($fic) 关闭 $fic 文件。
- 第 25 行:fopen(filename, "r") 以读取模式(r=read)打开 filename 文件。如果打开失败(文件不存在),fopen 返回 false。
- 第 29 行:fgets($fic,1000) 读取文件的下一行,限制为 1000 个字符。 在 while ($line = fgets($fic, 1000)) {…} 操作中,包含两个连续的操作:1) $line = fgets(...) 2) while ( ! $line)。当文件的最后一个字符被读取后,fgets 函数返回空字符串,while 循环随即终止。
- 第 31 行:fgets 函数读取一行文本,包括换行符。第 70–79 行中的 cutNewLineChar 函数会移除任何换行符。
- 第 72 行:strlen($string) 函数返回 $string 中的字符数。
- 第 73 行:substr($line, $position, $size) 函数从 $line 中返回 $size 个字符,从第 $position 个字符开始(其中第一个字符为第 0 个)。在 Windows 系统中,行结束标记为 "\r\n"。在 Unix 系统中,行结束标记为字符串 "\n"。
- 第 35 行:array_shift($array) 函数从 $array 中移除第一个元素,并将其作为结果返回。
- 第 37 行:使用了 array_shift($array) 函数,但其结果被忽略
- 第 57 行:is_array($variable) 函数返回 true 表示 $variable 是数组,否则返回 false。
- 第 58 行:join 函数的作用与我们之前遇到的 implode 函数相同