PHP基础学习

PHP

PHP教程

1.搭建环境

1.搭建环境

Apache服务器和PHP的安装 配置conf文件

2.测试环境

在Apache的安装目录下的htdocs的文件目录下,建立一个文件phpinfo.php

<?php
phpinfo();
?>

开启Apache的服务 这个要到对应的目录下运行这些指令

httpd.exe -k install  # 安装服务
httpd.exe -k start  # 开启服务
httpd.exe -t   # 查看是否有错误  

要使php的short-open-tag起作用,要修改php.ini的文件信息,将这个标签改成short-open-tag = On

这样配置之后,打开浏览器访问localhost/phpinfo.php,就可以看到相应的信息了

3.PhpStorm配置php环境

PhpStorm配置php环境

2.php语法

php脚本可以放在文档中的任何位置,php脚本以<?php开始,?>结束,php文件通常的默认文件拓展名为.php,php文件中通常包含HTML标签和一些PHP脚本代码

代码实例

<!DOCTYPE html>
<html>
<body>
<h1>My first PHP page</h1>
<?php
echo "Hello World!";
?>
</body>
</html>

php中的每一个代码都必须以分号结束,分号是一种分隔符,用于把指令集区分开,通过php,有两种在浏览器输出文本的基础指令echoprint

1.php中的注释

//这个是php的单行注释
/*
这个是php的多行注释
*/

3.php变量

<!DOCTYPE html>
<html>
<body>
<h1>My first PHP page</h1>
<?php
    $x = 5;
    $y = 6;
    $z = $x + $y;
    print $z;
?>
</body>
</html>

1.php变量规则

  • 变量以$符号开始,后面跟着变量的名称
  • 变量名必须以字母或者下划线字符开始
  • 变量名只能包含字母数字字符以及下划线(A-z、0-9和_)
  • 变量名不能包含空格
  • 变量名是区分大小写的($y$Y是两个不同的变量)

php没有声明变量得命令,变量在您第一次赋值给它的时候就被创建了

注意:当你赋一个文本值给变量时,请在文本值两侧加上引号

php是一门弱类型语言

不必向php声明该变量的数据类型,PHP会根据变量的值,自动把变量转换为正确的数据类型。在强类型的编程语言中,我们必须在使用变量前先声明(定义)变量的类型和名称。

2.php变量作用域

变量的作用域是脚本中变量可被引用/使用的部分。

PHP有四种不同的变量作用域:local global static parameter

测试代码

<?php
$x=5; // 全局变量
function myTest($x)
{
    $y=10; // 局部变量
    echo "<p>Test variables inside the function:</p>";
    echo "Variable x is: $x";
    echo "<br>";
    echo "Variable y is: $y";
}
myTest($x);
echo "<p>Test variables outside the function:</p>";
echo "Variable x is: $x";
echo "<br>";
echo "Variable y is: $y";
?>

1.php global关键字

global 关键字用于函数内访问全局变量。

在函数内调用函数外定义的全局变量,我们需要在函数中的变量前加上 global 关键字:

<?php
$x=5; // 全局变量
function myTest()
{
    global $x;  // 声明为全局变量
    $y=10; // 局部变量
    echo "<p>Test variables inside the function:</p>";
    echo "Variable x is: $x";
    echo "<br>";
    echo "Variable y is: $y";
}
myTest();
echo "<p>Test variables outside the function:</p>";
echo "Variable x is: $x";
echo "<br>";
echo "Variable y is: $y";
?>

PHP 将所有全局变量存储在一个名为 $GLOBALS[*index*] 的数组中。 index 保存变量的名称。这个数组可以在函数内部访问,也可以直接用来更新全局变量。

测试代码

<?php
$x = 5; // 全局变量
$y = 6;
function myTest()
{
    $GLOBALS['y'] = $GLOBALS['x'] + $GLOBALS['y'];
}
echo "$y</br>";
myTest();
echo $y;
?>

2.php static作用域

这个的作用是使变量在使用的过程中,不会被函数不使用时,而被删除掉

测试代码

<?php
function myTest()
{
    static $x = 1;
    echo "$x<br/>";
    $x++;
}
myTest();
myTest();
myTest();
?>

4.php的echo和print语句

PHP 是通过 print 和 echo 语句来动态输出 HTML 内容,虽然 print 和 echo 语句两者的功能几乎是完全一样,但是还是有一点差别的。

php echo,print和print_r的区别

  • echo 可以输出一个或多个字符串
  • print 只能输出简单类型变量的值 (int,string)
  • print_r 可以输出复杂类型变量的值 (数组对象)

注意:

echo输出的速度比print快,echo是PHP语句,没有返回值,print和print_r是PHP函数,函数有返回值。print返回值为1(int类型),print_r返回值为true(bool类型)。

1.php的echo语句

echo 是一个语言结构,使用的时候可以不用加括号,也可以加上括号: echo 或 echo()。

代码实例

<?php
$x = 5;
$cars = array("Volve","BMW","Toyota");
echo "Hello World"," feng"," php","</br>";
echo $x,"</br>";
echo "$x</br>";
echo "$cars[0]";
?>

