前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >php代码抄写笔记

php代码抄写笔记

作者头像
木尤
发布2020-07-14 15:30:57
4K0
发布2020-07-14 15:30:57
举报
文章被收录于专栏:我的csdn我的csdn

PHP笔记随笔

1th.php代码内可以包含html内容,或者说php脚本文件内php解释器仅仅解释

代码语言:javascript
复制
<!DOCTYPE HTML>
<HTML>
<BODY>
<?php
	echo "我的第一段php脚本";
?>
</BODY>
</HTML>

2nd

PHP内嵌html

代码语言:javascript
复制
<HTML>
<BODY>
<h1>我的第一张PHP页面</h1>
<?php
    echo "Hello World!";
?>
</BODY>
</HTML>

3rd

php的三种注释

代码语言:javascript
复制
<!DOCTYPE HTML>
<HTML>
<BODY>
<?php
    //这是单行注释
    #这个也是单行注释
    /*
    第一行注释
    第二行注释
    */
?>
</BODY>
</HTML>

4th

变量大小写

用户定义的函数、类和关键词大小写不敏感; 变量大小写敏感。

代码语言:javascript
复制
<?php
  echo "haha";
  ECHO "HAHA";
  eCHO "haha";
  $color = 'red';
  $Color = 'green';
  $COLOR = 'yellow';
  echo 'the color is '.$color;
  echo 'the color is '.$Color;
  echo 'the color is '.$COLOR;
?>

5th

php变量

以$开头,变量名以字母或下划线开头,可以含有数字

代码语言:javascript
复制
<?php
$x = 5;
$y = 6;
$z = $x + $y;
echo $z;
?>

6th

php变量作用域

php变量类型松散,定义时变量一个类型,在之后可以赋予另一种类型的参数。 三种作用域:local、global、static global关键字用在函数内变量前表示声明以后使用的变量为全局变量。 static关键字用在函数内变量前表示该变量在函数执行完成后不销毁,且static关键字定义的变量赋予的仅是初始值,再次执行函数,不会执行定义中的赋值操作。

代码语言:javascript
复制
<?php
$x = 5;//全局作用域
$y = 5;

function myTest(){
    $x = 10;
	$x++;
	$y = 10;//局部作用域
	global $y;//等同于直接使用GLOBALS['y']
	$y++;
    static $s = 1;
	$s++;
	echo "变量x是:$x<br>";
	echo "变量y是:$y<br>";
	echo "变量s是:$s<br>";
}

myTest();
myTest();
myTest();

?>

7th echo为php的一个结构,print可以看作一个函数,有返回值,var_dump()函数可以输出内容和类型

单双引号的区别

代码语言:javascript
复制
<?php
	$x = "haha";
	echo "\$x is $x<br>";
	echo print('$x is $x');
?>

输出:

代码语言:javascript
复制
$x is haha
$x is $x
1

8th

整数、浮点数表示方法

代码语言:javascript
复制
<?php
$a = 1;
$b = 2.0e3;
$c = 0x1a;//十六进制
$d = 017;//8进制
var_dump($a, $b, $c, $d);
?>

输出: int(1) float(2000) int(26) int(15) 9th

类的定义及对象的使用(个人扩展)

代码语言:javascript
复制
<?php
class Car{
	var $color = "N/A"; //尼玛,前面需要加var关键字
	function __construct($color){  //构造函数也属于函数,定义时需要加function关键字,不需要写出返回值类型
		echo "==>Object created! <br><br>The car's color is $color.<br>";
		$this->color = $color;
	}
	
	function __destruct(){
		echo "<br>==>Object teminated!<br>";
	}
	
	function get_color(){
		return $this->color;
	}
	function set_color($color){
		$this->color = $color;
		echo "The car's color is set to $color.<br>";
	}
}

$car = new Car("red");//构造函数有一个变量,new对象时应该赋予参数
$car->set_color("white");
?>

输出

代码语言:javascript
复制
==>Object created! 

The car's color is red.
The car's color is set to white.

==>Object teminated!

10th

php字符串函数

代码语言:javascript
复制
<?php
	echo strlen("hello");
	echo '<br>';
	echo strpos("Hello, World!", "World");
?>

输出

代码语言:javascript
复制
5
7

11th

php使用define()函数定义常量

默认不敏感(FALSE),要让敏感才设置TRUE define('COUNTRY', 'CN', TRUE); //大小写敏感 使用 echo COUNTRY; 12th

php运算符:

算数运算符、赋值运算符、字符串运算符、递增减运算符、比较运算符、逻辑运算符、数组运算符 %、.、.=、++、--、===、!=、!==、and、or、xor、&&、||、! 13th

php数组的联合及比较

代码语言:javascript
复制
<?php
$a = array("BMW"=>"white", "MAZIDA"=>"yellow");
$b = array("BMW"=>"black", "car"=>"yellow");
$c = $a + $b;   //键名一样只取前者,后者忽略
var_dump($a == $b);
var_dump($a === $b);
var_dump($c);
?>

输出 bool(false) bool(false) array(3) { ["BMW"]=> string(5) "white" ["MAZIDA"]=> string(6) "yellow" ["car"]=> string(6) "yellow" } 14th

if、else、elseif语句

