更多内容大家可以前往我的个人博客浏览:eyes++的个人空间
零: php介绍
PHP (全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器")是一款免费开源的服务器端脚本语言。PHP文件可包含文本、HTML、JavaScript代码和PHP代码,PHP代码在服务器上执行,结果以纯HTML形式返回给浏览器。
PHP的功能:
PHP 可以生成动态页面内容
PHP 可以创建、打开、读取、写入、关闭服务器上的文件
PHP 可以收集表单数据
PHP 可以发送和接收 cookies
PHP 可以添加、删除、修改您的数据库中的数据
PHP 可以限制用户访问您的网站上的一些页面
PHP 可以加密数据
PHP的优点:
PHP 可在不同的平台上运行(Windows、Linux、Unix、Mac OS X 等)
PHP 与目前几乎所有的正在被使用的服务器相兼容(Apache、IIS 等)
PHP 提供了广泛的数据库支持
PHP 是免费的,可从官方的 PHP 资源下载它: www.php.net
PHP 易于学习,并可高效地运行在服务器端
一: 基础语法
(1). php文件可包含多种成分
纯php代码:
<?php
echo "hello world";
html代码和php代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>HTML</p>
<?php
echo "hello world";
?>
</body>
</html>
(2).变量
php变量规则:
变量以 $ 符号开始,后面跟着变量的名称
变量名必须以字母或者下划线字符开始
变量名只能包含字母数字字符以及下划线(A-z、0-9 和 _ )
变量名不能包含空格
变量名是区分大小写的($y 和 $Y 是两个不同的变量)
PHP是弱类型语言,声明变量时不必声明数据类型,php会自动转换数据类型
展示:
<?php
$x = 5;
$y = 6.1;
$z = -2;
$sum = $x + $y + $z;
echo $sum;
$str = "hello";
echo $str;
(3).常量
常量是一个简单值的标识符。该值在脚本中不能改变。
一个常量由英文字母、下划线、和数字组成,但数字不能作为首字母出现。 (常量名不需要加 $ 修饰符)。
使用常量时,不能在常量名前添加$ 符号,不然会将常量转换成新的未定义变量使用,会导致报错。
注意: 常量在整个脚本中都可以使用。
设置常量,使用 define() 函数,函数语法如下:
bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )
该函数有三个参数:
name:必选参数,常量名称,即标志符。
value:必选参数,常量的值。
case_insensitive :可选参数,如果设置为 TRUE,该常量则大小写不敏感。默认是大小写敏感的。
<?php
// 区分大小写的常量名
define("GREETING", "hello php");
echo GREETING; // 输出 "hello php"
echo '<br>';
echo greeting; // 输出 "greeting"
echo '<br>';
// 不区分大小写的常量名
define("GREET", "hello world", true);
echo GREET; // 输出 "hello world"
echo '<br>';
echo greet; // 输出 "hello world"
echo '<br>';
// 常量是全局的
define("A", "it's a test.");
function myTest() {
echo A;
define("B", "it's also a test.");
}
myTest(); // 输出 "it's a test"
echo B; // 输出 "it's also a test"
(4).作用域
变量的作用域是脚本中变量可被引用/使用的部分,PHP有四种不同的变量作用域:
- local 局部作用域
- global 全局作用域
- static 静态作用域
- parameter 参数作用域
局部作用域与全局作用域
在所有函数外部定义的变量,拥有全局作用域。除了函数外,全局变量可以被脚本中的任何部分访问。而要在一个函数中访问一个全局变量,需要使用 global 关键字。
在PHP函数内部声明的变量是局部变量,仅能在函数内部访问:
<?php
$x = 5; // 全局变量
// 声明函数
function test()
{
$y = 10; // 局部变量
echo "<p>测试函数内变量:</p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
}
// 调用函数
test();
echo "<p>测试函数外变量:</p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
global 关键字用于函数内访问全局变量。在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字
<?php
$x = 5; // 全局变量
// 声明函数
function test()
{
$y = 10; // 局部变量
global $x; // 获取全局变量
echo "<p>测试函数内变量:</p>";
echo "变量 x 为: $x";
echo "<br>";
echo "变量 y 为: $y";
}
// 调用函数
test();
PHP 将所有全局变量存储在一个名为 $GLOBALS[index] 的数组中。 index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量。
<?php
$x = 5;
$y = 10;
// 声明函数
function test()
{
echo $GLOBALS['x'] + $GLOBALS['y'];
echo "<br>"; // 换行
$GLOBALS['x'] += 1; // 改变全局变量 $x
}
// 调用函数
test();
echo $x;
static作用域
当一个函数完成时,它的所有变量通常都会被删除。然而,有时候我们希望某个局部变量不要被删除。要做到这一点,就需要在第一次声明变量时使用 static 关键字
<?php
// 声明函数(不是static作用域)
function test()
{
$x = 0;
echo $x;
$x++;
echo "\r\n"; // 换行符
}
// 调用函数
test();
test();
test();
// 声明函数(是static作用域)
function test2()
{
static $y = 0;
echo $y;
$y++;
echo PHP_EOL;
}
// 调用函数
test2();
test2();
test2();
参数作用域
参数是通过调用代码将值传递给函数的局部变量。参数是在参数列表中声明的,作为函数声明的一部分。
<?php
// 声明函数
function test($x)
{
echo "x: $x";
echo "<br>";
}
// 调用函数
test(5);
echo "x: $x";
(5). echo与print
PHP里最基本的两个输出方式:echo、print。其中echo可以输出一个或多个字符串,print只允许输出一个字符串。echo的输出速度比print快,print有返回值1,而echo没有返回值。
echo是一个语言结构,使用时可以不加括号,也可以加括号,即echo或echo()。其字符串里可以包含html标签。
<?php
echo "<h2>hello world</h2>";
echo "hello PHP! <br>";
echo "1", "2", "3", "4", "5", "<br>";
echo 1024;
print 同样是一个语言结构,可以使用括号,也可以不用:print或print()。
<?php
$x = 10;
print "<h2>hello world</h2>";
print "hello PHP! <br>";
print 1024;
print "<br>";
print $x;
print "<br>";
print (print "hh");
(6). EOF(heredoc)
PHP EOF(heredoc)是一种在命令行shell(如sh、csh、ksh、bash、PowerShell和zsh)和程序语言(像Perl、PHP、Python和Ruby)里定义一个字符串的方法。
使用概述:
- 必须后接分号,否则编译通不过。
- EOF 可以用任意其它字符代替,只需保证结束标识与开始标识一致。
- 结束标识必须顶格独自占一行(即必须从行首开始,前后不能衔接任何空白和字符)。
- 开始标识可以不带引号或带单双引号,不带引号与带双引号效果一致,解释内嵌的变量和转义符号,带单引号则不解释内嵌的变量和转义符号。
- 当内容需要内嵌引号(单引号或双引号)时,不需要加转义符,本身对单双引号转义,此处相当与q和qq的用法。
- 位于开始标记和结束标记之间的变量可以被正常解析,但是函数则不可以。在 heredoc 中,变量不需要用连接符 . 或 , 来拼接
<?php
echo <<<EOF
<h1>我是标题</h1>
<p>我是段落</p>
EOF;
$name = "php";
$a = <<<EOF
"hello "$name
world
EOF;
echo $a;
二:数据类型
php有7种基本数据类型:
- String(字符串)
- Integer(整型)
- Float(浮点型)
- Boolean(布尔型)
- Array(数组)
- Object(对象)
- NULL(空值)
(0).php数据类型的判断
php数据类型的判断方法有print_r和var_dump。
print_r打印关于变量的易于理解的信息,如果给出的是 string、integer 或 float,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。 注意,print_r() 将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。
(1).php简单的数据类型
<?php
// 字符串
echo "字符串测试:"."<br>";
$x = "Hello world!";
var_dump($x);
echo "<br>";
$x = 'Hello!';
var_dump($x);
// 整型
echo "<br>"."整型测试:"."<br>";
$x = 5985;
var_dump($x);
echo "<br>";
$x = -345; // 负数
var_dump($x);
echo "<br>";
$x = 0x8C; // 十六进制数
var_dump($x);
echo "<br>";
$x = 047; // 八进制数
var_dump($x);
// 浮点型
echo "<br>"."浮点型测试:"."<br>";
$x = 10.365;
var_dump($x);
echo "<br>";
$x = 2.4e3;
var_dump($x);
echo "<br>";
$x = 8E-5;
var_dump($x);
// 布尔型
echo "<br>"."布尔型测试:"."<br>";
$x = true;
$y = false;
var_dump($x);
var_dump($y);
// 空值测试
echo "<br>"."空值测试:"."<br>";
$x = "Hello world!";
$x = null;
var_dump($x);
(2).php字符串
PHP并置运算符
在 PHP 中,只有一个字符串运算符。并置运算符 (.) 用于把两个字符串值连接起来。
<?php
$txt1 = "hello world!";
$txt2 = "php is the best";
echo $txt1 . ' ' . $txt2;
PHP strlen() 函数
strlen() 函数返回字符串的长度(字节数)
<?php
$x = "hello php";
$y = 123;
$z = "你好";
echo strlen($x) . "<br>";
echo strlen($y) . "<br>";
echo strlen($z) . "<br>";
PHP strpos() 函数
strpos() 函数用于在字符串内查找一个字符或一段指定的文本。如果在字符串中找到匹配,该函数会返回第一个匹配的字符位置。如果未找到匹配,则返回 FALSE。
<?php
$x = "hello php";
echo strpos($x, 'o') . '<br>';
echo strpos($x, 'l') . '<br>';
if(strpos($x, 'n'))
{
echo strpos($x, 'n');
} else{
echo 'FALSE';
}
(3).php数组
在 PHP 中,array() 函数用于创建数组:
$cars = array("Volvo", "BMW", "Toyota");
echo "I like " . $cars[0] . ", " . $cars[1] . " and " . $cars[2] . ".";
在 PHP 中,有三种类型的数组:
数值数组 - 带有数字 ID 键的数组
关联数组 - 带有指定的键的数组,每个键关联一个值
多维数组 - 包含一个或多个数组的数组
数值数组
这里有两种创建数值数组的方法:
$cars=array("Volvo","BMW","Toyota");
或者:
$cars[0]="Volvo";
$cars[1]="BMW";
$cars[2]="Toyota";
关联数组
关联数组即使用人工分配给数组的指定的键的数组。这里有两种创建关联数组的方法:
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
或者:
$age['Peter']="35";
$age['Ben']="37";
$age['Joe']="43";
多维数组
一个数组中的值可以是另一个数组,另一个数组的值也可以是一个数组。依照这种方式,我们可以创建二维或者三维数组。
<?php
// 二维数组:
$cars = array
(
array("Volvo",100,96),
array("BMW",60,59),
array("Toyota",110,100)
);
print("<pre>"); // 格式化输出数组
print_r($cars);
print("</pre>");
// 自动分配 ID 键的多维数组
$sites = array
(
"runoob"=>array
(
"菜鸟教程",
"http://www.runoob.com"
),
"google"=>array
(
"Google 搜索",
"http://www.google.com"
),
"taobao"=>array
(
"淘宝",
"http://www.taobao.com"
)
);
print("<pre>"); // 格式化输出数组
print_r($sites);
print("</pre>");
获取数组长度
count() 函数用于返回数组的长度(元素的数量)
<?php
$cars = array("Volvo","BMW","Toyota");
echo count($cars);
遍历数值数组
<?php
$cars = array("Volvo","BMW","Toyota");
$arrlength = count($cars);
for($x = 0; $x < $arrlength; $x++)
{
echo $cars[$x];
echo "<br>";
}
遍历数关联数组
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
foreach($age as $x=>$x_value)
{
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
(4).php对象
在”九:面向对象“里会详细说明
三:类型比较
虽然 PHP 是弱类型语言,但也需要明白变量类型及它们的意义,因为我们经常需要对 PHP 变量进行比较,包含松散和严格比较。
松散比较:使用两个等号 == 比较,只比较值,不比较类型。
严格比较:用三个等号 === 比较,除了比较值,也比较类型。
<?php
if(42 == "42") {
echo '1、值相等';
}
echo PHP_EOL; // 换行符
if(42 === "42") {
echo '2、类型相等';
} else {
echo '3、类型不相等';
}
比较 0、false、null :
<?php
echo '0 == false: ';
var_dump(0 == false);
echo '0 === false: ';
var_dump(0 === false);
echo "<br><br>";
echo '0 == null: ';
var_dump(0 == null);
echo '0 === null: ';
var_dump(0 === null);
echo "<br><br>";
echo 'false == null: ';
var_dump(false == null);
echo 'false === null: ';
var_dump(false === null);
echo "<br><br>";
echo '"0" == false: ';
var_dump("0" == false);
echo '"0" === false: ';
var_dump("0" === false);
echo "<br><br>";
echo '"0" == null: ';
var_dump("0" == null);
echo '"0" === null: ';
var_dump("0" === null);
echo "<br><br>";
echo '"" == false: ';
var_dump("" == false);
echo '"" === false: ';
var_dump("" === false);
echo "<br><br>";
echo '"" == null: ';
var_dump("" == null);
echo '"" === null: ';
var_dump("" === null);
四:条件判断
switch语句
<?php
$favcolor = "red";
switch ($favcolor)
{
case "red":
echo "你喜欢的颜色是红色!";
break;
case "blue":
echo "你喜欢的颜色是蓝色!";
break;
case "green":
echo "你喜欢的颜色是绿色!";
break;
default:
echo "你喜欢的颜色不是 红, 蓝, 或绿色!";
}
if…else语句
<?php
$t = date("H"); // 获得当前小时数
if ($t < "20")
{
echo "Have a good day!";
}
else
{
echo "Have a good night!";
}
if…elseif…else语句
<?php
$t = date("H");
if ($t < "10")
{
echo "Have a good morning!";
}
elseif ($t < "20")
{
echo "Have a good day!";
}
else
{
echo "Have a good night!";
}
如果你觉得最后这两个实例的运行结果不对,那是因为自 PHP5.0 开始,用PHP获取系统时间时,时间比当前时间少 8 个小时。原因是 PHP.ini 中没有设置 timezone 时,PHP 是使用的 UTC 时间,所以在中国时间要少 8 小时。因此你的时间都要 -8,所以代码是没问题的。
五:循环语句
while循环
<?php
$i=1;
while($i<=5)
{
echo "The number is " . $i . "<br>";
$i++;
}
do…while循环
<?php
$i=1;
do
{
$i++;
echo "The number is " . $i . "<br>";
}
while ($i<=5);
for循环
<?php
for ($i=1; $i<=5; $i++)
{
echo "数字为 " . $i . "<br>";
}
foreach循环
用于遍历数组
<?php
$x = array("Google", "Runoob", "Taobao");
foreach ($x as $value)
{
echo $x. ". " . $value . "<br>";
}
$y = array(1=>"Google", 2=>"Runoob", 3=>"Taobao");
foreach ($y as $key => $value)
{
echo "key 为 " . $key . ",对应的 value 为 ". $value . "<br>";
}
六:超级全局变量
超级全局变量在PHP 4.1.0之后被启用, 是PHP系统中自带的变量,在一个脚本的全部作用域中都可用。PHP中预定义了几个超级全局变量(superglobals) ,这意味着它们在一个脚本的全部作用域中都可用。 你不需要特别说明,就可以在函数及类中使用。PHP 超级全局变量列表如下:
- $GLOBALS
- $_SERVER
- $_REQUEST
- $_POST
- $_GET
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
PHP $GLOBALS:
$GLOBALS 是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。
<?php
$x = 75;
$y = 25;
function addition()
{
$GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];
}
addition();
echo $z;
以上实例中 z 是一个$GLOBALS数组中的超级全局变量,该变量同样可以在函数外访问。
PHP $_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.runoob.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 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:someone@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"。 |
<?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'];
echo "<br>";
echo $_SERVER['SCRIPT_NAME'];
PHP $_REQUEST:
PHP $_REQUEST 用于收集HTML表单提交的数据。
以下实例显示了一个输入字段(input)及提交按钮(submit)的表单(form)。 当用户通过点击 “Submit” 按钮提交表单数据时, 表单数据将发送至标签中 action 属性中指定的脚本文件。 在这个实例中,我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据,你可以修改该指定的脚本文件名。 然后,我们可以使用超级全局变量 $_REQUEST 来收集表单中的 input 字段数据:
<html>
<body>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
$name = $_REQUEST['fname'];
echo $name;
?>
</body>
</html>
提交前:
提交后:
另外超级全局变量里的$_GET和$_POST也是非常重要的,详细介绍可以参考我的另一篇博客:PHP表单汇总
七:魔术常量
PHP 向它运行的任何脚本提供了大量的预定义常量。
不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了。
有八个魔术常量它们的值随着它们在代码中的位置改变而改变。
- __LINE__
- __FINE__
- __DIR__
- __FUNCTION__
- __CLASS__
- __TRAIT__
- __METHOD__
- __NAMESPACE__
__LINE__:
文件中当前的行号:
<?php
echo '这是第 " ' . __LINE__ . ' " 行';
__FILE__:
文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。
<?php
echo '该文件位于 " ' . __FILE__ . ' " ';
__DIR__:
文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。
它等价于 dirname(__FILE__)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)
<?php
echo '该文件位于 " ' . __DIR__ . ' " ';
__FUNCTION__:
返回所在函数的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
<?php
function test() {
echo '函数名为:' . __FUNCTION__ ;
}
test();
__CLASS__:
返回所在类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。
在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar)。注意自 PHP 5.4 起 __CLASS__ 对 trait 也起作用。当用在 trait 方法中时,__CLASS__ 是调用 trait 方法的类的名字。
<?php
class test {
function _print() {
echo '类名为:' . __CLASS__ . "<br>";
echo '函数名为:' . __FUNCTION__ ;
}
}
$t = new test();
$t->_print();
__TRAIT__:
Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits。
Trait 名包括其被声明的作用区域(例如 Foo\Bar)。
从基类继承的成员被插入的 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();
__METHOD__:
类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
<?php
function test() {
echo '函数名为:' . __METHOD__ ;
}
test();
__NAMESPACE__:
当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。
<?php
namespace MyProject;
echo '命名空间为:"', __NAMESPACE__, '"'; // 输出 "MyProject"
八:函数
PHP 的真正威力源自于它的函数。在 PHP 中,提供了超过 1000 个内建的函数。因此有个流行的梗就是”PHP是最好的语言“。
PHP 函数准则:
函数的名称应该提示出它的功能
函数名称以字母或下划线开头(不能以数字开头)
一个简单的函数:
<?php
// 创建函数
function writeName()
{
echo "Kai Jim Refsnes";
}
echo "Her name is ";
// 调用函数
writeName();
为了给函数添加更多的功能,我们可以添加参数,参数类似变量。参数就在函数名称后面的一个括号内指定。
<?php
function writeName($fname)
{
echo $fname . "<br>";
}
echo "Her name is ";
writeName("Kai Jim");
echo "Her sister's name is ";
writeName("Hege");
echo "Her brother's name is ";
writeName("Stale");
如需让函数返回一个值,请使用 return 语句。
<?php
function add($x, $y)
{
$total = $x+$y;
return $total;
}
echo "1 + 16 = " . add(1,16);
九:命名空间
PHP 命名空间(namespace)是在PHP 5.3中加入的,如果你学过C#和Java,那命名空间就不算什么新事物。 不过在PHP当中还是有着相当重要的意义。
PHP 命名空间可以解决以下两类问题:
用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
定义命名空间
默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。语法格式如下:
<?php
// 定义代码在 'MyProject' 命名空间中
namespace MyProject;
// ... 代码 ...
也可以在同一个文件中定义不同的命名空间代码:
<?php
namespace MyProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
namespace AnotherProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
一般不建议使用这种语法在单个文件中定义多个命名空间。建议使用下面的大括号形式的语法。
<?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 代码包括空白符都不能出现在命名空间的声明之前。
<?php
declare(encoding='UTF-8'); //定义多个命名空间和不包含在命名空间中的代码
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
子命名空间
与目录和文件的关系很像,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义,下面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。
<?php
namespace MyProject\Sub\Level; //声明分层次的单个命名空间
const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */ }
命名空间的使用
PHP 命名空间中的类名可以通过三种方式引用:
非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。
限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。
十:面向对象
在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。
对象的主要三个特性:
对象的行为:可以对对象施加那些操作,开灯,关灯就是行为。
对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。
对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。
面向对象的内容:
类 − 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
对象 − 是类的实例。
成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
成员函数 − 定义在类的内部,可用于访问对象的数据。
继承 − 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
父类 − 一个类被其他类继承,可将该类称为父类,或基类,或超类。
子类 − 一个类继承其他类称为子类,也可称为派生类。
多态 − 多态性是指相同的函数或方法可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
重载 − 简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
抽象性 − 抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
封装 − 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
构造函数 − 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
析构函数 − 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
php类的定义
常见语法格式如下:
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
解析:
类使用 class 关键字后加上类名定义。
类名后的一对大括号({})内可以定义变量和方法。
类的变量使用 var 来声明, 变量也可以初始化值。
函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。
示例:
<?php
class Site {
/* 成员变量 */
var $url;
var $title;
/* 成员函数 */
function setUrl($par){
$this->url = $par; // $this代表自身
}
function getUrl(){
echo $this->url . "<br>";
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . "<br>";
}
}
// 声明对象
$runoob = new Site;
$taobao = new Site;
$google = new Site;
// 调用成员函数,设置标题和URL
$runoob->setTitle( "菜鸟教程" );
$taobao->setTitle( "淘宝" );
$google->setTitle( "Google 搜索" );
$runoob->setUrl( 'www.runoob.com' );
$taobao->setUrl( 'www.taobao.com' );
$google->setUrl( 'www.google.com' );
// 调用成员函数,获取标题和URL
$runoob->getTitle();
$taobao->getTitle();
$google->getTitle();
$runoob->getUrl();
$taobao->getUrl();
$google->getUrl();
PHP 构造函数
构造函数是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,在创建对象的语句中与 new 运算符一起使用。在上面的例子中我们就可以通过构造方法来初始化 $url 和 $title 变量。
function __construct( $par1, $par2 ) {
$this->url = $par1;
$this->title = $par2;
}
这样我们就不需要再调用 setTitle 和 setUrl 方法了,如下:
<?php
class Site {
/* 成员变量 */
var $url;
var $title;
function __construct( $par1, $par2 ) {
$this->url = $par1;
$this->title = $par2;
}
/* 成员函数 */
function setUrl($par){
$this->url = $par;
}
function getUrl(){
echo $this->url . "<br>";
}
function setTitle($par){
$this->title = $par;
}
function getTitle(){
echo $this->title . "<br>";
}
}
$runoob = new Site('www.runoob.com', '菜鸟教程');
$taobao = new Site('www.taobao.com', '淘宝');
$google = new Site('www.google.com', 'Google 搜索');
// 调用成员函数,获取标题和URL
$runoob->getTitle();
$taobao->getTitle();
$google->getTitle();
$runoob->getUrl();
$taobao->getUrl();
$google->getUrl();
PHP 析构函数
析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言。
<?php
class MyDestructableClass {
function __construct() {
print "构造函数\n";
$this->name = "MyDestructableClass";
}
function __destruct() {
print "销毁 " . $this->name . "\n";
}
}
$obj = new MyDestructableClass();
PHP 继承
PHP 使用关键字 extends 来继承一个类,PHP 不支持多继承
<?php
// 父类
class Site
{
var $par = "taobao";
}
// 子类扩展站点类别
class Child_Site extends Site
{
var $category = 3;
function getVar()
{
echo $this->category . "<br>";
echo $this->par . "<br>";
}
}
$site = new Child_Site();
$site -> getVar();
方法重写
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。以下实例中重写了 getUrl 与 getTitle 方法:
<?php
// 父类
class Site
{
function printing()
{
echo "我还没被修改"."<br>";
}
}
// 子类扩展站点类别
class Child_Site extends Site
{
function printing()
{
echo "我已经被修改了"."<br>";
}
}
$Site = new Site();
$Csite = new Child_Site();
$Site -> printing();
$Csite -> printing();
$Site -> printing();
控制访问
PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。
public(公有):公有的类成员可以在任何地方被访问。
protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问。
private(私有):私有的类成员则只能被其定义所在的类访问。
属性的访问控制:
类属性必须定义为公有,受保护,私有之一。如果用 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
方法的访问控制
类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。
<?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\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
接口
使用接口(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 getValue();
abstract protected function prefixValue($prefix);
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . "<br>";
}
}
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_') . "<br>";
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . "<br>";
Static关键字
声明类属性或方法为 static(静态),就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。静态属性不可以由对象通过 -> 操作符来访问。自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字 self,parent 或 static。
<?php
class Foo {
public static $my_static = 'foo';
public function staticValue() {
return self::$my_static;
}
}
print Foo::$my_static . "<br>";
$foo = new Foo();
print $foo->staticValue() . "<br>";
Final关键字
PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called" . "<br>";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called" . "<br>";
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called" . "<br>";
}
}