2.php的print语句

print 同样是一个语言结构,可以使用括号,也可以不使用括号: print 或 print()。不能输出多个参数

代码实例

<?php
$x = 5;
$cars = array("Volve","BMW","Toyota");
print "Hello World</br>";
print "$x</br>";
print "$cars[0]";
?>

3.php的print_r语句

print_r 显示关于一个变量的易于理解的信息,如果给出的是string、integer或float,将打印变量值本身。

如果给出的是array,将会按照一定格式显示键和元素。object与数组类似。

使用时必须加上括号:print_r()。

小提示:print_r()会将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。

代码实例

<?php
$s1 = "Hello World";
$cars = array("Volvo","BMW","Toyota");
print_r("$s1</br>");
print_r($cars); // Array ( [0] => Volvo [1] => BWM [2] => Toyota )
?>

5.php的数据类型

php的数据类型包括:String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型), Array(数组), Object(对象), NULL(空值)。

1.php的字符串

一个字符串是一串字符的序列,你可以将任何文本放在单引号和双引号中

<?php
$s1 = "Hello World";
$s2 = 'Hello PHP';
echo "$s1</br>";
echo $s2;
?>

2.php的整数类型

整数是一个没有小数的数字。

整数规则:

  • 整数必须至少有一个数字(0-9)
  • 整数不能包含逗号或空格
  • 整数是没有小数点的
  • 整数可以是正数或负数
  • 整型可以用三种格式来指定:十进制,十六进制(以0x为前缀)或八进制(前缀为0)。

使用php的var_dump()函数返回变量的数据类型和值

<?php
$x = 120;  // 十进制
var_dump($x);
echo "</br>$x</br>";
$y = 0x81;   // 十六进制
var_dump($y);
echo "</br>$y</br>";
$z = 047;   // 八进制
var_dump($z);
echo "</br>$z</br>";
?>

3.php的浮点数类型

浮点数是带小数部分的数字,或是指数形式。

<?php
$x = 10.365;  // 小数类型的   10.365
var_dump($x);
echo "<br>";
$x = 2.4e3;  // 指数类型的   2400
var_dump($x);
echo "<br>";
$x = 8E-5;  // 指数类型的   8.0E-5
var_dump($x);
?>

4.php的布尔型

布尔型可以是 TRUE 或 FALSE。

<?php
$x = true;
echo $x == 1,"</br>";
$y = false;
echo $y == 0;
?>

5.php的数组

数组可以在一个变量中存储多个值。

<?php
$cars = array("Volvo","BWM","Toyota");
var_dump($cars);   // array(3) { [0]=> string(5) "Volvo" [1]=> string(3) "BWM" [2]=> string(6) "Toyota" }
?>

6.php的对象

对象数据类型也可以用于存储数据。在 PHP 中,对象必须声明。首先,你必须使用class关键字声明类对象。类是可以包含属性和方法的结构。

<?php
class Car
{
    var $color;
    function Car($color) {
        $this->color = $color;
    }
    function what_color() {
        return $this->color;
    }
}
echo "Hello World";
$car = new Car("red");
echo $car->color;
echo $car->what_color();  // 没反应,后面在修
?>

7.php的null值

NULL 值表示变量没有值。NULL 是数据类型为 NULL 的值。NULL 值指明一个变量是否为空值。 同样可用于数据空值和NULL值的区别。可以通过设置变量值为 NULL 来清空变量数据:

<?php
$s1 = "Hello World";
echo $s1,"</br>";
$s1 = null;  // 清空变量
var_dump($s1);
?>

6.php常量

常量值被定义后,在脚本的其他任何地方都不能被改变。

常量是一个简单值的标识符。该值在脚本中不能改变。

一个常量由英文字母、下划线、和数字组成,但数字不能作为首字母出现。(常量名不需要加 $ 修饰符)。

注意: 常量在整个脚本中都可以使用。

1.设置常量

设置常量,一般使用define()函数

bool define ( string $name , mixed $value [, bool $case_insensitive = false ] )

该函数有三个参数:

  • constant name:必选参数,常量名称,即标志符。
  • value:必选参数,常量的值。
  • case insensitive:可选参数,如果设置为TRUE,该常量则大小写不敏感。默认是大小写敏感的。
// 方式一
<?php
define("GREETING","WELCOME TO PHP");
echo GREETING;
?>
// 方式二
<?php
const GREETING = "WELCOME TO PHP";
echo GREETING;
?>

常量是全局的,常量在定义后,默认是全局变量,可以在整个运行的脚本的任何地方使用。

7.php字符串

一个字符串(string)就是由一系列的字符组成,其中每个字符等同于一个字节。字符串变量用于存储并处理文本。字符串变量用于包含有字符的值。在创建字符串之后,我们就可以对它进行操作了。您可以直接在函数中使用字符串,或者把它存储在变量中。

1.php的并置运算符

在 PHP 中,只有一个字符串运算符。并置运算符 (.) 用于把两个字符串值连接起来。

<?php
$s1 = "Hello";
$s2 = "World";
echo $s1." ".$s2;
?>

