[TOC]
PHP简介
PHP 是服务器端脚本语言。
- PHP 文件可包含文本、HTML、JavaScript代码和 PHP 代码
- PHP 代码在服务器上执行,结果以纯 HTML 形式返回给浏览器
- PHP 文件的默认文件扩展名是 “.php”
- 用户定义的函数和语言关键字对大小写不敏感。
PHP基本知识
PHP语法
PHP 脚本可以放在文档中的任何位置;PHP 文件通常包含 HTML 标签和一些 PHP 脚本代码。
- PHP 脚本以 结束
- PHP 中的每个代码行都必须以分号
;
结束。分号是一种分隔符,用于把指令集区分开来。 - 在PHP中,有两种在浏览器输出文本的基础指令:echo 和 print。
- 注释:
//
单行注释;/**/
多行注释
实例:
<html>
<?php
/*
第一个PHP代码
*/
echo "hello world"; //输出hello world
?>
</html>
PHP变量
变量是用于存储数据的容器。
PHP 变量规则:跟其他编程语言很像比如C++
- 变量以 $ 符号开始,后面跟着变量的名称
- 变量名必须以字母或者下划线字符开始
- 变量名只能包含字母、数字以及下划线(A-z、0-9 和 _ )
- 变量名不能包含空格
- 变量名是区分大小写的($y 和 $Y 是两个不同的变量)
PHP 没有声明变量的命令;变量在您第一次赋值给它的时候被创建:
<?php
$text = "hello world";
$x = 5;
$y = 6;
$z = $x + $y;
echo $z;
echo $text;
?>
PHP变量作用域
变量的作用域是脚本中变量可被引用/使用的部分。
PHP 有四种不同的变量作用域:
- local – 局部作用域
- global – 全局作用域
- static – 静态作用域
- parameter – 函数参数作用域
在所有函数外部定义的变量,拥有全局作用域。除了函数外,全局变量可以被脚本中的任何部分访问,要在一个函数中访问一个全局变量,需要使用 global 关键字。
在 PHP 函数内部声明的变量是局部变量,仅能在函数内部访问
这里记得加上
<meta charset="utf-8">
不然中文是乱码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My PHP</title>
</head>
<body>
<?php
$x=5; // 全局变量
$z=10;//全局变量
function myTest()
{
global $z;//声明全局变量
$y=10; // 局部变量
echo "<p>测试函数内变量:<p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
echo "<br>";
echo "变量 z 为: $z";
}
myTest();
echo "<p>测试函数外变量:<p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
?>
</body>
</html>
输出结果:在函数内部没有使用global $x
声明全局变量,所以无法使用全局变量x,而z却可以
PHP 将所有全局变量存储在一个名为 $GLOBALS[index]
的数组中。 index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量。
<?php
$x=5;
$y=10;
function myTest()
{
$GLOBALS['y']=$GLOBALS['x']+$GLOBALS['y'];
}
myTest();
echo "\$y = $y";
//输出为:$y = 15
?>
static作用域
当一个函数完成时,它的所有变量通常都会被删除。然而,有时候您希望某个局部变量不要被删除。要做到这一点,则需要在第一次声明变量时使用 static 关键字:
<?php
function myTest()
{
static $x=0; //该变量仍然是函数的局部变量。
echo $x;
$x++;
echo PHP_EOL; // 换行符
}
myTest();
myTest();
myTest();
//输出为:0 1 2
?>
总结:
- 1、定义在函数外部的就是全局变量,它的作用域从定义处一直到文件结尾。
- 2、函数内定义的变量就是局部变量,它的作用域为函数定义范围内。
- 3、函数之间存在作用域互不影响。
- 4、函数内访问全局变量需要 global 关键字或者使用 $GLOBALS[index] 数组
输出语句
这里讲解4个输出方式:echo
,print
,print_r
,var_dump
其中echo 和 print两者都是语言结构,是用来输出字符串的,echo 和 print 在输出之前,都会将参数的进行转换,尝试转换为字符串类型。使用的时候可以不用加括号,也可以加上括号: echo ,echo();print、print();输出字符串可以包含 HTML 标签
echo 和 print 区别:
- echo - 可以输出一个或多个字符串,echo true的时候显示1,echo false的时候啥都没有。
- print - 只允许输出一个字符串,返回值总为 1
提示:echo 输出的速度比 print 快, echo 没有返回值,print有返回值1。
print_r(): 可以把字符串和数字简单地打印出来,而数组则以括起来的键和值得列表形式显示,并以Array开头。但print_r()输出布尔值和NULL的结果没有意义,因为都是打印”\n”。因此用var_dump()函数更适合调试。print_r() 将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。
var_dump():会输出变量的值和类型; 判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型。此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
<?php
$txt1="var PHP";
$txt2="RUNOOB.COM";
$cars=array("Volvo","BMW","Toyota");
echo "<hr/>";
echo "echo input" ;
echo "<br/>";
echo "$txt1";
echo "<br/>";
echo "{$text2}is good";
echo "<br/>";
echo "this ", "is ", "a ", "string";
print "<hr/>";
print "print input";
print "<br/>";
print "$txt1";
print "<br/>";
print "{$text2}is good";
print_r("<hr/>");
print_r("print_r input");
print_r("<br/>");
print_r($txt1);
print_r("<br/>");
print_r("{$text2}is good");
print_r("<br/>");
print_r($cars);
print_r("<hr/>");
var_dump("var_dump input");
print_r("<br/>");
var_dump("{$text2} is good");
print_r("<br/>");
var_dump($cars);
?>
输出结果:
PHP EOF
PHP EOF(heredoc)是一种在命令行shell和程序语言里定义一个字符串的方法。
使用概述:
- 必须后接分号,否则编译通不过。
- EOF 可以用任意其它字符代替,只需保证结束标识与开始标识一致。
- 结束标识必须顶格独自占一行(即必须从行首开始,前后不能衔接任何空白和字符)。
- 开始标识可以不带引号或带单双引号,不带引号与带双引号效果一致,解释内嵌的变量和转义符号,带单引号则不解释内嵌的变量和转义符号。
- 当内容需要内嵌引号(单引号或双引号)时,不需要加转义符,本身对单双引号转义,此处相当于q和qq的用法。
- 在 PHP 定界符 EOF 中的任何特殊字符都不需要转义,双引号和html语言除外
注意:
1.以 <<<EOF 开始标记开始,以 EOF 结束标记结束,结束标记必须顶头写,不能有缩进和空格,且在结束标记末尾要有分号 。
2.开始标记和结束标记相同,比如常用大写的 EOT、EOD、EOF 来表示,但是不只限于那几个(也可以用:JSON、HTML等),只要保证开始标记和结束标记不在正文中出现即可。
3.位于开始标记和结束标记之间的变量可以被正常解析,但是函数则不可以。在 heredoc 中,变量不需要用连接符 . 或 , 来拼接,如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My PHP</title>
</head>
<body>
<?php
echo <<<EOF
<h1>我的第一个标题</h1>
<p>我的第一个段落。</p>
EOF;
// 结束需要独立一行且前后不能空格
$name="runoob";
$a= <<<x
"abc"$name
"123"
x;
// 结束需要独立一行且前后不能空格
echo $a;
?>
</body>
</html>
类型比较
- 松散比较:使用两个等号 == 比较,只比较值,不比较类型。
- 严格比较:用三个等号 === 比较,除了比较值,也比较类型。
对于数组:
== : 如果 x 和 y 具有相同的键/值对,则返回 true
=== : 如果 x 和 y 具有相同的键/值对,且顺序相同类型相同,则返回 true
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My PHP</title>
</head>
<body>
<?php
if(42 == "42") {
echo '1、值相等';
}
echo "<br/>";
if(42 === "42") {
echo '2、类型相等';
} else {
echo '3、类型不相等';
}
?>
<?php
echo "<hr/>";
echo '0 == false: ';
var_dump(0 == false);
echo "<br/>";
echo '0 === false: ';
var_dump(0 === false);
echo "<hr/>";
echo '0 == null: ';
var_dump(0 == null);
echo "<br/>";
echo '0 === null: ';
var_dump(0 === null);
echo "<br/>";
echo "<hr/>";
echo 'false == null: ';
var_dump(false == null);
echo "<br/>";
echo 'false === null: ';
var_dump(false === null);
echo "<hr/>";
echo '"0" == false: ';
var_dump("0" == false);
echo "<br/>";
echo '"0" === false: ';
var_dump("0" === false);
echo "<hr/>";
echo '"0" == null: ';
var_dump("0" == null);
echo "<br/>";
echo '"0" === null: ';
var_dump("0" === null);
echo "<hr/>";
echo '"" == false: ';
var_dump("" == false);
echo "<br/>";
echo '"" === false: ';![3](./PHP/3.png)
var_dump("" === false);
echo "<hr/>";
echo '"" == null: ';
var_dump("" == null);
echo "<br/>";
echo '"" === null: ';
var_dump("" === null);
?>
</body>
</html>
输出结果:
PHP常量
常量值被定义后,在脚本的其他任何地方都不能被改变。
一个常量由字母、下划线、和数字组成,但数字不能作为首字母出现。常量名不需要加 $ 修饰符。
注意: 常量在整个脚本中都可以使用。
设置常量,使用 define() 函数,函数语法如下:
bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )
该函数有三个参数:
name:必选参数,常量名称,即标志符。
value:必选参数,常量的值。
case_insensitive :可选参数,如果设置为 TRUE,该常量则大小写不敏感,默认是大小写敏感的。
注意:自 PHP 7.3.0 开始,定义不区分大小写的常量已被弃用。从 PHP 8.0.0 开始,只有 false 是可接受的值,传递 true 将产生一个警告。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My PHP</title>
</head>
<body>
<?php
// 区分大小写的常量名
define("GREETING", "欢迎访问 Runoob.com");
echo GREETING; // 输出 "欢迎访问 Runoob.com"
echo '<br/>';
echo greeting; // 输出 "greeting",但是有警告信息,表示该常量未定义
function test(){
echo GREETING;
}
echo '<br/>';
test()
?>
</body>
</html>
PHP字符串
在 PHP 中,只有一个字符串运算符。
并置运算符 .
用于把两个字符串值连接起来。
<?php
$txt1="Hello world!";
$txt2="What a nice day!";
echo $txt1 . " " . $txt2;
/*输出:Hello world! What a nice day!*/
?>
strlen()函数
strlen() 函数返回字符串的长度(字节数)。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My PHP</title>
</head>
<body>
<?php
echo strlen("Hello world!");
echo "<br/>";
echo strlen("中文字符"); //一个中文占 3 个字符数。
echo "<br/>";
echo mb_strlen("中文字符", 'utf-8'); //使用 mb_strlen 设置指定编码输出中文字符个数:
/*
输出:
12
12
4
*/
?>
</body>
</html>
strpos() 函数
strpos() 函数用于在字符串内查找一个字符或一段指定的文本。
如果在字符串中找到匹配,该函数会返回第一个匹配的字符位置。如果未找到匹配,则返回 FALSE。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My PHP</title>
</head>
<body>
<?php
echo strpos('开始23测试ceshi', '测试');
echo mb_strpos('开始23测试ceshi', '测试');
echo strpos('123测试ceshi', '测试');
echo mb_strpos('123测试ceshi', '测试');
/*输出:8 8 3 3
可能是版本问题:mb_strpos是按字的本来是
*/
?>
</body>
</html>
PHP运算符
//与c语言中的差不多
(expr1) ? (expr2) : (expr3)
对 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。
自 PHP 5.3 起,可以省略三元运算符中间那部分。表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1,否则返回 expr3。
<?php
// 普通写法
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
echo $username, "<br/>";
// PHP 5.3+ 版本写法
$username = $_GET['user'] ?: 'nobody';
echo $username, "<br/>";
?>
输入:三目运算符
PHP7+版本特性
<?php
// 如果 $_GET['user'] 不存在返回 'nobody',否则返回 $_GET['user'] 的值
$username = $_GET['user'] ?? 'nobody';
// 类似的三元运算符
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
?>
PHP7+ 支持组合比较符(combined comparison operator)也称之为太空船操作符,符号为 <=>。组合比较运算符可以轻松实现两个变量的比较,当然不仅限于数值类数据的比较。
语法格式如下:
$c = $a <=> $b;
解析如下:
如果 $a > $b, 则 $c 的值为 1。
如果 $a == $b, 则 $c 的值为 0。
如果 $a < $b, 则 $c 的值为 -1。
数组拼接
<?php
$a1 = array("id" => '1',"username" => 'a1');
$a2 = array("id" => '2',"username" => 'a2');
var_dump($a1 + $a2);
echo "<hr/>";
$a3 = array("id1" => '1',"username1" => 'a3');
$a4 = array("id2" => '2',"username2" => 'a4');
var_dump($a3+$a4);
?>
如果key相同就保留第一个(不同版本不一样,我是5.3),有的版本是把相同key的value值拼接起来
if,switch,while,for语法
与c差不多,不写了;
PHP数组
在 PHP 中,array() 函数用于创建数组:array();
也可以用[]
在 PHP 中,有三种类型的数组:
- 数值数组 - 带有数字 ID 键的数组
- 关联数组 - 带有指定的键的数组,每个键关联一个值
- 多维数组 - 包含一个或多个数组的数组
数值数组
这里有两种创建数值数组的方法:
自动分配 ID 键(ID 键总是从 0 开始):
$cars=array("Volvo","BMW","Toyota");
or
$cars=array["Volvo","BMW","Toyota"];
人工分配 ID 键:
$cars[0]="Volvo";
$cars[1]="BMW";
$cars[2]="Toyota";
eg:
<?php
$cars=array("Volvo","BMW","Toyota");
/*
$cars[0]="Volvo";
$cars[1]="BMW";
$cars[2]="Toyota";
*/
echo "I like " . $cars[0] . ", " . $cars[1] . " and " . $cars[2] . ".";
?>
获取数组的长度 - count() 函数
count() 函数用于返回数组的长度(元素的数量):
<?php
$cars=array("Volvo","BMW","Toyota");
$arrlength=count($cars);
for($x=0;$x<$arrlength;$x++)
{
echo $cars[$x];
echo "<br>";
}
?>
关联数组
关联数组是使用自己分配给数组的指定的键的数组。
这里有两种创建关联数组的方法:
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
or:
$age['Peter']="35";
$age['Ben']="37";
$age['Joe']="43";
遍历并打印关联数组中的所有值,您可以使用 foreach 循环
<?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 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象有两种语法:
foreach (array_expression as $value)
statement
foreach (array_expression as $key => $value)
statement
数组排序
数组中的元素可以按字母或数字顺序进行降序或升序排列:
- sort() - 对数组进行升序排列
- rsort() - 对数组进行降序排列
- asort() - 根据关联数组的值,对数组进行升序排列
- ksort() - 根据关联数组的键,对数组进行升序排列
- arsort() - 根据关联数组的值,对数组进行降序排列
- krsort() - 根据关联数组的键,对数组进行降序排列
注意:如果用sort或rsort对关联数组排序,则key会被修改为数字
写个冒泡排序吧:
<?php
//升序
function my_sort(array $arr){
$n = count($arr);
$flag = true;
for($i = $n - 1; $i >= 0 && $flag; $i--){
for($j = 0;$j < $i; $j++){
$flag = false;
if($arr[$j] > $arr[$j + 1]){
$tmp = $arr[$j];
$arr[$j] = $arr[$j + 1];
$arr[$j + 1] = $tmp;
$flag = true;
}
}
}
return $arr;
}
$arr = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
$arr = my_sort($arr);
print_r($arr);
?>
超全局变量
超级全局变量在PHP 4.1.0之后被启用, 是PHP系统中自带的变量,在一个脚本的全部作用域中都可用。
PHP中预定义了几个超级全局变量(superglobals) ,这意味着它们在一个脚本的全部作用域中都可用。 你不需要特别说明,就可以在函数及类中使用。
PHP 超级全局变量列表:
- $GLOBALS – 这个在上面讲过了
- $_SERVER
- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
$_SERVER
$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。
下表列出了所有 $_SERVER 变量中的重要元素:
元素/代码 | 描述 |
---|---|
$_SERVER[‘PHP_SELF’] | 当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $SERVER[‘PHP_SELF’] 将得到 /test.php/foo.bar。__FILE_ 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。 |
$_SERVER[‘GATEWAY_INTERFACE’] | 服务器使用的 CGI 规范的版本;例如,”CGI/1.1”。 |
$_SERVER[‘SERVER_ADDR’] | 当前运行脚本所在的服务器的 IP 地址。 |
$_SERVER[‘SERVER_NAME’] | 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。(如: www.xxx.com) |
$_SERVER[‘SERVER_SOFTWARE’] | 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24) |
$_SERVER[‘SERVER_PROTOCOL’] | 请求页面时通信协议的名称和版本。例如,”HTTP/1.0”。 |
$_SERVER[‘REQUEST_METHOD’] | 访问页面使用的请求方法;例如,”GET”, “HEAD”,”POST”,”PUT”。 |
$_SERVER[‘REQUEST_TIME’] | 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496) |
$_SERVER[‘QUERY_STRING’] | query string(查询字符串),如果有的话,通过它进行页面访问。 |
$_SERVER[‘HTTP_ACCEPT’] | 当前请求头中 Accept: 项的内容,如果存在的话。 |
$_SERVER[‘HTTP_ACCEPT_CHARSET’] | 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:”iso-8859-1,*,utf-8”。 |
$_SERVER[‘HTTP_HOST’] | 当前请求头中 Host: 项的内容,如果存在的话。 |
$_SERVER[‘HTTP_REFERER’] | 引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。) |
$_SERVER[‘HTTPS’] | 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。 |
$_SERVER[‘REMOTE_ADDR’] | 浏览当前页面的用户的 IP 地址。 |
$_SERVER[‘REMOTE_HOST’] | 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。 |
$_SERVER[‘REMOTE_PORT’] | 用户机器上连接到 Web 服务器所使用的端口号。 |
$_SERVER[‘SCRIPT_FILENAME’] | 当前执行脚本的绝对路径。 |
$_SERVER[‘SERVER_ADMIN’] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:xxxx@runoob.com) |
$_SERVER[‘SERVER_PORT’] | Web 服务器使用的端口。默认值为 “80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。 |
$_SERVER[‘SERVER_SIGNATURE’] | 包含了服务器版本和虚拟主机名的字符串。 |
$_SERVER[‘PATH_TRANSLATED’] | 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 |
$_SERVER[‘SCRIPT_NAME’] | 包含当前脚本的路径。这在页面需要指向自己时非常有用。FILE 常量包含当前脚本(例如包含文件)的完整路径和文件名。 |
$_SERVER[‘SCRIPT_URI’] | URI 用来指定要访问的页面。例如 “/index.html”。 |
$_REQUEST,$_POST,$_GET
三个都是用来接收HTML表单数据的,这个我不知道咋说,如果你知道get,post等传递数据的方式应该可以理解
PHP函数
函数是通过调用函数来执行的。
语法:函数名称以字母或下划线开头(不能以数字开头)
<?php
function functionName() {
// 要执行的代码
}
?>
其他的没啥了,讲一些特别的点吧
可变参数
php 也存在可变参数的函数,使用…实现:(高版本可以使用)
<?php
function test(...$args) //定义可变参数函数,使用...实现
{
$num=count($args);//统计参数个数
echo "函数调用参数个数:" . $num ."<br/>";
echo "函数参数详情:" . "<br/>";
foreach($args as $arg)
{
echo $arg . " ";
};//遍历打印出参数
echo "<hr/>";
}
test("a");//一个参数
test("a","b");//两个参数
test("a","b","c");//三个参数
?>
函数作为参数和返回值
php 的函数可作为参数或返回值传递:(低版本可以使用)
<?php
function add ($x, $y) {
return $x + $y;
}
function sub ($x, $y) {
return $x == $y;
}
//函数作为参数
function calc ($fun, $x, $y) {
return $fun($x, $y);
}
//函数作为返回值
function getAdd() {
return add;
}
//函数作为参数
$res = calc(add, 1,2);
echo 'Res:: ' . $res;
echo "<br/>";
//函数作为返回值
$add = getAdd();
echo 'Res:: '.$add(3, 9);
?>
类与对象
其实跟C++差不多,没啥好说的>_<
PHP 定义类通常语法格式如下:
<?php
class phpClass {
var $var1;
protected $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
解析如下:
类使用 class 关键字后加上类名定义。
类名后的一对大括号({})内可以定义变量和方法。
类的变量使用 var 来声明, 变量也可以初始化值 - - - var 定义,则被视为公有。
函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。
变量 $this 代表自身的对象。
构造函数
void __construct ([ mixed $args [, $... ]] )
析构函数
void __destruct ( void )
继承
PHP 使用关键字 extends 来继承一个类,PHP 不支持多继承,格式如下:
class Child extends Parent {
// 代码部分
}
可以对父类的public 和 protected的方法进行重写
<?php
class person{
var $age = 10;
public $name = "XiaozaYa";
function __construct($age, $name){
echo "parent ".__FUNCTION__."<br/>";
$this->age = $age;
$this->name = $name;
}
function __destruct(){
echo "parent".__FUNCTION__."<br/>";
}
function print_info(){
echo "name:".$this->name."<br/>";
echo "age:".$this->age."<br/>";
}
}
class worker extends person{
private $sex = female;
function __construct(){
echo "child ".__FUNCTION__."<br/>";
}
function __destruct(){
echo "child".__FUNCTION__."<br/>";
}
function print_info(){
echo "name:".$this->name."<br/>";
echo "age:".$this->age."<br/>";
echo "sex:".$this->sex."<br/>";
}
}
$haha = new worker(18, "haha");
$haha->print_info();
?>
接口
使用接口(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);
}
return $template;
}
}
?>
常量
可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。
常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。
自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字(如 self,parent 或 static)。
<?php
class MyClass
{
const constant = '常量值';
function showConstant() {
echo self::constant . "<br/>";
}
}
echo MyClass::constant . "<br/>";
$classname = "MyClass";
echo $classname::constant . "<br/>"; // 自 5.3.0 起
$class = new MyClass();
$class->showConstant();
echo $class::constant . "<br/>";// 自 PHP 5.3.0 起
?>
抽象类
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
定义为抽象的类不能被实例化。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。
此外,子类方法可以包含父类抽象方法中不存在的可选参数。
例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则也是可以正常运行的。
<?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";
?>
PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct() 。
魔术常量
PHP 向它运行的任何脚本提供了大量的预定义常量。
__LINE__
:文件中的当前行号;
__FILE__
:文件的完整路径和文件名;如果用在被包含文件中,则返回被包含的文件名;
自 PHP 4.0.2 起,FILE 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。
__DIR__
:文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录;
它等价于 dirname(FILE);除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)
__FUNCTION__
:函数名称(PHP 4.3.0 新加);
自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写);在 PHP 4 中该值总是小写字母的;
__CLASS__
:类的名称(PHP 4.3.0 新加);自 PHP 5 起本常量返回该类被定义时的名字(区分大小写);
在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar);注意自 PHP 5.4 起 CLASS 对 trait 也起作用。当用在 trait 方法中时,CLASS 是调用 trait 方法的类的名字;
__TRAIT__
:Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits;Trait 名包括其被声明的作用区域(例如 Foo\Bar);
从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法;
__METHOD__
:类的方法名(PHP 5.0.0 新加);返回该方法被定义时的名字(区分大小写);
__NAMESPACE__
:当前命名空间的名称(区分大小写);此常量是在编译时定义的(PHP 5.3.0 新增);
命名空间
PHP 命名空间(namespace)是在 PHP 5.3 中加入的,目的是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误。
PHP 命名空间可以解决以下两类问题:
- 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,例如:
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。以下代码会出现语法错误:
<html>
<?php
namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
?>
or
下面这个是正确的
<html>
<?php
declare(encoding='UTF-8'); //定义多个命名空间和不包含在命名空间中的代码
namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
?>
PHP表单
PHP 中的 $_GET
和 $_POST
变量用于检索表单中的信息,比如用户输入。
有一点很重要的事情值得注意,当处理 HTML 表单时,PHP 能把来自 HTML 页面中的表单元素自动变成可供 PHP 脚本使用。
$_GET、$_POST 和 $_REQUEST
的区别?
$_GET 变量接受所有以 get 方式发送的请求,及浏览器地址栏中的 ? 之后的内容。
$_POST 变量接受所有以 post 方式发送的请求,例如,一个 form 以 method=post 提交,提交后 php 会处理 post 过来的全部变量。
$_REQUEST 支持两种方式发送过来的请求,即 post 和 get 它都可以接受,显示不显示要看传递方法,get 会显示在 url 中(有字符数限制),post 不会在 url 中显示,可以传递任意多的数据(只要服务器支持)。
高级教程
多维数组
语法格式:
array (
array (
array (elements...),
array (elements...),
...
),
array (
array (elements...),
array (elements...),
...
),
...
)
eg:
<pre>
<?php
// 二维数组:
$cars = array
(
array("arr[0]",100,96),
array("arr[1]",60,59),
array("arr[2]",110,100)
);
print_r($cars);
?>
</pre>
文件包含
在 PHP 中,您可以在服务器执行 PHP 文件之前在该文件中插入一个文件的内容。
include 和 require 语句用于在执行流中插入写在其他文件中的有用的代码。
include 和 require 除了处理错误的方式不同之外,在其他方面都是相同的:
- require 生成一个致命错误(E_COMPILE_ERROR),在错误发生后脚本会停止执行。
- include 生成一个警告(E_WARNING),在错误发生后脚本会继续执行。
- require 一般放在 PHP 文件的最前面,程序在执行前就会先导入要引用的文件。
- include 一般放在程序的流程控制中,当程序执行时碰到才会引用,简化程序的执行流程。
因此,如果您希望继续执行,并向用户输出结果,即使包含文件已丢失,那么请使用 include。否则,在框架、CMS 或者复杂的 PHP 应用程序编程中,请始终使用 require 向执行流引用关键文件。这有助于提高应用程序的安全性和完整性,在某个关键文件意外丢失的情况下。
包含文件省去了大量的工作。这意味着您可以为所有网页创建标准页头、页脚或者菜单文件。然后,在页头需要更新时,您只需更新这个页头包含文件即可。
语法:
include 'filename';
或者
require 'filename';
文件上传
Cookie
设置cookie
setcookie() 函数用于设置 cookie。
注释:setcookie() 函数必须位于 <html>
标签之前。
语法:
setcookie(name, value, expire, path, domain);
/*
name:cookie name
value:cookie vaule
expire:cookie过期时间
path:cookie生效路径
domain:主机
*/
注释:在发送 cookie 时,cookie 的值会自动进行 URL 编码,在取回时进行自动解码。(为防止 URL 编码,请使用 setrawcookie() 取而代之。)
取回cookie
PHP 的 $_COOKIE 变量用于取回 cookie 的值。
在下面的实例中,我们取回了名为 “user” 的 cookie 的值,并把它显示在了页面上:
<?php
// 输出 cookie 值
echo $_COOKIE["user"];
// 查看所有 cookie
print_r($_COOKIE);
?>
删除cookie
当删除 cookie 时,您应当使过期日期变更为过去的时间点。
删除的实例:
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("user", "", time()-3600);
?>
Session
PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置。Session 变量存储单一用户的信息,并且对于应用程序中的所有页面都是可用的。
HTTP是无状态协议:
您在计算机上操作某个应用程序时,您打开它,做些更改,然后关闭它。这很像一次对话(Session)。计算机知道您是谁。它清楚您在何时打开和关闭应用程序。然而,在因特网上问题出现了:由于 HTTP 地址无法保持状态,Web 服务器并不知道您是谁以及您做了什么。
PHP session 解决了这个问题,它通过在服务器上存储用户信息以便随后使用。然而,会话信息是临时的,在用户离开网站后将被删除。如果您需要永久存储信息,可以把数据存储在数据库中。
Session 的工作机制是:为每个访客创建一个唯一的 id (UID),并基于这个 UID 来存储变量。UID 存储在 cookie 中,或者通过 URL 进行传导。
session是存储在服务端的,而cookie是存储在各户端的。
开始 PHP Session
在您把用户信息存储到 PHP session 中之前,首先必须启动会话。
注释:session_start() 函数必须位于 <html>
标签之前:
eg:
<?php session_start(); ?>
<html>
<body>
</body>
</html>
上面的代码会向服务器注册用户的会话,以便您可以开始保存用户信息,同时会为用户会话分配一个 UID。
存储 Session 变量
存储和取回 session 变量的正确方法是使用 PHP $_SESSION 变量:
eg:
<?php
session_start();
// 存储 session 数据
$_SESSION['views']=1;
?>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<?php
// 检索 session 数据
echo "浏览量:". $_SESSION['views'];
?>
</body>
</html>
销毁 Session
如果您希望删除某些 session 数据,可以使用 unset() 或 session_destroy() 函数。
unset() 函数用于释放指定的 session 变量:
<?php
session_start();
if(isset($_SESSION['views'])) {
unset($_SESSION['views']);
}
?>
您也可以通过调用 session_destroy() 函数彻底销毁 session:
注释:session_destroy() 将重置 session,您将失去所有已存储的 session 数据。
<?php
session_destroy();
?>
错误处理
- 简单的 “die()” 语句
- 自定义错误和错误触发器
- 错误报告
die
<?php
if(!file_exists("welcome.txt")) {
die("文件不存在");
} else {
$file=fopen("welcome.txt","r");
}
?>
自定义错误处理器
- 定义错误处理函数
- 设置错误处理函数
- 触发错误
定义错误处理函数
创建一个自定义的错误处理器非常简单。我们很简单地创建了一个专用函数,可以在 PHP 中发生错误时调用该函数。
该函数必须有能力处理至少两个参数 (error level 和 error message),但是可以接受最多五个参数(可选的:file, line-number 和 error context):
语法:
error_function(error_level,error_message,error_file,error_line,error_context)
参数 | 描述 |
---|---|
error_level | 必需。为用户定义的错误规定错误报告级别。必须是一个数字。参见下面的表格:错误报告级别。 |
error_message | 必需。为用户定义的错误规定错误消息。 |
error_file | 可选。规定错误发生的文件名。 |
error_line | 可选。规定错误发生的行号。 |
error_context | 可选。规定一个数组,包含了当错误发生时在用的每个变量以及它们的值。 |
错误报告级别
这些错误报告级别是用户自定义的错误处理程序处理的不同类型的错误:
值 | 常量 | 描述 |
---|---|---|
2 | E_WARNING | 非致命的 run-time 错误。不暂停脚本执行。 |
8 | E_NOTICE | run-time 通知。在脚本发现可能有错误时发生,但也可能在脚本正常运行时发生。 |
256 | E_USER_ERROR | 致命的用户生成的错误。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_ERROR。 |
512 | E_USER_WARNING | 非致命的用户生成的警告。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_WARNING。 |
1024 | E_USER_NOTICE | 用户生成的通知。这类似于程序员使用 PHP 函数 trigger_error() 设置的 E_NOTICE。 |
4096 | E_RECOVERABLE_ERROR | 可捕获的致命错误。类似 E_ERROR,但可被用户定义的处理程序捕获。(参见 set_error_handler()) |
8191 | E_ALL | 所有错误和警告。(在 PHP 5.4 中,E_STRICT 成为 E_ALL 的一部分) |
现在,让我们创建一个处理错误的函数:
function customError($errno, $errstr) {
echo "<b>Error:</b> [$errno] $errstr<br>";
echo "脚本结束";
die();
}
上面的代码是一个简单的错误处理函数。当它被触发时,它会取得错误级别和错误消息。然后它会输出错误级别和消息,并终止脚本。
现在,我们已经创建了一个错误处理函数,我们需要确定在何时触发该函数。
设置错误处理程序
PHP 的默认错误处理程序是内建的错误处理程序。我们打算把上面的函数改造为脚本运行期间的默认错误处理程序。
可以修改错误处理程序,使其仅应用到某些错误,这样脚本就能以不同的方式来处理不同的错误。然而,在本例中,我们打算针对所有错误来使用我们自定义的错误处理程序:
set_error_handler("customError");
由于我们希望我们的自定义函数能处理所有错误,set_error_handler() 仅需要一个参数,可以添加第二个参数来规定错误级别。
eg:
<?php
// 错误处理函数
function customError($errno, $errstr) {
echo "<b>Error:</b> [$errno] $errstr";
}
// 设置错误处理函数
set_error_handler("customError");
// 触发错误
echo($test);
/*
输出:Error: [8] Undefined variable: test
*/
?>
触发错误
在脚本中用户输入数据的位置,当用户的输入无效时触发错误是很有用的。在 PHP 中,这个任务由 trigger_error() 函数完成。
eg:
在本例中,如果 “test” 变量大于 “1”,就会发生错误:
<?php
$test=2;
if ($test>1) {
trigger_error("变量值必须小于等于 1");
}
?>
以上代码的输出如下所示:
Notice: 变量值必须小于等于 1 in /www/test/runoob.php on line 5
您可以在脚本中任何位置触发错误,通过添加的第二个参数,您能够规定所触发的错误类型。
可能的错误类型:
- E_USER_ERROR - 致命的用户生成的 run-time 错误。错误无法恢复。脚本执行被中断。
- E_USER_WARNING - 非致命的用户生成的 run-time 警告。脚本执行不被中断。
- E_USER_NOTICE - 默认。用户生成的 run-time 通知。在脚本发现可能有错误时发生,但也可能在脚本正常运行时发生。
eg:
<?php
// 错误处理函数
function customError($errno, $errstr) {
echo "<b>Error:</b> [$errno] $errstr<br>";
echo "脚本结束";
die();
}
// 设置错误处理函数
set_error_handler("customError",E_USER_WARNING);
// 触发错误
$test=2;
if ($test>1) {
trigger_error("变量值必须小于等于 1",E_USER_WARNING);
}
/*
输出:
Error: [512] 变量值必须小于等于 1
脚本结束
*/
?>
异常处理
try、throw 和 catch
适当的处理异常代码应该包括:
- try - 使用异常的函数应该位于 “try” 代码块内。如果没有触发异常,则代码将照常继续执行。但是如果异常被触发,会抛出一个异常。
- throw - 里规定如何触发异常。每一个 “throw” 必须对应至少一个 “catch”。
- catch - “catch” 代码块会捕获异常,并创建一个包含异常信息的对象。
<?php
// 创建一个有异常处理的函数
function checkNum($number) {
if($number>1) {
throw new Exception("变量值必须小于等于 1");
}
return true;
}
// 在 try 块 触发异常
try {
checkNum(2);
// 如果抛出异常,以下文本不会输出
echo '如果输出该内容,说明 $number 变量';
}
// 捕获异常
catch(Exception $e) {
echo 'Message: ' .$e->getMessage();
}
/*
输出:Message: 变量值必须小于等于 1
*/
?>
自定义Exception类
我们简单地创建了一个专门的类,当 PHP 中发生异常时,可调用其函数。该类必须是 exception 类的一个扩展。
这个自定义的 customException 类继承了 PHP 的 exception 类的所有属性,您可向其添加自定义的函数。
创建 customException 类:
<?php
class customException extends Exception
{
public function errorMessage()
{
// 错误信息
$errorMsg = '错误行号 '.$this->getLine().' in '.$this->getFile()
.': <b>'.$this->getMessage().'</b> 不是一个合法的 E-Mail 地址';
return $errorMsg;
}
}
$email = "someone@example...com";
try
{
// 检测邮箱
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
{
// 如果是个不合法的邮箱地址,抛出异常
throw new customException($email);
}
}
catch (customException $e)
{
//display custom message
echo $e->errorMessage();
}
?>
设置顶层异常处理器
set_exception_handler() 函数可设置处理所有未捕获异常的用户定义函数。
<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>