代码语言:javascript
复制
<?php
$s = 80;
if($s >= 0 && $s <= 100){
	if($s < 60){
		echo "很差!";
	}
	elseif($s < 80){
		echo "普通!";
	}
	elseif($s <= 100){
		echo "高手";
	}
}
else echo "参数有误!";
?>

15th

switch语句

代码语言:javascript
复制
<?php
$level= 'C';
switch($level){
	case('A'):
	case('B'):  //同时满足多种条件
		echo "level A and level B are both good!"; 
		break;  //必须使用break,不然会继续执行default下的代码块
	case('C'):
		echo "Not that good!";
		break;
	default:
		echo "Arguments error!";
}
?>

16th

PHP数组:数组是一个能够在单个变量中存储多个值的特殊变量

在PHP中创建数组用到函数array();

a.创建数值数组

代码语言:javascript
复制
<?php
$cars=array("Volvo","BMW","Toyota");
echo "I like " . $cars[0] . ", " . $cars[1] . " and " . $cars[2] . ".";
?>

输出

代码语言:javascript
复制
I like Volvo, BMW and Toyota.
a.a.获取数组的长度 - count() 函数
代码语言:javascript
复制
<?php
$cars=array("Volvo","BMW","Toyota");
echo count($cars);
?>

输出

代码语言:javascript
复制
3
a.b.遍历数值数组(用for循环)
代码语言:javascript
复制
<?php
$cars=array("Volvo","BMW","Toyota");
$arrlength=count($cars);
 
for($x=0;$x<$arrlength;$x++)
{
    echo $cars[$x];
    echo "<br>";
}
?>

输出

代码语言:javascript
复制
Volvo
BMW
Toyota

b.PHP 关联数组

定义方法:

$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");

or

$age['Peter']="35"; $age['Ben']="37"; $age['Joe']="43";

实例

代码语言:javascript
复制
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
echo "Peter is " . $age['Peter'] . " years old.";
?>

输出

代码语言:javascript
复制
Peter is 35 years old.
b.a遍历关联数组

遍历并打印关联数组中的所有值,您可以使用 foreach 循环,如下所示:

实例

代码语言:javascript
复制
<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
 
foreach($age as $x=>$x_value)
{
    echo "Key=" . $x . ", Value=" . $x_value;
    echo "<br>";
}
?>

输出

代码语言:javascript
复制
Key=Peter, Value=35
Key=Ben, Value=37
Key=Joe, Value=43

17th

数组排序

PHP 数组排序函数:

  • sort() - 对数组进行升序排列
  • rsort() - 对数组进行降序排列
  • asort() - 根据关联数组的值,对数组进行升序排列
  • ksort() - 根据关联数组的键,对数组进行升序排列
  • arsort() - 根据关联数组的值,对数组进行降序排列
  • krsort() - 根据关联数组的键,对数组进行降序排列

sort() - 对数组进行升序排列

实例

代码语言:javascript
复制
<?php
//将数组cars中的元素按字母升序排序
$cars=array("Volvo","BMW","Toyota");
sort($cars);
?>

输出

代码语言:javascript
复制
Array ( [0] => BMW [1] => Toyota [2] => Volvo )

or

代码语言:javascript
复制
<?php
//将数组numbers中的元素按数字升序排序
$numbers=array(4,6,2,22,11);
sort($numbers);
?>

输出

代码语言:javascript
复制
Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 11 [4] => 22 )

rsort() - 对数组进行降序排列

实例

代码语言:javascript
复制
<?php
//对cars数组中的元素按字母降序排序
$cars=array("Volvo","BMW","Toyota");
rsort($cars);
?>

输出

代码语言:javascript
复制
Array ( [0] => Volvo [1] => Toyota [2] => BMW )

or

代码语言:javascript
复制
<?php
//对numbers数组中的元素按数字降序排序
$numbers=array(4,6,2,22,11);
rsort($numbers);
?>

输出

代码语言:javascript
复制
Array ( [0] => 22 [1] => 11 [2] => 6 [3] => 4 [4] => 2 )

asort() - 根据数组的值,对数组进行升序排列

实例

代码语言:javascript
复制
<?php
//对关联数组age进行升序排序
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
asort($age);
?>

输出

代码语言:javascript
复制
Array ( [Peter] => 35 [Ben] => 37 [Joe] => 43 )

ksort() - 根据数组的键,对数组进行升序排列

实例

代码语言:javascript
复制
<?php
//对关联数组age进行升序排序
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
ksort($age);
?>

输出

代码语言:javascript
复制
Array ( [Ben] => 37 [Joe] => 43 [Peter] => 35 )

arsort() - 根据数组的值,对数组进行降序排列

实例

代码语言:javascript
复制
<?php
//对关联数组age进行降序排序
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
arsort($age);
?>

输出

代码语言:javascript
复制
Array ( [Joe] => 43 [Ben] => 37 [Peter] => 35 )

krsort() - 根据数组的键,对数组进行降序排列

实例

代码语言:javascript
复制
<?php
//对关联数组age进行降序排序
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
krsort($age);
?>

输出

代码语言:javascript
复制
Array ( [Peter] => 35 [Joe] => 43 [Ben] => 37 )

PHP 超级全局变量

PHP中预定义了几个超级全局变量(superglobals) ,这意味着它们在一个脚本的全部作用域中都可用。 你不需要特别说明,就可以在函数及类中使用。