2.php的strlen函数

strlen() 函数返回字符串的长度(字符数)。

<?php
$s1 = "Hello";
echo strlen($s1);
?>

3.php的strpos函数

strpos() 函数用于在字符串内查找一个字符或一段指定的文本。

如果在字符串中找到匹配,该函数会返回第一个匹配的字符位置。如果未找到匹配,则返回 FALSE。

<?php
echo strpos("Hello world!","world"); 
?>

完全的php String函数

PHP String函数

8.php运算符

PHP 中的运算符分为:算术运算符、递增/递减运算符、比较运算符、逻辑运算符、数组运算符、三元运算符等。

1.php算术运算符

+加,-减,*乘,/除,%取模,-取反,.并置

<?php
$x = 10;
$y = 6;
echo $x+$y,"</br>";
echo $x-$y,"</br>";
echo $x*$y,"</br>";
echo $x/$y,"</br>";
echo "Hello"." "."World";
?>

2.php赋值运算符

基本赋值语句是=,将基本赋值语句和算术运算符结合起来就行了

<?php
$x = 10;
$x += 6;
echo $x;
?>

3.php递增/递减运算符

++-- 这两个符号放的位置不同,结果也会不同的

<?php
$x = 10;
echo $x++,"</br>";
$y = 9;
echo ++$y;
?>

4.php比较运算符

=====(恒等于,值和类型都相同),!=<>(不相同),!==不恒等于,>大于,<小于,>=大于等于,<=小于等于

<?php
$x = 100;
$y = "100";
var_dump($x==$y);  // true
echo "</br>";
var_dump($x===$y);
echo "</br>";
var_dump($x!=$y);
echo "</br>";
var_dump($x!==$y);  // true
echo "</br>";
$a = 50;
$b = 90;
var_dump($a > $b);
echo "</br>";
var_dump($a < $b);
?>

5.php逻辑运算符

andorxor(异或),&&||!

6.php数组运算符

<?php
$x = array("a" => "red", "b" => "green");
$y = array("c" => "blue", "d" => "yellow");
$z = $x + $y; // $x 和 $y 数组合并
var_dump($z);
echo "</br>";
var_dump($x == $y);
echo "</br>";
var_dump($x === $y);
echo "</br>";
var_dump($x != $y);
echo "</br>";
var_dump($x <> $y);
echo "</br>";
var_dump($x !== $y);
?>

7.php三元运算符

expression;true expression,false expression;

<?php
$test = 'w3cschool在线教程';
$username = $test; echo $username, PHP_EOL;
?>

8.php错误控制运算符

PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误诊断都被抑制。

如果用 set_error_handler() 设定了自定义的错误处理函数,即使诊断信息被抑制,也仍然会被调用,因此自定义错误处理函数应该调用 error_reporting(),并验证 @ 操作符是否按照如下方式使用:

<?php
function my_error_handler($err_no, $err_msg, $filename, $linenum) { // 自定义的错误处理函数
    if (!(error_reporting() & $err_no)) {
        return false; // 静默
    }
    // ...
}
?>

注意:运算符只对表达式有效。如果能从某处获得值,就能在它前面加上运算符。

9.php运算符优先级

PHP运算符

9.php if...else语句

本节介绍 PHP if...else 语句的使用,通过该语句,你可以有选择性的执行代码片段。条件语句用于根据不同条件执行不同动作。

在 PHP 中,提供了下列条件语句:

  • if 语句 - 在条件成立时执行代码
  • if...else 语句 - 在条件成立时执行一块代码,条件不成立时执行另一块代码
  • if...else if....else 语句 - 在若干条件之一成立时执行一个代码块
  • switch 语句 - 在若干条件之一成立时执行一个代码块

1.php if语句

if语句用于仅当指定条件成立时执行代码

<?php
$t = date("H");  // 标准时间的小时数
if($t<"20"){
    echo "Have a good day";
}
?>

2.php if...else语句

在条件成立时执行一块代码,条件不成立时执行另一块代码,请使用 if....else 语句。该语句的含义为:当条件为真时,执行条件成立时的代码;如果条件为假,则执行条件不成立时的代码,语法如下:

<?php
$t = date("H")+8;
if($t<"20"){
    echo "Have a good day";
}else{
    echo "Good night";
}
?>

3.php if...else if...else语句

在若干条件之一成立时执行一个代码块,请使用 if....else if...else 语句。

<?php
$t = date("H")+8;
if($t<"10"){
    echo "Have a good morning";
}else if($t<"15"){
    echo "Have a good afternoon";
}else{
    echo "Have a good night";
}
?>

10.php switch语句

switch 语句用于根据多个不同条件执行不同动作。

如果您希望有选择地执行若干代码块之一,请使用 switch 语句。

<?php
$favColor = "red";
switch ($favColor){
    case "red":
        echo "Your favorite color is red";
        break;
    case "blue":
        echo "Your favorite color is blue";
        break;
    default:
        echo "I don't know your favorite color";
        break;
}
?>

switch记得使用break语句

11.php 数组

数组能够在单个变量中存储多个值:

