PHP基础学习
PHP
1.搭建环境
1.搭建环境
2.测试环境
在Apache的安装目录下的htdocs
的文件目录下,建立一个文件phpinfo.php
<?php
phpinfo();
?>
开启Apache的服务 这个要到对应的目录下运行这些指令
httpd.exe -k install # 安装服务
httpd.exe -k start # 开启服务
httpd.exe -t # 查看是否有错误
要使php的short-open-tag
起作用,要修改php.ini
的文件信息,将这个标签改成short-open-tag = On
这样配置之后,打开浏览器访问localhost/phpinfo.php
,就可以看到相应的信息了
3.PhpStorm配置php环境
2.php语法
php脚本可以放在文档中的任何位置,php脚本以<?php
开始,?>
结束,php文件通常的默认文件拓展名为.php
,php文件中通常包含HTML标签和一些PHP脚本代码
代码实例
<!DOCTYPE html>
<html>
<body>
<h1>My first PHP page</h1>
<?php
echo "Hello World!";
?>
</body>
</html>
php中的每一个代码都必须以分号结束,分号是一种分隔符,用于把指令集区分开,通过php,有两种在浏览器输出文本的基础指令echo
和print
1.php中的注释
//这个是php的单行注释
/*
这个是php的多行注释
*/
3.php变量
<!DOCTYPE html>
<html>
<body>
<h1>My first PHP page</h1>
<?php
$x = 5;
$y = 6;
$z = $x + $y;
print $z;
?>
</body>
</html>
1.php变量规则
- 变量以
$
符号开始,后面跟着变量的名称 - 变量名必须以字母或者下划线字符开始
- 变量名只能包含字母数字字符以及下划线(
A-z、0-9和_
) - 变量名不能包含空格
- 变量名是区分大小写的(
$y
和$Y
是两个不同的变量)
php没有声明变量得命令,变量在您第一次赋值给它的时候就被创建了
注意:当你赋一个文本值给变量时,请在文本值两侧加上引号
php是一门弱类型语言
不必向php声明该变量的数据类型,PHP会根据变量的值,自动把变量转换为正确的数据类型。在强类型的编程语言中,我们必须在使用变量前先声明(定义)变量的类型和名称。
2.php变量作用域
变量的作用域是脚本中变量可被引用/使用的部分。
PHP有四种不同的变量作用域:local global static parameter
测试代码
<?php
$x=5; // 全局变量
function myTest($x)
{
$y=10; // 局部变量
echo "<p>Test variables inside the function:</p>";
echo "Variable x is: $x";
echo "<br>";
echo "Variable y is: $y";
}
myTest($x);
echo "<p>Test variables outside the function:</p>";
echo "Variable x is: $x";
echo "<br>";
echo "Variable y is: $y";
?>
1.php global关键字
global 关键字用于函数内访问全局变量。
在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字:
<?php
$x=5; // 全局变量
function myTest()
{
global $x; // 声明为全局变量
$y=10; // 局部变量
echo "<p>Test variables inside the function:</p>";
echo "Variable x is: $x";
echo "<br>";
echo "Variable y is: $y";
}
myTest();
echo "<p>Test variables outside the function:</p>";
echo "Variable x is: $x";
echo "<br>";
echo "Variable y is: $y";
?>
PHP 将所有全局变量存储在一个名为 $GLOBALS[*index*]
的数组中。 index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量。
测试代码
<?php
$x = 5; // 全局变量
$y = 6;
function myTest()
{
$GLOBALS['y'] = $GLOBALS['x'] + $GLOBALS['y'];
}
echo "$y</br>";
myTest();
echo $y;
?>
2.php static作用域
这个的作用是使变量在使用的过程中,不会被函数不使用时,而被删除掉
测试代码
<?php
function myTest()
{
static $x = 1;
echo "$x<br/>";
$x++;
}
myTest();
myTest();
myTest();
?>
4.php的echo和print语句
PHP 是通过 print 和 echo 语句来动态输出 HTML 内容,虽然 print 和 echo 语句两者的功能几乎是完全一样,但是还是有一点差别的。
php echo,print和print_r的区别
- echo 可以输出一个或多个字符串
- print 只能输出简单类型变量的值 (int,string)
- print_r 可以输出复杂类型变量的值 (数组对象)
注意:
echo输出的速度比print快,echo是PHP语句,没有返回值,print和print_r是PHP函数,函数有返回值。print返回值为1(int类型),print_r返回值为true(bool类型)。
1.php的echo语句
echo 是一个语言结构,使用的时候可以不用加括号,也可以加上括号: echo 或 echo()。
代码实例
<?php
$x = 5;
$cars = array("Volve","BMW","Toyota");
echo "Hello World"," feng"," php","</br>";
echo $x,"</br>";
echo "$x</br>";
echo "$cars[0]";
?>
2.php的print语句
print 同样是一个语言结构,可以使用括号,也可以不使用括号: print 或 print()。不能输出多个参数
代码实例
<?php
$x = 5;
$cars = array("Volve","BMW","Toyota");
print "Hello World</br>";
print "$x</br>";
print "$cars[0]";
?>
3.php的print_r语句
print_r 显示关于一个变量的易于理解的信息,如果给出的是string、integer或float,将打印变量值本身。
如果给出的是array,将会按照一定格式显示键和元素。object与数组类似。
使用时必须加上括号:print_r()。
小提示:print_r()会将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。
代码实例
<?php
$s1 = "Hello World";
$cars = array("Volvo","BMW","Toyota");
print_r("$s1</br>");
print_r($cars); // Array ( [0] => Volvo [1] => BWM [2] => Toyota )
?>
5.php的数据类型
php的数据类型包括:String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型), Array(数组), Object(对象), NULL(空值)。
1.php的字符串
一个字符串是一串字符的序列,你可以将任何文本放在单引号和双引号中
<?php
$s1 = "Hello World";
$s2 = 'Hello PHP';
echo "$s1</br>";
echo $s2;
?>
2.php的整数类型
整数是一个没有小数的数字。
整数规则:
- 整数必须至少有一个数字(0-9)
- 整数不能包含逗号或空格
- 整数是没有小数点的
- 整数可以是正数或负数
- 整型可以用三种格式来指定:十进制,十六进制(以0x为前缀)或八进制(前缀为0)。
使用php的var_dump()
函数返回变量的数据类型和值
<?php
$x = 120; // 十进制
var_dump($x);
echo "</br>$x</br>";
$y = 0x81; // 十六进制
var_dump($y);
echo "</br>$y</br>";
$z = 047; // 八进制
var_dump($z);
echo "</br>$z</br>";
?>
3.php的浮点数类型
浮点数是带小数部分的数字,或是指数形式。
<?php
$x = 10.365; // 小数类型的 10.365
var_dump($x);
echo "<br>";
$x = 2.4e3; // 指数类型的 2400
var_dump($x);
echo "<br>";
$x = 8E-5; // 指数类型的 8.0E-5
var_dump($x);
?>
4.php的布尔型
布尔型可以是 TRUE 或 FALSE。
<?php
$x = true;
echo $x == 1,"</br>";
$y = false;
echo $y == 0;
?>
5.php的数组
数组可以在一个变量中存储多个值。
<?php
$cars = array("Volvo","BWM","Toyota");
var_dump($cars); // array(3) { [0]=> string(5) "Volvo" [1]=> string(3) "BWM" [2]=> string(6) "Toyota" }
?>
6.php的对象
对象数据类型也可以用于存储数据。在 PHP 中,对象必须声明。首先,你必须使用class关键字声明类对象。类是可以包含属性和方法的结构。
<?php
class Car
{
var $color;
function Car($color) {
$this->color = $color;
}
function what_color() {
return $this->color;
}
}
echo "Hello World";
$car = new Car("red");
echo $car->color;
echo $car->what_color(); // 没反应,后面在修
?>
7.php的null值
NULL 值表示变量没有值。NULL 是数据类型为 NULL 的值。NULL 值指明一个变量是否为空值。 同样可用于数据空值和NULL值的区别。可以通过设置变量值为 NULL 来清空变量数据:
<?php
$s1 = "Hello World";
echo $s1,"</br>";
$s1 = null; // 清空变量
var_dump($s1);
?>
6.php常量
常量值被定义后,在脚本的其他任何地方都不能被改变。
常量是一个简单值的标识符。该值在脚本中不能改变。
一个常量由英文字母、下划线、和数字组成,但数字不能作为首字母出现。(常量名不需要加 $ 修饰符)。
注意: 常量在整个脚本中都可以使用。
1.设置常量
设置常量,一般使用define()
函数
bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )
该函数有三个参数:
- constant name:必选参数,常量名称,即标志符。
- value:必选参数,常量的值。
- case insensitive:可选参数,如果设置为TRUE,该常量则大小写不敏感。默认是大小写敏感的。
// 方式一
<?php
define("GREETING","WELCOME TO PHP");
echo GREETING;
?>
// 方式二
<?php
const GREETING = "WELCOME TO PHP";
echo GREETING;
?>
常量是全局的,常量在定义后,默认是全局变量,可以在整个运行的脚本的任何地方使用。
7.php字符串
一个字符串(string)就是由一系列的字符组成,其中每个字符等同于一个字节。字符串变量用于存储并处理文本。字符串变量用于包含有字符的值。在创建字符串之后,我们就可以对它进行操作了。您可以直接在函数中使用字符串,或者把它存储在变量中。
1.php的并置运算符
在 PHP 中,只有一个字符串运算符。并置运算符 (.) 用于把两个字符串值连接起来。
<?php
$s1 = "Hello";
$s2 = "World";
echo $s1." ".$s2;
?>
2.php的strlen函数
strlen() 函数返回字符串的长度(字符数)。
<?php
$s1 = "Hello";
echo strlen($s1);
?>
3.php的strpos函数
strpos() 函数用于在字符串内查找一个字符或一段指定的文本。
如果在字符串中找到匹配,该函数会返回第一个匹配的字符位置。如果未找到匹配,则返回 FALSE。
<?php
echo strpos("Hello world!","world");
?>
完全的php String函数
8.php运算符
PHP 中的运算符分为:算术运算符、递增/递减运算符、比较运算符、逻辑运算符、数组运算符、三元运算符等。
1.php算术运算符
+
加,-
减,*
乘,/
除,%
取模,-
取反,.
并置
<?php
$x = 10;
$y = 6;
echo $x+$y,"</br>";
echo $x-$y,"</br>";
echo $x*$y,"</br>";
echo $x/$y,"</br>";
echo "Hello"." "."World";
?>
2.php赋值运算符
基本赋值语句是=
,将基本赋值语句和算术运算符结合起来就行了
<?php
$x = 10;
$x += 6;
echo $x;
?>
3.php递增/递减运算符
++
,--
这两个符号放的位置不同,结果也会不同的
<?php
$x = 10;
echo $x++,"</br>";
$y = 9;
echo ++$y;
?>
4.php比较运算符
==
,===
(恒等于,值和类型都相同),!=
,<>
(不相同),!==
不恒等于,>
大于,<
小于,>=
大于等于,<=
小于等于
<?php
$x = 100;
$y = "100";
var_dump($x==$y); // true
echo "</br>";
var_dump($x===$y);
echo "</br>";
var_dump($x!=$y);
echo "</br>";
var_dump($x!==$y); // true
echo "</br>";
$a = 50;
$b = 90;
var_dump($a > $b);
echo "</br>";
var_dump($a < $b);
?>
5.php逻辑运算符
and
,or
,xor
(异或),&&
,||
,!
6.php数组运算符
<?php
$x = array("a" => "red", "b" => "green");
$y = array("c" => "blue", "d" => "yellow");
$z = $x + $y; // $x 和 $y 数组合并
var_dump($z);
echo "</br>";
var_dump($x == $y);
echo "</br>";
var_dump($x === $y);
echo "</br>";
var_dump($x != $y);
echo "</br>";
var_dump($x <> $y);
echo "</br>";
var_dump($x !== $y);
?>
7.php三元运算符
expression;true expression,false expression;
<?php
$test = 'w3cschool在线教程';
$username = $test; echo $username, PHP_EOL;
?>
8.php错误控制运算符
PHP 支持一个错误控制运算符:@
。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误诊断都被抑制。
如果用 set_error_handler() 设定了自定义的错误处理函数,即使诊断信息被抑制,也仍然会被调用,因此自定义错误处理函数应该调用 error_reporting(),并验证 @
操作符是否按照如下方式使用:
<?php
function my_error_handler($err_no, $err_msg, $filename, $linenum) { // 自定义的错误处理函数
if (!(error_reporting() & $err_no)) {
return false; // 静默
}
// ...
}
?>
注意:运算符只对表达式有效。如果能从某处获得值,就能在它前面加上运算符。
9.php运算符优先级
9.php if...else语句
本节介绍 PHP if...else 语句的使用,通过该语句,你可以有选择性的执行代码片段。条件语句用于根据不同条件执行不同动作。
在 PHP 中,提供了下列条件语句:
- if 语句 - 在条件成立时执行代码
- if...else 语句 - 在条件成立时执行一块代码,条件不成立时执行另一块代码
- if...else if....else 语句 - 在若干条件之一成立时执行一个代码块
- switch 语句 - 在若干条件之一成立时执行一个代码块
1.php if语句
if语句用于仅当指定条件成立时执行代码
<?php
$t = date("H"); // 标准时间的小时数
if($t<"20"){
echo "Have a good day";
}
?>
2.php if...else语句
在条件成立时执行一块代码,条件不成立时执行另一块代码,请使用 if....else 语句。该语句的含义为:当条件为真时,执行条件成立时的代码;如果条件为假,则执行条件不成立时的代码,语法如下:
<?php
$t = date("H")+8;
if($t<"20"){
echo "Have a good day";
}else{
echo "Good night";
}
?>
3.php if...else if...else语句
在若干条件之一成立时执行一个代码块,请使用 if....else if...else 语句。
<?php
$t = date("H")+8;
if($t<"10"){
echo "Have a good morning";
}else if($t<"15"){
echo "Have a good afternoon";
}else{
echo "Have a good night";
}
?>
10.php switch语句
switch 语句用于根据多个不同条件执行不同动作。
如果您希望有选择地执行若干代码块之一,请使用 switch 语句。
<?php
$favColor = "red";
switch ($favColor){
case "red":
echo "Your favorite color is red";
break;
case "blue":
echo "Your favorite color is blue";
break;
default:
echo "I don't know your favorite color";
break;
}
?>
switch记得使用break语句
11.php 数组
数组能够在单个变量中存储多个值:
<?php
$car = array("Volvo",'BMW',"Toyota");
echo "I like ".$car[0].",".$car[1].",".$car[2].".";
?>
1.php创建数组
在php中,使用array()
函数创建数组
在 PHP 中,有三种类型的数组:
- 数值数组 - 带有数字 ID 键的数组
- 关联数组 - 带有指定的键的数组,每个键关联一个值
- 多维数组 - 包含一个或多个数组的数组
1.数值数组
自动分配ID键(ID键总是从0开始的)
$car = array("Volvo",'BMW',"Toyota");
人工手动分配ID键
$cars[0]="Volvo";
$cars[1]="BMW";
$cars[2]="Toyota";
获取到数组的长度--count()函数
count() 函数用于返回数组的长度(元素的数量):
<?php
$car = array("Volvo",'BMW',"Toyota");
echo "I like ".$car[0].",".$car[1].",".$car[2].".","</br>";
echo count($car);
?>
遍历数值数组
遍历并打印数值数组中的所有值,您可以使用 for 循环
<?php
$car = array("Volvo",'BMW',"Toyota");
for($i = 0;$i<count($car);$i++){
echo $car[$i],"</br>";
}
?>
2.关联数组
关联数组是使用您分配给数组的指定的键的数组。
<?php
$age = array("Ben"=>"37","Joe"=>"43");
$age["Peter"] = "35";
echo "peter is"." ".$age["Peter"]." "."years old.";
?>
遍历关联数组
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
foreach($age as $x=>$x_value)
{
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
?>
foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象
3.多维数组
记录
2.php array函数
12.php 数组排序
数组中的元素可以按字母或数字顺序进行降序或升序排列。对原数组进行排序操作,改变原数组的操作
介绍下列 PHP 数组排序函数:
- sort() - 对数组进行升序排列
- rsort() - 对数组进行降序排列
- asort() - 根据关联数组的值,对数组进行升序排列
- ksort() - 根据关联数组的键,对数组进行升序排列
- arsort() - 根据关联数组的值,对数组进行降序排列
- krsort() - 根据关联数组的键,对数组进行降序排列
1.sort() 对数组进行升序排序
// 对字母进行升序排序
<?php
$cars=array("Volvo","BMW","Toyota");
sort($cars);
print_r($cars);
?>
// 对数字进行升序排序
<?php
$numbers=array(4,6,2,22,11);
sort($numbers);
print_r($numbers);
?>
2.rsort() 对数组进行降序排序
<?php
$cars=array("Volvo","BMW","Toyota"); // 对字母进行降序排序
rsort($cars);
print_r($cars);
?>
<?php echo "</br>"?>
<?php
$numbers=array(4,6,2,22,11); // 对数字进行降序排序
rsort($numbers);
print_r($numbers);
?>
3.asort() 根据数组的值,对数组进行升序排序
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
asort($age);
print_r($age);
?>
4.ksort() 根据数组的键,对数组进行升序排序
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
ksort($age); // 对数组的键进行筛选
print_r($age);
?>
5.arsort() 根据数组的值,对数组进行降序排序
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
arsort($age);
print_r($age);
?>
6.krsort() 根据数组的建立,对数组进行降序排列
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
krsort($age);
print_r($age);
?>
13.php的超级全局变量
超级全局变量是在全部作用域中始终可用的内置变量。
php的超级全局变量有
- $GLOBALS
- $_SERVER
- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
1.php--$GLOBALS
$GLOBALS 是PHP的一个超级全局变量组,在一个PHP脚本的全部作用域中都可以访问。
$GLOBALS 是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。
<?php
$x = 75;
$y = 25;
function addition(){
$GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y']; // 通过$GLOBALS变量组进行传值
}
addition();
echo $z;
?>
2.php--$_SERVER
$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由Web 服务器创建。不能保证每个服务器都提供全部项目;
<?php
echo $_SERVER['PHP_SELF'];
echo "<br>";
echo $_SERVER['SERVER_NAME']; // 服务器的名称
echo "<br>";
echo $_SERVER['HTTP_HOST']; // 主机地址
echo "<br>";
echo $_SERVER['HTTP_REFERER']; // 网络的防盗链技术
echo "<br>";
echo $_SERVER['HTTP_USER_AGENT']; // UserAgent
echo "<br>";
echo $_SERVER['SCRIPT_NAME']; // 脚本文件的名称
?>
$_SERVER的重要元素 PHP 超级全局变量
$_SERVER['PHP_SELF'] 当前执行脚本的文件名,与 document root 有关。(文件的路径)
$_SERVER['GATEWAY_INTERFACE'] 服务器使用的 CGI 规范的版本;
$_SERVER['SERVER_ADDR'] 当前运行脚本所在的服务器的 IP 地址。
$_SERVER['SERVER_NAME'] 当前运行脚本所在的服务器的主机名。
$_SERVER['SERVER_SOFTWARE'] 服务器标识字符串,在响应请求时的头信息中给出。
$_SERVER['SERVER_PROTOCOL'] 请求页面时通信协议的名称和版本。
$_SERVER['REQUEST_METHOD'] 访问页面使用的请求方法;(post,get,put,head等)
$_SERVER['REQUEST_TIME'] 请求开始时的时间戳。(返回秒)
$_SERVER['QUERY_STRING'] query string(查询字符串),如果有的话,通过它进行页面访问。
$_SERVER['HTTP_ACCEPT'] 当前请求头中 Accept: 项的内容,如果存在的话。
$_SERVER['HTTP_ACCEPT_CHARSET'] 当前请求头中 Accept-Charset: 项的内容,如果存在的话。
$_SERVER['HTTP_HOST'] 当前请求头中 Host: 项的内容,如果存在的话。
$_SERVER['HTTP_REFERER'] 引导用户代理到当前页的前一页的地址(如果存在)。该值是不可相信的
$_SERVER['HTTPS'] 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。
$_SERVER['REMOTE_ADDR'] 浏览当前页面的用户的 IP 地址。
$_SERVER['REMOTE_HOST'] 浏览当前页面的用户的主机名。
$_SERVER['REMOTE_PORT'] 用户机器上连接到 Web 服务器所使用的端口号。
$_SERVER['SCRIPT_FILENAME'] 当前执行脚本的绝对路径。(根路径和文件名的绝对位置)
$_SERVER['SERVER_ADMIN'] 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。
$_SERVER['SERVER_PORT'] Web 服务器使用的端口。默认值为 "80"。
$_SERVER['SERVER_SIGNATURE'] 包含了服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] 当前脚本所在文件系统(非文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] 包含当前脚本的路径。
$_SERVER['SCRIPT_URI'] URI 用来指定要访问的页面。
3.php--$_REQUEST
PHP $_REQUEST 用于收集HTML表单提交的数据
<html>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> // 本页面直接处理
Name:<input name="name" type="text">
<input type="submit">
</form>
<?php
$name = &$_REQUEST["name"];
echo $name;
?>
</body>
</html>
4.php--$_POST
PHP $_POST 被广泛应用于收集表单数据,在HTML form标签的指定该属性:"method="post"。
<html>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> // 本页面直接处理
Name:<input name="name" type="text">
<input type="submit">
</form>
<?php
$name = &$_REQUEST["name"];
echo $name;
?>
</body>
</html>
5.php--$_GET
PHP $_GET 同样被广泛应用于收集表单数据,在HTML form标签的指定该属性:"method="get"。
$_GET 也可以收集URL中发送的数据。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="test.php?subject=PHP">点我</a>
</body>
</html>
<html>
<body>
<?php
if($_GET["subject"]!=null){
echo $_GET["subject"];
}
?>
</body>
</html>
14.php while循环
在 PHP 中,提供了下列循环语句:
- while - 只要指定的条件成立,则循环执行代码块
- do...while - 首先执行一次代码块,然后在指定的条件成立时重复这个循环
- for - 循环执行代码块指定的次数
- foreach - 根据数组中每个元素来循环代码块
1.php--while循环
实例:一直将i加到5为止
<?php
$i = 0;
$sum = 0;
while($i<=5){
$sum += $i;
$i++;
}
echo $sum;
?>
2.php--do..while循环
<?php
$i = 0;
$sum = 0;
do{
$i++;
$sum += $i;
}while($i<=5);
echo $sum;
?>
这个比上面的多循环了一次
15.php for循环
1.for循环
语法
for (初始值; 条件; 增量)
{
要执行的代码;
}
参数:
- 初始值:主要是初始化一个变量值,用于设置一个计数器(但可以是任何在循环的开始被执行一次的代码)。
- 条件:循环执行的限制条件。如果为 TRUE,则循环继续。如果为 FALSE,则循环结束。
- 增量:主要用于递增计数器(但可以是任何在循环的结束被执行的代码)。
注释:上面的初始值和增量参数可为空,或者有多个表达式(用逗号分隔)。
<?php
$sum = 0;
for($i = 0;$i <= 5;$i++){
$sum += $i;
}
echo $sum;
?>
2.foreach循环
语法
foreach ($array as $value)
{
要执行代码;
}
实例
<?php
$number = array("one","two","three");
foreach ($number as $item) {
echo $item,"</br>";
}
?>
注意:foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量,将发出错误信息。
16.php函数
函数是通过调用函数来执行的。你可以在页面的任何位置调用函数。
1.创建php函数
语法
function functionName()
{
要执行的代码;
}
PHP 函数准则:
- 函数的名称应该提示出它的功能
- 函数名称以字母或下划线开头(不能以数字开头)
<html>
<body>
<?php
function writeName()
{
echo "feng";
}
echo "My name is ";
writeName();
?>
</body>
</html>
2.php函数--添加参数
为了给函数添加更多的功能,我们可以添加参数。参数类似变量。参数就在函数名称后面有一个括号内指定。
<html>
<body>
<?php
function writeName($fname)
{
echo $fname . " Refsnes.</br>";
}
echo "My name is ";
writeName("Kai Jim");
echo "My sister's name is ";
writeName("Hege");
?>
</body>
</html>
3.php函数--return返回值
如需让函数返回一个值,请使用 return 语句。
<html>
<body>
<?php
function add($x,$y)
{
$total = $x + $y;
return $total;
}
echo "1 + 16 = " . add(1,16);
?>
</body>
</html>
17.php魔术常量
1.__LINE__
文件中的当前行号
<?php
echo __LINE__;
?>
2.__FILE__
文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
<?php
echo __FILE__;
?>
3.__DIR__
文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__
)。
<?php
echo __DIR__,"</br>";
echo dirname(__FILE__)
?>
4.__FUNCTION__
返回该函数被定义时的名字(区分大小写)。
<?php
function myTest(){
echo __FUNCTION__;
}
myTest();
?>
5.__CLASS__
返回该类被定义时的名字
<?php
class Test{
function MyPrintClass(){
echo __CLASS__;
}
}
$test = new Test();
$test->MyPrintClass();
?>
6.__TRAIT__
PHP中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的。trait就是解决了继承只能继承一个的缺陷(多继承)
从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法名一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello(); // 调用父类的方法
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld; // 多继承
}
$o = new MyHelloWorld();
$o->sayHello();
?>
7.__METHOD__
返回函数的名称,作用和__FUNCTION__
一样的
<?php
function myTest(){
echo __METHOD__;
}
myTest();
?>
8.__NAMESPACE__
当前命名空间的名称(区分大小写)
<?php
namespace MyProject;
echo '命名空间为:', __NAMESPACE__;
?>
18.命名空间
PHP 命名空间可以解决以下两类问题:
- 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
1.定义命名空间
默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。
命名空间通过关键字 namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。
你也可以在同一个文件中定义不同的命名空间代码
将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,例如:
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection {} // 类
function connect(){
echo "Connected";
}
}
namespace { // 全局代码
session_start();
$a = MyProject\CONNECT_OK; // 使用命名空间后的取值
echo $a;
MyProject\connect();
}
?>
在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。
<?php
declare(encoding='UTF-8');
namespace MyProject {
const CONNECT_OK = 1;
class Connection {} // 类
function connect(){
echo "Connected";
}
}
namespace { // 全局代码
session_start();
$a = MyProject\CONNECT_OK; // 使用命名空间后的取值
echo $a;
MyProject\connect();
}
?>
2.子命名空间
与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义:
<?php
declare(encoding='UTF-8');
namespace MyProject\Sub\Level{
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { echo "枫"; }
}
namespace {
\MyProject\Sub\Level\Connect();
}
?>
3.命名空间使用
PHP 命名空间中的类名可以通过三种方式引用:
- 非限定名称,或不包含前缀的类名称
- 限定名称,或包含前缀的名称
- 完全限定名称,或包含了全局前缀操作符的名称
file1.php
<?php
namespace Foo\Bar\subnamespace; // 子命名空间
const FOO = 1;
function foo() {}
class foo
{
static function staticmethod() {}
}
?>
file2.php
<?php
namespace Foo\Bar;
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
static function staticmethod() {}
}
/* 非限定名称 */
foo(); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO 2
/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
// 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO 1
/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO 2
?>
注意访问任意全局类、函数或常量,都可以使用完全限定名称
注意下面的两种情况,一个是有大括号的,一个是没有大括号的,有区别的,注意
<?php
namespace foo;
function Mystrlen($a) {echo strlen($a);}
const MyINI_ALL = 1000;
class Exception {}
$a = \foo\MyINI_ALL;
echo $a,"</br>";
Mystrlen("Hello");
?>
<?php
namespace foo{
function Mystrlen($a) {echo strlen($a);}
const MyINI_ALL = 1000;
class Exception {}
}
namespace {
$a = \foo\MyINI_ALL;
echo $a,"</br>";
\foo\Mystrlen("Hello");
}
?>
4.命名空间和动态语言特征
PHP 命名空间的实现受到其语言自身的动态特征的影响。
file1.php
<?php
class classname
{
function __construct() // 类的构造函数
{
echo __METHOD__,"</br>";
}
}
function funcname()
{
echo __FUNCTION__,"</br>";
}
const constname = "global";
$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "</br>"; // prints global
?>
file2.php
<?php
namespace namespacename;
class classname
{
function __construct()
{
echo __METHOD__,"</br>";
}
}
function funcname()
{
echo __FUNCTION__,"</br>";
}
const constname = "namespaced";
include 'file1.php'; // 直接将代码传递了过来
$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "</b>"; // prints global
/* note that if using double quotes, "\\namespacename\\classname" must be used */
$a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // also prints namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // prints namespacename\funcname
$b = '\namespacename\funcname';
$b(); // also prints namespacename\funcname
echo constant('\namespacename\constname'), "</br>"; // prints namespaced
echo constant('namespacename\constname'), "</br>"; // also prints namespaced
?>
补充:constant就是索引后,返回常量的值
5.namespace关键词和__NAMESPACE__
常量
PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__
魔术常量和 namespace 关键字。
常量 __NAMESPACE__
的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。
<?php
namespace MyProject;
echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
?>
常量 __NAMESPACE__
在动态创建名称时很有用
<?php
namespace MyProject;
class Test{
function myTest(){
echo "Test";
}
}
function get($classname)
{
$a = __NAMESPACE__ . '\\' . $classname; // 防止字符串转义
return new $a;
}
$a = get("Test");
$a->myTest();
$c = new Test(); // 同一个命名空间下的代码
$c->myTest();
?>
<?php
namespace MyProject{
class Test{
function myTest(){
echo "Test";
}
}
function get($classname)
{
$a = __NAMESPACE__ . '\\' . $classname; // 防止字符串转义
return new $a;
}
}
namespace { // 不同的命名空间的代码
$a = \MyProject\get("Test");
$a->myTest();
$c = new \MyProject\Test();
$c->myTest();
}
?>
关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。
<?php
namespace sub{
function func(){
echo "Hello";
}
class cname{
function func(){
echo "World";
}
}
}
namespace { // 全局的变量
function func(){
echo "Hello";
}
const GREETING = "Hello";
namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$a->func();
$b = namespace\GREETING; // assigns value of constant CONSTANT to $b
echo $b;
}
?>
6.使用命名空间:别名/导入
PHP 命名空间支持 有两种使用别名或导入方式:为类名称使用别名,或为命名空间名称使用别名。
1.使用use操作符导入/使用别名
<?php
namespace foo{
class Test{
function func(){
echo "test";
}
}
}
namespace {
use \foo\Test as myTest;
$my = new myTest();
$my->func();
}
?>
注意还可以一行中包含多个use子句
导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。
2.导入和动态名称
<?php
namespace foo{
class Test{
function func(){
echo "test";
}
}
}
namespace {
use \foo\Test as myTest;
$my = new myTest();
$name = '\foo\Test'; // 动态名称,注意这里有个用法无法使用
//$name = 'myTest'; 这个用法似乎已经过时了,不能使用了
$my1 = new $name();
$my->func();
$my1->func();
}
?>
3.导入和完全限定名称
<?php
namespace name\sub\foo{
class Test{
function func(){
echo "test";
}
}
}
namespace {
class car{
function func(){
echo "Car";
}
}
use name\sub as sub; // 完全名称
$my = new sub\foo\Test();
$my->func();
}
?>
7.使用命名空间:后备全局函数/常量
在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称,例如
1.在命名空间中访问全局类
<?php
namespace A\B\C;
class Exception extends \Exception {} // 全局类,直接使用完全限定名称
$a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象
$b = new \Exception('hi'); // $b 是类 Exception 的一个对象,完全限定名称
//$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
?>
2.在命名空间中后备的全局函数/常量
下面的常量随着全局命名名称和当前命名名称的切换,出现了不同答案
<?php
namespace A\B\C;
const E_ERROR = 45;
function strlen($str)
{
return \strlen($str) - 1;
}
echo E_ERROR, "</br>"; // 输出 "45"
echo \INI_ALL, "</br>"; // 输出 "7" - 使用全局常量 INI_ALL
echo strlen('hi'), "\n"; // 输出 "1"
if (\is_array('hi')) { // 输出 "is not array",使用全局函数 is_array
echo "is array\n";
} else {
echo "is not array\n";
}
?>
8.全局空间
如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。
<?php
namespace A\B\C;
function strlen($s){
echo \strlen($s)-1; // 全局命名空间的使用
}
strlen("name");
?>
9.命名空间的顺序
19.php面向对象
对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。
对象的主要三个特性:对象的行为,对象的形态,对象的表示。
1.面向对象内容
- 类 − 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
- 对象 − 是类的实例。
- 成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
- 成员函数 − 定义在类的内部,可用于访问对象的数据。
- 继承 − 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
- 父类 − 一个类被其他类继承,可将该类称为父类,或基类,或超类。
- 子类 − 一个类继承其他类称为子类,也可称为派生类。
- 多态 − 多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
- 重载 − 简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
- 抽象性 − 抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
- 封装 − 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
- 构造函数 − 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
- 析构函数 − 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
2.php类定义
语法
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
解析如下:
- 类使用 class 关键字后加上类名定义。
- 类名后的一对大括号({})内可以定义变量和方法。
- 类的变量使用 var 来声明, 变量也可以初始化值。
- 函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。
<?php
class Site{
var $url;
function setUrl($url){
$this->url = $url;
}
function getUrl(){
return $this->url;
}
}
?>
$this
指的是自身的对象,也就是java的this一样的操作
3.php创建对象
类创建后,我们可以使用 new 运算符来实例化该类的对象
1.调用成员方法
在实例化对象后,我们可以使用该对象调用成员方法,该对象的成员方法只能操作该对象的成员变量
<?php
class Site{
var $url;
function setUrl($url){
$this->url = $url;
}
function getUrl(){
return $this->url;
}
}
$site1 = new Site();
$site1->setUrl("xcqandwrq");
$url = $site1->getUrl();
echo $url;
?>
2.php构造函数
构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
语法
void __construct ([ mixed $args [, $... ]] )
实例
<?php
class Site{
var $url;
function __construct($url){
$this->url = $url;
}
function setUrl($url){
$this->url = $url;
}
function getUrl(){
return $this->url;
}
}
$site1 = new Site("feng");
$site1->setUrl("xcqandwrq");
$url = $site1->getUrl();
echo $url;
?>
3.php析构函数
语法
void __destruct ( void )
实例
<?php
class Site{
var $url;
function __construct($url){
$this->url = $url;
}
function setUrl($url){
$this->url = $url;
}
function getUrl(){
return $this->url;
}
function __destruct()
{
echo "I am game over";
}
}
$site1 = new Site("feng");
$site1->setUrl("xcqandwrq");
$url = $site1->getUrl();
echo $url;
?>
4.继承
PHP 使用关键字 extends 来继承一个类,PHP 不支持多继承,语法如下
class Child extends Parent {
// 代码部分
}
实例
<?php
class Site{
var $url;
function __construct($url){
$this->url = $url;
}
function setUrl($url){
$this->url = $url;
}
function getUrl(){
return $this->url;
}
function __destruct()
{
echo "I am game over";
}
}
class Child_site extends Site{
var $category;
function __construct($url,$category)
{
parent::__construct($url);
$this->category = $category;
}
}
$site1 = new Site("feng");
$url = $site1->getUrl();
echo $url;
$site2 = new Child_site("xcqandwrq","java");
echo $site2->getUrl();
?>
5.方法重写
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
<?php
class Site{
var $url;
function __construct($url){
$this->url = $url;
}
function setUrl($url){
$this->url = $url;
}
function getUrl(){
return $this->url;
}
function __destruct()
{
echo "I am game over";
}
}
class Child_site extends Site{
var $category;
function __construct($url,$category)
{
parent::__construct($url);
$this->category = $category;
}
function getUrl() // 方法重写
{
echo "I am child"."</br>";
return parent::getUrl();
}
}
$site1 = new Site("feng");
$url = $site1->getUrl();
echo $url;
$site2 = new Child_site("xcqandwrq","java");
echo $site2->getUrl();
?>
6.访问控制
PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。
- public(公有):公有的类成员可以在任何地方被访问。
- protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问。
- private(私有):私有的类成员则只能被其定义所在的类访问。
1.属性的访问控制
类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。
<?php
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
//echo $obj->protected; // 这行会产生一个致命错误
//echo $obj->private; // 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private
class MyClass2 extends MyClass
{
// 可以对 public 和 protected 进行重定义,但 private 而不能
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
// echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
//echo $obj2->private; // 未定义 private
//echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined
?>
2.方法的访问控制
类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。
<?php
class MyClass
{
// 声明一个公有的构造函数
public function __construct() { }
// 声明一个公有的方法
public function MyPublic() { }
// 声明一个受保护的方法
protected function MyProtected() { }
// 声明一个私有的方法
private function MyPrivate() { }
// 此方法为公有
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
//$myclass->MyProtected(); // 这行会产生一个致命错误
//$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行
class MyClass2 extends MyClass
{
// 此方法为公有
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
// $this->MyPrivate(); // 这行会产生一个致命错误
}
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic</br>";
}
private function testPrivate() {
echo "Bar::testPrivate</br>";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic</br>";
}
private function testPrivate() {
echo "Foo::testPrivate</br>";
}
}
$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate Foo::testPublic test方法是在父类中,所以private只能调用父类中的方法了
?>
7.接口
使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
接口中定义的所有方法都必须是公有,这是接口的特性。
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。
<?php
// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// 实现接口
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace($name, $value, $template); // 将$template中的字符串$name换成$value的值
}
return $template;
}
}
$myTemplate = new Template();
$myTemplate->setVariable("World","PHP");
$template = $myTemplate->getHtml("Hello World");
echo $template;
?>
8.常量
可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。
常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。
<?php
class MyClass
{
const constant = '常量值'; //必须是共有的常量
function showConstant() {
echo self::constant . PHP_EOL;
}
}
echo MyClass::constant . PHP_EOL;// 类中的
$classname = "MyClass"; // 动态类中的
echo $classname::constant . PHP_EOL;
$class = new MyClass();
$class->showConstant(); // 实例对象的
echo $class::constant . PHP_EOL;
?>
9.抽象类
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
定义为抽象的类不能被实例化。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
<?php
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . PHP_EOL;
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1"; // 插值语句,注意这个语句的特点
}
}
class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
}
$class1 = new ConcreteClass1();
$class1->printOut(); // 继承方法,公有方法
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2();
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>
此外,子类方法可以包含父类抽象方法中不存在的可选参数。
<?php
abstract class AbstractClass
{
// 我们的抽象方法仅需要定义需要的参数
abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
// 我们的子类可以定义父类签名中不存在的可选参数
public function prefixName($name, $separator = ".") { // 默认参数的使用
if ($name == "Pacman") {
$prefix = "Mr";
} elseif ($name == "Pacwoman") {
$prefix = "Mrs";
} else {
$prefix = "";
}
return "{$prefix}{$separator} {$name}";
}
}
$class = new ConcreteClass();
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>
10.static关键字
声明类属性或方法为 static(静态),就可以不实例化类而直接访问。
静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。
静态属性不可以由对象通过 -> 操作符来访问。
<?php
class Foo {
public static $my_static = 'foo';
public static $number = 1;
public function staticValue() {
return self::$my_static.self::$number;
}
}
Foo::$number++; // 所有的对象共享一个元素
print Foo::$my_static . PHP_EOL; // 类的调用
$foo = new Foo();// 对象的调用
print $foo->staticValue() . PHP_EOL;
?>
11.Final关键字
如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called" . PHP_EOL;
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called" . PHP_EOL;
}
}
class ChildClass extends BaseClass {
// public function moreTesting() { 无法重写该方法
// echo "ChildClass::moreTesting() called" . PHP_EOL;
// }
public function test() {
echo "ChildClass::test() called" . PHP_EOL;
}
}
$child = new ChildClass();
$child->test();
$child->moreTesting();
?>
12.调用父类构造方法
PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct() 。
parent::__construct(参数);
<?php
class BaseClass {
public function __construct(){
echo "I am parent";
}
public function test() {
echo "BaseClass::test() called" . "</br>";
}
}
class ChildClass extends BaseClass {
public function __construct(){
parent::__construct();
echo "I am child";
}
public function test() {
echo "ChildClass::test() called" . PHP_EOL;
}
}
$child = new ChildClass();
$child->test();
?>
相应的参数也可以传递到父类的构造函数中