PHP 超级全局变量列表:

  • $GLOBALS
  • $_SERVER
  • $_REQUEST
  • $_POST
  • $_GET
  • $_FILES
  • $_ENV
  • $_COOKIE
  • $_SESSION

PHP $GLOBALS

$GLOBALS 是PHP的一个超级全局变量组,在一个PHP脚本的全部作用域中都可以访问。

$GLOBALS 是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。

实例

代码语言:javascript
复制
<?php 
$x = 75; 
$y = 25;
 
function addition() 
{ 
    $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y']; 
}
 // z 是一个$GLOBALS数组中的超级全局变量,该变量同样可以在函数外访问。
addition(); 
echo $z; 
?>

输出

代码语言:javascript
复制
100

PHP $_SERVER

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。不能保证每个服务器都提供全部项目;服务器可能会忽略一些,或者提供一些没有在这里列举出来的项目。

实例

代码语言:javascript
复制
<?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'];
?>

输出

代码语言:javascript
复制
/try/demo_source/demo_global_server.php
www.runoob.com
www.runoob.com
https://www.runoob.com/try/showphp.php?filename=demo_global_server
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36
/try/demo_source/demo_global_server.php

PHP $_REQUEST

PHP $_REQUEST 用于收集HTML表单提交的数据。

以下实例显示了一个输入字段(input)及提交按钮(submit)的表单(form)。 当用户通过点击 “Submit” 按钮提交表单数据时, 表单数据将发送至标签中 action 属性中指定的脚本文件。 在这个实例中,我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据,你可以修改该指定的脚本文件名。 然后,我们可以使用超级全局变量 $_REQUEST 来收集表单中的 input 字段数据:

实例

代码语言:javascript
复制
<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>

PHP $_POST

PHP $_POST 被广泛应用于收集表单数据,在HTML form标签的指定该属性:"method=“post”。

以下实例显示了一个输入字段(input)及提交按钮(submit)的表单(form)。 当用户通过点击 “Submit” 按钮提交表单数据时, 表单数据将发送至标签中 action 属性中指定的脚本文件。 在这个实例中,我们指定文件来处理表单数据。如果你希望其他的PHP文件来处理该数据,你可以修改该指定的脚本文件名。 然后,我们可以使用超级全局变量 $_POST 来收集表单中的 input 字段数据:

实例

代码语言:javascript
复制
<html>
<body>
 
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="fname">
<input type="submit">
</form>
 
<?php 
$name = $_POST['fname']; 
echo $name; 
?>
 
</body>
</html>

PHP $_GET

PHP $_GET 同样被广泛应用于收集表单数据,在HTML form标签的指定该属性:"method=“get”。

$_GET 也可以收集URL中发送的数据。

假定我们有一个包含参数的超链接HTML页面:

代码语言:javascript
复制
<html>
<body>

<a href="test_get.php?subject=PHP&web=runoob.com">Test $GET</a>

</body>
</html>

当用户点击链接 “Test $GET”, 参数 “subject” 和 “web” 将发送至"test_get.php",你可以在 “test_get.php” 文件中使用 $_GET 变量来获取这些数据。

以下实例显示了 “test_get.php” 文件的代码:

代码语言:javascript
复制
<html>
<body>
 
<?php 
echo "Study " . $_GET['subject'] . " @ " . $_GET['web'];
?>
 
</body>
</html>

PHP循环

在 PHP 中,提供了下列循环语句:

  • while - 只要指定的条件成立,则循环执行代码块
  • do…while - 首先执行一次代码块,然后在指定的条件成立时重复这个循环
  • for - 循环执行代码块指定的次数
  • foreach - 根据数组中每个元素来循环代码块

while循环

while 循环将重复执行代码块,直到指定的条件不成立。

语法

代码语言:javascript
复制
while (条件)
{
    要执行的代码;
}

实例

下面的实例首先设置变量 i 的值为 1 ($i=1;)。

然后,只要 i 小于或者等于 5,while 循环将继续运行。循环每运行一次,i 就会递增 1:

代码语言:javascript
复制
<html>
<body>

<?php
$i=1;
while($i<=5)
{
    echo "The number is " . $i . "<br>";
    $i++;
}
?>

</body>
</html>

输出:

代码语言:javascript
复制
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5

do…while 语句

do…while 语句会至少执行一次代码,然后检查条件,只要条件成立,就会重复进行循环。

语法

代码语言:javascript
复制
do
{
    要执行的代码;
}
while (条件);

实例

下面的实例首先设置变量 i 的值为 1 ($i=1;)。

然后,开始 do…while 循环。循环将变量 i 的值递增 1,然后输出。先检查条件(i 小于或者等于 5),只要 i 小于或者等于 5,循环将继续运行:

代码语言:javascript
复制
<html>
<body>

<?php
$i=1;
do
{
    $i++;
    echo "The number is " . $i . "<br>";
}
while ($i<=5);
?>

</body>
</html>

输出:

代码语言:javascript
复制
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6

for 循环

for 循环用于您预先知道脚本需要运行的次数的情况。

语法

代码语言:javascript
复制
for (初始值; 条件; 增量)
{
    要执行的代码;
}

参数:

  • 初始值:主要是初始化一个变量值,用于设置一个计数器(但可以是任何在循环的开始被执行一次的代码)。
  • 条件:循环执行的限制条件。如果为 TRUE,则循环继续。如果为 FALSE,则循环结束。
  • 增量:主要用于递增计数器(但可以是任何在循环的结束被执行的代码)。