<?php
$car = array("Volvo",'BMW',"Toyota");
echo "I like ".$car[0].",".$car[1].",".$car[2].".";
?>

1.php创建数组

在php中,使用array()函数创建数组

在 PHP 中,有三种类型的数组:

  • 数值数组 - 带有数字 ID 键的数组
  • 关联数组 - 带有指定的键的数组,每个键关联一个值
  • 多维数组 - 包含一个或多个数组的数组

1.数值数组

自动分配ID键(ID键总是从0开始的)

$car = array("Volvo",'BMW',"Toyota");

人工手动分配ID键

$cars[0]="Volvo";        
$cars[1]="BMW";        
$cars[2]="Toyota";

获取到数组的长度--count()函数

count() 函数用于返回数组的长度(元素的数量):

<?php
$car = array("Volvo",'BMW',"Toyota");
echo "I like ".$car[0].",".$car[1].",".$car[2].".","</br>";
echo count($car);
?>

遍历数值数组

遍历并打印数值数组中的所有值,您可以使用 for 循环

<?php
$car = array("Volvo",'BMW',"Toyota");
for($i = 0;$i<count($car);$i++){
    echo $car[$i],"</br>";
}
?>

2.关联数组

关联数组是使用您分配给数组的指定的键的数组。

<?php
$age = array("Ben"=>"37","Joe"=>"43");
$age["Peter"] = "35";
echo "peter is"." ".$age["Peter"]." "."years old.";
?>

遍历关联数组

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

foreach($age as $x=>$x_value)
{
    echo "Key=" . $x . ", Value=" . $x_value;
    echo "<br>";
}
?>

foreach 语法结构提供了遍历数组的简单方式。foreach 仅能够应用于数组和对象

3.多维数组

记录

2.php array函数

PHP Array函数

12.php 数组排序

数组中的元素可以按字母或数字顺序进行降序或升序排列。对原数组进行排序操作,改变原数组的操作

介绍下列 PHP 数组排序函数:

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

1.sort() 对数组进行升序排序

// 对字母进行升序排序
<?php
$cars=array("Volvo","BMW","Toyota");
sort($cars);
print_r($cars);
?>
// 对数字进行升序排序
<?php
$numbers=array(4,6,2,22,11);
sort($numbers);
print_r($numbers);
?>

2.rsort() 对数组进行降序排序

<?php
$cars=array("Volvo","BMW","Toyota");  // 对字母进行降序排序
rsort($cars);
print_r($cars);
?>
<?php echo "</br>"?>
<?php
$numbers=array(4,6,2,22,11);  // 对数字进行降序排序
rsort($numbers);
print_r($numbers);
?>

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

<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
asort($age);
print_r($age);
?>

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

<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");   
ksort($age);  // 对数组的键进行筛选
print_r($age);
?>

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

<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
arsort($age);
print_r($age);
?>

6.krsort() 根据数组的建立,对数组进行降序排列

<?php
$age=array("Peter"=>"35","Ben"=>"37","Joe"=>"43");
krsort($age);
print_r($age);
?>

PHP Array函数

13.php的超级全局变量

超级全局变量是在全部作用域中始终可用的内置变量。

php的超级全局变量有

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

1.php--$GLOBALS

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

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

<?php
$x = 75;
$y = 25;
function addition(){
    $GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];  // 通过$GLOBALS变量组进行传值
}
addition();
echo $z;
?>

2.php--$_SERVER

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由Web 服务器创建。不能保证每个服务器都提供全部项目

<?php
echo $_SERVER['PHP_SELF'];  
echo "<br>";
echo $_SERVER['SERVER_NAME'];   // 服务器的名称
echo "<br>";
echo $_SERVER['HTTP_HOST'];  // 主机地址
echo "<br>";
echo $_SERVER['HTTP_REFERER'];  // 网络的防盗链技术
echo "<br>";
echo $_SERVER['HTTP_USER_AGENT'];  // UserAgent
echo "<br>";
echo $_SERVER['SCRIPT_NAME'];   // 脚本文件的名称
?>

$_SERVER的重要元素 PHP 超级全局变量

$_SERVER['PHP_SELF'] 当前执行脚本的文件名,与 document root 有关。(文件的路径)

$_SERVER['GATEWAY_INTERFACE'] 服务器使用的 CGI 规范的版本;

$_SERVER['SERVER_ADDR'] 当前运行脚本所在的服务器的 IP 地址。

$_SERVER['SERVER_NAME'] 当前运行脚本所在的服务器的主机名。

$_SERVER['SERVER_SOFTWARE'] 服务器标识字符串,在响应请求时的头信息中给出。

$_SERVER['SERVER_PROTOCOL'] 请求页面时通信协议的名称和版本。

$_SERVER['REQUEST_METHOD'] 访问页面使用的请求方法;(post,get,put,head等)

$_SERVER['REQUEST_TIME'] 请求开始时的时间戳。(返回秒)

$_SERVER['QUERY_STRING'] query string(查询字符串),如果有的话,通过它进行页面访问。

$_SERVER['HTTP_ACCEPT'] 当前请求头中 Accept: 项的内容,如果存在的话。

