PHP前置基础
变量
变量的简介
变量是一个可以改变的量
变量可以理解为是一个房间(仓库),而房间(仓库)是用于存放东西的,而变量也是。
变量的命名规范
- 变量的名字要有意义,比如
$name , $age , $addr
变量的命名规则
- 小驼峰命名法: 变量名的第二个单词大写,其余小写,例如:
$myName (推荐) - 大驼峰命名法: 变量名的每个单词的首字母大写,其余小写,例如:
$MyName
- 在声明变量的时候,等号两边加上空格,例如
$name = 'x1ong';
单双引号的区别
php
<?php
$name = 'x1ong';
echo '$name'; // $name;
echo "$name"; // x1ong
?>
<?php
echo '\n'; // 输出字符串\n
echo "\n"; // 换行
?>
php
<?php
# \ 的作用在于将特殊字符转为普通字符
echo '\\'; // 输出 /
echo '\''; // 输出 '
echo "\""; // 输出 "
?>
- 如果想让字符串和变量或其他字符连接在一起的话,需要使用
. 进行连接。
php
<?php
$name = 'x1ong';
echo 'my name is ' . $name . "\n"; // my name is x1ong
echo $name . 666; // x1ong666
?>
- 如果在双引号里面使用变量的时候,建议将变量名使用
{} 包裹
php
<?php
$name = 'x1ong';
echo "{$name}"; // x1ong
?>
常见数据类型
php
<?php
$int1 = 123;
$int2 = 456;
$int3 = 789;
var_dump($int1); // int(123)
var_dump($int2); // int(456)
var_dump($int3); // int(789)
?>
php
<?php
$float1 = 3.14;
var_dump($float1); // double(3.14)
?>
php
<?php
$bool1 = true;
var_dump($bool1); // bool(true)
$bool1 = false;
var_dump($bool1); // bool(true)
?>
php
<?php
// 通过双引号或单引号包裹起来的都是字符串类型
$str1 = 'helloworld';
var_dump($str1); // string(10) "helloworld"
$str2 = "你好世界";
var_dump($str2); // string(12) "你好世界"
?>
php
<?php
// 数组中可以是任意类型,我们将数组中的每个值,称之为元素
// 索引数组
$arr = array(1,3.14,'hello',true);
var_dump($arr);
// 关联数组
$arr2 = [
'name' => 'x1ong',
'age' => 17,
'addr' => 'henan'
];
var_dump($arr2);
// 同时也可以使用[] 定义一个数组
// 索引数组
$arr3 = [1,3,'hello',true,3.14];
var_dump($arr3);
// 关联数组
$arr4 = [
'name' => 'x1ong',
'age' => '8'
];
var_dump($arr4);
?>
数组类型转换
简介
数组类型转换指的是将一个数据类型转为另一个数组类型。比如 int 类型转为 string 类型。
类型转换相关函数
php
<?php
$number1 = '123';
var_dump(intval($number1)); // int(123)
$number2 = '123abc';
var_dump(intval($number2)); // int(123)
$number3 = 'abc123';
var_dump(intval($number3)); // int(0)
$number4 = true;
var_dump(intval(number4)); // int(0)
$number5 = false;
var_dump(intval(number5)); // int(0)
$number6 = '3.14';
var_dump(intval($number6)); // int(3)
?>
php
<?php
$number1 = '123';
var_dump(floatval($number1)); // double(123)
$number2 = '123abc';
var_dump(floatval($number2)); // double(123)
$number3 = 'abc123';
var_dump(floatval($number3)); // double(0)
$number4 = true;
var_dump(floatval(number4)); // double(0)
$number5 = false;
var_dump(floatval(number5)); // double(0)
$number6 = '3.14';
var_dump(floatval($number6)); // double(3.14)
?>
php
<?php
$number1 = '123';
var_dump(boolval($number1)); // bool(true)
$number2 = '123abc';
var_dump(boolval($number2)); // bool(true)
$number3 = 'abc123';
var_dump(boolval($number3)); // bool(true)
$number4 = true;
var_dump(boolval(number4)); // bool(true)
$number5 = false;
var_dump(boolval(number5)); // bool(true)
$number6 = '3.14';
var_dump(boolval($number6)); // bool(true)
$number7 = 0;
var_dump(boolval($number7)); // bool(false)
$number8 = array();
var_dump(boolval($number8)); // bool(false)
$number9 = '';
var_dump(boolval($number9)); // bool(false)
$number10 = null;
var_dump(boolval($number9)); // bool(false)
?>
判断数据类型常用函数
php
<?php
is_array($value); # 判断变量是否是一个数组
is_string($value); # 判断变量是否是一个字符串
is_bool($value); # 判断变量是否是一个布尔值
is_float($value); # 判断变量是否是一个浮点数
is_object($value); # 判断变量是否是一个对象
is_numerbic($value); # 判断变量是否是一个整型
is_resource($value); # 判断变量是否是一个资源类型
is_null($value); # 判断变量是否是一个空类型
is_scalar($value); # 判断变量是否是一个标量
gettype($value); # 返回变量的数据类型 获取变量的类型
var_dump($value); # 输出变量的值和其数据类型
?>
总结
bash
1.null转换为整型会是0
2.null转换为浮点数也是0
3.null转换为字符串会是空字符串''
4.'123.abc'这样的字符串转换为整数会将数字后面的所有字符都剔除,结果为123。
5.'abc1234'这样的字符串转换为整数,以非数字开头,则转换的结果为0,转换为浮点型也是。
6.'123.456.789abc'这样的字符串转换为浮点型,会将123.456后面的都去掉(包括数字),从而结果为123.456
运算符
算数运算符
注意:在使用取余运算符的时候,如果被除数是负数,那么最终取到的余数也是一个负数
比较运算符
逻辑运算符
逻辑运算用来组合逻辑运算的结果,是程序设计中一组非常重要的运算符
自增自减运算符
这里分为先 ++ 还是后 ++ 。++ 放在变量前面表示先自身增1,之后在做输出(或者执行后续代码)。++ 放在变量的后面表示当前行执行完之后再执行自身增 1 。(-- 也是如此)
php
<?php
$number = 10;
echo $number++; // 10
echo $number; // 11
$number2 = 1;
echo ++$number2; // 2
?>
为false的几种情况
bash
1. 整型除0以外,转为布尔值都为true。
2. 如果浮点型0.00000000后面都是0则为false,如果后面有一个非0的数字,即为真。
3. 字符串类型只有空字符串转为布尔值为false,注意是空字符串''或"",而不是" "
4. 空字符串的0位false,其他都为true
5. 空数组为false,其余都为真
6.null作为判断条件时也为false
流程控制语句
if 判断
单分支结构
php
if (条件表达式) {
真区间
}
双分支结构
php
if (条件表达式) {
真区间
}else {
假区间
}
多分支结构
php
if (条件表达式) {
真区间
} elseif (条件表达式) {
真区间
} elseif (条件表达) {
真区间
} else {
假区间
}
示例
php
<?php
$score = 200;
if ($score < 60) {
echo"不及格<br/>";
} elseif ($score == 60) {
echo"及格<br/>";
} elseif ($score <= 70) {
echo"良好<br/>";
} elseif ($score <= 80 ) {
echo"优秀<br/>";
} elseif ($score <= 90 ) {
echo"厉害了<br/>";
} elseif ($score == 100) {
echo"超神<br/>";
} else {
echo"成绩不太合法哦!<br/>";
}
?>
switch 判断
语法
php
switch (条件表达式) {
case1:
echo"我是1的内容";
break;
case2:
echo"我是2的内容";
break;
case3:
echo"我是3的内容";
break;
default:
echo"我是默认内容";
break;
}
示例
php
<?php
$res = 4 ;
switch ($res) {
case1:
echo"我是1的内容<br/>";
break;
case2:
echo"我是2的内容<br/>";
break;
case3:
echo"我是3的内容<br/>";
break;
default:
echo"我是默认内容<br/>";
break;
}
?>
随机塞子示例
php
<?php
$randmo_num = mt_rand(1,6);
echo"你的幸运数字为: " . $randmo_num . "<br/>";
switch ($randmo_num) {
case1:
echo"做家务<br/>";
break;
case2:
echo"只是洗个衣服<br/>";
break;
case3:
echo"洗全套<br/>";
break;
case4:
echo"去洗头<br/>";
break;
case5:
echo"比心心(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤<br/>";
break;
case6:
echo"去刷碗<br/>";
break;
}
?>
总结
当进行单值匹配的时候可以使用 switch 分支语句,当进行范围匹配的时候可以使用 if 分支语句。
循环结构
简介
生活中的循环即重复的做某件事情,而程序中的循环指的是重复的执行某个代码块。
php 中主要有三种循环,即 for 循环、while 循环 和 do..while 循环。
for 循环
语法
php
for (初始化表达式; 条件判断; 变量更新) {
循环体;
}
示例
php
<?php
for ($i = 1;$i <= 5;$i++) {
echo $i . "<br/>";
}
?>
while 循环
语法
php
while (条件表达式) {
循环体
变量更新
}
示例
php
<?php
$i = 1;
while ($i <= 5) {
echo"The number is " . $i . "<br />";
$i ++;
}
/*
输出:
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
*/
?>
do..while 循环
语法
php
do {
循环体
变量更新
}while (条件表达式)
示例
php
<?php
$i = 1;
do {
echo"The number is " . $i . "<br />";
}while (i > 10);
/*
输出: The number is 1;
*/
?>
循环关键字
continue 表示跳过本次循环,开始下一次循环。
break 示例
php
<?php
for ($i=1; $i <=5; $i++) {
echo "The number is " . $i . "<br />";
break;
}
/*
输出: The number is 1<br />
*/
?>
continue 示例
php
<?php
for ($i=1; $i <=5; $i++) {
if ($i == 4) {
continue;
}
echo "The number is " . $i . "<br />";
}
/*
输出:
The number is 1
The number is 2
The number is 3
The number is 5
*/
?>
函数
无参函数
语法:
php
funciton 函数名() {
// 函数体代码
}
示例:
php
<?php
function test() {
echo "hello world";
}
// 定义函数之后,并不会立即执行函数,需要使用函数名()进行调用。
test(); // 调用函数
?>
有参函数
语法:
php
// 在定义的时候,传入的参数名叫做形参,如果在定义的时候,就指定了参数的值,那么在调用的时候,可以传入对应参数的值
function 函数名(参数1,参数2,参数3) {
// 函数体代码
}
示例:
php
<?php
function info($name = 'x1ong',$age = 17,$addr = '河南'){
echo "My name is " . $name;
echo "<br />";
echo "My age is " . $age;
echo "<br />";
echo "My address is " . $addr;
echo "<br />";
echo "<hr />";
}
info(); // 使用默认函数 参数的值使用默认值
info('lulu',18,'henan'); // 这里写入的参数叫做实参 如果给函数传入了值那么就不再使用默认参数的值
info('test','18','文件','10',10,30,40,50,60); // 参数可以多,但是不能少
function login($name,$password){
echo "username is : " . $name;
echo "<br />";
echo "password is : " . $password;
}
login('x1ong','Admin123'); // 实参可以多于形参,但是实参不能少于形参
// 从一个将实参中的数字作为形参的参数数组。
function admin(...$arr){
var_dump($arr);
echo "<br />";
}
admin(1,'hello','world','admin','xxx');
// 将实参中的数字打散按位填充作为形参的值,
function arr($name,$age,$addr,$gender){
echo $name;
echo "<br />";
echo $age;
echo "<br />";
echo $addr;
echo "<br />";
echo $gender;
echo "<br />";
}
arr(...['x1ong',17,'henan','sex']);
?>
匿名函数
php
<?php
$x1ong = function (){
echo "helloworld";
};
$x1ong();
?>
内置函数
数学函数
php
# 随机数:
rand() # 产生一个随机整数
mt_rand() # 更好的产生一个随机数
# 小数:
floor() # 舍去法取整
ceil() # 进1法取整
round() # 四舍五入取整
# 其他:
abs() # 取绝对值
pi() # 无参 获取pi的值
# M_PI 常量 获取的值跟pi() 的值一致。
min() # 返回数组中的最小数
max() # 返回数组中的最大数
字符串函数
php
# 大小写转换:
strtolower() # 将所有字母转换为小写
strtouppper() # 将所有字母转换为大写
lcfirst() # 将首字母小写
ucfirst() # 将首字母大写
ucwords() # 每个单词的首字母大写,默认以空格区分单词,可以指定
# 空白处理:
trim() # 首尾去空,可以指定去除的字符
ltrim() # 只取出左边的空白字符,可以指定去除的字符
rtrim() # 别名chop() 去除右边的空白字符,可以指定去除的字符
# 查找定位:
strstr() # 别名strchr() 查找字符串首次出现的位置,如果存在则返回之后的所有字符串,否则返回false
stristr() # 不区分大小写的strstr()
strrchar() # 查找字符串最后一次出现的位置,如果存在则返回之后的所有字符,否则返回false
strpos() # 返回字符串首次出现的位置
stripos() # strpos的忽略大小写版本
strrpos() # 返回字符串最后一次出现的位置
strripos() # strrpos()的忽略大小写版本
substr() # 返回字符串的子串(截取字符串)
# 比较:
strcmp() # 二进制比较字符串
strcasecmp() # strcmp() 忽略大小写的版本
strnatcmp() # 自然顺序比较
strnatcasecmp() # strnatcmp()忽略大小写版本
# 顺序:
str_shuffle() # 随意打乱字符串
strev() # 反转字符串
# 转换:
char() # 将ascii转换为字符
ord() # 将字符串的首字母转换为ascii码
时间函数
date() 函数把时间戳格式的数字,转为可读性更好的时间格式
配置时区函数:
php
<?php
date_default_timezone_set('RPC'); // 设置当前时区为中国标准时间 默认为UTC
?>
配置时区 配置文件
php
date.timezone = "asia/shanghai"
示例:
php
<?php
echo time();
date_default_timezone_set('PRC'); // 设置当前时区为中国标准时间,默认为UTC,比中国慢了8个小时,该配置只对当前php文件生效,对所有文件生效需要修改配置文件。
echo '<br />';
echo date_default_timezone_get() ; // 获取当前的时区
echo '<br />';
echo date('Y-m-d h:i:s'); // 格式化时间戳,如果不指定,默认为当前时间
/*
输出:
1691749048
PRC
2023-08-11 06:17:28
*/
?>
文件包含
文件包含主要指,将其他文件的代码引入到当前页面之中。这就叫做文件包含。include() 程序执行到include时才会进行文件包含,如果找不到包含的文件路径,则只会发出警告继续执行后面的代码。
include_once() 与 include() 基本一致,但是 include_once 遇到已经包含过的文件不会重复包含,而 include() 会。
require() 和 include() 基本一致 但是require()包含的文件如果不存在,则程序就会停止执行。
require_once() 和 include_once() 基本一致,不同的是 require_once() 包含的文件如果不存在,程序则会终止执行。
php
<?php
include 'filename1.php';
require 'filename2.php';
?>
数组类型
数组的取值
php
<?php
$arr = array(1,3,'hello',true);
echo $arr[0]; // 1
echo $arr[1]; // 3
echo $arr[2]; // hello
// 数组元素的赋值
$arr[2] = 'world';
echo $arr[2]; // world
?>
php
<?php
$arr = array(
'name' => 'x1ong',
'age' => 10,
'address' => 'HN'
);
echo $arr['name']; // x1ong
echo $arr['age']; // 10
echo $arr['address']; // HN
?>
php
<?php
$info = array(
'name' => ['x1ong','xiaoming','xiaohong','xiaoliang'],
'age' => [10,9,8,7],
'address' => ['JX','HN','BJ','CQ']
);
echo $info['name'][0] . "<br />";
echo $info['age'][0] . "<br />";
echo $info['address'][0] . "<br />";
?>
php
<?php
$info = array(
'student' => array(
'names' => ['x1ong','xiaoming','xiaohong'],
'age' => [10,9,8,7],
'address' => ['BJ','HN','SH','CQ']
),
);
echo $info['student']['names'][0] . "<br />";
echo $info['student']['age'][0] . "<br />";
echo $info['student']['address'][0] . "<br />";
?>
数组的遍历
遍历索引数组的值
php
<?php
$arr = ['x1ong','xiaoming','xiaohong','xiaoliang'];
$length = count($arr); // 计算数组的长度
$flag = 0;
while ($flag < $length){
echo $arr[$flag] . "<br />";
$flag++;
}
/*
输出:
x1ong
xiaoming
xiaohong
xiaoliang
*/
?>
遍历关联数组的值
php
<?php
$arr = array(
'name' => 'x1ong',
'age' => 17,
'addr' => 'China',
);
foreach ($arr as $key => $value) {
echo $key . '=' . $value . "<br />";
}
/*
输出:
name=x1ong
age=17
addr=China
*/
?>
数组相关的函数
php
# key和value相关函数
array_keys() # 获取数组的key
array_values() # 获取数组的value
array_flip() # 交换数组中key和value的位置,原本的key变value,value变key
in_array() # 判断某个值是否在数组中
array_search() # 在数组中搜索某个值,在则返回它的key,不在则返回false
array_key_exists() # 判断某个键是否在某个数组中,返回值true和false
count() # 获取数组中元素的个数
array_change_key_case(array,case) # 将数组中的所有key转为全大写或小写 ,case值为CASE_UPPER或CASE_LoWER(默认值)
array_count_values() # 计算数组中值出现的次数。
array_key_first() # 得到数组中第一个key名
array_key_lsast() # 得到数组中最后一个key名
array_pop() # 弹出数组中的最后一个元素
array_push() # 将一个单元或多个单元压入数组的末尾
array_unshfit() # 将一个单元或多个压入数组的开始
array_reverse() # 将数组反转
array_sum() # 对数组中的数值进行求和。
array_product() # 对数组中的数值求乘积
array_unique() # 删除数组中重复的值
shuffle() # 随便排序一个数组
array_rand() # 从数组中随机取出一个或多个随机键
超全局变量
超全局变量在 php4.1.0 以后被启用,是 php 的内置变量,在脚本的任意位置都可以访问到该变量 php 的超全局变量列表
| |
|---|
$GLOBALS | 存放了所有全局变量的数组, key 就是变量的名称 |
$_SERVER | |
$_REQUEST | 用于收集通过 GET 或 POST 提交的参数和值 |
$_POST | 接受所有来自 POST 传输的参数,参数名为 key ,值为 value |
$_GET | 接受所有来自 GET 传输的参数,参数名为key,值为value |
$_FILES | |
$_ENV | |
$_COOKIE | 接收请求头中的 Cookie 字段的 key 和 value |
Cookie
Cookie 的简介
cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏览器请求页面时,这台计算机将会发送 cookie。通过 PHP,您能够创建并取回 cookie 的值。
创建 Cookie
setcookie() 函数用于设置 cookie。注释:setcookie() 函数必须位于 <html> 标签之前。
语法:
php
setcookie(name, value, expire, path, domain);
示例一:
在下面的例子中,我们将创建名为 “user“ 的 cookie,并为它赋值 “admin“。我们也规定了此 cookie 在一小时后过期:
php
<?php
setcookie("user", "admin", time()+3600);
?>
<html>
...
如何取回 Cookie 的值
php
<?php
// 输出 cookie 值
echo $_COOKIE["user"];
// 查看所有 cookie
print_r($_COOKIE);
?>
如何删除 Cookie
php
<?php
// 设置 cookie 过期时间为过去 1 小时
setcookie("user", "", time()-3600);
?>
Session
session 的简介
session 和 cookie都是一种会话控制,都是跟踪用户会话的技术手段。而会话就是服务器和客户端的一次次通话。
session与cookie的几个重要区别:
- session 在服务端,而 cookie 在客户端存储
- cookie 在本地,可以随便修改,因此 session 更安全
- cookie 在本地,可以永久有效,但是 session 在服务器,如果设置永久有效,随着用户的增多,那么会导致内存溢出。
- session 会在一段时间内保存到你的服务器,如果服务器追求访问速度,那么不推荐使用 session
- cookie 需要浏览器支持,而 session 不需要。
使用 session
**1. 在每个文件中每次使用 session 之前需要开启 session **
php
<?php
session_start();
?>
2. 设置 session
php
<?php
// ...
if ( $result['username'] === $in_username && $result['password'] === $in_password ) {
// 设置 session
$_SESSION['username'] = $in_username;
}
// ...
?>
3. 销毁 session
php
<?php
// 使用 session_destroy() 进行销毁
session_destroy(); // 销毁一个会话中的全部数据
// 使用 unset() 函数销毁
unset($_SESSION['uname']);
?>
文件操作
文件的读取
readfile()
**语法: ** readfile(filename)
作用: 将一个文件的文件内容读取出来,并输出。
php
<?php
readfile('1.txt');
?>
file()
语法:file(filename, flags 可选参数)
作用: 把整个文件内容读入到一个索引数组中。以行进行分割。
php
<?php
print_r(file('1.txt'));
/*
Array
(
[0] => helloworld
[1] => 你好世界
)
*/
?>
file_get_contents()
语法:file_get_contents(filename, ...可选参数)
作用: 将整个文件的内容读取到一个字符串。
php
<?php
echo file_get_contents('1.txt');
?>
文件的创建及写入
file_put_contents()
语法:file_put_contents(filename,data,...可选参数)
作用: 将数据写入到文件
php
<?php
file_put_contents('flag.txt','helloworld'); // 此时创建文件flag.txt 内容为 helloworld
?>
fopen() 相关
语法:file(filename, mode,...可选参数)
作用: 打开文件或者 URL
文件打开模式:
| |
|---|
r | |
r+ | |
'w' | 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建。 |
'w+' | |
'a' | 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。在这种情况下,fseek() 没有效果,写入总是追加。 |
'a+' | 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。在这种情况下,fseek() 只相应读取位置,写入总是追加。 |
php
<?php
// 1. 打开文件
$file = fopen('2.txt','w');
// 2. 写入文件内容
fwrite($file,'helloworld');
// 3. 关闭文件
fclose($file);
?>
这里也可以通过fseek()改变文件读取位置的指针,也可以使用fread()函数做文件的读取。
PHP类和对象基础
基础概念
类是对一个类别的抽象概念,而具体的则是对象,比如汽车就是一个类
而对象则是我的宝马,而不是宝马,宝马也是一个类,对象是一个具体到每个事物
PHP官方解释: 类是对象的抽象,对象是类的具像(具体对象)
如何创建一个类:
使用class关键字进行创建,Class ClassName{}
php
<?php
class Demo {
// 这里面是类中的内容
}
?>
类中的成员
成员属性 —> 变量(在类中定义的变量称之为属性)行为 –> 成员方法(在类中定义的函数称之为方法)
类名的命名规范:
类名通常使用大驼峰式命名法persontest 的大驼峰命名法就是PersonTest 小驼峰命名法就是personTest
创建一个demo类
php
<?php
class Demo {
public $name = 'x1ong';
public function eat() {
echo $this->name . '在吃饭!';
}
}
// 初始化(实例化)这个Demo类
$obj = new Demo;
// 调用类中的eat方法
$obj->eat(); // 输出: x1ong在吃饭
?>
类的继承
继承的好处:
- 子类继承了父类,那么就拥有了父类可以有的属性和方法
- 子类拥有父亲的所有可以拿到的属性,还有自己独特的属性
继承的语法:
php
class 子类名 extends 父类名 {}
php
<?php
// 父类
class Person {
public $name = 'x1ong';
public function addInfo() {
echo "<h1>这是一个没用的信息</h1>";
}
}
// SubClass子类继承Person
class SubClass extends Person {
}
// 实例化子类
$obj = new SubClass();
// 子类可以直接调用父类的公有方法
$obj->addInfo();
// 子类可以直接调用父类的公有属性
echo $obj->name;
?>
类的访问权限
public 公用的,可以在外部访问、类内部访问、被继承。protected 受保护的,可以在类内部访问,可以被继承,不能在类外部访问。private 私有的,只能在类的内部访问,不可以被继承,不可以在类外部访问。
在类中的属性必须要加上访问权限,如果没有则会报错。 在类中的方法,可以不加访问权限,默认则为public。
以下使用属性演示访问权限,方法的访问权限一致:
php
<?php
// 父类
class Person {
public $name = 'x1ong';
protected $id = '41282820020327xxxx';
private $position = '计算机从业人员';
}
// SubPerson继承父类Proson
class SubPerson extends Person {
function __construct() {
// public 可以在外部访问、类内部访问、被继承
echo '我父亲的名字为: ' . $this->name . PHP_EOL;
// protected 可以在类内部访问,可以被继承,不能在类外部访问
echo '我父亲的身份证号为: ' . $this->id . PHP_EOL;
// provate 只能在类的内部访问,不可以被继承,不可以在类外部访问。
// echo '我父亲的职位为: ' . $this->position . PHP_EOL;
}
}
$obj = new SubPerson;
// 外部访问public 可以
echo $obj->name;
// 外部访问protected 不可以
echo $obj->id;
// 外部访问private 不可以
// echo $obj->position;
?>
类中方法的重写
重写的前置知识
重写方法也叫做重载重写的作用: 父类的方法不适合子类使用,那么这个时候子类可以重写父类的方法重写一般分为两种:
子类调用的方法是子类重写后的方法,父类还是调用父类的方法
在子类中如果想要调用父类的方法,就需要使用parent关键字,其语法如下:
php
parent::FunctionName();
php
<?php
// 父类
class Person {
public $name = 'x1ong';
function jump() {
echo '我能跳3米';
}
}
// SubPerson 继承父类Person
class SubPerson extends Person {
// 魔术方法: __construct 当对象被实例化的时候自动调用
function __construct() {
// 子类调用父类的方法 使用parent关键字
parent::jump();
}
}
$obj = new SubPerson;
?>
完全重写
完全重写:不使用父类的方法,直接在子类中重写定义一个相同的方法名。
php
<?php
class Person{
function jump() {
echo '我能跳3米' . PHP_EOL;
}
}
class SubPerson extends Person {
function jump() {
echo '我能跳9米' . PHP_EOL;
}
}
$obj = new SubPerson;
$obj->jump(); // 我能跳9米
$obj2 = new Person;
$obj2->jump(); // 我能跳3米
?>
子类调用的方法是子类重写后的方法,父类还是调用父类的方法
在父类方法的基础上强化
在父类方法的基础上增加一些额外的功能
php
<?php
class Person {
function work() {
echo '我工作勤勤恳恳' . PHP_EOL;
}
}
class SubPerson extends Person {
function work() {
// 调用父类方法
parent::work();
// 在父类的基础上增加功能
echo "我恋爱认认真真" . PHP_EOL;
}
}
$obj = new SubPerson;
$obj->work();
?>
重写的权限只能放大
重写方法的访问权限只能放大,不能缩写。
缩小化报错代码:
php
<?php
class Person {
public function work() {
echo '我工作勤勤恳恳' . PHP_EOL;
}
}
class SubPerson extends Person {
// 从父类的public降级到protected 权限缩小化 报错!!!
protected function work() {
// 完全重写
echo '我恋爱认认真真' . PHP_EOL;
}
}
?>
放大化正常代码:
php
<?php
class Person {
private function work() {
echo '我工作勤勤恳恳' . PHP_EOL;
}
}
class SubPerson extends Person {
// 从父类的private升级到protected 权限放大化 正常!!!
protected function work() {
// 完全重写
echo '我恋爱认认真真' . PHP_EOL;
}
}
?>
final 关键字
在定义类的时候,前面加上 final 关键字,表示该类内部的属性和方法不能被继承,在定义方法的前面加上 final 表示该函数不能被重写
无法继承的类
php
<?php
final class Person {
public $name = "x1ong";
public function eat() {
echo $this->name . "正在吃饭";
}
}
// 报错代码: Fatal error: Class subClass may not inherit from final class (Person)
class subClass extends Person {
}
无法重写的方法
php
<?php
class Person {
public $name = "x1ong";
final public function eat() {
echo $this->name . "正在吃饭";
}
}
class subClass extends Person {
// 报错代码: Fatal error: Cannot override final method Person::eat()
public function eat() {
// ...
}
}
类常量
基础概念
类常量,也就是定义在类中的常量,在类的外部可以使用 define 和 const 进行定义常量
php中我们可以理解为值不变的量叫作常量,那么,什么又是类常量呢?其实类常量也很容易理解,我们可以把类中始终保持不变的值称为常量,如果该常量定义在类中就可以称之为类常量。一定要记得在定义和使用常量的时候不需要使用 $ 符号。
常量定义方法:
php
<?php
// 定义常量式1:
define("USER","root");
echo USER;
// 定义常量方式2:
const NAME = 'x1ong';
echo NAME;
?>
类常量的定义方法:
在类内部只能使用 const 定义常量,因此推荐在类外部使用 define 进行定义常量,在类的内部使用const关键字进行定义。
php
<?php
class Demo {
// 类常量的定义方式
const NAME = 'x1ong';
}
类常量的调用方式
在类的内部:
php
// self::常量名 或者 $this::常量名
在类的外部:
php
// 类名::常量名 或者 $obj_name::常量名
php
<?php
class Conn {
const USERNAME = 'root';
const PASSWORD = 'toor';
function config() {
// 类内调用
echo '用户名: ' . self::USERNAME . PHP_EOL;
echo '密码: ' . $this::PASSWORD . PHP_EOL;
}
}
$obj = new Conn;
$obj->config();
// 类外调用
echo Conn::USERNAME . PHP_EOL;
echo $obj::PASSWORD . PHP_EOL;
静态属性和静态方法
基础概念
static 关键字如果用来修饰属性或者方法时,那么该属性是属于整个类的,而不是属于某个对象,因此可以直接通过类名调用。
php
<?php
class Demo {
// 定义静态属性
static public $name = 'x1ong';
// 定义静态方法
static function msg() {
echo 'My name is ' . self::$name;
}
}
$obj = new Demo;
// 类外访问
Demo::msg();
调用方式
在类的内部调用静态属性:
php
// self::$静态属性名
在类的外部调用静态属性:
php
// 类名::$静态属性名 或者 $obj_name::$静态属性名
在类的内部调用静态方法:
php
// self::静态方法名() 或者 类名::静态方法名() static::静态方法名()
在类的外部调用静态方法:
php
// 类名::静态方法名() 或者 $obj_name::静态方法名()
php
<?php
class Demo {
static public $name = 'x1ong';
static public $age = 18;
function msg() {
// 类内部调用
echo 'My name is ' . self::$name . PHP_EOL;
echo 'MY age is ' . $this::$age . PHP_EOL;
}
static function info() {
echo 'hello world' . PHP_EOL;
}
}
$obj = new Demo;
$obj->msg();
// 类外访问
Demo::info();
$obj::info();
魔术方法
__construct()
触发条件:构造函数,当一个类被实例化的时候自动调用 参数: 任意长度的参数,常用于初始化属性的值
php
<?php
class Demo {
public $name;
public $age;
public $gender;
function __construct($name,$age,$gender) {
// 属性初始化
$this->name = $name;
$this->age = $age;
$this->gender = $gender;
}
}
$obj = new Demo('x1ong',17,'male'); // 实例化(初始化)类
echo $obj->name;
echo $obj->age;
echo $obj->gender;
?>
__destruct()
触发条件: 析构函数,在对象的所有引用被删除或者当对象被销毁时执行的魔术方法。 参数: 无参数
php
<?php
class Demo {
function msg() {
echo '这是一条无用的信息' . "<br />";
}
function __destruct() {
echo '我是__destruct()执行的内容' . "<br />";
}
}
$obj = new Demo; // 执行1次
$obj->msg();
echo 'helloworld' . "<br />";
// 序列化和反序列化
$ser = serialize($obj);
unserialize($ser); // 执行2次
?>
__toString()
触发条件: 当对象被 echo(被作为字符串输出) 时触发 一般情况下,该函数都需要有return 参数:无参数
php
<?php
class Demo {
function __toString() {
return '我是当对象被echo的时候执行的函数 __toString';
}
}
$obj = new Demo;
echo $obj;
?>
__invoke()
触发条件:当对象被当成函数时调用
php
<?php
class Demo {
function __invoke() {
echo '我是对象被当做函数调用时执行的__invoke()';
}
}
$obj = new Demo;
$obj();
__get()
触发条件: 当对象从外部访问一个不存在(或不可访问)的属性时调用该方法 参数: $name 该值为访问的属性名
php
<?php
class Demo {
private $name = 'x1ong';
function __get($name) {
echo '你访问的属性值不存在或不可访问,访问名称为: ' . $name;
}
}
$obj = new Demo;
echo $obj->name;
?>
__set()
触发条件: 当对象对外部设置一个不存在(或不可访问)的属性时调用该方法 参数: 形参2个 例如 value 该值分别为访问的属性和设置的值。
在类的外部可以为类的属性重新赋值:
php
<?php
class Demo {
public $name = 'x1ong';
}
$obj = new Demo;
echo $obj->name . PHP_EOL; // x1ong
// 为类的属性name重新赋值
$obj->name = 'pony';
echo $obj->name . PHP_EOL; // pony
?>
但是遇到了访问不到的属性,一旦为他们重新赋值则会报错:
php
<?php
class Demo {
protected $name = 'x1ong';
}
$obj = new Demo;
echo $obj->name . PHP_EOL; // x1ong
// 为类的属性重新赋值 报错 !!! 原因:外部访问不到protected
$obj->name = 'pony';
?>
那么如何为外部访问不到的属性重新赋值呢,这个时候就需要用到魔术方法__set():
php
<?php
class Demo {
// 受保护的属性 类的外部访问不到
protected $name = 'x1ong';
function __set($name,$value) {
// 在类的内部为属性重新赋值
$this->name = $value;
echo $this->name . PHP_EOL;
echo '当设置一个类外无法访问的属性时,自动调用__set()方法' . PHP_EOL;
}
}
$obj = new Demo;
// 为类的属性重新赋值
$obj->name = 'pony';
?>
__clone()
触发条件: 在克隆一个对象的时候调用 在这里可以对克隆出来的对象属性做一些操作 参数:无
php
<?php
class Demo {
public $name;
public $age;
public $gender;
function __construct($name,$age,$gender) {
$this->name = $name;
$this->age = $age;
$this->gender = $gender;
}
function __clone() {
echo '我在对象被克隆的时候调用: __clone()' . PHP_EOL;
}
}
$obj = new Demo('x1ong',18,'male');
$obj2 = clone $obj; // 克隆一个对象
echo $obj2->name; // x1ong
?>
__call()
触发条件:在调用一个不存在的方法时调用 参数:args2(传入的参数值,是个数组)
php
<?php
class Demo {
function __call($args1,$args2) {
echo '我是调用对象的一个不存在的方法时执行的__call()';
echo $args1 . PHP_EOL;
print_r($args2);
}
}
$obj = new Demo;
$obj->addInfo(1,2,3);
__callStatic()
触发条件:当调用不存在的静态方法时 参数:args2
php
<?php
class Demo {
static function __callStatic($name, $arguments) {
echo '我是当调用一个不存在的静态方法时执行的__callStatic()' . PHP_EOL;
echo '调用的静态方法名为' . $name . PHP_EOL;
echo '传入的参数为:' . PHP_EOL;
print_r($arguments);
}
}
$obj = new Demo;
Demo::config('root');
__isset()
触发条件:对不可访问或不存在属性使用isset()或者empty()的时候触发 参数:$args1(不存在的成员属性名称)
php
<?php
class Demo {
function __isset($name) {
echo '我是当对不可访问属性使用isset()或者empty()的时候触发的__isset()' . PHP_EOL;
echo '访问的属性名为' . $name . PHP_EOL;
}
}
$obj = new Demo;
// 触发一次 __isset()
isset($obj->x1ong);
// 触发一次 __isset()
empty($obj->name);
__unset()
触发条件:对不可访问或不存在的属性使用unset()时触发 参数:$args1(不可访问或者不存在的属性名称)
php
<?php
class Demo {
function __unset($name) {
echo '我是对不可访问或不存在的属性使用unset()时触发__unset()' . PHP_EOL;
echo '访问的属性名为' . $name . PHP_EOL;
}
}
$obj = new Demo;
// 触发点
unset($obj->name);
抽象类和接口
前置知识
- 抽象类的定义和普通类定义是一样的,只不过前面加上了一个关键字:
abstract - 抽象类里面一般都要有抽象方法,抽象方法一般都是让子类实现的。并且子类必须实现,不实现就报错
- 抽象方法如果有参数,参数有默认值,那么实现该方法时候的参数名一致,并且如抽象方法有默认值,
- 抽象类可以继承抽象类,子类在实现的时候所有抽象方法都要实现
普通类
php
<?php
class Demo {
public $name;
function __construct($name) {
$this->name = $name;
echo $this->name;
}
}
$obj = new Demo("x1ong");
?>
抽象类
php
<?php
// 定义一个抽象类
abstract class Grandpa {
abstract public function medal();
}
数据库操作
mysqli 连接数据库
面向过程数据库连接示例
php
<?php
$host = 'localhost';
$username = 'root';
$password = 'toor';
$db = 'mysql';
// 创建连接
$conn = @mysqli_connect($host, $username, $password, $db);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "数据库连接成功";
?>
面向过程登录页面示例
php
<?php
$db_host = 'localhost';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';
// 创建连接
$conn = mysqli_connect($db_host, $db_user, $db_pass, $db_database);
// 检测连接
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$username = addslashes($_POST['username']);
$password = md5($_POST['password']);
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = mysqli_query($conn, $sql);
$rows = mysqli_fetch_assoc($result);
if ($rows['username'] === $username && $rows['password'] === $password) {
echo "<script>alert('登录成功!欢迎用户: {$username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
</body>
</html>
面相对象数据库连接实例
php
<?php
// 数据库连接信息
$db_host = '127.0.0.1';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';
// 创建连接
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_database);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "数据库连接成功";
?>
面向对象登录页面示例
php
<?php
// 数据库连接信息
$db_host = '127.0.0.1';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';
// 创建连接
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_database);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$username = addslashes($_POST['username']);
$password = md5($_POST['password']);
$sql = "SELECT * FROM users WHERE username='$username' AND password='$password'";
$result = $conn->query($sql);
$rows = $result->fetch_assoc();
if ($rows['username'] === $username && $rows['password'] === $password) {
echo "<script>alert('登录成功!欢迎用户: {$username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
</body>
</html>
预处理语句登录页面示例
php
<?php
// 数据库连接信息
$db_host = '127.0.0.1';
$db_user = 'root';
$db_pass = 'toor';
$db_database = 'login';
// 创建连接
$conn = @new mysqli($db_host, $db_user, $db_pass, $db_database);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$in_username = $_POST['username'];
$in_password = md5($_POST['password']);
// 预处理
$sql = $conn->prepare("SELECT username,password FROM users WHERE username=? AND password=?");
// 绑定参数
$sql->bind_param('ss',$in_username, $in_password);
// 绑定结果
$sql->bind_result($username,$password);
// 执行语句
$sql->execute();
// 将结果与变量进行绑定
$sql->fetch();
// 关闭连接
$sql->close();
$conn->close();
if ($in_username === $username && $in_password === $password) {
echo "<script>alert('登录成功!欢迎用户: {$username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
</body>
</html>
预处理语句的工作原理:
- 预处理:创建 SQL 语句模板并发送到数据库。预留的值使用参数
"?" 标记 。例如:
sql
INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
- 数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出。
- 执行:最后,将应用绑定的值传递给参数(
"?" 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。
相比于直接执行SQL语句,预处理语句有两个主要优点:
- 预处理语句大大减少了分析时间,只做了一次查询(虽然语句多次执行)。
- 绑定参数减少了服务器带宽,你只需要发送查询的参数,而不是整个语句。
- 预处理语句针对SQL注入是非常有用的,因为参数值发送后使用不同的协议,保证了数据的合法性。
PDO 连接数据库
PDO 连接数据库登录示例
php
<?php
// 数据库配置信息
define("DB_TYPE", "mysql");
define("DB_HOST", "127.0.0.1");
define("DB_USER", "root");
define("DB_PASS", "toor");
define("DB_NAME", "login");
define("DB_PORT", "3306");
define("DB_CHARSET", "utf8");
// 定义dsn信息
$tpl = '%s:host=%s;dbname=%s;port=%s;cahrset=%s';
$args = [DB_TYPE, DB_HOST, DB_NAME, DB_PORT, DB_CHARSET];
$dsn = sprintf($tpl, ...$args);
// 创建数据库连接对象并检查连接
try {
$conn = new PDO($dsn, DB_USER, DB_PASS);
// 设置结果集的默认获取模式:只要关联部分
$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login page</title>
</head>
<body>
<form method="post">
username: <input type="text" name="username" placeholder="请输入用户名">
<br>
password: <input type="password" name="password" placeholder="请输入密码">
<br>
<input type="submit" name="submit" value="login">
</form>
</body>
</html>
<?php
if (isset($_POST['username']) and isset($_POST['password']) and isset($_POST['submit'])) {
$in_username = $_POST['username'];
$in_password = md5($_POST['password']);
$sql = "SELECT `username`,`password` FROM `users` WHERE `username` = ? AND `password` = ? LIMIT 0,1";
// 预处理语句
$stmt = $conn->prepare($sql);
// 绑定参数
$stmt->bindParam(1, $in_username);
$stmt->bindParam(2, $in_password);
// 执行sql语句
$stmt->execute();
// 获取结果集
$result = $stmt->fetch();
if ($result['username'] === $in_username && $result['password'] === $in_password) {
echo "<script>alert('登录成功!欢迎用户: {$in_username}')</script>";
}else {
echo "<script>alert('登录失败,用户名或密码错误!')</script>";
}
}
?>
文件上传操作
文件上传示例
php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<br>
<br>
<button>上传</button>
</form>
</body>
</html>
<?php
if (isset($_FILES['file'])) {
define("UPLOAD_PATH", "uploads/");
$fileName = $_FILES['file']['name'];
$tmpPath = $_FILES['file']['tmp_name'];
$allowExt = ['jpg', 'png', 'jpeg', 'gif'];
$fileExt = pathinfo($fileName)['extension'];
$filePath = UPLOAD_PATH . date('YmdHis') . rand(1,99) . "." . $fileExt;
if (is_uploaded_file($tmpPath)) {
if (in_array($fileExt, $allowExt)) {
if (move_uploaded_file($tmpPath, $filePath)) {
echo '<p style="color:red">上传成功</p>';
echo "<img src='$filePath' width='200' >";
}
}else {
echo '<p style="color:red">文件类型错误</p>';
}
}
}
?>