注释:上面的初始值增量参数可为空,或者有多个表达式(用逗号分隔)。

实例

下面的实例定义一个初始值为 i=1 的循环。只要变量 i 小于或者等于 5,循环将继续运行。循环每运行一次,变量 i 就会递增 1:

实例

代码语言:javascript
复制
<?php
for ($i=1; $i<=5; $i++)
{
    echo "The number is " . $i . "<br>";
}
?>

输出:

代码语言:javascript
复制
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5

foreach 循环

foreach 循环用于遍历数组。

语法

代码语言:javascript
复制
foreach ($array as $value)
{
    要执行代码;
}

每进行一次循环,当前数组元素的值就会被赋值给 $value 变量(数组指针会逐一地移动),在进行下一次循环时,您将看到数组中的下一个值。

实例

下面的实例演示了一个输出给定数组的值的循环:

代码语言:javascript
复制
<?php
$x=array("one","two","three");
foreach ($x as $value)
{
    echo $value . "<br>";
}
?>

输出:

代码语言:javascript
复制
one
two
three

PHP函数

PHP 内建函数

如需查看所有数组函数的完整参考手册和实例,请访问我们的 PHP 参考手册

php函数

创建 PHP 函数

函数是通过调用函数来执行的。

语法

代码语言:javascript
复制
<?php
function functionName()
{
    // 要执行的代码
}
?>

PHP 函数准则:

  • 函数的名称应该提示出它的功能
  • 函数名称以字母或下划线开头(不能以数字开头)

实例

一个简单的函数,在其被调用时能输出我的名称:

代码语言:javascript
复制
<?php
function writeName()
{
    echo "Kai Jim Refsnes";
}
 
echo "My name is ";
writeName();
?>

输出:

代码语言:javascript
复制
My name is Kai Jim Refsnes

PHP 函数 - 添加参数

为了给函数添加更多的功能,我们可以添加参数,参数类似变量。

参数就在函数名称后面的一个括号内指定。

实例 1

下面的实例将输出不同的名字,但姓是相同的:

代码语言:javascript
复制
<?php
function writeName($fname)
{
    echo $fname . " Refsnes.<br>";
}
 
echo "My name is ";
writeName("Kai Jim");
echo "My sister's name is ";
writeName("Hege");
echo "My brother's name is ";
writeName("Stale");
?>

输出:

代码语言:javascript
复制
My name is Kai Jim Refsnes.
My sister's name is Hege Refsnes.
My brother's name is Stale Refsnes.

实例 2

下面的函数有两个参数:

代码语言:javascript
复制
<?php
function writeName($fname,$punctuation)
{
    echo $fname . " Refsnes" . $punctuation . "<br>";
}
 
echo "My name is ";
writeName("Kai Jim",".");
echo "My sister's name is ";
writeName("Hege","!");
echo "My brother's name is ";
writeName("Ståle","?");
?>

输出:

代码语言:javascript
复制
My name is Kai Jim Refsnes.
My sister's name is Hege Refsnes!
My brother's name is Ståle Refsnes?

PHP 函数 - 返回值

如需让函数返回一个值,请使用 return 语句。

代码语言:javascript
复制
<?php
function add($x,$y)
{
    $total=$x+$y;
    return $total;
}
 
echo "1 + 16 = " . add(1,16);
?>

输出:

代码语言:javascript
复制
1 + 16 = 17

PHP魔术常量

PHP 向它运行的任何脚本提供了大量的预定义常量。

不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了。

有八个魔术常量它们的值随着它们在代码中的位置改变而改变。

例如 LINE 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写,如下:

LINE

文件中的当前行号。

实例

代码语言:javascript
复制
<?php
echo '这是第 " '  . __LINE__ . ' " 行';
?>

以上实例输出结果为:

代码语言:javascript
复制
这是第 “ 2 ” 行

FILE

文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。

自 PHP 4.0.2 起,FILE 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。

实例:

代码语言:javascript
复制
<?php
echo '该文件位于 " '  . __FILE__ . ' " ';
?>

以上实例输出结果为:

代码语言:javascript
复制
该文件位于 “ E:\wamp\www\test\index.php ”

DIR

文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。

它等价于 dirname(FILE)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增)

代码语言:javascript
复制
<?php
echo '该文件位于 " '  . __DIR__ . ' " ';
?>

以上实例输出结果为:

代码语言:javascript
复制
该文件位于 “ E:\wamp\www\test ”

FUNCTION

函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。

代码语言:javascript
复制
<?php
function test() {
    echo  '函数名为:' . __FUNCTION__ ;
}
test();
?>

以上实例输出结果为:

代码语言:javascript
复制
函数名为:test

CLASS

类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。

在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar)。注意自 PHP 5.4 起 CLASS 对 trait 也起作用。当用在 trait 方法中时,CLASS 是调用 trait 方法的类的名字。

代码语言:javascript
复制
<?php
class test {
    function _print() {
        echo '类名为:'  . __CLASS__ . "<br>";
        echo  '函数名为:' . __FUNCTION__ ;
    }
}
$t = new test();
$t->_print();
?>

以上实例输出结果为:

代码语言:javascript
复制
类名为:test
函数名为:_print

TRAIT

Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits。

Trait 名包括其被声明的作用区域(例如 Foo\Bar)。