$_SERVER['HTTP_ACCEPT_CHARSET'] 当前请求头中 Accept-Charset: 项的内容,如果存在的话。

$_SERVER['HTTP_HOST'] 当前请求头中 Host: 项的内容,如果存在的话。

$_SERVER['HTTP_REFERER'] 引导用户代理到当前页的前一页的地址(如果存在)。该值是不可相信的

$_SERVER['HTTPS'] 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。

$_SERVER['REMOTE_ADDR'] 浏览当前页面的用户的 IP 地址。

$_SERVER['REMOTE_HOST'] 浏览当前页面的用户的主机名。

$_SERVER['REMOTE_PORT'] 用户机器上连接到 Web 服务器所使用的端口号。

$_SERVER['SCRIPT_FILENAME'] 当前执行脚本的绝对路径。(根路径和文件名的绝对位置)

$_SERVER['SERVER_ADMIN'] 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。

$_SERVER['SERVER_PORT'] Web 服务器使用的端口。默认值为 "80"。

$_SERVER['SERVER_SIGNATURE'] 包含了服务器版本和虚拟主机名的字符串。

$_SERVER['PATH_TRANSLATED'] 当前脚本所在文件系统(非文档根目录)的基本路径。

$_SERVER['SCRIPT_NAME'] 包含当前脚本的路径。

$_SERVER['SCRIPT_URI'] URI 用来指定要访问的页面。

3.php--$_REQUEST

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

<html>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> // 本页面直接处理
    Name:<input name="name" type="text">
    <input type="submit">
</form>
<?php
    $name = &$_REQUEST["name"];
    echo $name;
?>
</body>
</html>

4.php--$_POST

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

<html>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> // 本页面直接处理
    Name:<input name="name" type="text">
    <input type="submit">
</form>
<?php
    $name = &$_REQUEST["name"];
    echo $name;
?>
</body>
</html>

5.php--$_GET

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

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="test.php?subject=PHP">点我</a>
</body>
</html>
<html>
<body>
<?php
if($_GET["subject"]!=null){
    echo $_GET["subject"];
}
?>
</body>
</html>

14.php while循环

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

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

1.php--while循环

实例:一直将i加到5为止

<?php
$i = 0;
$sum = 0;
while($i<=5){
    $sum += $i;
    $i++;
}
echo $sum;
?>

2.php--do..while循环

<?php
$i = 0;
$sum = 0;
do{
    $i++;
    $sum += $i;
}while($i<=5);
echo $sum;
?>

这个比上面的多循环了一次

15.php for循环

1.for循环

语法

 for (初始值; 条件; 增量)
 {
 要执行的代码;
 } 

参数:

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

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

<?php
$sum = 0;
for($i = 0;$i <= 5;$i++){
    $sum += $i;
}
echo $sum;
?>

2.foreach循环

语法

foreach ($array as $value)
{
    要执行代码;
} 

实例

<?php
$number = array("one","two","three");
foreach ($number as $item) {
    echo $item,"</br>";
}
?>

注意:foreach 仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量,将发出错误信息。

16.php函数

函数是通过调用函数来执行的。你可以在页面的任何位置调用函数。

1.创建php函数

语法

function functionName()
{
    要执行的代码;
}

PHP 函数准则:

  • 函数的名称应该提示出它的功能
  • 函数名称以字母或下划线开头(不能以数字开头)
<html>
<body>
<?php
function writeName()
{
    echo "feng";
}

echo "My name is ";
writeName();
?>
</body>
</html>

2.php函数--添加参数

为了给函数添加更多的功能,我们可以添加参数。参数类似变量。参数就在函数名称后面有一个括号内指定。

<html>
<body>
<?php
function writeName($fname)
{
    echo $fname . " Refsnes.</br>";
}

echo "My name is ";
writeName("Kai Jim");
echo "My sister's name is ";
writeName("Hege");
?>
</body>
</html>

3.php函数--return返回值

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

<html>
<body>
<?php
function add($x,$y)
{
    $total = $x + $y;
    return $total;
}
echo "1 + 16 = " . add(1,16);
?>
</body>
</html>

17.php魔术常量

1.__LINE__

文件中的当前行号

<?php
echo __LINE__;
?>

2.__FILE__

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

<?php
echo __FILE__;
?>

3.__DIR__

文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__)。

<?php
echo __DIR__,"</br>";
echo dirname(__FILE__)
?>

4.__FUNCTION__

返回该函数被定义时的名字(区分大小写)。

<?php
function myTest(){
    echo __FUNCTION__;
}
myTest();
?>

5.__CLASS__

返回该类被定义时的名字

<?php
class Test{
    function MyPrintClass(){
        echo __CLASS__;
    }
}
$test = new Test();
$test->MyPrintClass();
?>

6.__TRAIT__

PHP中使用trait关键字是为了解决一个类既想集成基类的属性和方法,又想拥有别的基类的方法,而trait一般情况下是和use搭配使用的。trait就是解决了继承只能继承一个的缺陷(多继承)

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