从基类继承的成员被插入的 SayWorld Trait 中的 MyHelloWorld 方法所覆盖。其行为 MyHelloWorld 类中定义的方法一致。优先顺序是当前类中的方法会覆盖 trait 方法,而 trait 方法又覆盖了基类中的方法。

代码语言:javascript
复制
<?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();
?>

以上例程会输出:

代码语言:javascript
复制
Hello World!

METHOD

类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

实例:

代码语言:javascript
复制
<?php
function test() {
    echo  '函数名为:' . __METHOD__ ;
}
test();
?>

以上实例输出结果为:

代码语言:javascript
复制
函数名为:test

NAMESPACE

当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。

实例:

代码语言:javascript
复制
<?php
namespace MyProject;
 
echo '命名空间为:"', __NAMESPACE__, '"'; // 输出 "MyProject"
?>

以上实例输出结果为:

代码语言:javascript
复制
命名空间为:"MyProject"

PHP 命名空间(namespace)

PHP 命名空间(namespace)是在PHP 5.3中加入的,如果你学过C#和Java,那命名空间就不算什么新事物。 不过在PHP当中还是有着相当重要的意义。

PHP 命名空间可以解决以下两类问题:

  1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
  2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

定义命名空间

默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。

命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。语法格式如下;

代码语言:javascript
复制
<?php  
// 定义代码在 'MyProject' 命名空间中  
namespace MyProject;  
 
// ... 代码 ...  

你也可以在同一个文件中定义不同的命名空间代码,如:

代码语言:javascript
复制
<?php  
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
?>  

不建议使用这种语法在单个文件中定义多个命名空间。建议使用下面的大括号形式的语法。

代码语言:javascript
复制
<?php
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace AnotherProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
?>

将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,例如:

代码语言:javascript
复制
<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。

代码语言:javascript
复制
<?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();
}
?>

以下代码会出现语法错误:

代码语言:javascript
复制
<html>
<?php
namespace MyProject; // 命名空间前出现了“<html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
?>

子命名空间

与目录和文件的关系很像,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义:

代码语言:javascript
复制
<?php
namespace MyProject\Sub\Level;  //声明分层次的单个命名空间

const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }

?>

上面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。


命名空间使用

PHP 命名空间中的类名可以通过三种方式引用:

  1. **非限定名称,或不包含前缀的类名称,**例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。
  2. **限定名称,或包含前缀的名称,**例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
  3. **完全限定名称,或包含了全局前缀操作符的名称,**例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

下面是一个使用这三种方式的实例:

file1.php 文件代码

代码语言:javascript
复制
<?php
namespace Foo\Bar\subnamespace; 

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>

file2.php 文件代码

代码语言:javascript
复制
<?php
namespace Foo\Bar;
include 'file1.php';

const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}

/* 非限定名称 */
foo(); // 解析为函数 Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo ,方法为 staticmethod
echo FOO; // 解析为常量 Foo\Bar\FOO

/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
                                  // 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO
                                  
/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
?>

注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。

在命名空间内部访问全局类、函数和常量:

代码语言:javascript
复制
<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen('hi'); // 调用全局函数strlen
$b = \INI_ALL; // 访问全局常量 INI_ALL
$c = new \Exception('error'); // 实例化全局类 Exception
?>

命名空间和动态语言特征

PHP 命名空间的实现受到其语言自身的动态特征的影响。因此,如果要将下面的代码转换到命名空间中,动态访问元素。

example1.php 文件代码:

代码语言:javascript
复制
<?php
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "global";

$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global
?>

必须使用完全限定名称(包括命名空间前缀的类名称)。注意因为在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜杠是不必要的。

动态访问命名空间的元素

代码语言:javascript
复制
<?php
namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__,"\n";
    }
}
function funcname()
{
    echo __FUNCTION__,"\n";
}
const constname = "namespaced";

include 'example1.php';

$a = 'classname';
$obj = new $a; // 输出 classname::__construct
$b = 'funcname';
$b(); // 输出函数名
echo constant('constname'), "\n"; // 输出 global

/* 如果使用双引号,使用方法为 "\\namespacename\\classname"*/
$a = '\namespacename\classname';
$obj = new $a; // 输出 namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // 输出 namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // 输出 namespacename\funcname
$b = '\namespacename\funcname';
$b(); // 输出 namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // 输出 namespaced
echo constant('namespacename\constname'), "\n"; // 输出 namespaced
?>

namespace关键字和__NAMESPACE__常量

PHP支持两种抽象的访问当前命名空间内部元素的方法,NAMESPACE 魔术常量和namespace关键字。

常量__NAMESPACE__的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。

NAMESPACE 示例, 在命名空间中的代码

代码语言:javascript
复制
<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // 输出 "MyProject"
?>

NAMESPACE 示例,全局代码

代码语言:javascript
复制
<?php

echo '"', __NAMESPACE__, '"'; // 输出 ""
?>

常量 NAMESPACE 在动态创建名称时很有用,例如:

使用__NAMESPACE__动态创建名称

代码语言:javascript
复制
<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}
?>

关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。

namespace操作符,命名空间中的代码

代码语言:javascript
复制
<?php
namespace MyProject;

use blah\blah as mine; // see "Using namespaces: importing/aliasing"

blah\mine(); // calls function blah\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method "method" of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b
?>

namespace操作符, 全局代码