<?php
class Base {
    public function sayHello() {
        echo 'Hello ';
    }
}
trait SayWorld {
    public function sayHello() {
        parent::sayHello(); // 调用父类的方法
        echo 'World!';
    }
}
class MyHelloWorld extends Base {
    use SayWorld;    // 多继承
}
$o = new MyHelloWorld();
$o->sayHello();
?>

7.__METHOD__

返回函数的名称,作用和__FUNCTION__一样的

<?php
function myTest(){
    echo __METHOD__;
}
myTest();
?>

8.__NAMESPACE__

当前命名空间的名称(区分大小写)

<?php
namespace MyProject;
echo '命名空间为:', __NAMESPACE__;
?>

18.命名空间

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

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

1.定义命名空间

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

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

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

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

<?php
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection {}  // 类
    function connect(){
        echo "Connected";
    }
}
namespace { // 全局代码
    session_start();
    $a = MyProject\CONNECT_OK; // 使用命名空间后的取值
    echo $a;
    MyProject\connect();
}
?>

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

<?php
declare(encoding='UTF-8');
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection {}  // 类
    function connect(){
        echo "Connected";
    }
}
namespace { // 全局代码
    session_start();
    $a = MyProject\CONNECT_OK; // 使用命名空间后的取值
    echo $a;
    MyProject\connect();
}
?>

2.子命名空间

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

<?php
declare(encoding='UTF-8');
namespace MyProject\Sub\Level{
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function Connect() { echo "枫"; }
}
namespace {
    \MyProject\Sub\Level\Connect();
}
?>

3.命名空间使用

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

  • 非限定名称,或不包含前缀的类名称
  • 限定名称,或包含前缀的名称
  • 完全限定名称,或包含了全局前缀操作符的名称

file1.php

<?php
namespace Foo\Bar\subnamespace; // 子命名空间
const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>

file2.php

<?php
namespace Foo\Bar;  
include 'file1.php';
const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}
/* 非限定名称 */
foo(); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO    2
/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
// 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO   1

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

注意访问任意全局类、函数或常量,都可以使用完全限定名称

注意下面的两种情况,一个是有大括号的,一个是没有大括号的,有区别的,注意

<?php
namespace foo;
function Mystrlen($a) {echo strlen($a);}
const MyINI_ALL = 1000;
class Exception {}

$a = \foo\MyINI_ALL;
echo $a,"</br>";
Mystrlen("Hello");
?>
<?php
namespace foo{
    function Mystrlen($a) {echo strlen($a);}
    const MyINI_ALL = 1000;
    class Exception {}
}
namespace {
    $a = \foo\MyINI_ALL;
    echo $a,"</br>";
    \foo\Mystrlen("Hello");
}
?>

4.命名空间和动态语言特征

PHP 命名空间的实现受到其语言自身的动态特征的影响。

file1.php

<?php
class classname
{
    function __construct() // 类的构造函数
    {
        echo __METHOD__,"</br>";
    }
}
function funcname()
{
    echo __FUNCTION__,"</br>";
}
const constname = "global";
$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "</br>"; // prints global
?>

file2.php

<?php
namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__,"</br>";
    }
}
function funcname()
{
    echo __FUNCTION__,"</br>";
}
const constname = "namespaced";
include 'file1.php';   // 直接将代码传递了过来
$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "</b>"; // prints global
/* note that if using double quotes, "\\namespacename\\classname" must be used */
$a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // also prints namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // prints namespacename\funcname
$b = '\namespacename\funcname';
$b(); // also prints namespacename\funcname
echo constant('\namespacename\constname'), "</br>"; // prints namespaced
echo constant('namespacename\constname'), "</br>"; // also prints namespaced
?>

补充:constant就是索引后,返回常量的值

5.namespace关键词和__NAMESPACE__常量

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

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

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

常量 __NAMESPACE__ 在动态创建名称时很有用

<?php
namespace MyProject;
class Test{
    function myTest(){
        echo "Test";
    }
}
function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;   // 防止字符串转义
    return new $a; 
}
$a = get("Test");
$a->myTest();
$c = new Test();  // 同一个命名空间下的代码
$c->myTest();
?>
<?php
namespace MyProject{
    class Test{
        function myTest(){
            echo "Test";
        }
    }
    function get($classname)
    {
        $a = __NAMESPACE__ . '\\' . $classname;  // 防止字符串转义
        return new $a;
    }
}
namespace {  // 不同的命名空间的代码
    $a = \MyProject\get("Test");
    $a->myTest();
    $c = new \MyProject\Test();
    $c->myTest();
}
?>

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

<?php
namespace sub{
    function func(){
        echo "Hello";
    }
    class cname{
        function func(){
            echo "World";
        }
    }
}
namespace {  // 全局的变量
    function func(){
        echo "Hello";
    }
    const GREETING = "Hello";
    namespace\func(); // calls function func()
    namespace\sub\func(); // calls function sub\func()
    $a = new namespace\sub\cname(); // instantiates object of class sub\cname
    $a->func();
    $b = namespace\GREETING; // assigns value of constant CONSTANT to $b
    echo $b;
}
?>

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

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

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