代码语言:javascript
复制
<?php

namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method "method" of class cname
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b
?>

使用命名空间:别名/导入

PHP 命名空间支持 有两种使用别名或导入方式:为类名称使用别名,或为命名空间名称使用别名。

在PHP中,别名是通过操作符 use 来实现的. 下面是一个使用所有可能的三种导入方式的例子:

1、使用use操作符导入/使用别名

代码语言:javascript
复制
<?php
namespace foo;
use My\Full\Classname as Another;

// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;

// 导入一个全局类
use \ArrayObject;

$obj = new namespace\Another; // 实例化 foo\Another 对象
$obj = new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象
// 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象
?>

2、 一行中包含多个use语句

代码语言:javascript
复制
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
?>

导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。

3、导入和动态名称

代码语言:javascript
复制
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化一个 My\Full\Classname 对象
$a = 'Another';
$obj = new $a;      // 实际化一个 Another 对象
?>

另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。

4、导入和完全限定名称

代码语言:javascript
复制
<?php
use My\Full\Classname as Another, My\Full\NSname;

$obj = new Another; // 实例化 My\Full\Classname 类
$obj = new \Another; // 实例化 Another 类
$obj = new Another\thing; // 实例化 My\Full\Classname\thing 类
$obj = new \Another\thing; // 实例化 Another\thing 类
?>

使用命名空间:后备全局函数/常量

在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称,例如:

1、在命名空间中访问全局类

代码语言:javascript
复制
<?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 类
?>

对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。

2、 命名空间中后备的全局函数/常量

代码语言:javascript
复制
<?php
namespace A\B\C;

const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}

echo E_ERROR, "\n"; // 输出 "45"
echo INI_ALL, "\n"; // 输出 "7" - 使用全局常量 INI_ALL

echo strlen('hi'), "\n"; // 输出 "1"
if (is_array('hi')) { // 输出 "is not array"
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

全局空间

如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。

使用全局空间说明

代码语言:javascript
复制
<?php
namespace A\B\C;

/* 这个函数是 A\B\C\fopen */
function fopen() { 
     /* ... */
     $f = \fopen(...); // 调用全局的fopen函数
     return $f;
} 
?>

命名空间的顺序

自从有了命名空间之后,最容易出错的该是使用类的时候,这个类的寻找路径是什么样的了。

代码语言:javascript
复制
<?php
namespace A;
use B\D, C\E as F;

// 函数调用

foo();      // 首先尝试调用定义在命名空间"A"中的函数foo()
            // 再尝试调用全局函数 "foo"

\foo();     // 调用全局空间函数 "foo" 

my\foo();   // 调用定义在命名空间"A\my"中函数 "foo" 

F();        // 首先尝试调用定义在命名空间"A"中的函数 "F" 
            // 再尝试调用全局函数 "F"

// 类引用

new B();    // 创建命名空间 "A" 中定义的类 "B" 的一个对象
            // 如果未找到,则尝试自动装载类 "A\B"

new D();    // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
            // 如果未找到,则尝试自动装载类 "B\D"

new F();    // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
            // 如果未找到,则尝试自动装载类 "C\E"

new \B();   // 创建定义在全局空间中的类 "B" 的一个对象
            // 如果未发现,则尝试自动装载类 "B"

new \D();   // 创建定义在全局空间中的类 "D" 的一个对象
            // 如果未发现,则尝试自动装载类 "D"

new \F();   // 创建定义在全局空间中的类 "F" 的一个对象
            // 如果未发现,则尝试自动装载类 "F"

// 调用另一个命名空间中的静态方法或命名空间函数

B\foo();    // 调用命名空间 "A\B" 中函数 "foo"

B::foo();   // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
            // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"

D::foo();   // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
            // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"

\B\foo();   // 调用命名空间 "B" 中的函数 "foo" 

\B::foo();  // 调用全局空间中的类 "B" 的 "foo" 方法
            // 如果类 "B" 未找到,则尝试自动装载类 "B"

// 当前命名空间中的静态方法或函数

A\B::foo();   // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"

\A\B::foo();  // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
              // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"
?>

名称解析遵循下列规则:

  1. 对完全限定名称的函数,类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B
  2. 所有的非限定名称和限定名称(非完全限定名称)根据当前的导入规则在编译时进行转换。例如,如果命名空间 A\B\C 被导入为 C,那么对 C\D\e() 的调用就会被转换为 A\B\C\D\e()
  3. 在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e()
  4. 非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C()
  5. 在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数foo()的调用是这样解析的:
    1. 在当前命名空间中查找名为 A\B\foo() 的函数
    2. 尝试查找并调用 全局(global) 空间中的函数 foo()
  6. 在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用new C()及new D\E()的解析过程:new C()的解析:
    1. 在当前命名空间中查找A\B\C类。
    2. 尝试自动装载类A\B\C

    new D\E()的解析:

    1. 在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。
    2. 尝试自动装载类 A\B\D\E

    为了引用全局命名空间中的全局类,必须使用完全限定名称new \C()。

PHP 面向对象

在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。

在现实世界里我们所面对的事情都是对象,如计算机、电视机、自行车等。

对象的主要三个特性:

  • 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为。
  • 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。
  • 对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。

比如 Animal(动物) 是一个抽象类,我们可以具体到一只狗跟一只羊,而狗跟羊就是具体的对象,他们有颜色属性,可以写,可以跑等行为状态。

面向对象内容

  • − 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
  • 对象 − 是类的实例。
  • 成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
  • 成员函数 − 定义在类的内部,可用于访问对象的数据。
  • 继承 − 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
  • 父类 − 一个类被其他类继承,可将该类称为父类,或基类,或超类。
  • 子类 − 一个类继承其他类称为子类,也可称为派生类。
  • 多态 − 多态性是指相同的函数或方法可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
  • 重载 − 简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
  • 抽象性 − 抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
  • 封装 − 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
  • 构造函数 − 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
  • 析构函数 − 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。

下图中我们通过 Car 类 创建了三个对象:Mercedes, Bmw, 和 Audi。

代码语言:javascript
复制
$mercedes = new Car ();
$bmw = new Car ();
$audi = new Car ();

PHP 类定义

PHP 定义类通常语法格式如下:

代码语言:javascript
复制
<?php
class phpClass {
  var $var1;
  var $var2 = "constant string";
  
  function myfunc ($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

解析如下:

  • 类使用 class 关键字后加上类名定义。
  • 类名后的一对大括号({})内可以定义变量和方法。
  • 类的变量使用 var 来声明, 变量也可以初始化值。
  • 函数定义类似 PHP 函数的定义,但函数只能通过该类及其实例化的对象访问。

实例

代码语言:javascript
复制
<?php
class Site {
  /* 成员变量 */
  var $url;
  var $title;
  
  /* 成员函数 */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

变量 $this 代表自身的对象。

PHP_EOL 为换行符。

PHP 中创建对象

类创建后,我们可以使用 new 运算符来实例化该类的对象:

代码语言:javascript
复制
$runoob = new Site;
$taobao = new Site;
$google = new Site;

以上代码我们创建了三个对象,三个对象各自都是独立的,接下来我们来看看如何访问成员方法与成员变量。

调用成员方法

在实例化对象后,我们可以使用该对象调用成员方法,该对象的成员方法只能操作该对象的成员变量:

代码语言:javascript
复制
// 调用成员函数,设置标题和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();

完整代码如下

代码语言:javascript
复制
<?php
class Site {
  /* 成员变量 */
  var $url;
  var $title;
  
  /* 成员函数 */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}

$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();
?>

执行以上代码,输出结果为:

代码语言:javascript
复制
菜鸟教程
淘宝
Google 搜索
www.runoob.com
www.taobao.com
www.google.com

PHP 构造函数

构造函数是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,在创建对象的语句中与 new 运算符一起使用。

PHP 5 允许开发者在一个类中定义一个方法作为构造函数,语法格式如下:

代码语言:javascript
复制
void __construct ([ mixed $args [, $... ]] )

在上面的例子中我们就可以通过构造方法来初始化 $url 和 $title 变量:

代码语言:javascript
复制
function __construct( $par1, $par2 ) {
   $this->url = $par1;
   $this->title = $par2;
}

现在我们就不需要再调用 setTitle 和 setUrl 方法了:

代码语言:javascript
复制
$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();

析构函数

析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。

PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,其语法格式如下:

代码语言:javascript
复制
void __destruct ( void )

实例

代码语言:javascript
复制
<?php
class MyDestructableClass {
   function __construct() {
       print "构造函数\n";
       $this->name = "MyDestructableClass";
   }

   function __destruct() {
       print "销毁 " . $this->name . "\n";
   }
}

$obj = new MyDestructableClass();
?>

执行以上代码,输出结果为:

代码语言:javascript
复制
构造函数
销毁 MyDestructableClass

继承

PHP 使用关键字 extends 来继承一个类,PHP 不支持多继承,格式如下:

代码语言:javascript
复制
class Child extends Parent {
   // 代码部分
}

实例

实例中 Child_Site 类继承了 Site 类,并扩展了功能:

代码语言:javascript
复制
<?php 
// 子类扩展站点类别
class Child_Site extends Site {
   var $category;

    function setCate($par){
        $this->category = $par;
    }
  
    function getCate(){
        echo $this->category . PHP_EOL;
    }
}

方法重写

如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。

实例中重写了 getUrl 与 getTitle 方法:

代码语言:javascript
复制
function getUrl() {
   echo $this->url . PHP_EOL;
   return $this->url;
}
   
function getTitle(){
   echo $this->title . PHP_EOL;
   return $this->title;
}

访问控制

PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。

  • **public(公有):**公有的类成员可以在任何地方被访问。
  • **protected(受保护):**受保护的类成员则可以被其自身以及其子类和父类访问。
  • **private(私有):**私有的类成员则只能被其定义所在的类访问。
属性的访问控制

类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。

代码语言:javascript
复制
<?php
/**
 * Define MyClass
 */
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


/**
 * Define MyClass2
 */
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

?>
方法的访问控制

类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。

代码语言:javascript
复制
<?php
/**
 * Define MyClass
 */
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(); // 公有,受保护,私有都可以执行


/**
 * Define MyClass2
 */
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 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。

代码语言:javascript
复制
<?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)。

实例

代码语言:javascript
复制
<?php
class MyClass
{
    const constant = '常量值';

    function showConstant() {
        echo  self::constant . PHP_EOL;
    }
}

echo MyClass::constant . PHP_EOL;

$classname = "MyClass";
echo $classname::constant . PHP_EOL; // 自 5.3.0 起

$class = new MyClass();
$class->showConstant();

echo $class::constant . PHP_EOL; // 自 PHP 5.3.0 起
?>

抽象类

任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。

定义为抽象的类不能被实例化。

被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。

代码语言:javascript
复制
<?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;
?>

执行以上代码,输出结果为:

代码语言:javascript
复制
ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

此外,子类方法可以包含父类抽象方法中不存在的可选参数。

例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则也是可以正常运行的。

代码语言:javascript
复制
<?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";
?>

输出结果为:

代码语言:javascript
复制
Mr. Pacman
Mrs. Pacwoman

Static 关键字

声明类属性或方法为 static(静态),就可以不实例化类而直接访问。

静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。

由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。

静态属性不可以由对象通过 -> 操作符来访问。

自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字 self,parent 或 static。

代码语言:javascript
复制
<?php
class Foo {
  public static $my_static = 'foo';
  
  public function staticValue() {
     return self::$my_static;
  }
}

print Foo::$my_static . PHP_EOL;
$foo = new Foo();

print $foo->staticValue() . PHP_EOL;
?>    

执行以上程序,输出结果为:

代码语言:javascript
复制
foo
foo

Final 关键字

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

以下代码执行会报错:

代码语言:javascript
复制
<?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;
   }
}
// 报错信息 Fatal error: Cannot override final method BaseClass::moreTesting()
?>

调用父类构造方法

PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct()

代码语言:javascript
复制
<?php
class BaseClass {
   function __construct() {
       print "BaseClass 类中构造方法" . PHP_EOL;
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();  // 子类构造方法不能自动调用父类的构造方法
       print "SubClass 类中构造方法" . PHP_EOL;
   }
}
class OtherSubClass extends BaseClass {
    // 继承 BaseClass 的构造方法
}

// 调用 BaseClass 构造方法
$obj = new BaseClass();

// 调用 BaseClass、SubClass 构造方法
$obj = new SubClass();

// 调用 BaseClass 构造方法
$obj = new OtherSubClass();
?>

执行以上程序,输出结果为:

代码语言:javascript
复制
BaseClass 类中构造方法
BaseClass 类中构造方法
SubClass 类中构造方法
BaseClass 类中构造方法
注:笔记仅供学习交流,请勿用于违法行为,如造成后果,与笔者无关

本人小白一枚,如果各位老哥发现错误,还望指出

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/07/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PHP笔记随笔
  • 1th.php代码内可以包含html内容,或者说php脚本文件内php解释器仅仅解释
  • PHP内嵌html
  • php的三种注释
  • 变量大小写
  • php变量
  • php变量作用域
  • 单双引号的区别
  • 整数、浮点数表示方法
  • 类的定义及对象的使用(个人扩展)
  • php字符串函数
  • php使用define()函数定义常量
  • php运算符:
  • php数组的联合及比较
  • if、else、elseif语句
  • switch语句
  • PHP数组:数组是一个能够在单个变量中存储多个值的特殊变量
    • a.创建数值数组
      • a.a.获取数组的长度 - count() 函数
      • a.b.遍历数值数组(用for循环)
    • b.PHP 关联数组
      • b.a遍历关联数组
  • 数组排序
    • sort() - 对数组进行升序排列
      • rsort() - 对数组进行降序排列
        • asort() - 根据数组的值,对数组进行升序排列
          • ksort() - 根据数组的键,对数组进行升序排列
            • arsort() - 根据数组的值,对数组进行降序排列
              • krsort() - 根据数组的键,对数组进行降序排列
              • PHP 超级全局变量
                • PHP $GLOBALS
                  • PHP $_SERVER
                    • PHP $_REQUEST
                      • PHP $_POST
                        • PHP $_GET
                        • PHP循环
                          • while循环
                            • do…while 语句
                              • for 循环
                                • foreach 循环
                                • PHP函数
                                  • PHP 内建函数
                                    • php函数
                                      • PHP 函数 - 添加参数
                                        • PHP 函数 - 返回值
                                        • PHP魔术常量
                                          • LINE
                                            • FILE
                                              • DIR
                                                • FUNCTION
                                                  • CLASS
                                                    • TRAIT
                                                      • METHOD
                                                        • NAMESPACE
                                                        • PHP 命名空间(namespace)
                                                          • 定义命名空间
                                                            • 子命名空间
                                                              • 命名空间使用
                                                                • 命名空间和动态语言特征
                                                                  • namespace关键字和__NAMESPACE__常量
                                                                    • 使用命名空间:别名/导入
                                                                      • 使用命名空间:后备全局函数/常量
                                                                        • 全局空间
                                                                          • 命名空间的顺序
                                                                          • PHP 面向对象
                                                                            • 面向对象内容
                                                                              • PHP 类定义
                                                                                • 实例
                                                                                  • PHP 中创建对象
                                                                                    • 调用成员方法
                                                                                  • PHP 构造函数
                                                                                  • 析构函数
                                                                                    • 继承
                                                                                      • 方法重写
                                                                                        • 访问控制
                                                                                          • 属性的访问控制
                                                                                          • 方法的访问控制
                                                                                        • 接口
                                                                                          • 常量
                                                                                            • 抽象类
                                                                                              • Static 关键字
                                                                                                • Final 关键字
                                                                                                  • 调用父类构造方法
                                                                                                  领券
                                                                                                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档