<?php
namespace foo{
    class Test{
        function func(){
            echo "test";
        }
    }
}
namespace {
    use \foo\Test as myTest;
    $my = new myTest();
    $my->func();
}
?>

注意还可以一行中包含多个use子句

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

2.导入和动态名称

<?php
namespace foo{
    class Test{
        function func(){
            echo "test";
        }
    }
}
namespace {
    use \foo\Test as myTest;
    $my = new myTest();
    $name = '\foo\Test';  // 动态名称,注意这里有个用法无法使用
    //$name = 'myTest';  这个用法似乎已经过时了,不能使用了
    $my1 = new $name();
    $my->func();
    $my1->func();
}
?>

3.导入和完全限定名称

<?php
namespace name\sub\foo{
    class Test{
        function func(){
            echo "test";
        }
    }
}
namespace {
    class car{
        function func(){
            echo "Car";
        }
    }
    use name\sub as sub;   // 完全名称
    $my = new sub\foo\Test();
    $my->func();
}
?>

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

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

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

<?php
namespace A\B\C;
class Exception extends \Exception {}  // 全局类,直接使用完全限定名称
$a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象
$b = new \Exception('hi'); // $b 是类 Exception 的一个对象,完全限定名称
//$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
?>

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

下面的常量随着全局命名名称和当前命名名称的切换,出现了不同答案

<?php
namespace A\B\C;
const E_ERROR = 45;
function strlen($str)
{
    return \strlen($str) - 1;
}
echo E_ERROR, "</br>"; // 输出 "45"
echo \INI_ALL, "</br>"; // 输出 "7" - 使用全局常量 INI_ALL
echo strlen('hi'), "\n"; // 输出 "1"
if (\is_array('hi')) { // 输出 "is not array",使用全局函数 is_array
    echo "is array\n";
} else {
    echo "is not array\n";
}
?>

8.全局空间

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

<?php
namespace A\B\C;
function strlen($s){
    echo \strlen($s)-1;  // 全局命名空间的使用
}
strlen("name");
?>

9.命名空间的顺序

PHP 命名空间的使用顺序

19.php面向对象

对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。

对象的主要三个特性:对象的行为,对象的形态,对象的表示。

1.面向对象内容

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

2.php类定义

语法

<?php
class phpClass {
  var $var1;
  var $var2 = "constant string";
  function myfunc ($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

解析如下:

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

$this指的是自身的对象,也就是java的this一样的操作

3.php创建对象

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

1.调用成员方法

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

<?php
class Site{
    var $url;
    function setUrl($url){
        $this->url = $url;
    }
    function getUrl(){
        return $this->url;
    }
}
$site1 = new Site();
$site1->setUrl("xcqandwrq");
$url = $site1->getUrl();
echo $url;
?>

2.php构造函数

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

语法

void __construct ([ mixed $args [, $... ]] )

实例

<?php
class Site{
    var $url;
    function __construct($url){
        $this->url = $url;
    }
    function setUrl($url){
        $this->url = $url;
    }
    function getUrl(){
        return $this->url;
    }
}
$site1 = new Site("feng");
$site1->setUrl("xcqandwrq");
$url = $site1->getUrl();
echo $url;
?>

3.php析构函数

语法

void __destruct ( void )

实例

<?php
class Site{
    var $url;
    function __construct($url){
        $this->url = $url;
    }
    function setUrl($url){
        $this->url = $url;
    }
    function getUrl(){
        return $this->url;
    }
    function __destruct()
    {
        echo "I am game over";
    }
}
$site1 = new Site("feng");
$site1->setUrl("xcqandwrq");
$url = $site1->getUrl();
echo $url;
?>

4.继承

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

class Child extends Parent {
    // 代码部分
}

实例

<?php
class Site{
    var $url;
    function __construct($url){
        $this->url = $url;
    }
    function setUrl($url){
        $this->url = $url;
    }
    function getUrl(){
        return $this->url;
    }
    function __destruct()
    {
        echo "I am game over";
    }
}
class Child_site extends Site{
    var $category;
    function __construct($url,$category)
    {
        parent::__construct($url);
        $this->category = $category;
    }
}
$site1 = new Site("feng");
$url = $site1->getUrl();
echo $url;
$site2 = new Child_site("xcqandwrq","java");
echo $site2->getUrl();
?>

5.方法重写

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

<?php
class Site{
    var $url;
    function __construct($url){
        $this->url = $url;
    }
    function setUrl($url){
        $this->url = $url;
    }
    function getUrl(){
        return $this->url;
    }
    function __destruct()
    {
        echo "I am game over";
    }
}
class Child_site extends Site{
    var $category;
    function __construct($url,$category)
    {
        parent::__construct($url);
        $this->category = $category;
    }
    function getUrl()  // 方法重写
    {
        echo "I am child"."</br>";
        return parent::getUrl();
    }
}
$site1 = new Site("feng");
$url = $site1->getUrl();
echo $url;
$site2 = new Child_site("xcqandwrq","java");
echo $site2->getUrl();
?>

6.访问控制

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

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

1.属性的访问控制

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

<?php
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj = new MyClass();
echo $obj->public; // 这行能被正常执行
//echo $obj->protected; // 这行会产生一个致命错误
//echo $obj->private; // 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private
class MyClass2 extends MyClass
{
    // 可以对 public 和 protected 进行重定义,但 private 而不能
    protected $protected = 'Protected2';

    function printHello()
    {
        echo $this->public;
        echo $this->protected;
//        echo $this->private;
    }
}
$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
//echo $obj2->private; // 未定义 private
//echo $obj2->protected; // 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined
?>

2.方法的访问控制

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

<?php
class MyClass
{
    // 声明一个公有的构造函数
    public function __construct() { }

    // 声明一个公有的方法
    public function MyPublic() { }

    // 声明一个受保护的方法
    protected function MyProtected() { }

    // 声明一个私有的方法
    private function MyPrivate() { }

    // 此方法为公有
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}
$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
//$myclass->MyProtected(); // 这行会产生一个致命错误
//$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行
class MyClass2 extends MyClass
{
    // 此方法为公有
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
//        $this->MyPrivate(); // 这行会产生一个致命错误
    }
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行
class Bar
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }

    public function testPublic() {
        echo "Bar::testPublic</br>";
    }

    private function testPrivate() {
        echo "Bar::testPrivate</br>";
    }
}
class Foo extends Bar
{
    public function testPublic() {
        echo "Foo::testPublic</br>";
    }

    private function testPrivate() {
        echo "Foo::testPrivate</br>";
    }
}
$myFoo = new Foo();
$myFoo->test(); // Bar::testPrivate  Foo::testPublic  test方法是在父类中,所以private只能调用父类中的方法了
?>

7.接口

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。

接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。

接口中定义的所有方法都必须是公有,这是接口的特性。

要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。

<?php
// 声明一个'iTemplate'接口
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
// 实现接口
class Template implements iTemplate
{
    private $vars = array();

    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }

    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace($name, $value, $template);  // 将$template中的字符串$name换成$value的值
        }
        return $template;
    }
}
$myTemplate = new Template();
$myTemplate->setVariable("World","PHP");
$template = $myTemplate->getHtml("Hello World");
echo $template;
?>

8.常量

可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。

常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。

<?php
class MyClass
{
    const constant = '常量值';  //必须是共有的常量
    function showConstant() {
        echo  self::constant . PHP_EOL;
    }
}
echo MyClass::constant . PHP_EOL;// 类中的
$classname = "MyClass"; // 动态类中的
echo $classname::constant . PHP_EOL;
$class = new MyClass();
$class->showConstant(); // 实例对象的
echo $class::constant . PHP_EOL;
?>

9.抽象类

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

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

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

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

<?php
abstract class AbstractClass
{
    // 强制要求子类定义这些方法
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);
    // 普通方法(非抽象方法)
    public function printOut() {
        print $this->getValue() . PHP_EOL;
    }
}

class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";  // 插值语句,注意这个语句的特点
    }
}

class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }

    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}

$class1 = new ConcreteClass1();
$class1->printOut();  // 继承方法,公有方法
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2();
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>

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

<?php
abstract class AbstractClass
{
    // 我们的抽象方法仅需要定义需要的参数
    abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
    // 我们的子类可以定义父类签名中不存在的可选参数
    public function prefixName($name, $separator = ".") { // 默认参数的使用
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}
$class = new ConcreteClass();
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>

10.static关键字

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

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

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

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

<?php
class Foo {
    public static $my_static = 'foo';
    public static $number = 1;
    public function staticValue() {
        return self::$my_static.self::$number;
    }
}
Foo::$number++;  // 所有的对象共享一个元素
print Foo::$my_static . PHP_EOL;  // 类的调用
$foo = new Foo();// 对象的调用
print $foo->staticValue() . PHP_EOL;
?>

11.Final关键字

如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

<?php
class BaseClass {
    public function test() {
        echo "BaseClass::test() called" . PHP_EOL;
    }

    final public function moreTesting() {
        echo "BaseClass::moreTesting() called"  . PHP_EOL;
    }
}

class ChildClass extends BaseClass {
//    public function moreTesting() {   无法重写该方法
//        echo "ChildClass::moreTesting() called"  . PHP_EOL;
//    }
    public function test() {
        echo "ChildClass::test() called" . PHP_EOL;
    }
}
$child = new ChildClass();
$child->test();
$child->moreTesting();
?>

12.调用父类构造方法

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

parent::__construct(参数);
<?php
class BaseClass {
    public function __construct(){
        echo "I am parent";
    }
    public function test() {
        echo "BaseClass::test() called" . "</br>";
    }
}

class ChildClass extends BaseClass {
    public function __construct(){
        parent::__construct();
        echo "I am child";
    }
    public function test() {
        echo "ChildClass::test() called" . PHP_EOL;
    }
}
$child = new ChildClass();
$child->test();
?>

相应的参数也可以传递到父类的构造函数中

posted @ 2022-05-12 13:54  xcq保护我  阅读(54)  评论(0)    收藏  举报